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