diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 431146f1a..2493d620d 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2621,6 +2621,10 @@ bool DivEngine::switchMaster() { return true; } +void DivEngine::setMidiCallback(std::function what) { + midiCallback=what; +} + void DivEngine::synchronized(const std::function& what) { BUSY_BEGIN; what(); diff --git a/src/engine/engine.h b/src/engine/engine.h index 8e20dd418..1fe93f345 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -244,6 +244,8 @@ class DivEngine { size_t totalProcessed; + std::function midiCallback=[](const TAMidiMessage&) -> bool {return false;}; + DivSystem systemFromFile(unsigned char val); unsigned char systemToFile(DivSystem val); int dispatchCmd(DivCommand c); @@ -635,6 +637,10 @@ class DivEngine { // switch master bool switchMaster(); + // set MIDI input callback + // if the specified function returns true, note feedback will be inhibited. + void setMidiCallback(std::function what); + // perform secure/sync operation void synchronized(const std::function& what); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 515ae8e6d..259209e4a 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1541,21 +1541,23 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi // process MIDI events (TODO: everything) if (output->midiIn) while (!output->midiIn->queue.empty()) { TAMidiMessage& msg=output->midiIn->queue.front(); - int chan=msg.type&15; - switch (msg.type&0xf0) { - case TA_MIDI_NOTE_OFF: { - if (chan<0 || chan>=chans) break; - pendingNotes.push(DivNoteEvent(msg.type&15,-1,-1,-1,false)); - break; - } - case TA_MIDI_NOTE_ON: { - if (chan<0 || chan>=chans) break; - pendingNotes.push(DivNoteEvent(msg.type&15,-1,(int)msg.data[0]-12,msg.data[1],true)); - break; - } - case TA_MIDI_PROGRAM: { - // TODO: change instrument event thingy - break; + if (!midiCallback(msg)) { + int chan=msg.type&15; + switch (msg.type&0xf0) { + case TA_MIDI_NOTE_OFF: { + if (chan<0 || chan>=chans) break; + pendingNotes.push(DivNoteEvent(msg.type&15,-1,-1,-1,false)); + break; + } + case TA_MIDI_NOTE_ON: { + if (chan<0 || chan>=chans) break; + pendingNotes.push(DivNoteEvent(msg.type&15,-1,(int)msg.data[0]-12,msg.data[1],true)); + break; + } + case TA_MIDI_PROGRAM: { + // TODO: change instrument event thingy + break; + } } } logD("%.2x\n",msg.type); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 7cbf10970..870e7de1b 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2628,6 +2628,11 @@ bool FurnaceGUI::init() { firstFrame=true; + // TODO + e->setMidiCallback([this](const TAMidiMessage& msg) -> bool { + return true; + }); + return true; } @@ -2907,4 +2912,4 @@ FurnaceGUI::FurnaceGUI(): memset(patChanX,0,sizeof(float)*(DIV_MAX_CHANS+1)); memset(patChanSlideY,0,sizeof(float)*(DIV_MAX_CHANS+1)); memset(lastIns,-1,sizeof(int)*DIV_MAX_CHANS); -} \ No newline at end of file +}