mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-23 21:15:11 +00:00
MIDI out improvements
This commit is contained in:
parent
9e0e8f3345
commit
320250b831
3 changed files with 37 additions and 5 deletions
|
@ -873,6 +873,11 @@ void DivEngine::play() {
|
|||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -918,6 +923,14 @@ void DivEngine::stop() {
|
|||
for (int i=0; i<song.systemLen; i++) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,8 @@ struct DivChannelState {
|
|||
bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff;
|
||||
bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, noteOnInhibit, resetArp;
|
||||
|
||||
int midiNote, curMidiNote;
|
||||
int midiNote, curMidiNote, midiPitch;
|
||||
bool midiAftertouch;
|
||||
|
||||
DivChannelState():
|
||||
note(-1),
|
||||
|
@ -130,7 +131,9 @@ struct DivChannelState {
|
|||
noteOnInhibit(false),
|
||||
resetArp(false),
|
||||
midiNote(-1),
|
||||
curMidiNote(-1) {}
|
||||
curMidiNote(-1),
|
||||
midiPitch(-1),
|
||||
midiAftertouch(false) {}
|
||||
};
|
||||
|
||||
struct DivNoteEvent {
|
||||
|
|
|
@ -201,16 +201,24 @@ int DivEngine::dispatchCmd(DivCommand c) {
|
|||
chan[c.chan].curMidiNote=-1;
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
case DIV_CMD_PITCH: {
|
||||
int pitchBend=8192+(c.value<<5);
|
||||
if (pitchBend<0) pitchBend=0;
|
||||
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;
|
||||
}
|
||||
default:
|
||||
|
@ -963,6 +971,9 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
// volume
|
||||
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 (pat->data[whatRow][0]==0 && pat->data[whatRow][1]==0) {
|
||||
chan[i].midiAftertouch=true;
|
||||
}
|
||||
chan[i].volume=pat->data[whatRow][3]<<8;
|
||||
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
|
||||
}
|
||||
|
@ -1436,6 +1447,11 @@ bool DivEngine::nextTick(bool noAccum) {
|
|||
cycles++;
|
||||
}
|
||||
|
||||
// MIDI clock
|
||||
if (output) if (!skipping && output->midiOut!=NULL) {
|
||||
output->midiOut->send(TAMidiMessage(TA_MIDI_CLOCK,0,0));
|
||||
}
|
||||
|
||||
while (!pendingNotes.empty()) {
|
||||
DivNoteEvent& note=pendingNotes.front();
|
||||
if (note.on) {
|
||||
|
|
Loading…
Reference in a new issue