mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-04 20:05:05 +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++) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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:
|
||||||
|
if (chan[c.chan].lastIns!=c.value) {
|
||||||
output->midiOut->send(TAMidiMessage(0xc0|(c.chan&15),c.value,0));
|
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;
|
||||||
|
if (pitchBend!=chan[c.chan].midiPitch) {
|
||||||
|
chan[c.chan].midiPitch=pitchBend;
|
||||||
output->midiOut->send(TAMidiMessage(0xe0|(c.chan&15),pitchBend&0x7f,pitchBend>>7));
|
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) {
|
||||||
|
|
Loading…
Reference in a new issue