MIDI input: program change pass-through option

This commit is contained in:
tildearrow 2023-12-17 15:30:51 -05:00
parent 39481ab571
commit 478f7bb3bd
7 changed files with 46 additions and 14 deletions

View file

@ -3392,6 +3392,10 @@ void DivEngine::setMidiDirect(bool value) {
midiIsDirect=value;
}
void DivEngine::setMidiDirectProgram(bool value) {
midiIsDirectProgram=value;
}
void DivEngine::setMidiVolExp(float value) {
midiVolExp=value;
}

View file

@ -176,16 +176,16 @@ struct DivNoteEvent {
signed char channel;
unsigned char ins;
signed char note, volume;
bool on, nop, pad1, pad2;
DivNoteEvent(int c, int i, int n, int v, bool o):
bool on, nop, insChange, fromMIDI;
DivNoteEvent(int c, int i, int n, int v, bool o, bool ic=false, bool fm=false):
channel(c),
ins(i),
note(n),
volume(v),
on(o),
nop(false),
pad1(false),
pad2(false) {}
insChange(ic),
fromMIDI(fm) {}
DivNoteEvent():
channel(-1),
ins(0),
@ -193,8 +193,8 @@ struct DivNoteEvent {
volume(-1),
on(false),
nop(true),
pad1(false),
pad2(false) {}
insChange(false),
fromMIDI(false) {}
};
struct DivDispatchContainer {
@ -415,6 +415,7 @@ class DivEngine {
bool firstTick;
bool skipping;
bool midiIsDirect;
bool midiIsDirectProgram;
bool lowLatency;
bool systemsRegistered;
bool hasLoadedSomething;
@ -1188,6 +1189,9 @@ class DivEngine {
// set MIDI direct channel map
void setMidiDirect(bool value);
// set MIDI direct program change
void setMidiDirectProgram(bool value);
// set MIDI volume curve exponent
void setMidiVolExp(float value);
@ -1260,6 +1264,7 @@ class DivEngine {
firstTick(false),
skipping(false),
midiIsDirect(false),
midiIsDirectProgram(false),
lowLatency(false),
systemsRegistered(false),
hasLoadedSomething(false),

View file

@ -1370,8 +1370,15 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
pendingNotes.pop_front();
continue;
}
if (note.insChange) {
dispatchCmd(DivCommand(DIV_CMD_INSTRUMENT,note.channel,note.ins,0));
pendingNotes.pop_front();
continue;
}
if (note.on) {
dispatchCmd(DivCommand(DIV_CMD_INSTRUMENT,note.channel,note.ins,1));
if (!(midiIsDirect && midiIsDirectProgram && note.fromMIDI)) {
dispatchCmd(DivCommand(DIV_CMD_INSTRUMENT,note.channel,note.ins,1));
}
if (note.volume>=0 && !disCont[dispatchOfChan[note.channel]].dispatch->isVolGlobal()) {
float curvedVol=pow((float)note.volume/127.0f,midiVolExp);
int mappedVol=disCont[dispatchOfChan[note.channel]].dispatch->mapVelocity(dispatchChanOfChan[note.channel],curvedVol);
@ -1832,7 +1839,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
case TA_MIDI_NOTE_OFF: {
if (chan<0 || chan>=chans) break;
if (midiIsDirect) {
pendingNotes.push_back(DivNoteEvent(chan,-1,-1,-1,false));
pendingNotes.push_back(DivNoteEvent(chan,-1,-1,-1,false,false,true));
} else {
autoNoteOff(msg.type&15,msg.data[0]-12,msg.data[1]);
}
@ -1847,13 +1854,13 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
if (chan<0 || chan>=chans) break;
if (msg.data[1]==0) {
if (midiIsDirect) {
pendingNotes.push_back(DivNoteEvent(chan,-1,-1,-1,false));
pendingNotes.push_back(DivNoteEvent(chan,-1,-1,-1,false,false,true));
} else {
autoNoteOff(msg.type&15,msg.data[0]-12,msg.data[1]);
}
} else {
if (midiIsDirect) {
pendingNotes.push_back(DivNoteEvent(chan,ins,msg.data[0]-12,msg.data[1],true));
pendingNotes.push_back(DivNoteEvent(chan,ins,msg.data[0]-12,msg.data[1],true,false,true));
} else {
autoNoteOn(msg.type&15,ins,msg.data[0]-12,msg.data[1]);
}
@ -1861,7 +1868,9 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
break;
}
case TA_MIDI_PROGRAM: {
// TODO: change instrument event thingy
if (midiIsDirect && midiIsDirectProgram) {
pendingNotes.push_back(DivNoteEvent(chan,msg.data[0],0,0,false,true,true));
}
break;
}
}