parent
6f3b9f2e5d
commit
45ce940d66
7 changed files with 92 additions and 18 deletions
|
|
@ -2537,6 +2537,45 @@ void DivEngine::noteOff(int chan) {
|
|||
BUSY_END;
|
||||
}
|
||||
|
||||
void DivEngine::autoNoteOn(int ch, int ins, int note, int vol) {
|
||||
//if (ch<0 || ch>=chans) return;
|
||||
if (midiBaseChan<0) midiBaseChan=0;
|
||||
if (midiBaseChan>=chans) midiBaseChan=chans-1;
|
||||
int finalChan=midiBaseChan;
|
||||
|
||||
if (!playing) {
|
||||
reset();
|
||||
freelance=true;
|
||||
playing=true;
|
||||
}
|
||||
|
||||
do {
|
||||
if ((ins==-1 || getPreferInsType(finalChan)==getIns(ins)->type) && chan[finalChan].midiNote==-1) {
|
||||
chan[finalChan].midiNote=note;
|
||||
pendingNotes.push(DivNoteEvent(finalChan,ins,note,vol,true));
|
||||
break;
|
||||
}
|
||||
if (++finalChan>=chans) {
|
||||
finalChan=0;
|
||||
}
|
||||
} while (finalChan!=midiBaseChan);
|
||||
}
|
||||
|
||||
void DivEngine::autoNoteOff(int ch, int note, int vol) {
|
||||
if (!playing) {
|
||||
reset();
|
||||
freelance=true;
|
||||
playing=true;
|
||||
}
|
||||
//if (ch<0 || ch>=chans) return;
|
||||
for (int i=0; i<chans; i++) {
|
||||
if (chan[i].midiNote==note) {
|
||||
pendingNotes.push(DivNoteEvent(i,-1,-1,-1,false));
|
||||
chan[i].midiNote=-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DivEngine::setOrder(unsigned char order) {
|
||||
BUSY_BEGIN_SOFT;
|
||||
curOrder=order;
|
||||
|
|
@ -2621,6 +2660,11 @@ bool DivEngine::switchMaster() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void DivEngine::setMidiBaseChan(int chan) {
|
||||
if (chan<0 || chan>=chans) chan=0;
|
||||
midiBaseChan=chan;
|
||||
}
|
||||
|
||||
void DivEngine::setMidiCallback(std::function<int(const TAMidiMessage&)> what) {
|
||||
midiCallback=what;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ struct DivChannelState {
|
|||
bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff;
|
||||
bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, noteOnInhibit, resetArp;
|
||||
|
||||
int midiNote;
|
||||
|
||||
DivChannelState():
|
||||
note(-1),
|
||||
oldNote(-1),
|
||||
|
|
@ -126,7 +128,8 @@ struct DivChannelState {
|
|||
scheduledSlideReset(false),
|
||||
shorthandPorta(false),
|
||||
noteOnInhibit(false),
|
||||
resetArp(false) {}
|
||||
resetArp(false),
|
||||
midiNote(-1) {}
|
||||
};
|
||||
|
||||
struct DivNoteEvent {
|
||||
|
|
@ -231,6 +234,7 @@ class DivEngine {
|
|||
short vibTable[64];
|
||||
int reversePitchTable[4096];
|
||||
int pitchTable[4096];
|
||||
int midiBaseChan;
|
||||
|
||||
blip_buffer_t* samp_bb;
|
||||
size_t samp_bbInLen;
|
||||
|
|
@ -539,6 +543,9 @@ class DivEngine {
|
|||
// stop note
|
||||
void noteOff(int chan);
|
||||
|
||||
void autoNoteOn(int chan, int ins, int note, int vol=-1);
|
||||
void autoNoteOff(int chan, int note, int vol=-1);
|
||||
|
||||
// go to order
|
||||
void setOrder(unsigned char order);
|
||||
|
||||
|
|
@ -638,6 +645,9 @@ class DivEngine {
|
|||
// switch master
|
||||
bool switchMaster();
|
||||
|
||||
// set MIDI base channel
|
||||
void setMidiBaseChan(int chan);
|
||||
|
||||
// set MIDI input callback
|
||||
// if the specified function returns -2, note feedback will be inhibited.
|
||||
void setMidiCallback(std::function<int(const TAMidiMessage&)> what);
|
||||
|
|
@ -726,6 +736,7 @@ class DivEngine {
|
|||
view(DIV_STATUS_NOTHING),
|
||||
haltOn(DIV_HALT_NONE),
|
||||
audioEngine(DIV_AUDIO_NULL),
|
||||
midiBaseChan(0),
|
||||
samp_bbInLen(0),
|
||||
samp_temp(0),
|
||||
samp_prevSample(0),
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@ struct DivInstrument {
|
|||
DivInstrument():
|
||||
name(""),
|
||||
mode(false),
|
||||
type(DIV_INS_STD) {
|
||||
type(DIV_INS_FM) {
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1552,7 +1552,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
|||
switch (msg.type&0xf0) {
|
||||
case TA_MIDI_NOTE_OFF: {
|
||||
if (chan<0 || chan>=chans) break;
|
||||
pendingNotes.push(DivNoteEvent(msg.type&15,-1,-1,-1,false));
|
||||
autoNoteOff(msg.type&15,msg.data[0]-12,msg.data[1]);
|
||||
if (!playing) {
|
||||
reset();
|
||||
freelance=true;
|
||||
|
|
@ -1563,14 +1563,9 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
|||
case TA_MIDI_NOTE_ON: {
|
||||
if (chan<0 || chan>=chans) break;
|
||||
if (msg.data[1]==0) {
|
||||
pendingNotes.push(DivNoteEvent(msg.type&15,-1,-1,-1,false));
|
||||
autoNoteOff(msg.type&15,msg.data[0]-12,msg.data[1]);
|
||||
} else {
|
||||
pendingNotes.push(DivNoteEvent(msg.type&15,ins,(int)msg.data[0]-12,msg.data[1],true));
|
||||
}
|
||||
if (!playing) {
|
||||
reset();
|
||||
freelance=true;
|
||||
playing=true;
|
||||
autoNoteOn(msg.type&15,ins,msg.data[0]-12,msg.data[1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue