home *** CD-ROM | disk | FTP | other *** search
- desc:Convert midi notes into modal randomness
-
- slider1:0<0,11,{1,1.5,2,2.5,3,4,4.5,5,5.5,6,6.5,7>interval A
- slider2:50<0,100,1>probability A
-
- slider3:4<0,11,{1,1.5,2,2.5,3,4,4.5,5,5.5,6,6.5,7>interval B
- slider4:30<0,100,1>probability B
-
- slider5:7<0,11,{1,1.5,2,2.5,3,4,4.5,5,5.5,6,6.5,7>interval C
- slider6:40<0,100,1>probability C
-
- slider7:9<0,11,{1,1.5,2,2.5,3,4,4.5,5,5.5,6,6.5,7>interval D
- slider8:20<0,100,1>probability D
-
- slider9:50<0,100,1>speed
- slider10:50<0,100,1>octave randomness
- slider11:50<0,100,1>timing randomness
- slider12:50<0,100,1>velocity randomness
-
- slider13:10<0,600,1>decay time (seconds)
- slider14:4<0,8,1>number of simultaneous notes
-
- slider15:4<1,8,1>quantize targets per beat
- slider16:0<0,100,1>quantize strength
-
- @init
-
- // SPB = samples per beat.
- // NPB = notes per beat.
- // SPN = samples per note.
-
- NOTE_ON = 9;
- NOTE_OFF = 8;
-
- MIN_NPB = 0.25;
- MAX_NPB = 4.0;
- MIN_DECAY_VEL = 2;
-
- // Note buffer offsets.
- B_LEN = 0; // Play this note for this many samples.
- B_ITEMS = 1;
- buf = 0;
- memset(buf, 0, 128*B_ITEMS);
-
- // Input queue offsets.
- Q_NOTE = 0;
- Q_VEL = 1; // Input velocity, decays according to speed slider.
- Q_POS = 2; // When this note is due to trigger another note.
- Q_ITEMS = 3;
- queue = 128*B_ITEMS;
- memset(queue, 0, 16*Q_ITEMS);
-
- active_notes = 0;
- max_active_notes = 0;
-
- @slider
-
- iA = slider1;
- pA = 0.01*slider2;
- iB = slider3;
- pB = 0.01*slider4;
- iC = slider5;
- pC = 0.01*slider6;
- iD = slider7;
- pD = 0.01*slider8;
-
- speed = 0.02*slider9;
- r_oct = 0.07*slider10;
- r_time = 0.01*slider11;
- r_vel = 0.02*slider12;
-
- decay = slider13;
- max_active_notes = slider14;
- q_tgt = slider15;
- quant = 0.01*slider16;
-
- pSum = pA+pB+pC+pD;
- pSum > 0 ? (
- pA /= pSum;
- pB = pA+pB/pSum;
- pC = pB+pC/pSum;
- pD = pC+pD/pSum;
- );
-
- NPB = MIN_NPB+speed*(MAX_NPB-MIN_NPB);
- decay_samples = 0.5*decay*srate;
-
-
- @block
-
- BP0 = beat_position;
- SPB = srate * 60.0 / tempo;
- SPN = SPB / NPB;
-
- midirecv(mpos, msg1, msg23);
- while (
- (msg1/16)|0 == NOTE_ON ? (
- vel = (msg23/256)|0;
- note = msg23 - (vel*256);
-
- pq = active_notes*Q_ITEMS;
- queue[pq+Q_NOTE] = note;
- queue[pq+Q_VEL] = vel;
- queue[pq+Q_POS] = mpos;
-
- active_notes += 1;
- );
- midirecv(mpos, msg1, msg23);
- );
-
- active_notes > max_active_notes ? (
- dq = active_notes - max_active_notes;
- memcpy(queue, queue+dq*Q_ITEMS, max_active_notes*Q_ITEMS);
- active_notes = max_active_notes;
- );
-
- active_notes ? (
- qi = 0;
- while (
- dead = 0;
- pq = qi*Q_ITEMS;
- mpos = queue[pq+Q_POS];
- mpos < samplesblock ? (
-
- note = queue[pq+Q_NOTE];
-
- r = rand(1);
- r < pA ? (
- note += iA;
- ) : (
- r < pB ? (
- note += iB;
- ) : (
- r < pC ? (
- note += iC;
- ) : (
- r < pD ? (
- note += iD;
- ); ); ); );
-
- // rand(1) < 0.5 ? (
- // note -= 12;
- // );
-
- oct = (r_oct*(rand(1)-0.5))|0;
- note += oct*12;
-
- in_vel = queue[pq+Q_VEL];
-
- len = (SPN/2*(1.0+r_time*(rand(1)-0.5)))|0;
- pos = len + (SPN*(1.0+r_time*(rand(1)-0.5)))|0;
-
- qb = (0.5+q_tgt*(BP0+pos/SPB))|0;
- qb = max(qb, 1);
- qpos = (qb-BP0*q_tgt)*(SPB/q_tgt);
-
- pos = (pos*(1.0-quant)+qpos*quant)|0;
-
- pn = note*B_ITEMS+B_LEN;
- buf[pn] == 0 ? (
- out_vel = (in_vel*(1.0+r_vel*(rand(1)-0.5)))|0;
- buf[pn] = len;
- midisend(mpos, NOTE_ON*16, out_vel*256+note);
- ); // Else skip it.
-
- in_vel *= 1.0 - pos/decay_samples; //permute?
- in_vel |= 0;
-
- in_vel < MIN_DECAY_VEL ? (
- dead = 1;
- ) : (
- queue[pq+Q_POS] = pos;
- queue[pq+Q_VEL] = in_vel;
- );
- ) : (
- queue[pq+Q_POS] = mpos - samplesblock;
- );
-
- dead ? (
- memcpy(queue+pq, queue+pq+Q_ITEMS, (active_notes-i)*Q_ITEMS);
- active_notes -= 1;
- ) : (
- qi += 1;
- );
-
- qi < active_notes;
- );
- );
-
- ni = 0;
- while (
- pn = ni*B_ITEMS+B_LEN;
- len = buf[pn];
- len > 0 ? (
- len -= samplesblock;
- len < samplesblock ? (
- midisend(len, NOTE_OFF*16, ni);
- len = 0;
- );
- buf[pn] = len;
- );
- ni += 1;
- ni < 128;
- );
-
-
-
-
-
-