parent
859b2cf8db
commit
3906fc1dd4
|
@ -2138,10 +2138,12 @@ void DivEngine::noteOff(int chan) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivEngine::autoNoteOn(int ch, int ins, int note, int vol) {
|
void DivEngine::autoNoteOn(int ch, int ins, int note, int vol) {
|
||||||
//if (ch<0 || ch>=chans) return;
|
bool isViable[DIV_MAX_CHANS];
|
||||||
|
bool canPlayAnyway=false;
|
||||||
if (midiBaseChan<0) midiBaseChan=0;
|
if (midiBaseChan<0) midiBaseChan=0;
|
||||||
if (midiBaseChan>=chans) midiBaseChan=chans-1;
|
if (midiBaseChan>=chans) midiBaseChan=chans-1;
|
||||||
int finalChan=midiBaseChan;
|
int finalChan=midiBaseChan;
|
||||||
|
int finalChanType=getChannelType(finalChan);
|
||||||
|
|
||||||
if (!playing) {
|
if (!playing) {
|
||||||
reset();
|
reset();
|
||||||
|
@ -2149,16 +2151,55 @@ void DivEngine::autoNoteOn(int ch, int ins, int note, int vol) {
|
||||||
playing=true;
|
playing=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1. check which channels are viable for this instrument
|
||||||
|
DivInstrument* insInst=getIns(ins);
|
||||||
|
for (int i=0; i<chans; i++) {
|
||||||
|
if (ins==-1 || ins>=song.insLen || getPreferInsType(i)==insInst->type || getPreferInsSecondType(i)==insInst->type) {
|
||||||
|
if (insInst->type==DIV_INS_OPL) {
|
||||||
|
if (insInst->fm.ops==2 || getChannelType(i)==DIV_CH_OP) {
|
||||||
|
isViable[i]=true;
|
||||||
|
canPlayAnyway=true;
|
||||||
|
} else {
|
||||||
|
isViable[i]=false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isViable[i]=true;
|
||||||
|
canPlayAnyway=true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isViable[i]=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canPlayAnyway) return;
|
||||||
|
|
||||||
|
// 2. find a free channel
|
||||||
do {
|
do {
|
||||||
if ((ins==-1 || ins>=song.insLen || getPreferInsType(finalChan)==getIns(ins)->type || getPreferInsSecondType(finalChan)==getIns(ins)->type) && chan[finalChan].midiNote==-1) {
|
if (isViable[finalChan] && chan[finalChan].midiNote==-1 && getChannelType(finalChan)==finalChanType) {
|
||||||
chan[finalChan].midiNote=note;
|
chan[finalChan].midiNote=note;
|
||||||
|
chan[finalChan].midiAge=midiAgeCounter++;
|
||||||
pendingNotes.push(DivNoteEvent(finalChan,ins,note,vol,true));
|
pendingNotes.push(DivNoteEvent(finalChan,ins,note,vol,true));
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
if (++finalChan>=chans) {
|
if (++finalChan>=chans) {
|
||||||
finalChan=0;
|
finalChan=0;
|
||||||
}
|
}
|
||||||
} while (finalChan!=midiBaseChan);
|
} while (finalChan!=midiBaseChan);
|
||||||
|
|
||||||
|
// 3. find the oldest channel
|
||||||
|
int candidate=finalChan;
|
||||||
|
do {
|
||||||
|
if (isViable[finalChan] && getChannelType(finalChan)==finalChanType && chan[finalChan].midiAge<chan[candidate].midiAge) {
|
||||||
|
candidate=finalChan;
|
||||||
|
}
|
||||||
|
if (++finalChan>=chans) {
|
||||||
|
finalChan=0;
|
||||||
|
}
|
||||||
|
} while (finalChan!=midiBaseChan);
|
||||||
|
|
||||||
|
chan[candidate].midiNote=note;
|
||||||
|
chan[candidate].midiAge=midiAgeCounter++;
|
||||||
|
pendingNotes.push(DivNoteEvent(candidate,ins,note,vol,true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivEngine::autoNoteOff(int ch, int note, int vol) {
|
void DivEngine::autoNoteOff(int ch, int note, int vol) {
|
||||||
|
|
|
@ -89,6 +89,7 @@ struct DivChannelState {
|
||||||
bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, noteOnInhibit, resetArp;
|
bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, noteOnInhibit, resetArp;
|
||||||
|
|
||||||
int midiNote, curMidiNote, midiPitch;
|
int midiNote, curMidiNote, midiPitch;
|
||||||
|
size_t midiAge;
|
||||||
bool midiAftertouch;
|
bool midiAftertouch;
|
||||||
|
|
||||||
DivChannelState():
|
DivChannelState():
|
||||||
|
@ -135,6 +136,7 @@ struct DivChannelState {
|
||||||
midiNote(-1),
|
midiNote(-1),
|
||||||
curMidiNote(-1),
|
curMidiNote(-1),
|
||||||
midiPitch(-1),
|
midiPitch(-1),
|
||||||
|
midiAge(0),
|
||||||
midiAftertouch(false) {}
|
midiAftertouch(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -339,6 +341,7 @@ class DivEngine {
|
||||||
int reversePitchTable[4096];
|
int reversePitchTable[4096];
|
||||||
int pitchTable[4096];
|
int pitchTable[4096];
|
||||||
int midiBaseChan;
|
int midiBaseChan;
|
||||||
|
size_t midiAgeCounter;
|
||||||
|
|
||||||
blip_buffer_t* samp_bb;
|
blip_buffer_t* samp_bb;
|
||||||
size_t samp_bbInLen;
|
size_t samp_bbInLen;
|
||||||
|
@ -894,6 +897,7 @@ class DivEngine {
|
||||||
audioEngine(DIV_AUDIO_NULL),
|
audioEngine(DIV_AUDIO_NULL),
|
||||||
exportMode(DIV_EXPORT_MODE_ONE),
|
exportMode(DIV_EXPORT_MODE_ONE),
|
||||||
midiBaseChan(0),
|
midiBaseChan(0),
|
||||||
|
midiAgeCounter(0),
|
||||||
samp_bb(NULL),
|
samp_bb(NULL),
|
||||||
samp_bbInLen(0),
|
samp_bbInLen(0),
|
||||||
samp_temp(0),
|
samp_temp(0),
|
||||||
|
|
Loading…
Reference in a new issue