MIDI output improvements
This commit is contained in:
parent
c27c650c11
commit
122694d7c9
5 changed files with 117 additions and 47 deletions
|
|
@ -3683,6 +3683,8 @@ bool DivEngine::initAudioBackend() {
|
|||
clampSamples=getConfInt("clampSamples",0);
|
||||
lowLatency=getConfInt("lowLatency",0);
|
||||
metroVol=(float)(getConfInt("metroVol",100))/100.0f;
|
||||
midiOutClock=getConfInt("midiOutClock",0);
|
||||
midiOutMode=getConfInt("midiOutMode",DIV_MIDI_MODE_NOTE);
|
||||
if (metroVol<0.0f) metroVol=0.0f;
|
||||
if (metroVol>2.0f) metroVol=2.0f;
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,12 @@ enum DivHaltPositions {
|
|||
DIV_HALT_BREAKPOINT
|
||||
};
|
||||
|
||||
enum DivMIDIModes {
|
||||
DIV_MIDI_MODE_OFF=0,
|
||||
DIV_MIDI_MODE_NOTE,
|
||||
DIV_MIDI_MODE_LIGHT_SHOW
|
||||
};
|
||||
|
||||
struct DivChannelState {
|
||||
std::vector<DivDelayedCommand> delayed;
|
||||
int note, oldNote, lastIns, pitch, portaSpeed, portaNote;
|
||||
|
|
@ -340,6 +346,8 @@ class DivEngine {
|
|||
bool lowLatency;
|
||||
bool systemsRegistered;
|
||||
bool hasLoadedSomething;
|
||||
bool midiOutClock;
|
||||
int midiOutMode;
|
||||
int softLockCount;
|
||||
int subticks, ticks, curRow, curOrder, prevRow, prevOrder, remainingLoops, totalLoops, lastLoopPos, exportLoopCount, nextSpeed;
|
||||
size_t curSubSongIndex;
|
||||
|
|
@ -1008,6 +1016,8 @@ class DivEngine {
|
|||
lowLatency(false),
|
||||
systemsRegistered(false),
|
||||
hasLoadedSomething(false),
|
||||
midiOutClock(false),
|
||||
midiOutMode(DIV_MIDI_MODE_NOTE),
|
||||
softLockCount(0),
|
||||
subticks(0),
|
||||
ticks(0),
|
||||
|
|
|
|||
|
|
@ -257,52 +257,79 @@ int DivEngine::dispatchCmd(DivCommand c) {
|
|||
|
||||
if (output) if (!skipping && output->midiOut!=NULL) {
|
||||
if (output->midiOut->isDeviceOpen()) {
|
||||
int scaledVol=(chan[c.chan].volume*127)/MAX(1,chan[c.chan].volMax);
|
||||
if (scaledVol<0) scaledVol=0;
|
||||
if (scaledVol>127) scaledVol=127;
|
||||
switch (c.cmd) {
|
||||
case DIV_CMD_NOTE_ON:
|
||||
case DIV_CMD_LEGATO:
|
||||
if (chan[c.chan].curMidiNote>=0) {
|
||||
output->midiOut->send(TAMidiMessage(0x80|(c.chan&15),chan[c.chan].curMidiNote,scaledVol));
|
||||
if (midiOutMode==DIV_MIDI_MODE_NOTE) {
|
||||
int scaledVol=(chan[c.chan].volume*127)/MAX(1,chan[c.chan].volMax);
|
||||
if (scaledVol<0) scaledVol=0;
|
||||
if (scaledVol>127) scaledVol=127;
|
||||
switch (c.cmd) {
|
||||
case DIV_CMD_NOTE_ON:
|
||||
case DIV_CMD_LEGATO:
|
||||
if (chan[c.chan].curMidiNote>=0) {
|
||||
output->midiOut->send(TAMidiMessage(0x80|(c.chan&15),chan[c.chan].curMidiNote,scaledVol));
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].curMidiNote=c.value+12;
|
||||
if (chan[c.chan].curMidiNote<0) chan[c.chan].curMidiNote=0;
|
||||
if (chan[c.chan].curMidiNote>127) chan[c.chan].curMidiNote=127;
|
||||
}
|
||||
output->midiOut->send(TAMidiMessage(0x90|(c.chan&15),chan[c.chan].curMidiNote,scaledVol));
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
if (chan[c.chan].curMidiNote>=0) {
|
||||
output->midiOut->send(TAMidiMessage(0x80|(c.chan&15),chan[c.chan].curMidiNote,scaledVol));
|
||||
}
|
||||
chan[c.chan].curMidiNote=-1;
|
||||
break;
|
||||
case DIV_CMD_INSTRUMENT:
|
||||
if (chan[c.chan].lastIns!=c.value) {
|
||||
output->midiOut->send(TAMidiMessage(0xc0|(c.chan&15),c.value,0));
|
||||
}
|
||||
break;
|
||||
case DIV_CMD_VOLUME:
|
||||
if (chan[c.chan].curMidiNote>=0 && chan[c.chan].midiAftertouch) {
|
||||
chan[c.chan].midiAftertouch=false;
|
||||
output->midiOut->send(TAMidiMessage(0xa0|(c.chan&15),chan[c.chan].curMidiNote,scaledVol));
|
||||
}
|
||||
break;
|
||||
case DIV_CMD_PITCH: {
|
||||
int pitchBend=8192+(c.value<<5);
|
||||
if (pitchBend<0) pitchBend=0;
|
||||
if (pitchBend>16383) pitchBend=16383;
|
||||
if (pitchBend!=chan[c.chan].midiPitch) {
|
||||
chan[c.chan].midiPitch=pitchBend;
|
||||
output->midiOut->send(TAMidiMessage(0xe0|(c.chan&15),pitchBend&0x7f,pitchBend>>7));
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].curMidiNote=c.value+12;
|
||||
if (chan[c.chan].curMidiNote<0) chan[c.chan].curMidiNote=0;
|
||||
if (chan[c.chan].curMidiNote>127) chan[c.chan].curMidiNote=127;
|
||||
case DIV_CMD_PANNING: {
|
||||
int pan=convertPanSplitToLinearLR(c.value,c.value2,127);
|
||||
output->midiOut->send(TAMidiMessage(0xb0|(c.chan&15),0x0a,pan));
|
||||
break;
|
||||
}
|
||||
output->midiOut->send(TAMidiMessage(0x90|(c.chan&15),chan[c.chan].curMidiNote,scaledVol));
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
case DIV_CMD_NOTE_OFF_ENV:
|
||||
if (chan[c.chan].curMidiNote>=0) {
|
||||
output->midiOut->send(TAMidiMessage(0x80|(c.chan&15),chan[c.chan].curMidiNote,scaledVol));
|
||||
case DIV_CMD_HINT_PORTA: {
|
||||
if (c.value2>0) {
|
||||
if (c.value<=0 || c.value>=255) break;
|
||||
//output->midiOut->send(TAMidiMessage(0x80|(c.chan&15),chan[c.chan].curMidiNote,scaledVol));
|
||||
int target=c.value+12;
|
||||
if (target<0) target=0;
|
||||
if (target>127) target=127;
|
||||
|
||||
if (chan[c.chan].curMidiNote>=0) {
|
||||
output->midiOut->send(TAMidiMessage(0xb0|(c.chan&15),0x54,chan[c.chan].curMidiNote));
|
||||
}
|
||||
output->midiOut->send(TAMidiMessage(0xb0|(c.chan&15),0x05,1/*MIN(0x7f,c.value2/4)*/));
|
||||
output->midiOut->send(TAMidiMessage(0xb0|(c.chan&15),0x41,0x7f));
|
||||
|
||||
output->midiOut->send(TAMidiMessage(0x90|(c.chan&15),target,scaledVol));
|
||||
} else {
|
||||
output->midiOut->send(TAMidiMessage(0xb0|(c.chan&15),0x41,0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
chan[c.chan].curMidiNote=-1;
|
||||
break;
|
||||
case DIV_CMD_INSTRUMENT:
|
||||
if (chan[c.chan].lastIns!=c.value) {
|
||||
output->midiOut->send(TAMidiMessage(0xc0|(c.chan&15),c.value,0));
|
||||
}
|
||||
break;
|
||||
case DIV_CMD_VOLUME:
|
||||
if (chan[c.chan].curMidiNote>=0 && chan[c.chan].midiAftertouch) {
|
||||
chan[c.chan].midiAftertouch=false;
|
||||
output->midiOut->send(TAMidiMessage(0xa0|(c.chan&15),chan[c.chan].curMidiNote,scaledVol));
|
||||
}
|
||||
break;
|
||||
case DIV_CMD_PITCH: {
|
||||
int pitchBend=8192+(c.value<<5);
|
||||
if (pitchBend<0) pitchBend=0;
|
||||
if (pitchBend>16383) pitchBend=16383;
|
||||
if (pitchBend!=chan[c.chan].midiPitch) {
|
||||
chan[c.chan].midiPitch=pitchBend;
|
||||
output->midiOut->send(TAMidiMessage(0xe0|(c.chan&15),pitchBend&0x7f,pitchBend>>7));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1055,11 +1082,6 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
|||
cycles++;
|
||||
}
|
||||
|
||||
// MIDI clock
|
||||
if (output) if (!skipping && output->midiOut!=NULL) {
|
||||
//output->midiOut->send(TAMidiMessage(TA_MIDI_CLOCK,0,0));
|
||||
}
|
||||
|
||||
if (!pendingNotes.empty()) {
|
||||
bool isOn[DIV_MAX_CHANS];
|
||||
memset(isOn,0,DIV_MAX_CHANS*sizeof(bool));
|
||||
|
|
@ -1106,6 +1128,12 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
|||
if (!freelance) {
|
||||
if (--subticks<=0) {
|
||||
subticks=tickMult;
|
||||
|
||||
// MIDI clock
|
||||
if (output) if (!skipping && output->midiOut!=NULL && midiOutClock) {
|
||||
output->midiOut->send(TAMidiMessage(TA_MIDI_CLOCK,0,0));
|
||||
}
|
||||
|
||||
if (stepPlay!=1) {
|
||||
tempoAccum+=curSubSong->virtualTempoN;
|
||||
while (tempoAccum>=curSubSong->virtualTempoD) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue