commit
6aaa87b3d0
Binary file not shown.
|
After Width: | Height: | Size: 174 KiB |
@ -0,0 +1,69 @@ |
|||||||
|
|
||||||
|
# distances bending |
||||||
|
|
||||||
|
## materials |
||||||
|
the code and its player have four different voices at their disposal: *difference tones*, *noise flute*, *breath noise*, and *future tones*. |
||||||
|
|
||||||
|
### tones |
||||||
|
difference and future tones are generated live by supercollider oscillators. |
||||||
|
|
||||||
|
the **difference tones** range from 20 to 160 herz. we call them difference tones because their frequencies are defined by differences between some of the frequencies played by clara and bec. |
||||||
|
|
||||||
|
the **future tones** range from 800 to 6000 herz. at the times when they are played, they anticipate tones that clara and bec will play in the future, meaning later in the piece. |
||||||
|
|
||||||
|
### samples |
||||||
|
noise flute and breath noise are samples provided by clara and bec. |
||||||
|
|
||||||
|
**noise flute** consists of eight mono samples (the files `S2_480_mix.wav`, `S2_560_mix.wav`, `S2_640_mix.wav`, etc. are named according to frequency; in the score, these will be sample `a`, `b`, `c`, etc.). |
||||||
|
|
||||||
|
**breath noise** is a single stereo sample that lasts for around five minutes. in one-hour versions of the piece, it is triggered once, at the 35-minute mark. |
||||||
|
|
||||||
|
## organization |
||||||
|
in 2023 a one-hour version of the piece was presented (at oscillation and again at p.a.s.). |
||||||
|
|
||||||
|
this version had six sections numbered II to VII. the table in `DB 1H Time distribution table V3.pdf` sets out the framework within which the code provided the ability (via `generate-score_2023.scd`) to specify scores for playing the samples and tones. |
||||||
|
|
||||||
|
for example, in section II, the palette is constrained to: |
||||||
|
|
||||||
|
- difference tones at 20 40 herz, |
||||||
|
- noise flute samples a–c, |
||||||
|
- future tones ranging from 800 to 1100 herz. |
||||||
|
|
||||||
|
the hand-written notes in `IMG_3122.jpg` specify minimum and maximum numbers of occurrences for each class of event. |
||||||
|
|
||||||
|
for example, in section II, these are: |
||||||
|
|
||||||
|
- difference tones: at least 0 events, at most 1 event, |
||||||
|
- noise flute: at least 0, at most 2 events, |
||||||
|
- future tones: at least 1, at most 3 events, no frequency to be played more than once. |
||||||
|
|
||||||
|
## code |
||||||
|
|
||||||
|
init.scd |
||||||
|
|
||||||
|
- instructions for setting up Babyface sound card with bbfpromix (linux) |
||||||
|
- initialize server |
||||||
|
- set up SynthDefs `\difference`, `\future`, `\mono_sampler`, `\stereo_sampler` |
||||||
|
- amplitudes for the samples are hard-coded as arguments to `\mono_sampler` and `\stereo_sampler` |
||||||
|
- populate Dicts and set up TUI triggers (with durations) for tones |
||||||
|
- load samples |
||||||
|
- instantiate sample synths and set up TUI triggers for samples |
||||||
|
|
||||||
|
generate-score_2023.scd |
||||||
|
|
||||||
|
- each section of the piece gets a Dictionary containing its sound materials (frequencies, sample identifiers) and its start time and duration (in minutes) |
||||||
|
- post the temporal contraints we're working with |
||||||
|
- specify the events and post them: this is the score a player can play from |
||||||
|
- re-initialize some variables (in case we want to generate a new score) |
||||||
|
|
||||||
|
triggers.scd |
||||||
|
|
||||||
|
- pink noise for sound checking |
||||||
|
- code blocks for triggering events. for each block, the first line or lines functions as a play button. for tones, the amplitude is also set (and can be altered) here. example: |
||||||
|
``` |
||||||
|
( ~play_dTone.value( |
||||||
|
"20hz", amp: 0.18, out: 1); ) |
||||||
|
~dTone_synths["20hz"].set(\gate, 0); |
||||||
|
``` |
||||||
|
- note that samples don't have amplitudes modifiable at in the trigger blocks; as noted above, they're in init.scd |
||||||
|
- the last line in each trigger block is the stop button |
||||||
@ -0,0 +1,280 @@ |
|||||||
|
|
||||||
|
( |
||||||
|
// generate score II - V (unsorted) |
||||||
|
|
||||||
|
// sound parameters - dif[ference tones], noi[se flute], fut[ure tones] |
||||||
|
// |
||||||
|
~ii = Dictionary.newFrom( |
||||||
|
[\label, "II ", \dif, [[20,40], [1,1]], \noi, [[\a,\b,\c,], [0,1,2]], |
||||||
|
\fut, [[800,880,900,1000,1100],[1,2,3]]]); |
||||||
|
~iii = Dictionary.newFrom( |
||||||
|
[\label, "III", \dif, [[40,80],[1,1]], \noi, [[\d,\e,\f],[0,1,2]], |
||||||
|
\fut, [[1760,1800,2020],[1,2,3]]]); |
||||||
|
~iv = Dictionary.newFrom( |
||||||
|
[\label, "IV ", \dif, [[80,160],[0,1,2]], \noi, [[nil],[0]], |
||||||
|
\fut, [[3000,3300,4200],[1,2,3]]]); |
||||||
|
~v = Dictionary.newFrom( |
||||||
|
[\label, "V ", \dif, [[0],[0]], \noi, [[\g,\h],[0,1,2]], |
||||||
|
\fut, [[6000],[1]]]); |
||||||
|
|
||||||
|
// temporal bounds |
||||||
|
"".postln; "Temporal constraints".postln; |
||||||
|
[~ii, ~iii, ~iv, ~v].do({ arg item, i; var a, b, c; |
||||||
|
|
||||||
|
// minutes [start, duration] |
||||||
|
a = [[0, 19], [20, 13], [40, 8], [49, 5]]; |
||||||
|
|
||||||
|
// .put: Associate two objects and add them to the Dictionary. |
||||||
|
item.put(\start, a[i].at(0)); |
||||||
|
item.put(\duration, a[i].at(1)); |
||||||
|
|
||||||
|
item.put(\end, a[i].at(1)); // unused? |
||||||
|
item.put(\bounds, a.at(i)); // unused? |
||||||
|
|
||||||
|
// seconds - unused for now |
||||||
|
b = a.deepCollect(2, { arg j; j * 60}); |
||||||
|
c = b.collect({ arg k; k[1] = k[0] + k[1]}); |
||||||
|
|
||||||
|
// post |
||||||
|
(item[\label].asString + item[\bounds].asString + "minutes").postln }); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// generate scores II - V (unsorted) |
||||||
|
"".postln; " s c o r e".postln; |
||||||
|
|
||||||
|
[~ii, ~iii, ~iv, ~v].do({ arg section, i; |
||||||
|
"".postln; |
||||||
|
(" * *" + section[\label]).postln; |
||||||
|
|
||||||
|
// difference tones and noise samples |
||||||
|
// may repeat |
||||||
|
[\dif, \noi].do({ arg it; // the types of event we want |
||||||
|
n = section[it][1].choose; // the no. of events of each type |
||||||
|
if ( n > 0, {("##" + it.asString ++ ": ").postln}, {}); // label: type |
||||||
|
|
||||||
|
n.do({ arg i; |
||||||
|
(section[it][0].choose.asString ++ ": ").post; // freq / sample code |
||||||
|
((section[\duration].rand + section[\start]).asString |
||||||
|
+ "min." + 60.rand.asString).post; // timestamp |
||||||
|
"".postln; "".postln; |
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
// future tones |
||||||
|
// one use per frequency |
||||||
|
x = section[\fut][0]; |
||||||
|
|
||||||
|
n = section[\fut][1].choose; // the no. of events of each type |
||||||
|
if ( n > 0, {("##" + \fut.asString ++ ": ").postln}, {}); // label: type |
||||||
|
|
||||||
|
n.do ({ arg i; |
||||||
|
// choose a frequency, return it and delete it from the array |
||||||
|
(x.removeAt(x.size.rand).asString ++ ": ").post; |
||||||
|
((section[\duration].rand + section[\start]).asString |
||||||
|
+ "min." + 60.rand.asString).postln; // timestamp |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
// "".postln; |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
// since removeAt has deleted items from \fut, |
||||||
|
// (because we didn't want future tones to be repeatable) |
||||||
|
// restore the dictionary so that we can generate |
||||||
|
// a new score when we want to |
||||||
|
// TODO: make an unrepeating stream up to n and |
||||||
|
// use that to select \fut items rather than removing them |
||||||
|
f = [ |
||||||
|
[[800,880,900,1000,1100],[1,2,3]], |
||||||
|
[[1760,1800,2020],[1,2,3]], |
||||||
|
[[3000,3300,4200],[1,2,3]], |
||||||
|
[[6000],[1]]]; |
||||||
|
|
||||||
|
// .add: if the key value pair already exists in the Dictionary, the key's value will be replaced |
||||||
|
[~ii, ~iii, ~iv, ~v].do({ arg section, i; section.add(\fut -> f[i].value ) }); |
||||||
|
|
||||||
|
""; |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
// current code ends here |
||||||
|
|
||||||
|
// below here, only scraps of earlier code |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
) |
||||||
|
|
||||||
|
x = ~ii[\fut][0]; |
||||||
|
y = x.size.rand; |
||||||
|
x.removeAt(x.size.choose); |
||||||
|
x; |
||||||
|
|
||||||
|
( |
||||||
|
// generate scores II - V (unsorted, repeats allowed) |
||||||
|
"".postln; |
||||||
|
|
||||||
|
[~ii, ~iii, ~iv, ~v].do({ arg item, i; |
||||||
|
("*" + item[\label]).postln; |
||||||
|
|
||||||
|
[\dif, \noi, \fut].do({ arg it; // the types of event we want |
||||||
|
n = item[it][1].choose; // the no. of events of each type |
||||||
|
if ( n > 0, {("##" + it.asString ++ ": ").postln}, {}); // label: type |
||||||
|
//"".postln; |
||||||
|
n.do({ arg i; |
||||||
|
(item[it][0].choose.asString ++ ": ").post; // freq / sample code |
||||||
|
((item[\duration].rand + item[\start]).asString |
||||||
|
+ "min." + 60.rand.asString).post; // timestamp |
||||||
|
"".postln; "".postln; |
||||||
|
}); |
||||||
|
}); |
||||||
|
"".postln; |
||||||
|
|
||||||
|
}); |
||||||
|
"".postln; |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
( |
||||||
|
// generate score II |
||||||
|
"".postln; "* II *".postln; |
||||||
|
"".postln; |
||||||
|
[\dif, \noi, \fut].do({ arg it; // the types of event we want |
||||||
|
n = ~ii[it][1].choose; // the no. of events of each type |
||||||
|
if ( n > 0, {("##" + it.asString ++ ": ").postln}, {}); // label: type |
||||||
|
//"".postln; |
||||||
|
n.do({ arg i; |
||||||
|
(~ii[it][0].choose.asString ++ ": ").post; // freq / sample code |
||||||
|
(~ii[\duration].rand.asString |
||||||
|
+ "min." + 60.rand.asString).post; // timestamp |
||||||
|
"".postln; "".postln; |
||||||
|
}); |
||||||
|
}); |
||||||
|
"".postln; |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
( |
||||||
|
"".postln; |
||||||
|
"~lengthII = ".post; ~lengthII = (11 * 60).postln; // total section time |
||||||
|
"n = ".post; n = [1,2,3].choose.postln; // no. of rests |
||||||
|
"~lengthRstsII = ".post; ~lengthRstsII = ( ~lengthII - (n * 31.5) ).postln; |
||||||
|
|
||||||
|
// rest lengths will go in here |
||||||
|
a = Array.fill([2,n], 0); |
||||||
|
|
||||||
|
// iterate over n rest events |
||||||
|
n.do({ arg i; var j, k; |
||||||
|
j = i - 1; |
||||||
|
|
||||||
|
// for this rest, put duration in row 0 |
||||||
|
k = if( i > 0, // after first iteration |
||||||
|
{ a[1].at(j) }, { 0 }); // |
||||||
|
a[0].put( i, (~lengthRstsII - k).rand.asInteger.max(30) ); |
||||||
|
|
||||||
|
// put sum of durations through n in row 1 |
||||||
|
l = if( i > 0, |
||||||
|
{ a[0].at(i) + a[1].at(j) }, { a[0].at(i) } ); |
||||||
|
a[1].put( i, l); |
||||||
|
}); |
||||||
|
a; |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
a; |
||||||
|
|
||||||
|
a[0] = ~lengthRstsII.rand.asInteger; |
||||||
|
|
||||||
|
a[1] = (~lengthRstsII - a[0]).rand.asInteger ; |
||||||
|
a[2] = (~lengthRstsII - a[0]) |
||||||
|
|
||||||
|
~lengthRstsII - a[1]; |
||||||
|
|
||||||
|
|
||||||
|
( |
||||||
|
n = 3; |
||||||
|
n.do({ |
||||||
|
arg i; |
||||||
|
j = i - 1; |
||||||
|
a[i] = (~lengthRstsII - ( a.at(j) )).rand.asInteger; |
||||||
|
}); |
||||||
|
) |
||||||
|
|
||||||
|
( |
||||||
|
j = 5; |
||||||
|
while( {j > 0}, { |
||||||
|
j.postln; |
||||||
|
j = j - 1; |
||||||
|
} ) |
||||||
|
) |
||||||
|
|
||||||
|
( |
||||||
|
n = 3; |
||||||
|
n.do({ arg i; var j; |
||||||
|
j = n - i - 1; |
||||||
|
{j > -1}.while( { |
||||||
|
j.postln; |
||||||
|
j = (j - 1) |
||||||
|
} ) |
||||||
|
}); |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
( |
||||||
|
n.do( { arg i; r = r.put( i, Rest().asString ) } ) |
||||||
|
) |
||||||
|
|
||||||
|
// number of total elements |
||||||
|
g = Array.fill(( n * 2 + 1 ), "rest"); |
||||||
|
|
||||||
|
|
||||||
|
// set the note durations to 30s |
||||||
|
// n.do({ arg i; g = g.put( (i * 2 + 1), 30) }); |
||||||
|
g.size.do( { arg i; g = g.put(i, if( i.even, "Rest()", 30) ) } ); g |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
p = (n * 2 + 1); |
||||||
|
d = Array.fill(p, { arg i; |
||||||
|
if( |
||||||
|
i.even, Rest |
||||||
|
) |
||||||
|
}) |
||||||
|
"total = ".postln; (~r3 + ~r1 + ~r2 + ~lengthEvtsII); |
||||||
|
) |
||||||
|
~durations = [Rest(~r1), 30, Rest(~r2), 30, Rest(~r3), 30]; |
||||||
|
|
||||||
|
( |
||||||
|
"n = ".post; n = [1,2,3].choose.postln; |
||||||
|
p = (n * 2 + 1); |
||||||
|
f = Array.fill( p, { [20,40].choose }).postln; |
||||||
|
d = Array.fill( p, { arg i; if(i.even, Rest(30.rand).asString, 30)}); |
||||||
|
) |
||||||
|
|
||||||
|
( |
||||||
|
p = Pbind ( |
||||||
|
\instrument, "sine", |
||||||
|
\freq, Pseq([800, 0, 1100, 600], 1), |
||||||
|
\dur, Pseq([2, Rest(1), 2, 2], 1), |
||||||
|
\amp, 4 |
||||||
|
// \futrrelease, 2, |
||||||
|
// \legato, 0.1 |
||||||
|
).play; |
||||||
|
|
||||||
|
) |
||||||
@ -0,0 +1,224 @@ |
|||||||
|
/* 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; |
||||||
|
|
||||||
@ -0,0 +1,124 @@ |
|||||||
|
|
||||||
|
|
||||||
|
// test speakers |
||||||
|
// ch 0, 1 |
||||||
|
y = { Out.ar (0, Pan2.ar(PinkNoise.ar, MouseX.kr(-1, 1), 0.05)) }.play; |
||||||
|
y.free; |
||||||
|
// ch 2, 3 |
||||||
|
z = { Out.ar (2, Pan2.ar(PinkNoise.ar, MouseX.kr(-1, 1), 0.05)) }.play; |
||||||
|
z.free; |
||||||
|
|
||||||
|
s.freeAll; |
||||||
|
|
||||||
|
// * let's play * |
||||||
|
|
||||||
|
|
||||||
|
// difference tones |
||||||
|
( ~play_dTone.value( |
||||||
|
"20hz", amp: 0.18, out: 1); ) |
||||||
|
~dTone_synths["20hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_dTone.value( |
||||||
|
"40hz", amp: 0.025, out: 1); ) |
||||||
|
~dTone_synths["40hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_dTone.value( |
||||||
|
"80hz", amp: 0.008, out: 1); ) |
||||||
|
~dTone_synths["80hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_dTone.value( |
||||||
|
"160hz", amp: 0.005, out: 1); ) |
||||||
|
~dTone_synths["160hz"].set(\gate, 0); |
||||||
|
|
||||||
|
|
||||||
|
// samples |
||||||
|
( ~playSamp.value("a"); ) |
||||||
|
~samp[0].set(\trigger, -1, \gate, 0); |
||||||
|
|
||||||
|
( "b"; |
||||||
|
~playSamp.value("b"); ) |
||||||
|
~samp[1].set(\trigger, -1, \gate, 0); |
||||||
|
|
||||||
|
( "c"; |
||||||
|
~playSamp.value("c"); ) |
||||||
|
~samp[2].set(\trigger, -1, \gate, 0); |
||||||
|
|
||||||
|
( "d"; |
||||||
|
~playSamp.value("d"); ) |
||||||
|
~samp[3].set(\trigger, -1, \gate, 0); |
||||||
|
|
||||||
|
( "e"; |
||||||
|
~playSamp.value("e"); ) |
||||||
|
~samp[4].set(\trigger, -1, \gate, 0); |
||||||
|
|
||||||
|
( "f"; |
||||||
|
~playSamp.value("f"); ) |
||||||
|
~samp[5].set(\trigger, -1, \gate, 0); |
||||||
|
|
||||||
|
( "g"; |
||||||
|
~playSamp.value("g"); ) |
||||||
|
~samp[6].set(\trigger, -1, \gate, 0); |
||||||
|
|
||||||
|
( "h"; |
||||||
|
~playSamp.value("h"); ) |
||||||
|
~samp[7].set(\trigger, -1, \gate, 0); |
||||||
|
|
||||||
|
|
||||||
|
( "breath noise"; |
||||||
|
"start"; ~playBreathSamp.value; ) |
||||||
|
"stop"; ~stopBreathSamp.value; |
||||||
|
|
||||||
|
|
||||||
|
// future tones |
||||||
|
( ~play_fTone.value("800hz", |
||||||
|
amp: 0.026, out: 1); ) |
||||||
|
~fTone_synths["800hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_fTone.value("880hz", |
||||||
|
amp: 0.025, out: 1); ) |
||||||
|
~fTone_synths["880hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_fTone.value("900hz", |
||||||
|
amp: 0.025, out: 1); ) |
||||||
|
~fTone_synths["900hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_fTone.value("1000hz", |
||||||
|
amp: 0.025, out: 1); ) |
||||||
|
~fTone_synths["1000hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_fTone.value("1100hz", |
||||||
|
amp: 0.024, out: 1); ) |
||||||
|
~fTone_synths["1100hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_fTone.value("1760hz", |
||||||
|
amp: 0.023, out: 1); ) |
||||||
|
~fTone_synths["1760hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_fTone.value("1800hz", |
||||||
|
amp: 0.023, out: 1); ) |
||||||
|
~fTone_synths["1800hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_fTone.value("2020hz", |
||||||
|
amp: 0.023, out: 1); ) |
||||||
|
~fTone_synths["2020hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_fTone.value("3000hz", |
||||||
|
amp: 0.023, out: 1); ) |
||||||
|
~fTone_synths["3000hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_fTone.value("3300hz", |
||||||
|
amp: 0.023, out: 1); ) |
||||||
|
~fTone_synths["3300hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_fTone.value("4200hz", |
||||||
|
amp: 0.022, out: 1); ) |
||||||
|
~fTone_synths["4200hz"].set(\gate, 0); |
||||||
|
|
||||||
|
( ~play_fTone.value("6000hz", |
||||||
|
amp: 0.021, out: 1); ) |
||||||
|
~fTone_synths["6000hz"].set(\gate, 0); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in new issue