diff --git a/supercollider/cicc_gui.scd b/supercollider/cicc_gui.scd index 1a3489e..a132f76 100644 --- a/supercollider/cicc_gui.scd +++ b/supercollider/cicc_gui.scd @@ -15,16 +15,16 @@ masterVol = 1; clockStringFunc = { - arg beat; - var measure, measureBeat, leadSpace; - measure = ((beat / 2) + 1).asInteger.asString; - measureBeat = ((beat % 2) + 1).asInteger.asString; - leadSpace = (3 - measure.size).collect({" "}).join; - leadSpace ++ measure ++ "." ++ measureBeat + arg measure, beat; + var measureString, beatString, leadSpace; + measureString = measure.asInteger.asString; + beatString = beat.asInteger.asString; + leadSpace = (3 - measureString.size).collect({" "}).join; + leadSpace ++ measureString ++ "." ++ beatString }; // [-30, -105, -104].asAscii and [-30, -105, -113].asAscii are unicode inverse bullet and normal bullet, respectively - metronomeStringFunc = { arg beat; if(beat % 2 == 0, {[-30, -105, -104].asAscii}, {[-30, -105, -113].asAscii}) }; - metronomeColorFunc = { arg beat; if(beat % 2 == 0, {Color.red},{Color.black}) }; + metronomeStringFunc = { arg beat; if(beat == 1, {[-30, -105, -104].asAscii}, {[-30, -105, -113].asAscii}) }; + metronomeColorFunc = { arg beat; if(beat == 1, {Color.red},{Color.black}) }; ~appStatusFunc = Task({ loop { @@ -39,12 +39,15 @@ win = Window("Counterfeiting in Colonial Connecticut", Rect(500, 500, 1100, 500), false).front; masterView = { - var view, masterIndicators, master, generator, transport, ranSeed, startPosText, pauseButton, clock, metronome; + var view, masterIndicators, master, generator, transport, ranSeed, startPosText, + prevSectionButton, prevSubsectionButton, playStopButton, nextSubsectionButton, nextSectionButton, clock, metronome; OSCFunc({ arg msg, time; { - var beat = msg[3]; - clock.string = clockStringFunc.value(beat); + var measure, beat; + measure = msg[3]; + beat = msg[4]; + clock.string = clockStringFunc.value(measure, beat); metronome.stringColor = metronomeColorFunc.value(beat); metronome.string = metronomeStringFunc.value(beat); }.defer; @@ -65,7 +68,31 @@ [~appStatus = StaticText(view).string_("status: ready"), stretch: 1], nil); transport = HLayout( - Button(view).states_([["play", Color.black], ["stop", Color.black, Color.grey]]).action_( + prevSectionButton = Button(view).states_([["<<", Color.black]]).action_({| pState | + if((~currentSection - 4) >= 0, { + if(~isPlaying, { + ~patterns[~currentSection].stop; + ~currentSection = (~currentSection - 4).trunc(4); + ~play.set(\sel, ~currentSection % 2); + ~patterns[~currentSection].play(quant: 0) + },{ + ~currentSection = ~currentSection - 1; + }) + }); + }), + prevSubsectionButton = Button(view).states_([["<", Color.black]]).action_({| pState | + if((~currentSection - 1) >= 0, { + if(~isPlaying, { + ~patterns[~currentSection].stop; + ~currentSection = (~currentSection - 1); + ~play.set(\sel, ~currentSection % 2); + ~patterns[~currentSection].play(quant: 0) + },{ + ~currentSection = ~currentSection - 1; + }) + }) + }), + playStopButton = Button(view).states_([["play", Color.black], ["stop", Color.black, Color.grey]]).action_( /* {| pState | pauseButton.value = 0; @@ -74,14 +101,40 @@ {~play.set(\startPos, startPos, \playRate, 1, \startTrig, 1)})} */ {| pState | - pauseButton.value = 0; - if(pState.value == 0, {~patterns[0].stop; - clock.string = clockStringFunc.value((startPos * ~totalDur * 5).asInteger)}, - {~currentSection = 0; ~play.set(\sel, ~currentSection % 2); ~patterns[~currentSection].play})} + if(pState.value == 0, { + ~isPlaying = false; + ~patterns[~currentSection].stop; + },{ + ~isPlaying = true; + ~play.set(\sel, ~currentSection % 2); + ~patterns[~currentSection].play(quant: 0) + }) + } ), - pauseButton = Button(view).states_([["pause", Color.black], ["pause", Color.black, Color.grey]]).action_( - {| pState | - if(pState.value == 1, {~play.set(\playRate, 0)},{~play.set(\playRate, 1)})}), + nextSubsectionButton = Button(view).states_([[">", Color.black]]).action_({| pState | + if((~currentSection + 1) < ~patterns.size, { + if(~isPlaying, { + ~patterns[~currentSection].stop; + ~currentSection = (~currentSection + 1); + ~play.set(\sel, ~currentSection % 2); + ~patterns[~currentSection].play(quant: 0) + },{ + ~currentSection = ~currentSection + 1; + }) + }) + }), + nextSectionButton = Button(view).states_([[">>", Color.black]]).action_({| pState | + if((~currentSection + 4) < ~patterns.size, { + if(~isPlaying, { + ~patterns[~currentSection].stop; + ~currentSection = (~currentSection + 4).trunc(4); + ~play.set(\sel, ~currentSection % 2); + ~patterns[~currentSection].play(quant: 0) + },{ + ~currentSection = ~currentSection - 1; + }) + }) + }), StaticText(view).string_("start time"), [Slider(view, Rect(0, 0, 30, 5)).action_( {|pos| diff --git a/supercollider/cicc_main.scd b/supercollider/cicc_main.scd index 5c8999d..4260657 100644 --- a/supercollider/cicc_main.scd +++ b/supercollider/cicc_main.scd @@ -20,6 +20,8 @@ appEnvironment.push; ~scoreData = ~allMusicData[1]; ~sectionOffsets = ~allMusicData[2]; ~currentSection = 0; +~currentSubsection = 0; +~isPlaying = false; ~play = Synth.new(\masterPlayerControl); diff --git a/supercollider/cicc_sonifier.scd b/supercollider/cicc_sonifier.scd index e8bea11..4326f09 100644 --- a/supercollider/cicc_sonifier.scd +++ b/supercollider/cicc_sonifier.scd @@ -54,10 +54,13 @@ SynthDef(\masterPlayerControl, { }).add; -SynthDef(\transport, {arg beat, fin; - SendReply.kr(Changed.kr(beat * (beat < fin)),'/measureClock', values: [beat]); - SendReply.kr(TDelay.kr(Changed.kr(beat * (beat < fin)), 0.25),'/measureClockReset', values: [beat]); - SendReply.kr(Changed.kr(beat < fin),'/playNextSubsection'); +SynthDef(\transport, {arg measure = 0, beat = 0, gate = 1, dur = 1; + measure.poll; + beat.poll; + SendReply.kr(Impulse.kr(0) * (measure > 0) * (beat > 0),'/measureClock', values: [measure, beat]); + SendReply.kr(TDelay.kr(Impulse.kr(0) * (measure > 0) * (beat > 0), 0.25),'/measureClockReset'); + SendReply.kr(Impulse.kr(0) * (measure < 1) * (beat < 1),'/playNextSubsection'); + EnvGen.kr(Env.sine(dur), gate, doneAction: 2); }).add; @@ -132,14 +135,16 @@ SynthDef(\droneOut, {arg gate, bus; OSCFunc({ arg msg, time; - ~currentSection = ~currentSection + 1; - ~play.set(\sel, ~currentSection % 2); - ~patterns[~currentSection].play(quant: 0) + if((~currentSection + 1) < ~patterns.size, { + ~currentSection = ~currentSection + 1; + ~play.set(\sel, ~currentSection % 2); + ~patterns[~currentSection].play(quant: 0) + }) },'/playNextSubsection', s.addr); //~~~~gen music ~genPatterns = {arg guitarSeqIn, accompLowSeqIn, accompHighSeqIn, sectionSeqIn, tempo = 0.08; - var calcSustains, genSectionSec, sectionLimits; + var calcSustains, genSectionSec, sectionLimits, measureCount; //~~~~helper sus function calcSustains = {arg stringSeq, durSeq; @@ -186,16 +191,26 @@ OSCFunc({ arg msg, time; resSeqs }; + measureCount = 0; sectionLimits = []; sectionSeqIn.slice(nil, 0).add(100000).doAdjacentPairs({arg a, b; sectionLimits = sectionLimits.add([a, b])}); sectionLimits.collect({arg timePair, secIndex; - var startTime, endTime, endBeat, + var startTime, endTime, beatLength, beatSeq, measureSeq, guitarSecSeq, accompLowSecSeq, accompHighSecSeq, stringSeq, fretSeq, durSeq, susSeq, trigSeq, openStrings, pattern; startTime = timePair[0]; endTime = timePair[1]; - endBeat = endTime - startTime; + + if((secIndex % 4) == 0, {measureCount = 0}); + beatLength = (endTime - startTime) / 8; + beatSeq = ((beatLength / 2) - 1).asInteger.collect({[1, 2]}); + beatSeq = if((beatLength % 2) == 0, {beatSeq.add([1, 2])}, {beatSeq.add([1, 2, 3])}); + measureSeq = measureCount + beatSeq.collect({arg measure, mIndex; measure.collect({mIndex + 1})}).flat; + measureCount = measureSeq.last; + beatSeq = beatSeq.flat; + measureSeq = measureSeq.add(0); + beatSeq = beatSeq.add(0); guitarSecSeq = genSectionSec.value(guitarSeqIn, startTime, endTime, 0); accompLowSecSeq = genSectionSec.value(accompLowSeqIn, startTime, endTime, 1); @@ -260,10 +275,11 @@ OSCFunc({ arg msg, time; \amp, 0.5, //\bus, if(secIndex % 2 == 0, {~accompHighBusA.index}, {~accompHighBusB.index})), \bus, ~accompHighBus.index), - Pmono(\transport, - \beat, Pseq((0..((endBeat / 8).asInteger))), - \dur, tempo * 8, - \fin, ((endBeat / 8).asInteger).postln + Pbind( + \instrument, \transport, + \measure, Pseq(measureSeq), + \beat, Pseq(beatSeq), + \dur, tempo * 8 ) ]); pattern