home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 February / PCWorld_2008-02_cd.bin / audio-video / reaper / reaper2028-install.exe / Effects / schwa / midi_modal_randomness < prev    next >
Text File  |  2007-12-09  |  4KB  |  210 lines

  1. desc:Convert midi notes into modal randomness
  2.  
  3. slider1:0<0,11,{1,1.5,2,2.5,3,4,4.5,5,5.5,6,6.5,7>interval A
  4. slider2:50<0,100,1>probability A
  5.  
  6. slider3:4<0,11,{1,1.5,2,2.5,3,4,4.5,5,5.5,6,6.5,7>interval B
  7. slider4:30<0,100,1>probability B
  8.  
  9. slider5:7<0,11,{1,1.5,2,2.5,3,4,4.5,5,5.5,6,6.5,7>interval C
  10. slider6:40<0,100,1>probability C
  11.  
  12. slider7:9<0,11,{1,1.5,2,2.5,3,4,4.5,5,5.5,6,6.5,7>interval D
  13. slider8:20<0,100,1>probability D
  14.  
  15. slider9:50<0,100,1>speed
  16. slider10:50<0,100,1>octave randomness
  17. slider11:50<0,100,1>timing randomness
  18. slider12:50<0,100,1>velocity randomness
  19.  
  20. slider13:10<0,600,1>decay time (seconds)
  21. slider14:4<0,8,1>number of simultaneous notes
  22.  
  23. slider15:4<1,8,1>quantize targets per beat
  24. slider16:0<0,100,1>quantize strength
  25.  
  26. @init
  27.  
  28. // SPB = samples per beat.
  29. // NPB = notes per beat.
  30. // SPN = samples per note.
  31.  
  32. NOTE_ON = 9;
  33. NOTE_OFF = 8;
  34.  
  35. MIN_NPB = 0.25;
  36. MAX_NPB = 4.0;
  37. MIN_DECAY_VEL = 2;
  38.  
  39. // Note buffer offsets.
  40. B_LEN = 0;    // Play this note for this many samples.
  41. B_ITEMS = 1;
  42. buf = 0;
  43. memset(buf, 0, 128*B_ITEMS);
  44.  
  45. // Input queue offsets.
  46. Q_NOTE = 0;
  47. Q_VEL = 1;  // Input velocity, decays according to speed slider.
  48. Q_POS = 2; // When this note is due to trigger another note.
  49. Q_ITEMS = 3;
  50. queue = 128*B_ITEMS;
  51. memset(queue, 0, 16*Q_ITEMS);
  52.  
  53. active_notes = 0;
  54. max_active_notes = 0;
  55.  
  56. @slider
  57.  
  58. iA = slider1;
  59. pA = 0.01*slider2;
  60. iB = slider3;
  61. pB = 0.01*slider4;
  62. iC = slider5;
  63. pC = 0.01*slider6;
  64. iD = slider7;
  65. pD = 0.01*slider8;
  66.  
  67. speed = 0.02*slider9;
  68. r_oct = 0.07*slider10;
  69. r_time = 0.01*slider11;
  70. r_vel = 0.02*slider12;
  71.  
  72. decay = slider13;
  73. max_active_notes = slider14;
  74. q_tgt = slider15;
  75. quant = 0.01*slider16;
  76.  
  77. pSum = pA+pB+pC+pD;
  78. pSum > 0 ? (
  79.   pA /= pSum;
  80.   pB = pA+pB/pSum;
  81.   pC = pB+pC/pSum;
  82.   pD = pC+pD/pSum;
  83. );
  84.  
  85. NPB = MIN_NPB+speed*(MAX_NPB-MIN_NPB);
  86. decay_samples = 0.5*decay*srate;
  87.  
  88.  
  89. @block
  90.  
  91. BP0 = beat_position;
  92. SPB = srate * 60.0 / tempo;
  93. SPN = SPB / NPB;
  94.  
  95. midirecv(mpos, msg1, msg23);
  96. while (
  97.   (msg1/16)|0 == NOTE_ON ? (
  98.     vel = (msg23/256)|0;
  99.     note = msg23 - (vel*256);
  100.   
  101.     pq = active_notes*Q_ITEMS;
  102.     queue[pq+Q_NOTE] = note;
  103.     queue[pq+Q_VEL] = vel;
  104.     queue[pq+Q_POS] = mpos;
  105.  
  106.     active_notes += 1;
  107.   );
  108.   midirecv(mpos, msg1, msg23);
  109. );
  110.  
  111. active_notes > max_active_notes ? (
  112.   dq = active_notes - max_active_notes;
  113.   memcpy(queue, queue+dq*Q_ITEMS, max_active_notes*Q_ITEMS);
  114.   active_notes = max_active_notes;
  115. );
  116.  
  117. active_notes ? (
  118.   qi = 0;
  119.   while (
  120.     dead = 0;
  121.     pq = qi*Q_ITEMS;
  122.     mpos = queue[pq+Q_POS];
  123.     mpos < samplesblock ? (
  124.  
  125.       note = queue[pq+Q_NOTE];
  126.           
  127.       r = rand(1);
  128.       r < pA ? ( 
  129.         note += iA; 
  130.       ) : (
  131.       r < pB ? (
  132.         note += iB;
  133.       ) : (
  134.       r < pC ? (
  135.         note += iC;
  136.       ) : (
  137.       r < pD ? (
  138.         note += iD;
  139.       ); ); ); );
  140.  
  141. //      rand(1) < 0.5 ? (
  142. //        note -= 12;
  143. //      );
  144.  
  145.       oct = (r_oct*(rand(1)-0.5))|0;
  146.       note += oct*12;
  147.  
  148.       in_vel = queue[pq+Q_VEL];      
  149.  
  150.       len = (SPN/2*(1.0+r_time*(rand(1)-0.5)))|0;
  151.       pos = len + (SPN*(1.0+r_time*(rand(1)-0.5)))|0;
  152.  
  153.       qb = (0.5+q_tgt*(BP0+pos/SPB))|0;
  154.       qb = max(qb, 1);
  155.       qpos = (qb-BP0*q_tgt)*(SPB/q_tgt);
  156.  
  157.       pos = (pos*(1.0-quant)+qpos*quant)|0;
  158.       
  159.       pn = note*B_ITEMS+B_LEN;
  160.       buf[pn] == 0 ? (
  161.         out_vel = (in_vel*(1.0+r_vel*(rand(1)-0.5)))|0;
  162.         buf[pn] = len;
  163.         midisend(mpos, NOTE_ON*16, out_vel*256+note);
  164.       ); // Else skip it.
  165.  
  166.       in_vel *= 1.0 - pos/decay_samples; //permute?
  167.       in_vel |= 0;
  168.  
  169.       in_vel < MIN_DECAY_VEL ? (
  170.         dead = 1;
  171.       ) : (
  172.         queue[pq+Q_POS] = pos;
  173.         queue[pq+Q_VEL] = in_vel;        
  174.       );
  175.     ) : (
  176.       queue[pq+Q_POS] = mpos - samplesblock;
  177.     );  
  178.  
  179.     dead ? (
  180.       memcpy(queue+pq, queue+pq+Q_ITEMS, (active_notes-i)*Q_ITEMS);
  181.       active_notes -= 1;
  182.     ) : (
  183.       qi += 1;
  184.     );
  185.  
  186.     qi < active_notes;
  187.   );
  188. );
  189.  
  190. ni = 0;
  191. while (
  192.   pn = ni*B_ITEMS+B_LEN;
  193.   len = buf[pn];
  194.   len > 0 ? (
  195.     len -= samplesblock;
  196.     len < samplesblock ? (
  197.       midisend(len, NOTE_OFF*16, ni);
  198.       len = 0;
  199.     );
  200.     buf[pn] = len;
  201.   );
  202.   ni += 1;
  203.   ni < 128;
  204. );
  205.  
  206.  
  207.  
  208.  
  209.  
  210.