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 >
Wrap
Text File
|
2007-12-09
|
4KB
|
210 lines
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;
);