( var formatPatternData; //busses ~postampBusses = 7.collect({Bus.audio(s, 1)}); ~preampBusses = 3.collect({Bus.audio(s, 1)}); ~accompBusses = 4.collect({Bus.audio(s, 1)}); SynthDef(\masterPlayerControl_ ++ ~hash, { var sigs, sigsPanned, masterSig, imp; sigs = ~postampBusses.collect({arg bus, i; In.ar(bus) * NamedControl.kr(\vol_ ++ i, 1, 0.1)}); sigsPanned = sigs.collect({arg sig, i; Pan2.ar(sig * NamedControl.kr(\mute_ ++ i, 1, 0.1), NamedControl.kr(\pan_ ++ i, 0.5, 0.1))}); masterSig = Mix.ar(sigsPanned.drop(-1)) * NamedControl.kr("vol_master" ++ i, 1, 0.1) * NamedControl.kr("mute_master" ++ i, 1, 0.1); Out.ar(0, masterSig); Out.ar(2, sigsPanned.last); //change this if you want the click to go somewhere else imp = Impulse.kr(10); SendReply.kr(imp, '/masterLevels_' ++ ~hash, values: [Amplitude.kr(masterSig)]); sigs.collect({arg sig, i; SendReply.kr(imp, '/trackLevel_' ++ i ++ "_" ++ ~hash, values: [Amplitude.kr(sig)])}); }).add; SynthDef(\transport_ ++ ~hash, {arg measure = 0, beat = 0, section = 0, subsection = 0, gate = 1, dur = 1; SendReply.kr(Impulse.kr(0) * (measure > 0) * (beat > 0),'/measureClock_' ++ ~hash, values: [measure, beat, section, subsection]); //SendReply.kr(Impulse.kr(0),'/nextSubsection_' ++ ~hash); EnvGen.kr(Env.sine(dur), gate, doneAction: 2); }).add; SynthDef(\click_ ++ ~hash, {arg beat = 0, gate = 1, dur = 1; Out.ar(~postampBusses[6], 10 * BPF.ar(WhiteNoise.ar * EnvGen.kr(Env.perc(0.01, 0.1), gate), 440 * ((beat <= 1) + 1), 0.02)); EnvGen.kr(Env.sine(dur), gate, doneAction: 2); }).add; //~~~~~~~~~~~~DEFINE SYNTHS~~~~~~~~~~~~ SynthDef(\amp_curve_ ++ ~hash, {arg amp = 0, dur = 0.1, gate = 1, bus = 0; Out.kr(bus, amp) }).add; SynthDef(\ens_ ++ ~hash, {arg freq = 440, amp = 1, dur = 1, gate = 1, bus = 0, ampBus = 0; Out.ar(bus, SinOsc.ar(freq, 2pi.rand, 0.1) * Latch.kr(In.kr(ampBus), Impulse.kr(0)) * EnvGen.kr(Env.asr(0.1, 1, 0.1), gate, doneAction: 2)) }).add; SynthDef(\accomp_ ++ ~hash, {arg freq = 440, amp = 1, attack = 1, dur = 1, gate = 1, bout = 0, ampBus = 0; Out.ar(bout, SinOsc.ar(freq, 2pi.rand, 1) * 0.01 * amp * Latch.kr(In.kr(ampBus), Impulse.kr(0)) * EnvGen.kr(Env.asr(attack, 1, 0.01), gate, doneAction: 2)) }).add; SynthDef(\clip_ ++ ~hash, {arg dur = 1, gate = 1, bin = 0, bus = 0; //Out.ar([0, 1], (In.ar(bin)).clip(0, 1) * pow(Line.kr(0, 1, 240), 2)) Out.ar(bus, (In.ar(bin)).clip(0, 1) * 50 * pow(Line.kr(0, 1, 10), 2)) }).add; SynthDef(\bass_mono_ ++ ~hash, {arg freq = 440, ampBus = 0, bus = 0; Poll.kr(Changed.kr(In.kr(ampBus)), In.kr(ampBus)); Out.ar(bus, (SinOsc.ar(freq) * 0.4 * In.kr(ampBus))) }).add; // group data by measures for navigation formatPatternData = {arg musData, measureLen; var dataLen; dataLen = musData[0][0].size; musData.collect({arg partData; var res; res = partData.flop; res = res.add(res[1]); res[1] = (res[1].differentiate.drop(1) ++ [10]); res = res.flop ++ measureLen.collect({arg measure; dataLen.collect({0}) ++ [measure * 16]}); res = res.sort({arg a, b; a.last < b.last}).flop; res = res.insert(1, (res.last.differentiate.drop(1) ++ [10])).flop; res = res.separate({arg a, b; (a.last / 16).trunc != (b.last / 16).trunc}); res.collect({arg measureData; measureData.flop}) }).flop }; //~~~~~~~~~~~~GENERATE PATTERNS~~~~~~~~~~~~ ~genPatterns = {arg ensData, accompData, bassData, ampData, sectionData; var measureLen, ensDataFormatted, accompDataFormatted, bassDataFormatted, ampDataFormatted, dUnit, section, subsection, patterns; measureLen = (( ensData.collect({arg partData; partData.last[1]}) ++ accompData.flatten.collect({arg partData; partData.last[1]}) ).maxItem.ceil(16) / 16).asInteger + 1; ensDataFormatted = formatPatternData.value(ensData, measureLen); accompDataFormatted = formatPatternData.value(accompData.flatten, measureLen); //bassDataFormatted = formatPatternData.value(bassData[..0], measureLen); //ampDataFormatted = formatPatternData.value([ampData, ampData, ampData, ampData], measureLen); dUnit = 8.reciprocal; patterns = measureLen.collect({arg measure; if(sectionData[measure * 4] != nil, { section = sectionData[measure * 4][2]; subsection = sectionData[measure * 4][3]; }); Ppar( ensDataFormatted[measure].collect({arg musData, m; Pbind( \instrument, \ens_ ++ ~hash, \freq, Pseq(musData[0].replace(0, Rest(0))), \dur, Pseq(musData[1] * dUnit), \sustain, Pseq(musData[2] * dUnit), \amp, [0.5, 0.3, 0.3, 0.3][m], //\amp, Pseq(musData[2].collect({arg item; [0, 0.25, 0.5, 0.75][item]}) * [1, 0.5, 0.25, 0.1][m] * 16); // * musData[3].collect({arg val; if(val < 0.25, {0}, {0.5})})) \ampBus, ~preampBusses[0].index, \bus, ~postampBusses[m].index ) }) ++ accompDataFormatted[measure].collect({arg musData, m; Pbind( \instrument, \accomp_ ++ ~hash, \freq, Pseq(musData[0].replace(0, Rest(0))), \dur, Pseq(musData[1] * dUnit), \sustain, Pseq(musData[2] * dUnit), \amp, Pseq(musData[3].collect({arg item; [0, 2, 4, 8][item]}) * 0.0125 * 1), //\attack, Pseq(musData[1] * abs(musData[3].clip(0, 0.25) * 2 - 1) * dUnit), \attack, Pseq(musData[2] * 1 * dUnit), \ampBus, ~preampBusses[0].index, \bout, Pseq(musData[4].collect({arg index; ~accompBusses[index].index})) ) }) ++ [ Pbind( \instrument, \transport_ ++ ~hash, \measure, measure + 1, \beat, Pseq([1, 2]), \section, section, \subsection, subsection, \dur, 8 * dUnit ), Pbind( \instrument, \click_ ++ ~hash, \beat, Pseq([1, 2]), \dur, 8 * dUnit ) ] ) }); [patterns, bassData, ampData] }; )