diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index fe38e8077..26e2402c7 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2673,6 +2673,10 @@ void DivEngine::setMidiBaseChan(int chan) { midiBaseChan=chan; } +void DivEngine::setMidiDirect(bool value) { + midiIsDirect=value; +} + void DivEngine::setMidiCallback(std::function what) { midiCallback=what; } diff --git a/src/engine/engine.h b/src/engine/engine.h index 01bed21f8..938ed134c 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -196,6 +196,7 @@ class DivEngine { bool softLocked; bool firstTick; bool skipping; + bool midiIsDirect; int softLockCount; int ticks, curRow, curOrder, remainingLoops, nextSpeed; double divider; @@ -650,6 +651,9 @@ class DivEngine { // set MIDI base channel void setMidiBaseChan(int chan); + // set MIDI direct channel map + void setMidiDirect(bool value); + // set MIDI input callback // if the specified function returns -2, note feedback will be inhibited. void setMidiCallback(std::function what); @@ -715,6 +719,7 @@ class DivEngine { softLocked(false), firstTick(false), skipping(false), + midiIsDirect(false), softLockCount(0), ticks(0), curRow(0), diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index cf02fa6ae..619555ab5 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1597,7 +1597,11 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi switch (msg.type&0xf0) { case TA_MIDI_NOTE_OFF: { if (chan<0 || chan>=chans) break; - autoNoteOff(msg.type&15,msg.data[0]-12,msg.data[1]); + if (midiIsDirect) { + pendingNotes.push(DivNoteEvent(chan,-1,-1,-1,false)); + } else { + autoNoteOff(msg.type&15,msg.data[0]-12,msg.data[1]); + } if (!playing) { reset(); freelance=true; @@ -1608,9 +1612,17 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi case TA_MIDI_NOTE_ON: { if (chan<0 || chan>=chans) break; if (msg.data[1]==0) { - autoNoteOff(msg.type&15,msg.data[0]-12,msg.data[1]); + if (midiIsDirect) { + pendingNotes.push(DivNoteEvent(chan,-1,-1,-1,false)); + } else { + autoNoteOff(msg.type&15,msg.data[0]-12,msg.data[1]); + } } else { - autoNoteOn(msg.type&15,ins,msg.data[0]-12,msg.data[1]); + if (midiIsDirect) { + pendingNotes.push(DivNoteEvent(chan,ins,msg.data[0]-12,msg.data[1],true)); + } else { + autoNoteOn(msg.type&15,ins,msg.data[0]-12,msg.data[1]); + } } break; } diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 83649a310..b9e616da3 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -363,18 +363,26 @@ void FurnaceGUI::drawSettings() { ImGui::Text("MIDI input"); ImGui::SameLine(); String midiInName=settings.midiInDevice.empty()?"":settings.midiInDevice; + bool hasToReloadMidi=false; if (ImGui::BeginCombo("##MidiInDevice",midiInName.c_str())) { if (ImGui::Selectable("",settings.midiInDevice.empty())) { settings.midiInDevice=""; + hasToReloadMidi=true; } for (String& i: e->getMidiIns()) { if (ImGui::Selectable(i.c_str(),i==settings.midiInDevice)) { settings.midiInDevice=i; + hasToReloadMidi=true; } } ImGui::EndCombo(); } + if (hasToReloadMidi) { + midiMap.read(e->getConfigPath()+DIR_SEPARATOR_STR+"midiIn_"+stripName(settings.midiInDevice)+".cfg"); + midiMap.compile(); + } + ImGui::Text("MIDI output"); ImGui::SameLine(); String midiOutName=settings.midiOutDevice.empty()?"":settings.midiOutDevice; @@ -393,12 +401,13 @@ void FurnaceGUI::drawSettings() { if (ImGui::TreeNode("MIDI input settings")) { ImGui::Checkbox("Note input",&midiMap.noteInput); ImGui::Checkbox("Velocity input",&midiMap.volInput); - ImGui::Checkbox("Use raw velocity value (don't map from linear to log)",&midiMap.rawVolume); - ImGui::Checkbox("Polyphonic/chord input",&midiMap.polyInput); + // TODO + //ImGui::Checkbox("Use raw velocity value (don't map from linear to log)",&midiMap.rawVolume); + //ImGui::Checkbox("Polyphonic/chord input",&midiMap.polyInput); ImGui::Checkbox("Map MIDI channels to direct channels",&midiMap.directChannel); ImGui::Checkbox("Program change is instrument selection",&midiMap.programChange); - ImGui::Checkbox("Listen to MIDI clock",&midiMap.midiClock); - ImGui::Checkbox("Listen to MIDI time code",&midiMap.midiTimeCode); + //ImGui::Checkbox("Listen to MIDI clock",&midiMap.midiClock); + //ImGui::Checkbox("Listen to MIDI time code",&midiMap.midiTimeCode); ImGui::Combo("Value input style",&midiMap.valueInputStyle,valueInputStyles,7); if (midiMap.valueInputStyle>3) { if (midiMap.valueInputStyle==6) { @@ -1570,6 +1579,8 @@ void FurnaceGUI::syncSettings() { midiMap.read(e->getConfigPath()+DIR_SEPARATOR_STR+"midiIn_"+stripName(settings.midiInDevice)+".cfg"); midiMap.compile(); + + e->setMidiDirect(midiMap.directChannel); } #define PUT_UI_COLOR(source) e->setConf(#source,(int)ImGui::GetColorU32(uiColors[source]));