Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
          }
        }
      }
    }
  }
}