Skip to content

Instantly share code, notes, and snippets.

@catfact
Last active April 2, 2016 13:54
Show Gist options
  • Save catfact/5d61ad5a8a962ff8d17fa56dc469bf3a to your computer and use it in GitHub Desktop.
Save catfact/5d61ad5a8a962ff8d17fa56dc469bf3a to your computer and use it in GitHub Desktop.
cmf 4track (sc)
//-- top level sound directory
d = (thisProcess.platform.recordingsDir ++ "/ftrack/").standardizePath;
//-- dictionary associating subdir names to path arrays
p = Dictionary.new;
PathName(d).folders.do({ |f| p.add(f.folderName.asSymbol -> f.files); });
//-- runtime state stored in this Event
e = (
stuck:[0, 0, 0, 0], // "stuck" flag
stick:0.1, // chance of anyone getting stuck
bb:0, // "back buffer" flag
durmin:1.00, // min in seconds
durmax:30.0, // max in seconds (initial)
dur:10.0, // current duration
start:0.0, // start time in seconds
len:[1, 1, 1, 1], // length of sources
fol:nil, // next folder to play, a \symbol
syn:[nil, nil, nil, nil], // array of Synths
xfmin:0.1,
xfmax:0.6,
xf:0.2 // additional crossfade (proportion of duration)
);
e.postln;
~print = { };
//-- synth
s = Server.default;
/*
s.boot;
*/
s.waitForBoot {
r = Routine {
// playback synth
SynthDef.new(\play, {
arg buf, out=0, amp=1.0, gate=1,
start=0.0, dur=20.0,
atk=1.0, rel=1.0, curve=1.0;
var env, agen, snd;
env = Env.asr(atk, 1.0, rel, curve);// (atk, dur, rel, curve);
agen = EnvGen.ar(env, gate, doneAction:2);
snd = PlayBuf.ar(1, buf, BufRateScale.kr(buf), startPos:start);
Out.ar(out, snd * agen * amp);
}).send(s);
// buffers, two quad arrays (1 current, 1 next).. wtf, just make them v.big
b = Array.fill(2, { Array.fill(4, {
Buffer.alloc(s, s.sampleRate * 60 * 20, 1) // 20 min, mono
}) });
g = Group.new(s);
s.sync;
// function to take first 4 files in a folder, read into set of buffers
~read = { arg bb, key;
var path;
4.do({ |i|
path = p[key][i].fullPath;
SoundFile.use(path, {|sf| e.len[i] = sf.numFrames / sf.sampleRate});
b[bb][i].read(path, e.len[i]);
});
};
// compute duration
~dur = {
e.dur = e.durmin + (e.durmax - e.durmin).rand;
e.start = (e.len.minItem - e.dur).max(0.0).rand;
};
// choose folder and queue it up
~fol = {
var new = e.fol;
while( {e.fol == new}, {new = p.keys.choose;});
e.fol = new;
~read.value(e.bb, e.fol);
};
// start next playback
~play = {
var xf;
e.xf = e.xfmin + (e.xfmax - e.xfmin).rand;
xf = e.xf * e.dur;
4.do({ |i|
if( (e.stuck[i] == 0) && (e.stick.coin),
{
e.stuck[i] = 1;
},
{
e.stuck[i] = 0;
if(e.syn[i].notNil, {
e.syn[i].set(\rel, xf);
e.syn[i].set(\gate, 0);
});
e.syn[i] = Synth.new(\play, [
\out, i % 2, // <- !! modulo for stereo
// \out, i, // <- !! just this for quad
\start, e.start,
\atk, xf,
\buf, b[e.bb][i] ], g);
});
});
e.bb = 1 - e.bb;
};
inf.do ({
~dur.value;
~fol.value;
s.sync;
~play.value;
~print.value;
e.dur.wait;
})
}.play;
}; // waitforboot
/*
s.quit;
*/
///// gui
//--window
{
~scrw = Window.screenBounds.width;
~scrh = Window.screenBounds.height;
v = Window.new("//\//\//\\", Rect(0, 0, ~scrw*0.4, ~scrh));
v.view.backColor_(Color.new(1.0, 0.7, 0.7));
v.view.decorator = FlowLayout(v.view.bounds);
~vdurlab = StaticText(v.view, Point(v.view.bounds.width, 80))
.stringColor_(Color.new(0.18, 0.25, 0.54))
.font_(Font("Arial", 32, true));
~vdursl = RangeSlider(v.view, Point(v.view.bounds.width, 80));
~vdursl.action_({|sl|
e.durmin = (sl.lo * 180).max(1.0);
e.durmax = (sl.hi * 180).max(1.0);
~vdurlab.string_("D: [ "++e.durmin++" , "++e.durmax++" ]");
}).backColor_(Color.new(0.82, 0.75, 0.74))
.knobColor_(Color.new(0.68, 0.85, 0.99));
~vxlab = StaticText(v.view, Point(v.view.bounds.width, 80))
.stringColor_(Color.new(0.18, 0.25, 0.54))
.font_(Font("Arial", 32, true));
~vxsl = RangeSlider(v.view, Point(v.view.bounds.width, 80));
~vxsl.action_({|sl|
e.xfmin = ~vxsl.lo;
e.xfmax = ~vxsl.hi;
~vxlab.string_("X: + [ "++(~vxsl.lo*100.0)++" , "++(~vxsl.hi*100.0)++" ]%");
}).backColor_(Color.new(0.82, 0.75, 0.74))
.knobColor_(Color.new(0.68, 0.85, 0.99));
~vtxt = StaticText(v.view,
Rect(60, 0, v.view.bounds.width - 60, v.view.bounds.height - 80));
~vtxt.font_(Font("Courier",18));
~vtxt.stringColor_(Color.new(0.5, 0.2, 0.3));
~vtxt.backColor_(Color.new(0.9, 0.6, 0.76));
~vtxt.align_(\right);
~print = {
e.asString.postln;
{
~vtxt.string = "";
[\fol, \dur, \start, \xf, \stuck].do({|sym|
~vtxt.string = ~vtxt.string ++ sym.asString ++ " : "
++ e[sym].asString ++ "\r\n";
});
}.defer;
};
v.front;
w = Window.new("\\//\\/||||\//\\/||||\//\\",
Rect(~scrw*0.4, 0, ~scrw*0.6, ~scrh));
w.view.backColor_(Color.new(0.9, 0.6, 0.76));
//-- text field
t = TextView(w);
t.string_(" scanning subfolders at: " ++ d ++ " ... \r\n");
t.backColor_(Color.new(0.9, 0.6, 0.76));
t.stringColor_(Color.new(0.9, 0.2, 0.5));
t.font = Font("Arial", 18);
//t.align_(\left);
w.view.onResize_({t.bounds_(Rect(60, 0, w.bounds.width, w.bounds.height)); });
w.front;
p.keysValuesDo({ |f, p_|
t.string_(t.string ++ "\r\n" ++ f ++ " : \r\n");
p_.do({ |p__| t.string_(t.string ++ p__.fullPath++ "\r\n" ); });
t.setStringColor(t.stringColor, 0, t.string.size);
});
}.defer;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment