You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

224 lines
5.4 KiB

/* 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;