Skip to content

Instantly share code, notes, and snippets.

@caseyanderson
Created January 20, 2019 19:05
Show Gist options
  • Save caseyanderson/ca05edb1a80dddbb018b6eaefd0653ec to your computer and use it in GitHub Desktop.
Save caseyanderson/ca05edb1a80dddbb018b6eaefd0653ec to your computer and use it in GitHub Desktop.
// route + mix
s.options.memSize = 2097152;
s.options.numInputBusChannels = 8;
s.options.numOutputBusChannels = 8;
s.boot;
///////// ROUTING AND MASTER MIX CONTROL
(
a = currentEnvironment;
~sources = Array.with('lightpad', 'looped');
// 1 group per source + finalMix group
~lightpad = Group.new;
~looped = Group.after(~lightpad);
~finalMix = Group.after(~looped);
~saveStuff = Group.after(~finalMix);
// number of loopers
~numLoopers = 3; // counts from 0 (this line is currently commented out in 4track_looper.scd
// make the audio and control busses for each sources
for( 0, (~sources.size - 1), { | i |
a[((~sources[i])++"Bus").asSymbol] = Bus.audio(s, 1);
a[((~sources[i])++"BusVol").asSymbol] = Bus.control(s, 1).set(0.0);
});
// master out record
~outRecordBuffer = Buffer.alloc( s, s.sampleRate * 60, 2, completionMessage: { ("Loaded ~outRecordBuffer! numFrames: " + (s.sampleRate * 60)).postln } );
~outRecordInfo = Bus.control(s, 1).set(0.0);
~outRecordBus = Bus.audio(s, 2);
)
(
// the master out synth
SynthDef( \masterOut, { | private, source1, source2, lightpadAmp = 0.5, loopedAmp = 0.5, out = 0, pan = 0, trig = 0 |
var env, finalsig, s1, s2, sig;
env = EnvGen.kr( Env.asr( 0.0, 0.95, 0.05), trig, doneAction: 2 );
s1 = In.ar(source1, 1) * lightpadAmp;
s2 = In.ar(source2, 1) * loopedAmp;
sig = s1 + s2;
finalsig = sig * env;
Out.ar(out, Pan2.ar(finalsig, pan));
Out.ar(private, Pan2.ar(finalsig, pan));
}).add;
SynthDef( \rec_manual_stereo, { | amp = 0.0, buf, inBus, rate = 1, recManualBus, off = 0, trig = 0 |
var env, in, phase;
in = In.ar( inBus, 2 );
phase = Phasor.ar(trig, BufRateScale.kr(buf) * rate, 0, (BufFrames.kr(buf)));
BufWr.ar(in, buf, phase);
Out.kr( recManualBus, phase );
FreeSelf.kr( off );
}).add;
// outputs buffer contents to disc
~saveBuf = { |info, contentBuf, format|
var infoBus = info.asString, buf = contentBuf.asString, form = format.asString;
a[(infoBus).asSymbol].get({ |value|
var dur = value, path;
path = thisProcess.platform.recordingsDir +/+ buf++"_"++Date.localtime.stamp ++ "."++form; // generated path
fork{
a[(buf).asSymbol].write(path, form, "int16", dur, 0);
s.sync;
("saved "++buf++"!").postln;
};
});
};
)
// setup GUI
(
~window = Window.new("mixer", Rect(0, 0, 465, 335))
.onClose_({
"closing".postln;
});
~window.background = Color.gray(0.15);
// coordinates for sources gui
~labelLeft = [10, 70 ];
~labelTop = [ 10, 10 ];
~numLeft = [ 10, 70 ];
~numTop = [240, 240 ];
~sliderLeft = [ 10, 70 ];
~sliderTop = [ 35, 35 ];
// setup sources control gui
for(0, (~sources.size - 1), { | i |
var num;
num = i+1;
// label
a[("s"++num++"Label").asSymbol] = StaticText(~window, Rect( ~labelLeft[i], ~labelTop[i], 50, 20));
a[("s"++num++"Label").asSymbol].align = \center;
a[("s"++num++"Label").asSymbol].background = Color.gray(0.15);
a[("s"++num++"Label").asSymbol].stringColor = Color.white;
a[("s"++num++"Label").asSymbol].string = ~sources[i].asString;
// display val in box
a[("s"++num++"Val").asSymbol] = NumberBox(~window, Rect(~numLeft[i], ~numTop[i], 50, 25));
a[("s"++num++"Val").asSymbol].align = \center;
a[("s"++num++"Val").asSymbol].background = Color.white;
// make the slider, connect to NumberBox
a[("s"++num).asSymbol] = Slider.new(~window, Rect(~sliderLeft[i], ~sliderTop[i], 50, 200))
.focusColor_(Color.red(alpha:0.6))
.background_(Color.black)
.action_({ |slider|
var val;
val = slider.value;
a[(~sources[i]++"BusVol").asSymbol].set(val); // set the volume bus
a[("s"++num++"Val").asSymbol].value_(val); // update the gui
});
// set source VolBus (lightpad and loop)
{ a[("s"++num).asSymbol].valueAction = 0.99 }.defer;
});
// loop controls
~lLabel = StaticText(~window, Rect(125, 10, 300, 20));
~lLabel.align = \center;
~lLabel.background = Color.gray(0.15);
~lLabel.stringColor = Color.white;
~lLabel.string = "///////// loop control /////////";
// looper coordinates
~lefts = [125, 155, 185, 225, 430];
~tops = [35, 65, 95, 125];
// setup looper control gui
for( 0, ~numLoopers, { | i |
var num;
num = i + 1;
// label
a[("l"++num++"Label").asSymbol] = NumberBox(~window, Rect( ~lefts[0], ~tops[i], 25, 25 ) );
a[("l"++num++"Label").asSymbol].align = \center;
a[("l"++num++"Label").asSymbol].background = Color.white;
a[("l"++num++"Label").asSymbol].value = num;
// status
a[("l"++num++"Status").asSymbol] = Button(~window, Rect( ~lefts[1], ~tops[i], 25, 25 ) )
.states_([
["", Color.black, Color.gray],
["", Color.black, Color.red]
]);
// numberbox slider value
a[("l"++num++"Val").asSymbol] = NumberBox(~window, Rect( ~lefts[2], ~tops[i], 35, 25));
a[("l"++num++"Val").asSymbol].align = \center;
// slider (vol)
a[("l"++num++"Vol").asSymbol] = Slider.new(~window, Rect( ~lefts[3], ~tops[i], 200, 25 ) )
.focusColor_(Color.red(alpha:0.6))
.background_(Color.black)
.action_({ |slider|
var val;
val = slider.value;
a[("l"++num++"Val").asSymbol].value_(val);
a[("lPlayVol"++num).asSymbol].set(val);
});
// record the loop
a[("l"++num++"RecLoop").asSymbol] = Button(~window, Rect( ~lefts[4], ~tops[i], 25, 25 ) )
.canFocus_(false)
.states_([
["R", Color.black, Color.gray],
["R", Color.black, Color.red]
])
.action_({ arg butt;
// ~recordLoopMono.value(num, "wav");
~saveBuf.value( ("bDur"++num), ("loopbuf"++num), "wav" );
});
// initial settings
{ a[("l"++num++"Vol").asSymbol].valueAction = 0.0 }.defer;
{ a[("l"++num++"Status").asSymbol].value_(0) }.defer;
});
~run = False; // flag to denote masterout is running
// master output toggle
~runMaster = Button(~window, Rect( 10, 270, 110, 25 ) )
.canFocus_(false)
.states_([
["OFF", Color.black, Color.gray],
["ON", Color.black, Color.red]
])
.action_({ arg butt;
if( butt.value == 1, {
if( ~run == False, {
"RUN MASTER OUT".postln;
~m = Synth.new(\masterOut, [\private, ~outRecordBus.index, \source1, ~lightpadBus.index, \source2, ~loopedBus.index, \lightpadAmp, ~lightpadBusVol.asMap, \loopedAmp, ~loopedBusVol.asMap, \trig, 1], ~finalMix);
~run = True;
});
},{
"STOP MASTER OUT".postln;
~m.set(\trig, 0);
~m.free;
~run = False;
});
});
// master rec toggle
~recMaster = Button(~window, Rect( 10, 300, 110, 25 ) )
.canFocus_(false)
.states_([
["XXX", Color.black, Color.gray],
["REC", Color.black, Color.red]
])
.action_({ arg butt;
if( butt.value == 1, {
if( ~run == True, {
"REC MASTER OUT".postln;
~allRec = Synth.new(\rec_manual_stereo, [ \amp, 0.9, \buf, ~outRecordBuffer, \inBus, ~outRecordBus.index, \recManualBus, ~outRecordInfo.index, \trig, 1 ], ~saveStuff);
},{
"RUN MASTER OUT FIRST!".postln;
});
},{
"STOP REC MASTER OUT".postln;
~allRec.set(\off, 1);
~saveBuf.value( "outRecordInfo", "outRecordBuffer", "wav"); // this doesnt happen?
});
});
~window.front;
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment