Skip to content

Instantly share code, notes, and snippets.

@zeffii
Forked from anonymous/SynthDesign3c.ck
Created December 2, 2013 03:35
Show Gist options
  • Save zeffii/7744593 to your computer and use it in GitHub Desktop.
Save zeffii/7744593 to your computer and use it in GitHub Desktop.
// 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