-
-
Save zeffii/7744593 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// persistent sound chain | |
NRev revL => dac.left; | |
NRev revR => dac.right; | |
revL.gain(0.0012); | |
revR.gain(0.0012); | |
Pan2 hatVPan => NRev hatVerb => dac; | |
Pan2 hatVPan2 => NRev hatVerb2 => dac; | |
hatVPan.gain(0.643); | |
hatVerb.mix(0.043); | |
hatVPan2.gain(0.643); | |
hatVerb2.mix(0.013); | |
Gain bdmaster => dac; | |
bdmaster.gain(0.2); | |
625::ms/3.9 => dur tick_time; | |
// [43,43,41-12,46, 42,45-12,47+12,47] @=> int note_array[]; | |
//[43, 42-12, 43, 41-12,43, 47, 41-12, 42, 0,42-12] @=> int note_array[]; | |
[43, 45, 61, 48-12, 43, 45-12, 46, 48, 43-12, 46, 49, 52-12, 46, 45, 47-12, 55] @=> int note_array[]; | |
[1,0,0,0, 1,0,0,0, 1,0,0,1, 0,0,1,0] @=> int bd_pattern[]; | |
[1,0,2,0, 1,0,2,0, 1,0,2,0, 1,3,0,2] @=> int ht_pattern[]; | |
[0,1,0,1, 0,1,0,1, 0,2,0,0, 1,0,1,1] @=> int ch_pattern[]; | |
[1,0,0,0, 1,0,0,0, 1,0,0,1, 0,0,1,0] @=> int bd_pattern2[]; | |
[1,0,4,0, 3,0,4,0, 1,0,4,0, 8,1,4,4] @=> int ht_pattern2[]; | |
[0,1,0,1, 0,1,0,1, 0,2,0,0, 1,0,1,1] @=> int ch_pattern2[]; | |
[bd_pattern2, ht_pattern2, ch_pattern2] @=> int patterns_b[][]; | |
// these are 32 ticks. | |
join_int_arrays(bd_pattern2, bd_pattern2) @=> int bd_pattern3[]; | |
[1,5,9,2, 1,2,9,8, 1,0,9,0, 8,1,9,3, | |
1,5,9,2, 1,2,9,8, 1,0,9,0, 8,1,9,2] @=> int ht_pattern3[]; | |
[0,1,0,1, 0,1,0,1, 0,2,0,0, 1,0,1,1, | |
0,1,0,1, 0,1,0,1, 0,1,0,0, 2,0,1,1] @=> int ch_pattern3[]; | |
[bd_pattern3, ht_pattern3, ch_pattern3] @=> int patterns_c[][]; | |
/* ............ intro ................*/ | |
Step s3 => Envelope freqFilterEnv => blackhole; | |
1 => int section1; | |
if (section1){ | |
13 => int num_loops_intro; | |
freqFilterEnv.duration(tick_time * 16 * (num_loops_intro-1)); | |
freqFilterEnv.keyOn(1); | |
int loop_num; | |
repeat(num_loops_intro){ | |
for(0 => int i; i<note_array.cap(); i++){ | |
note_array[i] => int mnote; | |
if (mnote>0){ | |
Math.random2f(-.6, .6) => float rpan; | |
generate_osc("saw", | |
mnote, rpan, 0.02, | |
[22, 120, 19, 2], /* envADSR */ | |
[2, 162, 59, 212], /* filterADSR */ | |
filtSweep(), 1.2); | |
} | |
tick_time/1.5 => now; | |
} | |
loop_num++; | |
if (loop_num ==(num_loops_intro-2)){ | |
freqFilterEnv.duration(tick_time * 16 * 1); | |
freqFilterEnv.keyOff(1); | |
trigger_chord("stomp3"); | |
} | |
} | |
// /* ............ intro perc................*/ | |
repeat(5){ step_seq1(0, 16); } | |
/* ............ pad pause ................*/ | |
trigger_chord("stomp3"); | |
pass_time(24); | |
/* ............ join back in ................*/ | |
step_seq1(4, 8); | |
step_seq1(0, 12); | |
step_seq1(4, 8); | |
step_seq2(0, 16, [0,1,1], patterns_b); | |
/* ............ percussion change ................*/ | |
repeat(1){ step_seq2(4, 16, [1,1,1], patterns_b); } | |
repeat(2){ step_seq2(0, 4, [1,1,1], patterns_b); } | |
} | |
repeat(4){ step_seq2(0, 32, [1,1,1], patterns_c); } | |
fun void pass_time(int ticks){ | |
(tick_time/1.5)*ticks => now; | |
} | |
fun void step_seq1(int start, int end){ | |
for(start => int i; i<end; i++){ | |
if (bd_pattern[i] == 1) trigger_kick(); | |
if (ht_pattern[i] == 1) trigger_hat("short"); | |
else if (ht_pattern[i] == 2) trigger_hat("long"); | |
else if (ht_pattern[i] == 3) do_shake(260); | |
if (ch_pattern[i] == 1) trigger_chord("stomp"); | |
else if (ch_pattern[i] == 2) trigger_chord("stomp2"); | |
tick_time/1.5 => now; | |
} | |
} | |
fun void step_seq2(int start, int end, int tracks[], int patterns[][]){ | |
patterns[0] @=> int bd[]; | |
patterns[1] @=> int hat[]; | |
patterns[2] @=> int chr[]; | |
for(start => int i; i<end; i++){ | |
if (tracks[0] == 1){ | |
if (bd[i] == 1) trigger_kick2(0.3); | |
} | |
if (tracks[1] == 1){ | |
hat[i] => int hatval; | |
if (hatval == 1) trigger_hat("short3"); | |
else if (hatval == 4) trigger_hat("diff"); | |
else if (hatval == 3) do_shake2(122, 4.9, 11); | |
else if (hatval == 8) do_shake2(42, 2.9, 20); | |
else if (hatval == 9) do_shake2(62, 3.9, 21); | |
} | |
if (tracks[2] == 1){ | |
chr[i] => int chval; | |
if (chval == 1) trigger_chord("stomp"); | |
else if (chval == 2) trigger_chord("stomp2"); | |
} | |
tick_time/1.5 => now; | |
} | |
} | |
fun void trigger_kick(){ | |
Math.random2f(-.6, .6) => float rpan; | |
generate_osc("sin", 57-27, rpan, 0.032, [2, 172, 19, 12],[2, 272, 69, 12], 54, 5.2); | |
generate_osc("sin", 32, rpan, 0.132, [2, 172, 19, 12],[2, 522, 9, 12], 7354, 2.2); | |
} | |
fun void trigger_kick2(float volume){ | |
do_kick2(volume); | |
} | |
fun void trigger_hat(string mode){ | |
Math.random2f(-.6, .6) => float rpan; | |
if (mode=="short") | |
generate_osc("sss", 60, rpan, 0.0052, [2, 32, 59, 12],[2, 131, 129, 12], 7954, 1.6); | |
else if (mode=="long") | |
generate_osc("sss", 80, rpan, 0.019, [2, 72, 59, 12],[2, 327, 369, 12], 7354, 4.8); | |
else if (mode=="short2") | |
generate_osc("sss", 80, rpan, 0.019, [2, 22, 19, 12],[2, 37, 369, 12], 7354, 4.8); | |
else if (mode=="short3") | |
generate_osc("sss", 80, rpan, 0.003, [2, 16, 13, 312],[2, 21, 599, 12], 1354, 3.8); | |
else if (mode=="diff") | |
generate_osc("sss", 80, rpan, 0.011, [2, 42, 59, 12],[2, 547, 119, 12], 10254, 14.8); | |
} | |
fun void trigger_chord(string ch_type){ | |
int chord[]; | |
string osc_type; | |
int decay_len, fdecay_len, ffreq, atk; | |
float fQ; | |
if (ch_type=="stomp") [46,47,50,53] @=> chord; | |
if (ch_type=="stomp2") [46,58,61,53] @=> chord; | |
if (ch_type == "stomp" || ch_type == "stomp2"){ | |
"sin" => osc_type; | |
2 => atk; | |
172 => decay_len, | |
212 => fdecay_len, | |
2354 => ffreq; | |
5.2 => fQ; | |
} | |
if (ch_type=="stomp3") { | |
"saw" => osc_type; | |
2 => atk; | |
[65,54,61,51] @=> chord; | |
2172 => decay_len, | |
2612 => fdecay_len, | |
654 => ffreq; | |
1.7 => fQ; | |
} | |
if (ch_type=="stomp3") { | |
1800 => atk; | |
} | |
for(0 => int i; i<chord.cap(); i++){ | |
Math.random2f(-.6, .6) => float rpan; | |
generate_osc(osc_type, chord[i], rpan, 0.012, | |
[atk, decay_len, 19, 12], | |
[atk, fdecay_len, 69, 12], | |
ffreq, fQ); | |
} | |
} | |
2.6::second => now; | |
// monophonic synth | |
fun void s_generate_osc( | |
string osc_type, | |
int note, | |
float pan, | |
float vgain, | |
int adsr[], int fadsr[], | |
int ffreq, float qual) | |
{ | |
/* | |
The chuck language doesn't permit an if/else statement to determine the | |
oscillator type of a variable named (for instance) vocOsc. I wanted the if / else | |
to act as a switch, depending on the string value of osc_type, i would have : | |
if (osc_type == "saw") SawOsc vocOsc; | |
else if (osc_type == "sin") SinOsc vocOsc; | |
etc... | |
tragically, the monstrosity below is a workaround that instantiates all oscillator | |
types, with gain 0.0 then sets the wanted osctype to gain > 0.0. | |
*/ | |
int mode; | |
if (osc_type=="saw") 0 => mode; | |
else if (osc_type=="sin") 1 => mode; | |
else if (osc_type=="tri") 2 => mode; | |
else if (osc_type=="sqr") 3 => mode; | |
else if (osc_type=="pls") 4 => mode; | |
else if (osc_type=="sss") 5 => mode; | |
ADSR voiceEnv; | |
LPF filt; | |
note => Std.mtof => float frequency; | |
SawOsc vocOscSW => filt => voiceEnv; vocOscSW.gain(0.0); frequency => vocOscSW.freq; | |
SinOsc vocOscSI => filt => voiceEnv; vocOscSI.gain(0.0); frequency => vocOscSI.freq; | |
TriOsc vocOscTR => filt => voiceEnv; vocOscTR.gain(0.0); frequency => vocOscTR.freq; | |
SqrOsc vocOscSQ => filt => voiceEnv; vocOscSQ.gain(0.0); frequency => vocOscSQ.freq; | |
PulseOsc vocOscPS => filt => voiceEnv; vocOscPS.gain(0.0); frequency => vocOscPS.freq; | |
Noise vocOscNS => filt => voiceEnv; vocOscNS.gain(0.0); | |
adsr[0] => int a; | |
adsr[1] => int d; | |
adsr[2] => int s; | |
adsr[3] => int r; | |
fadsr[0] => int fa; | |
fadsr[1] => int fd; | |
fadsr[2] => int fs; | |
fadsr[3] => int fr; | |
voiceEnv.set( a::ms, d::ms, s/100, r::ms ); | |
voiceEnv => Pan2 panObj => dac; | |
//voiceEnv => DelayL flanger1 => panObj; | |
Math.random2(2, 15) => int delayRandom; | |
//flanger1.delay(delayRandom::samp); | |
//flanger1.gain(0.7); | |
pan => panObj.pan; | |
panObj.left => revL; | |
panObj.right => revR; | |
if (mode==0) vgain => vocOscSW.gain; | |
if (mode==1) vgain => vocOscSI.gain; | |
if (mode==2) vgain => vocOscTR.gain; | |
if (mode==3) vgain => vocOscSQ.gain; | |
if (mode==4) vgain => vocOscPS.gain; | |
if (mode==5) vgain => vocOscNS.gain; | |
// filter function taken (and modified) from William Dilworth | |
44100/frequency => float grain; | |
Step s5 => ADSR filtEnv => blackhole; | |
filtEnv.set(fa::ms, fd::ms, fs/100, fr::ms); | |
filtEnv.keyOn(1); | |
voiceEnv.keyOn(1); | |
filt.Q(qual); | |
(a+d)::ms + now => time later; | |
while(now < later) | |
{ | |
filtEnv.last()*ffreq => filt.freq; | |
grain::samp => now; | |
if( now > later){ | |
(a+d)::ms => now; | |
voiceEnv.keyOff(1); | |
filtEnv.keyOff(1); | |
} | |
} | |
r*2::ms => now; // wait for tail to finish. | |
// disconnect to clean up | |
vocOscSW =< panObj; | |
vocOscSI =< panObj; | |
vocOscTR =< panObj; | |
vocOscSQ =< panObj; | |
vocOscPS =< panObj; | |
vocOscNS =< panObj; | |
panObj =< dac; | |
} | |
// This is a wrapper fnction for the osc, means I can call a sporked function | |
// without always adding the spork syntax. | |
fun void generate_osc( | |
string osc_type, | |
int note, | |
float pan, | |
float vgain, | |
int adsr[], int fadsr[], | |
int ffreq, float qual) | |
{ | |
spork ~ s_generate_osc(osc_type, note, pan, vgain, adsr, fadsr, ffreq, qual); | |
} | |
// filter sweep: | |
fun int filtSweep(){ | |
4100 => float frange; | |
((freqFilterEnv.last()*3100) + 400.0) $ int => int frequency; // cast to int | |
return frequency; | |
} | |
fun void do_shake(int length){ | |
spork ~ s_do_shake(length); | |
} | |
fun void s_do_shake(int length){ | |
Shakers espi => ADSR shakeEnv => hatVPan; | |
espi.preset(9); | |
espi.objects(1); | |
espi.energy(1.0); | |
espi.noteOn(1.0); | |
shakeEnv.set( 2::ms, length::ms, 0.20, 35::ms ); | |
shakeEnv.keyOn(1); | |
length::ms => now; | |
espi.noteOff(1.0); | |
shakeEnv.keyOff(1); | |
1::second => now; // time for tail. | |
shakeEnv =< hatVPan; | |
espi =< shakeEnv; | |
} | |
fun void do_shake2(int length, float vol, int preset){ | |
spork ~ s_do_shake2(length, vol, preset); | |
} | |
fun void s_do_shake2(int length, float vol, int preset){ | |
Shakers espi => ADSR shakeEnv => Gain tm => Dyno dank => hatVPan2; | |
tm.gain(vol/4); | |
dank.compress(); | |
espi.preset(preset); | |
espi.objects(22.0); | |
espi.energy(.22); | |
espi.decay(0.2); | |
espi.noteOn(1.0); | |
2::ms => now; // slight delay compensation | |
shakeEnv.set( 2::ms, length::ms, 0.20, 235::ms ); | |
shakeEnv.keyOn(1); | |
length::ms => now; | |
espi.noteOff(1.0); | |
shakeEnv.keyOff(1); | |
1::second => now; // time for tail. | |
shakeEnv =< hatVPan2; | |
espi =< shakeEnv; | |
} | |
fun void do_kick2(float volume){ | |
spork ~ s_do_kick2(volume); | |
} | |
fun void s_do_kick2(float volume){ | |
SawOsc spitch => SinOsc bd_osc => | |
Gain preAmp => ADSR bdADSR => bdmaster; | |
bdmaster.gain(volume); | |
20 => bd_osc.freq; | |
162.22 => spitch.gain; | |
2 => bd_osc.sync; | |
bdADSR.set( 1::ms, 211::ms, 0.0, 35::ms ); | |
2.6 => preAmp.gain; | |
-1.0 => spitch.phase; | |
.6 => spitch.sfreq; | |
bdADSR.keyOn(); | |
1.5::second => now; | |
bd_osc =< preAmp; | |
} | |
// util functions | |
fun int[] join_int_arrays(int arr1[], int arr2[]) | |
{ | |
[arr1, arr2] @=> int arr[][]; | |
int new_arr[0]; | |
for(0 => int j; j<arr.cap(); j++){ | |
for(0 => int i; i<arr[j].cap(); i++){ | |
new_arr << arr[j][i]; | |
} | |
} | |
return new_arr; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment