/* to do - - Stop self-abolition of samples - triangle waves - Gui - DONE Make synths auto-gate after defined periods - DONE that period randomized for future tones */ /* 4-ch Babyface setup: - start Babyface in CC mode (hold SELECT + DIM while plugging in) - pavucontrol, configuration tab: select Pro Audio profile - pavucontrol, output devices tab: set babyface as fallback - bbfpromix: select Hardware output AN1/2, then fade up AN1/2 software playback channels and pan 1 to L and 2 R. - select Hardware output PH3/4, then fade up PH3/4 software playback channels and pan 3 to L and 4 R. - Server.default.options.numOutputBusChannels = 4; - boot sc server */ "reboot"; if ( s.serverRunning, {s.quit} ); ( o = Server.default.options; o.numOutputBusChannels = 4; ) "initialize"; ( // initialize synths s.waitForBoot({ // init stages: // 1 (add synth defs) ** // 2 ( Gui ) ** // 3 (populate SinOsc Dicts, provide ~play_) ** // 4 (populate sampler Array, provide ~play_) ** s.makeBundle(nil, { // ** init: stage 1 (add synth defs) ** // # difference tones SynthDef(\difference, { arg freq = 20, gate = 0, out = 1, attack = 0.5, amp = 0.2, release = 1.0; var env, audio; env = Env.asr(attack, amp, release).kr(gate: gate); audio = SinOsc.ar(freq, mul: env); Out.ar(out, audio) }).add; // # future tones SynthDef(\future, { arg freq = 800, amp = 0.01, gate = 0, out = 1, attack = 0.5, sustain = 0.5, release = 0.5; var audio, env; env = Env.asr(attack, sustain, release).kr(gate: gate); audio = 0.5 * (LFTri.ar(freq, mul: env * amp) + LFTri.ar(freq, mul: env * amp)); Out.ar(out, audio) }).add; // # sampler SynthDef(\mono_sampler, { arg sample, gate = 0, trigger = -1, attack = 0.5, amp = 0.3, release = 0.5; var env, audio; env = Env.asr(attack, amp, release).kr(gate: gate); audio = PlayBuf.ar(1, sample, trigger: trigger, loop: 1); Out.ar(0, audio * env) }).add; // # sampler SynthDef(\stereo_sampler, { arg sample, gate = 0, trigger = -1, attack = 0.5, amp = 0.3, release = 0.5; var env, audio; env = Env.asr(attack, amp, release).kr(gate: gate); audio = PlayBuf.ar(2, sample, trigger: trigger, loop: 1); Out.ar([2], audio * env) }).add; // ** init: stage 2 ( Gui ) ** // wait for stage 1 to complete s.sync; s.makeGui; //s.plotTree; // ** init: stage 3 (populate Dicts, provide ~play_) ** // # 3.1 populate difference tone Dict ~dTone_synths = Dictionary.new(4); [20,40,80,160].do({ arg item, i; ~dTone_synths.add( (item.asString ++ "hz") -> Synth("difference", [ freq: item, amp: [0.4, 0.1, 0.02, 0.01].at(i), gate: 0 ]) ) }); // and set up triggers ~play_dTone = { arg key, amp = 0.2, out = 0; {~dTone_synths[key].set( \gate, 1, \amp, amp, \out, out ); ~dTone_synths[key].get(\freq, { arg val; ( val.asInteger.asString + "Hz, 30 sec.").postln }); 30.wait; // play for 30 sec ~dTone_synths[key].set(\gate, 0) // then release }.fork }; // # 3.2 populate future tone Dict ~fTone_synths = Dictionary.new(12); [800, 880, 900, 1000, 1100, 1760, 1800, 2020, 3000, 3300, 4200, 6000].do({ arg item, i; ~fTone_synths.add( (item.asString ++ "hz") -> Synth ("future", [ freq: item, amp: 0.01, gate: 0 ]) )}); // and set up triggers ~play_fTone = { arg key, amp = 0.01, out = 2; { // trigger the synth we want ~fTone_synths[key].set( \gate, 1, \amp, amp, \out, out); ~futDuration = (16.rand + 15); // post feedback ~fTone_synths[key].get(\freq, { arg val; (val.asInteger.asString + "Hz," + ~futDuration.value.asString + "seconds.") .asString.postln }); // wait and then release ~futDuration.value.wait; ~fTone_synths[key].set(\gate, 0) }.fork }; // 3.3 load samples ~filenames = ["S2_480_mix.wav", "S2_560_mix.wav", "S2_640_mix.wav", "S2_720_mix.wav", "S3_960_mix.wav", "S3_1120_mix.wav", "S3_1280_mix.wav", "S3_1440_mix.wav"]; ~sampleBuffer = ~filenames.collect({ arg filename; Buffer.read(s, Platform.userHomeDir.asString ++ "/a/23/audio/samples/Oscillation/samples/" ++ filename)}); ~breathSample = ( Buffer.read(s, Platform.userHomeDir.asString ++ "/a/23/audio/samples/Oscillation/breath_filter_stereo.wav") ); // ** init: stage 4 (populate sampler Array, provide ~play_) ** // wait for stage 3 to complete s.sync; // instantiate synths ~samp = Array.fill(8, {arg i; Synth(\mono_sampler, [\sample, ~sampleBuffer[i]])}); ~playSamp = { arg key; // // provide Dict associations ["a" -> 0, "b" -> 1... "h" -> 7] d = Dictionary.new(8); ["a", "b", "c", "d", "e", "f", "g", "h"].do({ arg item, i; d.add( item.asString -> i.asInteger ); }); // trigger samp { ~samp[d.at(key)].set(\trigger, 1, \gate, 1); t = (180.rand + 120); ("Sample" + key.asString + "," + t.asString ++ "sec.").postln; t.wait; ~samp[d.at(key)].set(\trigger, -1, \gate, 0)}.fork; }; ~breathSampleSynth = Synth(\stereo_sampler, [\sample, ~breathSample]); ~playBreathSamp = { ~breathSampleSynth.set(\trigger, 1, \gate, 1) }; ~stopBreathSamp = { ~breathSampleSynth.set(\trigger, -1, \gate, 0) }; }) // end makeBundle }) ) ~dTone_synths.getPairs; ~dTone_synths["20hz"]; // return 20hz synth d.getPairs; d.at("d").postln; d.postln;