// Flat 2012 - Thanks to the orignal author of midi_repeater
// License: GPL - http://www.gnu.org/licenses/gpl.html
desc:Bouncy MIDI Note Repeater
slider1:0.125<0.05,4,0.05>Starting repeat rate (beats)
slider2:4<1,16,1>Number of repeats before changing rate
slider3:0<-1,1>Slow down <- 0 -> Speed up
slider4:0.1<0,1>Velocity Decrease (0=No Decrease)

@init 
//Start addresses
status=0;
status2=128;
nbeats=256;
//"Array" allocation
memset(status,-1,128);
memset(status2,0,128);
memset(nbeats,0,128);

@slider 
div=slider1;
nblim=slider2;
accel=0.2*slider3+1; //Final value between 0.8 and 1.2
dim=0.2*(1-slider4)+0.8; // Final value between 0.8 and 1
  
@block
// The block section is entered every "sampleblock/srate" second
while (
midirecv(ts,msg1,msg23) ? 
(
  m=msg1&240;
  note=msg23&127;
  (m == 9*16 && msg23>=256) ? ( // Note on ?
    status[note]=0;
    nbeats[note]=1;
    vel=(msg23/256);
    vel<1?vel=1:vel>=127?vel=127:vel|=0;
    status2[note]=vel;
    midisend(ts,9*16,note+vel*256); // send note on
  ) : (m == 8*16 || m == 9*16) ? (
    status[note]=-1;
    status2[note]>0.0 ? (
      midisend(ts,8*16,note); // send note off
    );
    status2[note]=0; 
    nbeats[note]=0;
    div=slider1;
  ) : (
    midisend(ts,msg1,msg23); 
  );
  bla=1;
);
);

inc = (samplesblock/srate)*(tempo/60)*2/div;
x=0;
loop(128,
  status[x]>=0.0 ? 
  (
    status[x] += inc;
    status[x] >= 1.0 ? 
    (
      status[x] -= 1.0;
      status2[x]>0.0 ? (
          midisend(0,8*16,x);
      ) : (
          midisend(0,9*16,x - status2[x]*256);
          nbeats[x]+=1;
          nbeats[x] > nblim ? ( // Shall we begin modifying the repeat rate ?
            div /= accel; 	// Repeat rate modification
            ostat=status2[x];
            status2[x]=ceil(status2[x]*= dim); // Velocity modification
            status2[x] == 0 ? status2[x]=ostat; 
          );
      );
      status2[x]*=-1;
    );
  );
  x+=1;
);


@sample



