kind of MIDI output
This commit is contained in:
parent
45ce940d66
commit
f689409f02
7 changed files with 126 additions and 9 deletions
|
|
@ -790,13 +790,20 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
|||
}
|
||||
speedAB=false;
|
||||
playing=true;
|
||||
skipping=true;
|
||||
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->setSkipRegisterWrites(true);
|
||||
while (playing && curOrder<goal) {
|
||||
if (nextTick(preserveDrift)) return;
|
||||
if (nextTick(preserveDrift)) {
|
||||
skipping=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
int oldOrder=curOrder;
|
||||
while (playing && curRow<goalRow) {
|
||||
if (nextTick(preserveDrift)) return;
|
||||
if (nextTick(preserveDrift)) {
|
||||
skipping=false;
|
||||
return;
|
||||
}
|
||||
if (oldOrder!=curOrder) break;
|
||||
}
|
||||
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->setSkipRegisterWrites(false);
|
||||
|
|
@ -816,6 +823,7 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
|||
if (!preserveDrift) {
|
||||
ticks=1;
|
||||
}
|
||||
skipping=false;
|
||||
cmdStream.clear();
|
||||
}
|
||||
|
||||
|
|
@ -2864,6 +2872,16 @@ bool DivEngine::initAudioBackend() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (output->midiOut) {
|
||||
String outName=getConfString("midiOutDevice","");
|
||||
if (!outName.empty()) {
|
||||
// try opening device
|
||||
logI("opening MIDI output.\n");
|
||||
if (!output->midiOut->openDevice(outName)) {
|
||||
logW("could not open MIDI output device!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2876,6 +2894,12 @@ bool DivEngine::deinitAudioBackend() {
|
|||
output->midiIn->closeDevice();
|
||||
}
|
||||
}
|
||||
if (output->midiOut) {
|
||||
if (output->midiOut->isDeviceOpen()) {
|
||||
logI("closing MIDI output.\n");
|
||||
output->midiOut->closeDevice();
|
||||
}
|
||||
}
|
||||
output->quitMidi();
|
||||
output->quit();
|
||||
delete output;
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ struct DivChannelState {
|
|||
bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff;
|
||||
bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, noteOnInhibit, resetArp;
|
||||
|
||||
int midiNote;
|
||||
int midiNote, curMidiNote;
|
||||
|
||||
DivChannelState():
|
||||
note(-1),
|
||||
|
|
@ -129,7 +129,8 @@ struct DivChannelState {
|
|||
shorthandPorta(false),
|
||||
noteOnInhibit(false),
|
||||
resetArp(false),
|
||||
midiNote(-1) {}
|
||||
midiNote(-1),
|
||||
curMidiNote(-1) {}
|
||||
};
|
||||
|
||||
struct DivNoteEvent {
|
||||
|
|
@ -194,6 +195,7 @@ class DivEngine {
|
|||
bool cmdStreamEnabled;
|
||||
bool softLocked;
|
||||
bool firstTick;
|
||||
bool skipping;
|
||||
int softLockCount;
|
||||
int ticks, curRow, curOrder, remainingLoops, nextSpeed;
|
||||
double divider;
|
||||
|
|
@ -712,6 +714,7 @@ class DivEngine {
|
|||
cmdStreamEnabled(false),
|
||||
softLocked(false),
|
||||
firstTick(false),
|
||||
skipping(false),
|
||||
softLockCount(0),
|
||||
ticks(0),
|
||||
curRow(0),
|
||||
|
|
|
|||
|
|
@ -172,7 +172,49 @@ int DivEngine::dispatchCmd(DivCommand c) {
|
|||
if (cmdStreamEnabled && cmdStream.size()<2000) {
|
||||
cmdStream.push_back(c);
|
||||
}
|
||||
|
||||
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 (c.value!=DIV_NOTE_NULL) chan[c.chan].curMidiNote=c.value+12;
|
||||
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:
|
||||
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));
|
||||
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));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.chan=dispatchChanOfChan[c.dis];
|
||||
|
||||
return disCont[dispatchOfChan[c.dis]].dispatch->dispatch(c);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue