View Single Post
Old 06-16-2017, 06:46 AM   #4
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,688
Default

Here you are:

Code:
desc:MIDI Octave
//tags: MIDI processing

slider1:0<-11,11,1>Transpose Semitones
slider2:-5<-11,11,1>Previous Transpose
slider3:21<0,127,1>Lowest Key (MIDI Note #)
slider4:65<0,127,1>Midi CC Transpose
slider5:66<0,127,1>Midi CC Octave


// these lines tell Reaper the effect has no audio input/output,
// which enables processing optimizations.
// MIDI-only FX should always have these lines.
in_pin:none
out_pin:none

@init
global_info = 0;
notebuf = 0; // 4 entries per open note: orignote, channel, vel, transnote
buflen = 0;
last_transpose = 0;
gmem[global_info] = last_transpose;
last_samplepos = 0;
last_oct=0;
oo=0;
att=0;
oct1=slider3;
lowc=(((oct1+13) / 12) | 0) * 12;  // if lowest key is a C -> one octave up

@slider
att=0;
oct1=slider3;
lowc=(((oct1+13) / 12) | 0) * 12;  // if lowest key is a C -> one octave up

@block
samplepos = play_position*srate;
samplechg = samplepos-last_samplepos;
samplechg < -samplesblock/2.0 || samplechg > samplesblock*3.0/2.0 ? (
  buflen = 0;  // clear state on seek   
);
last_samplepos = samplepos;
slider1|0 != last_transpose || oct != last_oct ? (
  last_transpose = slider1|0;
  gmem[global_info] = last_transpose;
  last_oct  = oct;
  i = 0;
  loop (
    buflen,    
    n = notebuf[4*i]|0; // original note
    c = notebuf[4*i+1]|0; // channel
    v = notebuf[4*i+2]|0; // velocity
    t = notebuf[4*i+3]|0; // transposed note
    midisend(0, $x80|c, t&0x7F); // clear the sustaining transposed note    
    t & 0x80 ? (                 // octave had been sent
      midisend(0, $x80|c, (t&0x7F)-12); // clear the sustaining octave note        
    );
    t = (n+last_transpose)|0; // new transposed note    
    t < 0 ? t = 0 : t > 127 ? t = 127;
//    midisend(0, $x90|c, (v*256)|t); // send the new transposed note
    notebuf[4*i+3] = t; // update the buffer 
    oct ? (
      t-=12;
//      midisend(0, 0x90|c, (v*256)|t); // send the new octave note
      notebuf[4*i+3] = t|0x80; // update the buffer 
    );
    i = i+1;
  );
);
while (midirecv(offs, m1, m2) ) (       // m2 contains both note and velocity
    s = m1&$xF0;                        // Status
    s != 0xF0 ? (
      s == 0x90 || s == $x80 ? (        // note-on or note-off
        n = m2&0xFF;                    // original note
        v = (m2&$xFF00)/256;            // velocity
        no = s==0x90 && v != 0;
        att && no ? (                   // we are special
          att = 0;                      // next key is normal       
          (n >= lowc) && (n < lowc+24) ? (  // transpose request
            n -= lowc+12;                // +0 ... +11
            slider1 = n;
            m1 = 0;                      // no output
          );
        );  
        m1 ? (
          n >= 0 ? (
            c = m1&0xF; // channel
            t = (n+last_transpose)|0; // transposed note
            t < 0 ? t = 0 : t > 127 ? t = 127;
            m2 = m2+t-n; // apply transposition      
            oo && (t>12) ? (
              mo = m2-12;   //Sub - Octave
             ) : (
              mo = 0;
            );  
            i = -1;
            while (  // look for this note|channel already in the buffer
              i = i+1;
              i < buflen && (notebuf[4*i]|0 != n || notebuf[4*i+1]|0 != c);
            );
            no ? (// note-on, add to buffer        
              notebuf[4*i] = n;
              notebuf[4*i+1] = c;
              notebuf[4*i+2] = v;
              notebuf[4*i+3] = t | oo;
              i == buflen ? buflen = buflen+1;
             ) : (// note-off, remove from buffer        
              i < buflen ? (
                memcpy(notebuf+4*i, notebuf+4*(i+1), 4*(buflen-i-1));  // delete the entry
                buflen = buflen-1;
              );  
            );
          );
        );
       ):(
        s == 0xB0 ? (
          m2 == 0x017E ? (
            oct =1;
            oo = 0x80;
            m1 = 0;
           ):(
            m2 == 0x007F ? (
              oct = 0;
              oo = 0;
              m1 = 0;
             ):( 
              (m2 & 0x7F) == slider4 ? (
                (m2 >> 8 ) < 64 ? (             
                  slider2 = last_transpose;
                  att = 0;
                  slider1 = 0;
                  m1 = 0;
                 ) : (
                  slider1 = slider2;
                  last_transpose = 0;
                  gmem[global_info] = last_transpose;
                  att = 1;
                  m1 = 0;                 
                ); 
              );  
            );
          );        
        );  
      );
      m1 ? (
        midisend(offs, m1, m2);
        no ? (
          att = 0;                   // next key is handled normally
        );  
        mo && (s == 0x90 || s == $x80) ? ( // Sub-Octave
          midisend(offs, m1, mo);
        );  
      );
      
      
      nb0 = notebuf[4*0];            // why does this kill the error ?!?!?!?!?
      nb1 = notebuf[4*1];
      
      
        
    );
);
mschnell is offline   Reply With Quote