diff --git a/supercollider/cicc_gui.scd b/supercollider/cicc_gui.scd index ec7c6af..20ac02e 100644 --- a/supercollider/cicc_gui.scd +++ b/supercollider/cicc_gui.scd @@ -30,18 +30,19 @@ win = Window("Counterfeiting in Colonial Connecticut", Rect(500, 500, 1100, 500), false).front; masterView = { - var view, generator, transport, ranSeed, order, tempo, sectionDisplay, clock, metronome; + var updateTransport, updateSection, + view, generator, transport, ranSeed, order, tempo, sectionDisplay, clock, metronome; // this func updates the whole transport panel - ~updateTransport = {arg measure, beat; + updateTransport = {arg measure, beat; clock.string = clockStringFunc.value(measure, beat); metronome.stringColor = metronomeColorFunc.value(beat); metronome.string = metronomeStringFunc.value(beat); - fork {0.75.wait; {metronome.string = ""}.defer}; - }; + {0.75.wait; {metronome.string = ""}.defer}.fork(~tempoClock, quant: 0); + }.inEnvir; // this func handles the movement between sections - ~updateSection = {arg shift, stop = true, manualCall = true; + updateSection = {arg shift, stop = true, manualCall = true; var runThis; runThis = (manualCall || (manualCall.not && ~autoAdvance)); runThis = runThis && ((~currentSection + shift) < ~sectionOrder.size); @@ -71,7 +72,7 @@ sectionDisplay.string = "section: " ++ section.asString ++ "." ++ subSection.asString; if(~isPlaying, { ~play.set(\sel, ~currentSection % 2); - ~patterns[~sectionOrder[~currentSection]].play(quant: 0); + ~patterns[~sectionOrder[~currentSection]].play(~tempoClock, quant: 0); if(~interludes && ((~currentSection % 4) == 3) && (~currentSection != (~sectionOrder.size - 1)), { ~interludeTremelo.set(\gate, 1); ~interludeTremelo.set(\amp, 1); @@ -87,10 +88,10 @@ var measure, beat; measure = ~sectionStartMeasure[~sectionOrder[~currentSection]]; beat = 1; - ~updateTransport.value(measure, beat); + updateTransport.value(measure, beat); }); }); - }; + }.inEnvir; // these funcs receive messages from the synth OSCFunc({ arg msg, time; @@ -98,22 +99,23 @@ var measure, beat; measure = msg[3]; beat = msg[4]; - ~updateTransport.value(measure, beat) - }.defer; + updateTransport.value(measure, beat) + }.inEnvir.defer; },'/measureClock' ++ ~hash, s.addr); - //OSCFunc({ arg msg, time; {metronome.string = ""}.defer},'/measureClockReset', s.addr); + + OSCFunc({ arg msg, time; {updateSection.value(1, false, false)}.inEnvir.defer},'/playNextSubsection' ++ ~hash, s.addr); view = View(win); generator = HLayout( ranSeed = TextField(view, Rect(10, 10, 10, 20)).string_("20200525"), - Button(view).states_([["reset seed"]]).action_({ ranSeed.string = "20200525"}), - Button(view).states_([["random seed"]]).action_({ ranSeed.string = 50000000.rand.asString}), - Button(view).states_([["generate"]]).action_({~genAll.value(ranSeed.string.asInteger)}), - Button(view).states_([["transcribe"]]).action_({~transcribe.value(~scoreData)}), + Button(view).states_([["reset seed"]]).action_({ ranSeed.string = "20200525"}.inEnvir), + Button(view).states_([["random seed"]]).action_({ ranSeed.string = 50000000.rand.asString}.inEnvir), + Button(view).states_([["generate"]]).action_({~genAll.value(ranSeed.string.asInteger)}.inEnvir), + Button(view).states_([["transcribe"]]).action_({~transcribe.value(~scoreData)}.inEnvir), [StaticText(view).string_(" "), stretch: 1], nil); transport = HLayout( - Button(view).states_([["<<", Color.black]]).action_({arg pState; ~updateSection.value(-4)}), - Button(view).states_([["<", Color.black]]).action_({arg pState; ~updateSection.value(-1)}), + Button(view).states_([["<<", Color.black]]).action_({arg pState; updateSection.value(-4)}.inEnvir), + Button(view).states_([["<", Color.black]]).action_({arg pState; updateSection.value(-1)}.inEnvir), Button(view).states_([["play", Color.black], ["stop", Color.black, Color.grey]]).action_( {arg pState; if(pState.value == 0, { @@ -123,11 +125,11 @@ ~interludeTremelo.set(\gate, 0); measure = ~sectionStartMeasure[~currentSection]; beat = 1; - ~updateTransport.value(measure, beat); + updateTransport.value(measure, beat); ~interludeTremelo.set(\gate, 0); ~interludeTremelo.set(\amp, 0); },{ - fork { + { [1, 2, 1, 2].do({arg beat; { metronome.stringColor = metronomeColorFunc.value(beat); @@ -139,17 +141,17 @@ }); ~isPlaying = true; ~play.set(\sel, ~currentSection % 2); - ~patterns[~sectionOrder[~currentSection]].play(quant: 0); + ~patterns[~sectionOrder[~currentSection]].play(~tempoClock, quant: 0); if(~interludes && ((~currentSection % 4) == 3) && (~currentSection != (~sectionOrder.size - 1)), { ~interludeTremelo.set(\gate, 1); ~interludeTremelo.set(\amp, 1); }); - } + }.fork(~tempoClock, quant: 0); }) - } + }.inEnvir ), - Button(view).states_([[">", Color.black]]).action_({arg pState; ~updateSection.value(1)}), - Button(view).states_([[">>", Color.black]]).action_({arg pState; ~updateSection.value(4)}), nil, + Button(view).states_([[">", Color.black]]).action_({arg pState; updateSection.value(1)}.inEnvir), + Button(view).states_([[">>", Color.black]]).action_({arg pState; updateSection.value(4)}.inEnvir), nil, sectionDisplay = StaticText(win).string_("section: 1.1").font_(Font("Monaco", 70)), nil); view.layout_(HLayout( [VLayout( @@ -159,14 +161,14 @@ nil, transport, nil, HLayout( tempo = TextField(view).string_("90"), - Button(view).states_([["set tempo"]]).action_({TempoClock.tempo = tempo.string.asInteger / 60}), + Button(view).states_([["set tempo"]]).action_({~tempoClock.tempo = tempo.string.asInteger / 60}.inEnvir), StaticText(view).string_(" | "), Button(view).states_([["auto advance", Color.black], ["auto advance", Color.black, Color.grey]]).action_({ arg v; ~autoAdvance = if(v.value == 0, {false}, {true});~autoAdvance; - }).value_(1), + }.inEnvir).value_(1), Button(view).states_([["interludes", Color.black], ["interludes", Color.black, Color.grey]]).action_({ arg v; ~interludes = if(v.value == 0, {false}, {true}) - }), + }.inEnvir), [StaticText(view).string_(" "), stretch: 1]), [StaticText(view).string_(" "), stretch: 1], HLayout( @@ -181,8 +183,8 @@ }); }).flat; ~currentSection = 0; - ~updateSection.value(0); - }), + updateSection.value(0); + }.inEnvir), [StaticText(view).string_(" "), stretch: 1]), [StaticText(view).string_(" "), stretch: 1], generator ), alignment: \top]))}; @@ -203,11 +205,11 @@ VLayout( [HLayout( Slider(view).value_(0.8).action_( - {arg v; masterVol = v.value * 1.25; ~play.set(\masterVol, masterVol)}), + {arg v; masterVol = v.value * 1.25; ~play.set(\masterVol, masterVol)}.inEnvir), masterIndicators[0], masterIndicators[1]), stretch: 2], Button(view).states_([["mute", Color.black], ["mute", Color.black, Color.grey]]).action_( - {arg v; masterMute = (1 - v.value).abs; ~play.set(\masterMute, masterMute)}), + {arg v; masterMute = (1 - v.value).abs; ~play.set(\masterMute, masterMute)}.inEnvir), StaticText(view).string_(" master ").align_(\center) ), nil); tracks = {arg part; @@ -215,13 +217,13 @@ VLayout( HLayout( Slider(view).value_(0.8).action_( - {arg v; partVols[part] = v.value * 1.25; ~play.set(partAbbr[part] ++ "Vol", partVols[part])}), + {arg v; partVols[part] = v.value * 1.25; ~play.set(partAbbr[part] ++ "Vol", partVols[part])}.inEnvir), trackIndicators[part]), Button(view).states_([["mute", Color.black], ["mute", Color.black, Color.grey]]).action_( - {arg v; partMutes[part] = (1 - v.value).abs; ~play.set(partAbbr[part] ++ "Mute", partMutes[part])}), + {arg v; partMutes[part] = (1 - v.value).abs; ~play.set(partAbbr[part] ++ "Mute", partMutes[part])}.inEnvir), StaticText(view).string_("pan").align_(\center), Knob(view).value_(0.5).action_( - {arg v; partPans[part] = v.value * 2 - 1; ~play.set(partAbbr[part] ++ "Pan", partPans[part])}), + {arg v; partPans[part] = v.value * 2 - 1; ~play.set(partAbbr[part] ++ "Pan", partPans[part])}.inEnvir), StaticText(view).string_(trackNames[part]).align_(\center) ), nil) @@ -231,9 +233,9 @@ win.layout = VLayout( HLayout( transportButton = Button().states_([["transport", Color.white, Color.grey], ["transport", Color.black]]).action_( - {tabButtonReset.value; transportButton.value = 0; tabs.index = 0 }).value_(0), + {tabButtonReset.value; transportButton.value = 0; tabs.index = 0 }.inEnvir).value_(0), mixerButton = Button().states_([["mixer", Color.white, Color.grey], ["mixer", Color.black]]).action_( - {tabButtonReset.value; mixerButton.value = 0; tabs.index = 1 }).value_(1)), + {tabButtonReset.value; mixerButton.value = 0; tabs.index = 1 }.inEnvir).value_(1)), tabs = StackLayout(masterView.value, faderView.value)); }; ) \ No newline at end of file diff --git a/supercollider/cicc_main.scd b/supercollider/cicc_main.scd index ff0ede5..6116868 100644 --- a/supercollider/cicc_main.scd +++ b/supercollider/cicc_main.scd @@ -29,17 +29,15 @@ s.waitForBoot({ }; // set the global variables - TempoClock.tempo = 90 / 60; + ~tempoClock = TempoClock.new(90 / 60); ~dir = thisProcess.nowExecutingPath.dirname; ~genAll.value(20200525); - ~play = Synth.new(\masterPlayerControl); - ~interludeTremelo = Synth.new(\interludeTremelo); + ~play = Synth.new(\masterPlayerControl ++ ~hash); + ~interludeTremelo = Synth.new(\interludeTremelo ++ ~hash); ~autoAdvance = true; ~interludes = false; ~sectionOrder = ~patterns.size.collect({arg sec; sec}); ~generateGUI.value; - - appEnvironment.pop; }); - +appEnvironment.pop; ) \ No newline at end of file diff --git a/supercollider/cicc_sonifier.scd b/supercollider/cicc_sonifier.scd index 0f3dd7b..8dddcf5 100644 --- a/supercollider/cicc_sonifier.scd +++ b/supercollider/cicc_sonifier.scd @@ -9,7 +9,7 @@ ~accompLowUpperBusB = Bus.audio(s, 1); ~interludeTremoloBus = Bus.audio(s, 1); -SynthDef(\masterPlayerControl, { +SynthDef(\masterPlayerControl ++ ~hash, { arg sel = 0, masterVol = 1, masterMute = 1, guitarVol = 1, guitarPan = 0, guitarMute = 1, @@ -69,7 +69,7 @@ SynthDef(\masterPlayerControl, { }).add; -SynthDef(\transport, {arg measure = 0, beat = 0, gate = 1, dur = 1; +SynthDef(\transport ++ ~hash, {arg measure = 0, beat = 0, gate = 1, dur = 1; SendReply.kr(Impulse.kr(0) * (measure > 0) * (beat > 0),'/measureClock' ++ ~hash, values: [measure, beat]); SendReply.kr(Impulse.kr(0) * (measure < 1) * (beat < 1),'/playNextSubsection' ++ ~hash); EnvGen.kr(Env.sine(dur), gate, doneAction: 2); @@ -77,7 +77,7 @@ SynthDef(\transport, {arg measure = 0, beat = 0, gate = 1, dur = 1; //~~~~karplus -SynthDef(\karplus, {arg freq, gate = 1, amp = 0.5, bus; +SynthDef(\karplus ++ ~hash, {arg freq, gate = 1, amp = 0.5, bus; Out.ar(bus, Pluck.ar(WhiteNoise.ar(0.1), Impulse.kr(0), 220.reciprocal, freq.reciprocal, 10, coef:0) * Linen.kr(gate, doneAction: 2) * amp) @@ -85,7 +85,7 @@ SynthDef(\karplus, {arg freq, gate = 1, amp = 0.5, bus; //~~~~accompaniment -SynthDef(\accompBass, {arg freq1 = 100, freq2 = 100, gate = 1, amp = 0.5, busLower, busUpper, cutoff = 0; +SynthDef(\accompBass ++ ~hash, {arg freq1 = 100, freq2 = 100, gate = 1, amp = 0.5, busLower, busUpper, cutoff = 0; var env, lower, upper; env = EnvGen.kr(Env.perc(0.1, 10, level: amp), Impulse.kr(0) + Changed.kr(freq2)); lower = SinOsc.ar(freq1, 0, 0.5) * env; @@ -96,13 +96,13 @@ SynthDef(\accompBass, {arg freq1 = 100, freq2 = 100, gate = 1, amp = 0.5, busLow //this is not releasing properly -SynthDef(\accompTreble, {arg freq, gate = 1, sustain, amp, bus; +SynthDef(\accompTreble ++ ~hash, {arg freq, gate = 1, sustain, amp, bus; var treble; treble = SinOsc.ar(freq, 0, EnvGen.kr(Env.sine(sustain, amp * 0.1), gate, doneAction: 2)); Out.ar(bus, treble) }).add; -SynthDef(\interludeTremelo, { arg gate = 0, amp = 1; +SynthDef(\interludeTremelo ++ ~hash, { arg gate = 0, amp = 1; var tremeloTrig, freq, sig, feedback, fade; //fast tremelo - note that this can be slower so long as the delaytime of the feedback remains short tremeloTrig = Impulse.kr(50); @@ -118,8 +118,6 @@ SynthDef(\interludeTremelo, { arg gate = 0, amp = 1; Out.ar(~interludeTremoloBus, fade); }).add; -OSCFunc({ arg msg, time; {~updateSection.value(1, false, false)}.defer},'/playNextSubsection' ++ ~hash, s.addr); - //~~~~gen music ~genPatterns = {arg guitarSeqIn, accompLowSeqIn, accompHighSeqIn, sectionSeqIn, beatFrac = 1/8; var calcSustains, genSectionSec, sectionLimits, measureCount; @@ -204,7 +202,7 @@ OSCFunc({ arg msg, time; {~updateSection.value(1, false, false)}.defer},'/playNe pattern = EventPatternProxy.new; pattern.source = Ppar([ Pbind( - \instrument, \karplus, + \instrument, \karplus ++ ~hash, \amp, 0.3, \dur, Pseq(durSeq * beatFrac), \sustain, Pseq(susSeq * beatFrac), @@ -214,7 +212,7 @@ OSCFunc({ arg msg, time; {~updateSection.value(1, false, false)}.defer},'/playNe \bus, ~guitarBus.index), if(accompLowSecSeq.size > 1, { Pmono( - \accompBass, + \accompBass ++ ~hash, \amp, 0.5, \freq1, Pseq(accompLowSecSeq.slice(nil, 0)), \freq2, Pseq(accompLowSecSeq.slice(nil, 1)), @@ -223,7 +221,7 @@ OSCFunc({ arg msg, time; {~updateSection.value(1, false, false)}.defer},'/playNe \busUpper, if(secIndex % 2 == 0, {~accompLowUpperBusA.index}, {~accompLowUpperBusB.index})) }, { Pmono( - \accompBass, + \accompBass ++ ~hash, \amp, 0.5, \freq1, Pseq([accompLowSecSeq[0][0]]), \freq2, Pseq([accompLowSecSeq[0][1]]), @@ -232,14 +230,14 @@ OSCFunc({ arg msg, time; {~updateSection.value(1, false, false)}.defer},'/playNe \busUpper, if(secIndex % 2 == 0, {~accompLowUpperBusA.index}, {~accompLowUpperBusB.index})) }), Pbind( - \instrument, \accompTreble, + \instrument, \accompTreble ++ ~hash, \freq, Pseq(accompHighSecSeq.slice(nil, 0)), \dur, Pseq(accompHighSecSeq.slice(nil, 1) * beatFrac), \sustain, Pseq(accompHighSecSeq.slice(nil, 2) * beatFrac), \amp, 0.5, \bus, ~accompHighBus.index), Pbind( - \instrument, \transport, + \instrument, \transport ++ ~hash, \measure, Pseq(measureSeq), \beat, Pseq(beatSeq), \dur, beatFrac * 8