// Generative drum machine // 2-5-19 // Jon Vredenburg /* Ideas: Start with completely random - let the brain generate patterns Try Selection without replacement Try getting crazy with the rhythm - duhhh High level parameters - 1. tempo 2. maybe probabilities for groups of instruements? knob for kick prob, snare prob, cymbal prob all at 100, then every one is playing every beat? */ SndBuf samples[32]; Pan2 pan[samples.size()]; // reverb NRev rL => dac.chan(0); NRev rR => dac.chan(1); rL.mix(0.01); rR.mix(0.01); me.dir() + "kick1.wav" => samples[1].read; me.dir() + "kick2.wav" => samples[2].read; me.dir() + "snare1.wav" => samples[3].read; me.dir() + "snap1.wav" => samples[4].read; me.dir() + "shaker1.wav" => samples[5].read; me.dir() + "clap1.wav" => samples[6].read; me.dir() + "hihat1.wav" => samples[7].read; me.dir() + "hihat2.wav" => samples[8].read; // Some repeats - me.dir() + "clap1.wav" => samples[9].read; me.dir() + "hihat1.wav" => samples[10].read; me.dir() + "hihat2.wav" => samples[11].read; me.dir() + "bassA1.wav" => samples[12].read; me.dir() + "bassA1.wav" => samples[13].read; me.dir() + "synth1.wav" => samples[14].read; me.dir() + "synth2.wav" => samples[15].read; me.dir() + "synth3.wav" => samples[16].read; // connect for( int i; i < samples.size(); i++ ) { // not sound 0 => samples[i].gain; // connect samples[i] => pan[i]; pan[i].left => rL; pan[i].right => rR; } //0 => pan[16].pan; 483.87::ms => dur starting_beat; starting_beat => dur beat; 1 => float beat_divisor; spork ~ play(samples[16], 0.7, beat); // MIDI stuff fun void midiLoop() { // number of the device to open (see: chuck --probe) 0 => int device; // get command line if( me.args() ) me.arg(0) => Std.atoi => device; // the midi event MidiIn min; // the message for retrieving data MidiMsg msg; // open the device if( !min.open( device ) ) return; // print out device that was opened <<< "MIDI device:", min.num(), " -> ", min.name() >>>; // infinite time-loop while( true ) { // wait on the event 'min' min => now; // get the message(s) while( min.recv(msg) ) { // reject not 176 message if( msg.data1 != 176 ) continue; if(msg.data2 == 48){ <<< msg.data3 >>>; 500::ms => beat; 200::ms * 127 / (msg.data3 + 10) => beat; if(msg.data3 == 0){ starting_beat => beat; } } if(msg.data2 == 49){ <<< msg.data3 >>>; 400::ms => beat; } if(msg.data2 == 50){ <<< msg.data3 >>>; 300::ms => beat; } if(msg.data2 == 51){ <<< msg.data3 >>>; 600::ms => beat; } if(msg.data2 == 63){ rL.mix(0.01); rR.mix(0.01); <<< msg.data3 >>>; 1 => beat_divisor; if(msg.data3 > 15){ 2 => beat_divisor; } if(msg.data3 > 40){ 3 => beat_divisor; rL.mix(0.08); rR.mix(0.00); } if(msg.data3 > 70){ 4 => beat_divisor; rL.mix(0.00); rR.mix(0.08); } if(msg.data3 > 100){ 8 => beat_divisor; rL.mix(0.0); rR.mix(0.0); } } if( msg.data2 > 8 ) continue; // print out midi message } } } spork ~ midiLoop(); // spork for midi input Event new_section; fun void fm_thing(Event e){ // carrier sinosc c => dac; c.gain(0); // modulator sinosc m => blackhole; // carrier frequency 220 => float cf; // modulator frequency 410 => float mf => m.freq; // index of modulation .5 => float index; while(true){ e => now; c.gain(.3); Math.random2(-30, 30) + 440 => mf; // time-loop repeat( 1000 ) { // modulate cf + (index * mf * m.last()) => c.freq; // advance time by 1 samp 10::samp => now; } c.gain(0); } } spork ~ fm_thing(new_section); //while(true){ 4*beat => now; spork ~ play(samples[16], 0.25, beat*16); 0 => int counter; new_section.signal(); repeat(50){ //Suggested - 60 counter++; counter % 12 => counter; //beat/4 => now; beat / (4 / Math.random2(1,2)) => now; spork ~ play(samples[Math.random2(3,11)], Math.random2f(0.3,1), beat/beat_divisor); } new_section.signal(); starting_beat => beat; beat => now; spork ~ play(samples[16], 0.7, beat*4); beat => now; beat => now; spork ~ play(samples[2], .8, beat/beat_divisor); beat / 2 => now; spork ~ play(samples[2], .8, beat/beat_divisor); beat / 2 => now; spork ~ play(samples[3], .8, beat/beat_divisor); beat / 4 => now; spork ~ play(samples[3], .8, beat/beat_divisor); beat / 2 => now; spork ~ play(samples[3], .8, beat/beat_divisor); beat / 4 => now; main_theme_with_bass(2); spork ~ play(samples[2], .8, beat/beat_divisor); beat / 2 => now; repeat(60){ //Suggested - 60 - kick and snare beat / (4 / Math.random2(1,2)) => now; spork ~ play(samples[Math.random2(2,4)], Math.random2f(0.3,1), beat/beat_divisor); } new_section.signal(); main_theme(3); repeat(40){ //Suggested - 20 - Add Bass beat / (4 / Math.random2(1,2)) => now; spork ~ play(samples[Math.random2(6,13)], Math.random2f(0.3,1), beat/beat_divisor); } repeat(10){ // Suggested - 10 beat / (4 / Math.random2(1,2)) => now; spork ~ play(samples[Math.random2(10,13)], Math.random2f(0.1,1), beat/beat_divisor); } new_section.signal(); repeat(20){ // Suggested - 20 beat / (4 / Math.random2(1,2)) => now; spork ~ play(samples[Math.random2(10,11)], Math.random2f(0.1,1), beat/beat_divisor); // spork ~ play(samples[Math.random2(14,16)], Math.random2f(0.3,1), beat/beat_divisor); // Synth Stabs } starting_beat => beat; beat => now; spork ~ play(samples[16], 0.7, beat*11); 8*beat => now; repeat(4){ spork ~ play(samples[11], Math.random2f(.1,1), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[11], Math.random2f(.1,1), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[10], Math.random2f(.1,1), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[10], Math.random2f(.1,1), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[11], Math.random2f(.1,1), beat/beat_divisor); beat / 2 => now; spork ~ play(samples[10], Math.random2f(.1,1), beat/beat_divisor); } beat => now; spork ~ play(samples[16], 0.7, beat*11); repeat(8){ // Hihat only (with synth over top spork ~ play(samples[11], Math.random2f(.1,1), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[11], Math.random2f(.1,1), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[10], Math.random2f(.1,1), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[10], Math.random2f(.1,1), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[11], Math.random2f(.1,1), beat/beat_divisor); beat / 2 => now; spork ~ play(samples[10], Math.random2f(.1,1), beat/beat_divisor); } repeat(8){ // four on the floor kick pattern and hihat spork ~ play(samples[Math.random2(1,2)], Math.random2f(0.7,.8), beat/beat_divisor); spork ~ play(samples[11], Math.random2f(.1,1), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[11], Math.random2f(.1,1), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[10], Math.random2f(.1,1), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[10], Math.random2f(.1,1), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[Math.random2(1,2)], Math.random2f(0.7,.8), beat/beat_divisor); spork ~ play(samples[11], Math.random2f(.1,1), beat/beat_divisor); beat / 2 => now; spork ~ play(samples[10], Math.random2f(.1,1), beat/beat_divisor); beat / 2 => now; } repeat(150){ // Suggested - 200 beat / (4 / Math.random2(1,2)) => now; spork ~ play(samples[Math.random2(10,13)], Math.random2f(0.3,1), beat/beat_divisor); spork ~ play(samples[Math.random2(1,2)], Math.random2f(0.1,.8), beat/beat_divisor); } starting_beat => beat; beat => now; spork ~ play(samples[16], 0.7, beat*17); 32*beat => now; //} // while loop to make it infinite fun void main_theme(int reps){ repeat(reps){ spork ~ play(samples[2], .8, beat/beat_divisor); beat / 4 => now; beat / 4 => now; beat / 4 => now; beat / 4 => now; //spork ~ play(samples[3], .8, beat/beat_divisor); beat / 4 => now; beat / 4 => now; spork ~ play(samples[2], .8, beat/beat_divisor); beat / 4 => now; beat / 4 => now; //spork ~ play(samples[2], .8, beat/beat_divisor); beat / 4 => now; beat / 4 => now; beat / 4 => now; spork ~ play(samples[3], .8, beat/beat_divisor); beat / 4 => now; beat / 4 => now; spork ~ play(samples[3], .2, beat/beat_divisor); beat / 4 => now; spork ~ play(samples[3], .3, beat/beat_divisor); beat / 4 => now; spork ~ play(samples[3], .6, beat/beat_divisor); beat / 4 => now; } } fun void main_theme_with_bass(int reps){ repeat(reps){ spork ~ play(samples[2], .8, beat/beat_divisor); spork ~ play(samples[13], .8, beat/beat_divisor); beat / 4 => now; beat / 4 => now; beat / 4 => now; spork ~ play(samples[13], .8, beat/beat_divisor); beat / 4 => now; //spork ~ play(samples[3], .8, beat/beat_divisor); beat / 4 => now; spork ~ play(samples[13], .8, beat/beat_divisor); beat / 4 => now; spork ~ play(samples[2], .8, beat/beat_divisor); beat / 4 => now; beat / 4 => now; //spork ~ play(samples[2], .8, beat/beat_divisor); beat / 4 => now; beat / 4 => now; beat / 4 => now; spork ~ play(samples[3], .8, beat/beat_divisor); beat / 4 => now; spork ~ play(samples[12], Math.random2f(.2,.8), beat/beat_divisor); beat / 4 => now; spork ~ play(samples[3], .2, beat/beat_divisor); beat / 4 => now; spork ~ play(samples[3], .3, beat/beat_divisor); beat / 4 => now; spork ~ play(samples[3], .6, beat/beat_divisor); beat / 4 => now; } } fun void play(SndBuf buf, float gain){ 0 => buf.pos; gain => buf.gain; buf.length() => now; } fun void play(SndBuf buf, float gain, dur duration){ 0 => buf.pos; gain => buf.gain; duration => now; 0 => buf.gain; }