MIDI out improvements

This commit is contained in:
tildearrow 2022-04-09 01:50:44 -05:00
parent 9e0e8f3345
commit 320250b831
3 changed files with 37 additions and 5 deletions

View file

@ -873,6 +873,11 @@ void DivEngine::play() {
for (int i=0; i<DIV_MAX_CHANS; i++) { for (int i=0; i<DIV_MAX_CHANS; i++) {
keyHit[i]=false; keyHit[i]=false;
} }
if (output) if (!skipping && output->midiOut!=NULL) {
int pos=totalTicksR/6;
output->midiOut->send(TAMidiMessage(TA_MIDI_POSITION,(pos>>7)&0x7f,pos&0x7f));
output->midiOut->send(TAMidiMessage(TA_MIDI_MACHINE_PLAY,0,0));
}
BUSY_END; BUSY_END;
} }
@ -918,6 +923,14 @@ void DivEngine::stop() {
for (int i=0; i<song.systemLen; i++) { for (int i=0; i<song.systemLen; i++) {
disCont[i].dispatch->notifyPlaybackStop(); disCont[i].dispatch->notifyPlaybackStop();
} }
if (output) if (output->midiOut!=NULL) {
output->midiOut->send(TAMidiMessage(TA_MIDI_MACHINE_STOP,0,0));
for (int i=0; i<chans; i++) {
if (chan[i].curMidiNote>=0) {
output->midiOut->send(TAMidiMessage(0x80|(i&15),chan[i].curMidiNote,0));
}
}
}
BUSY_END; BUSY_END;
} }

View file

@ -86,7 +86,8 @@ struct DivChannelState {
bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff; bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff;
bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, noteOnInhibit, resetArp; bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, noteOnInhibit, resetArp;
int midiNote, curMidiNote; int midiNote, curMidiNote, midiPitch;
bool midiAftertouch;
DivChannelState(): DivChannelState():
note(-1), note(-1),
@ -130,7 +131,9 @@ struct DivChannelState {
noteOnInhibit(false), noteOnInhibit(false),
resetArp(false), resetArp(false),
midiNote(-1), midiNote(-1),
curMidiNote(-1) {} curMidiNote(-1),
midiPitch(-1),
midiAftertouch(false) {}
}; };
struct DivNoteEvent { struct DivNoteEvent {

View file

@ -201,16 +201,24 @@ int DivEngine::dispatchCmd(DivCommand c) {
chan[c.chan].curMidiNote=-1; chan[c.chan].curMidiNote=-1;
break; break;
case DIV_CMD_INSTRUMENT: case DIV_CMD_INSTRUMENT:
output->midiOut->send(TAMidiMessage(0xc0|(c.chan&15),c.value,0)); if (chan[c.chan].lastIns!=c.value) {
output->midiOut->send(TAMidiMessage(0xc0|(c.chan&15),c.value,0));
}
break; break;
case DIV_CMD_VOLUME: case DIV_CMD_VOLUME:
//output->midiOut->send(TAMidiMessage(0xb0|(c.chan&15),0x07,scaledVol)); 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; break;
case DIV_CMD_PITCH: { case DIV_CMD_PITCH: {
int pitchBend=8192+(c.value<<5); int pitchBend=8192+(c.value<<5);
if (pitchBend<0) pitchBend=0; if (pitchBend<0) pitchBend=0;
if (pitchBend>16383) pitchBend=16383; if (pitchBend>16383) pitchBend=16383;
output->midiOut->send(TAMidiMessage(0xe0|(c.chan&15),pitchBend&0x7f,pitchBend>>7)); if (pitchBend!=chan[c.chan].midiPitch) {
chan[c.chan].midiPitch=pitchBend;
output->midiOut->send(TAMidiMessage(0xe0|(c.chan&15),pitchBend&0x7f,pitchBend>>7));
}
break; break;
} }
default: default:
@ -963,6 +971,9 @@ void DivEngine::processRow(int i, bool afterDelay) {
// volume // volume
if (pat->data[whatRow][3]!=-1) { if (pat->data[whatRow][3]!=-1) {
if (dispatchCmd(DivCommand(DIV_ALWAYS_SET_VOLUME,i)) || (MIN(chan[i].volMax,chan[i].volume)>>8)!=pat->data[whatRow][3]) { if (dispatchCmd(DivCommand(DIV_ALWAYS_SET_VOLUME,i)) || (MIN(chan[i].volMax,chan[i].volume)>>8)!=pat->data[whatRow][3]) {
if (pat->data[whatRow][0]==0 && pat->data[whatRow][1]==0) {
chan[i].midiAftertouch=true;
}
chan[i].volume=pat->data[whatRow][3]<<8; chan[i].volume=pat->data[whatRow][3]<<8;
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
} }
@ -1436,6 +1447,11 @@ bool DivEngine::nextTick(bool noAccum) {
cycles++; cycles++;
} }
// MIDI clock
if (output) if (!skipping && output->midiOut!=NULL) {
output->midiOut->send(TAMidiMessage(TA_MIDI_CLOCK,0,0));
}
while (!pendingNotes.empty()) { while (!pendingNotes.empty()) {
DivNoteEvent& note=pendingNotes.front(); DivNoteEvent& note=pendingNotes.front();
if (note.on) { if (note.on) {