void MidiProbability::processMidiEvents(VstMidiEventVec *inputs, VstMidiEventVec *outputs, VstInt32 samples) { char listenchannel = FLOAT_TO_CHANNEL(param[kChannel]); char chch = FLOAT_TO_CHANNEL(param[kChCh]); //process incoming events------------------------------------------------------- for (unsigned int i=0;i<inputs[0].size();i++) { //copying event "i" from input (with all its fields) VstMidiEvent tomod = inputs[0][i]; int status = tomod.midiData[0] & 0xf0; // scraping channel const int channel = tomod.midiData[0] & 0x0f; // isolating channel (0-15) const int data1 = tomod.midiData[1] & 0x7f; const int data2 = tomod.midiData[2] & 0x7f; //make 0-velocity notes into "real" noteoffs for simplicity if (status==MIDI_NOTEON && data2==0) { status=MIDI_NOTEOFF; tomod.midiData[0] = MIDI_NOTEOFF | channel; } bool discard = false; int outch = channel; int outd1 = data1; int outd2 = data2; if (chch==-1) chch=rand()%16; //only look at the selected channel if (channel == listenchannel || listenchannel == -1) { //Incoming NoteOn--------------------------------------------------------------- if (status == MIDI_NOTEON) { bool stop=false; //use this to enforce slot precedence????????? // find the location of the note within the beat, in samples: for (int slot=0;slot<numSlots;slot++) { VstInt32 beatpos_samples = roundToInt(_beatpos[slot] * samplesPerBeat) + tomod.deltaFrames; // find "closeness" to selected stepsize float c = closeness(beatpos_samples); if (param[kStep1+numParamsPerSlot*slot]>=(21.f/22.f)) { c=1.0f; //apply to every note } if (stop) c=0.0f; float prob = param[kProb1+numParamsPerSlot*slot]; int index=kMode1+numParamsPerSlot*slot; if (param[index]<0.1f) mode = off; else if (param[index]<0.2f) mode = disc; else if (param[index]<0.3f) mode = octup; else if (param[index]<0.4f) mode = octdown; else if (param[index]<0.5f) mode = randtr; else if (param[index]<0.6f) mode = transp; else if (param[index]<0.7f) mode = randvel; else if (param[index]<0.8f) mode = offsetvel; else if (param[index]<0.9f) mode = chan; else mode = multi; if (param[kPower]<0.25f) mode=off; //probability //don't do anything unless prob > 0%, and mode is not "off" if (roundToInt(100.0f*prob)>0 && mode!=off) { float p = c*100.0f*prob; float R = (float)(rand()%99); if ( R<p ) { char transpose=0; char vel=0; if (mode==chan || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kChan] || mode==chan) { outch=chch; tomod.midiData[0]=MIDI_NOTEON | outch; noteAffected[data1][channel][chan]=outch+1; stop=true; } } if (mode==disc || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kSkip] || mode==disc) { discard=true; noteAffected[data1][channel][disc]=1; stop=true; } } if (mode==octup || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kOctUp] || mode==octup) { outd1+=12; noteAffected[data1][channel][octup]=12; stop=true; } } if (mode==octdown || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kOctDn] || mode==octdown) { outd1-=12; noteAffected[data1][channel][octdown]=-12; stop=true; } } if (mode==randtr || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kRandT] || mode==randtr) { transpose = rand()%24-12; if (outd1+transpose < 0) transpose=-transpose; else if (outd1+transpose > 127) transpose=-transpose; outd1+=transpose; noteAffected[data1][channel][randtr]=transpose; stop=true; } } if (mode==transp || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kTransp] || mode==transp) { transpose = roundToInt(72.f*param[kTranspAmt])-36; if (outd1+transpose < 0) transpose=-transpose; else if (outd1+transpose > 127) transpose=-transpose; outd1+=transpose; noteAffected[data1][channel][transp]=transpose; stop=true; } } if (mode==randvel || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kRandV] || mode==randvel) { vel = rand()%128-64; if (outd2+vel < 1) vel=-vel; else if (outd2+vel > 127) vel=-vel; outd2+=vel; tomod.midiData[2]=outd2; noteAffected[data1][channel][randvel]=vel; stop=true; } } if (mode==offsetvel || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kRandV] || mode==offsetvel) { vel = roundToInt(param[kVelAmt]*128.f)-64; if (outd2+vel < 1) vel=-vel; else if (outd2+vel > 127) vel=-vel; outd2+=vel; tomod.midiData[2]=outd2; noteAffected[data1][channel][offsetvel]=vel; stop=true; } } if (outd1>127) outd1=127; else if (outd1<0) outd1=0; tomod.midiData[1]=outd1; } } } if (!discard) notePlaying[outd1][outch]=true; } //incoming NoteOff-------------------------------------------------------------- else if (status == MIDI_NOTEOFF) { if (noteAffected[data1][channel][chan]!=0) { outch=noteAffected[data1][channel][chan]-1; tomod.midiData[0] = MIDI_NOTEOFF | outch; noteAffected[data1][channel][chan]=0; } if (noteAffected[data1][channel][disc]==1) { discard=true; noteAffected[data1][channel][disc]=0; } if (noteAffected[data1][channel][octup]!=0) { outd1+=12; noteAffected[data1][channel][octup]=0; } if (noteAffected[data1][channel][octdown]!=0) { outd1-=12; noteAffected[data1][channel][octdown]=0; } if (noteAffected[data1][channel][randtr]!=0) { outd1+= (noteAffected[data1][channel][randtr]); noteAffected[data1][channel][randtr]=0; } if (noteAffected[data1][channel][transp]!=0) { outd1+= (noteAffected[data1][channel][transp]); noteAffected[data1][channel][randtr]=0; } if (outd1>127) outd1=127; else if (outd1<0) outd1=0; tomod.midiData[1]=outd1; if (!discard) notePlaying[outd1][outch]=false; } //Incoming CC------------------------------------------------------------- else if (status==MIDI_CONTROLCHANGE) { bool stop=false; for (int slot=0;slot<numSlots;slot++) { VstInt32 beatpos_samples = roundToInt(_beatpos[slot] * samplesPerBeat) + tomod.deltaFrames; // find "closeness" to selected stepsize float c = closeness(beatpos_samples); if (param[kStep1+numParamsPerSlot*slot]>=(21.f/22.f)) { c=1.0f; //apply to every note } if (stop) c=0.0f; float prob = param[kProb1+numParamsPerSlot*slot]; int index=kMode1+numParamsPerSlot*slot; if (param[index]<0.1f) mode = off; else if (param[index]<0.2f) mode = disc; else if (param[index]<0.3f) mode = octup; else if (param[index]<0.4f) mode = octdown; else if (param[index]<0.5f) mode = randtr; else if (param[index]<0.6f) mode = transp; else if (param[index]<0.7f) mode = randvel; else if (param[index]<0.8f) mode = offsetvel; else if (param[index]<0.9f) mode = chan; else mode = multi; if (param[kPower]<0.5f) mode=off; //probability //don't do anything unless prob > 0%, and mode is not "off" if (roundToInt(100.0f*prob)>0 && mode!=off) { float p = c*100.0f*prob; float R = (float)(rand()%99); if ( R<p ) { char transpose=0; char vel=0; if (mode==chan || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kChan] || mode==chan) { outch=chch; tomod.midiData[0]=MIDI_CONTROLCHANGE | outch; stop=true; } } if (mode==disc || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kSkip] || mode==disc) { discard=true; stop=true; } } if (mode==randtr || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kRandT] || mode==randtr) { transpose = rand()%24-12; if (outd1+transpose < 0) transpose=-transpose; else if (outd1+transpose > 127) transpose=-transpose; outd1+=transpose; tomod.midiData[1]=outd1; noteAffected[data1][channel][randtr]=transpose; stop=true; } } if (mode==randvel || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kRandV] || mode==randvel) { vel = rand()%128-64; if (outd2+vel < 1) vel=-vel; else if (outd2+vel > 127) vel=-vel; outd2+=vel; tomod.midiData[2]=outd2; noteAffected[data1][channel][randvel]=vel; stop=true; } } } } } } //Other------------------------------------------------------------------- else { bool stop=false; for (int slot=0;slot<numSlots;slot++) { VstInt32 beatpos_samples = roundToInt(_beatpos[slot] * samplesPerBeat) + tomod.deltaFrames; // find "closeness" to selected stepsize float c = closeness(beatpos_samples); if (param[kStep1+numParamsPerSlot*slot]>=(21.f/22.f)) { c=1.0f; //apply to every note } if (stop) c=0.0f; float prob = param[kProb1+numParamsPerSlot*slot]; int index=kMode1+numParamsPerSlot*slot; if (param[index]==0.0f) mode = off; else if (param[index]<0.1f) mode = disc; else if (param[index]<0.2f) mode = octup; else if (param[index]<0.3f) mode = octdown; else if (param[index]<0.4f) mode = randtr; else if (param[index]<0.5f) mode = randvel; else if (param[index]<0.6f) mode = chan; // else if (param[index]<0.7f) mode = ; // else if (param[index]<0.8f) mode = ; // else if (param[index]<0.9f) mode = ; // else if (param[index]<1.0f) mode = ; else mode = multi; if (param[kPower]<0.75f) mode=off; //probability //don't do anything unless prob > 0%, and mode is not "off" if (roundToInt(100.0f*prob)>0 && mode!=off) { float p = c*100.0f*prob; float R = (float)(rand()%99); if ( R<p ) { char transpose=0; char vel=0; if (mode==chan || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kChan] || mode==chan) { outch=chch; tomod.midiData[0]=status | outch; stop=true; } } if (mode==disc || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kSkip] || mode==disc) { discard=true; stop=true; } } if (mode==randtr || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kRandT] || mode==randtr) { transpose = rand()%24-12; if (outd1+transpose < 0) transpose=-transpose; else if (outd1+transpose > 127) transpose=-transpose; outd1+=transpose; tomod.midiData[1]=outd1; noteAffected[data1][channel][randtr]=transpose; stop=true; } } if (mode==randvel || mode==multi) { float r = (float)(rand()%99); if (r<p*param[kRandV] || mode==randvel) { vel = rand()%128-64; if (outd2+vel < 1) vel=-vel; else if (outd2+vel > 127) vel=-vel; outd2+=vel; tomod.midiData[2]=outd2; noteAffected[data1][channel][randvel]=vel; stop=true; } } } } } } } // if listenchannel==channel if (!discard) outputs[0].push_back(tomod); } //for() inputs loop if (wasplaying && !isplaying) { //just stopped dbg("stopped"); for (int ch=0; ch<16; ch++) { for (int n=0; n<128; n++) { if (notePlaying[n][ch]) { VstMidiEvent kill; kill.midiData[0] = MIDI_NOTEOFF + ch; kill.midiData[1] = n; kill.midiData[2] = 0; kill.deltaFrames = samples-1; kill.detune = 0; outputs[0].push_back(kill); dbg("stopped, killed note " << n); } } } } wasplaying=isplaying; }
void buildDynProgMatrix( const AlignMatrix& w, const SentenceValues& huLength, const SentenceValues& enLength, QuasiDiagonal<double>& v, TrelliMatrix& trellis ) { const int huBookSize = w.size(); const int enBookSize = w.otherSize(); int huPos,enPos; // v[huPos][enPos] gives the similarity of the [0,huPos) and [0,enPos) intervals. // The smaller value, the better similarity. (Unlike in the original similarity matrix w, where bigger is better.) double infinity = 1e6; for ( huPos=0; huPos<=huBookSize; ++huPos ) { int rowStart = v.rowStart(huPos); int rowEnd = v.rowEnd(huPos); for ( enPos=rowStart; enPos<rowEnd; ++enPos ) { double& val = v.cell(huPos,enPos); unsigned char& trail = trellis.cell(huPos,enPos); bool quasiglobal_knightsMoveAllowed = true; if (quasiglobal_knightsMoveAllowed) { double lengthFitness(0); bool quasiglobal_lengthFitnessApplied = true; // The array is indexed by the step directions. The smaller value, the better. double values[Dead]; int i; for ( i=1; i<Dead; ++i ) values[i] = infinity; if (huPos>0) { values[HuSkip] = v[huPos-1][enPos] - skipScore; } if (enPos>0) { values[EnSkip] = v[huPos][enPos-1] - skipScore; } if ((huPos>0) && (enPos>0)) { if (quasiglobal_lengthFitnessApplied) { lengthFitness = closeness(huLength[huPos-1], enLength[enPos-1]); } else { lengthFitness = 0; } values[Diag] = v[huPos-1][enPos-1] - w[huPos-1][enPos-1] - lengthFitness ; } const double dotLength = 2.0 ; if ((huPos>1) && (enPos>0)) { if (quasiglobal_lengthFitnessApplied) { lengthFitness = closeness(huLength[huPos-2]+huLength[huPos-1]+dotLength, enLength[enPos-1]); } else { lengthFitness = 0; } const double& a = w[huPos-1][enPos-1] ; const double& b = w[huPos-2][enPos-1] ; double lengthSimilarity = values[HuHuEnSkip] = v[huPos-2][enPos-1] - ( a<b ? a : b ) - skipScore - lengthFitness ; // The worse of the two crossed square. } if ((huPos>0) && (enPos>1)) { if (quasiglobal_lengthFitnessApplied) { // Attention, the two-sentence length is the first argument. Usually the Hungarian is the first argument, but not here. lengthFitness = closeness(enLength[enPos-2]+enLength[enPos-1]+dotLength, huLength[huPos-1]); } else { lengthFitness = 0; } const double& a = w[huPos-1][enPos-1] ; const double& b = w[huPos-1][enPos-2] ; values[HuEnEnSkip] = v[huPos-1][enPos-2] - ( a<b ? a : b ) - skipScore - lengthFitness ; // The worse of the two crossed square. } unsigned char direction = Dead; double bestValue = infinity; for ( i=1; i<Dead; ++i ) { if (values[i]<bestValue) { bestValue = values[i]; direction = i; } } trail = direction; if (direction==Dead) { val = 0; } else { val = bestValue; } } else // (!quasiglobal_knightsMoveAllowed) { int borderCase = ( (huPos==0) ? 0 : 2 ) + ( (enPos==0) ? 0 : 1 ) ; switch (borderCase) { case 0: { val = 0; trail = Dead; break; } case 1: // huPos==0 { val = v[0][enPos-1] - skipScore ; trail = EnSkip; break; } case 2: // enPos==0 { val = v[huPos-1][0] - skipScore ; trail = HuSkip; break; } case 3: { double x = v[huPos-1][enPos] - skipScore ; double y = v[huPos] [enPos-1] - skipScore ; double xy = v[huPos-1][enPos-1] - w[huPos-1][enPos-1] ; double best = xy; trail = Diag; if (x<best) { best = x; trail = HuSkip; } if (y<best) { best = y; trail = EnSkip; } val = best; break; } } } } } }