( var formatPatternData; //busses ~partStarBus = Bus.audio(s, 1); ~partIBus = Bus.audio(s, 1); ~partIIBus = Bus.audio(s, 1); ~partIIIBus = Bus.audio(s, 1); ~accompBus = Bus.audio(s, 1); ~clickBus = Bus.audio(s, 1); ~busses = 6.collect({Bus.audio(s, 1)}); SynthDef(\masterPlayerControl_ ++ ~hash, { var sigs, sigsPanned, masterSig, imp; sigs = ~busses.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) * (measure < 1) * (beat < 1),'/nextSubsection_' ++ ~hash); EnvGen.kr(Env.sine(dur), gate, doneAction: 2); }).add; SynthDef(\click_ ++ ~hash, {arg beat = 0, gate = 1, dur = 1; Out.ar(~busses[5], 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(\ens_ ++ ~hash, {arg freq = 440, amp = 1, dur = 1, gate = 1, bus = 0; Out.ar(bus, SinOsc.ar(freq, 2pi.rand, amp * 0.1) * 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; Out.ar(bout, SinOsc.ar(freq, 2pi.rand, 1) * 0.01 * amp * 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) * 10 * pow(Line.kr(0, 1, 10), 2)) }).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, sectionData; var measureLen, ensDataFormatted, accompDataFormatted, dUnit, section, subsection; measureLen = (( ensData.collect({arg partData; partData.last[1]}) ++ accompData.flatten.collect({arg partData; partData.last[1]}) ).maxItem.ceil(16) / 16).asInteger; ensDataFormatted = formatPatternData.value(ensData, measureLen); accompDataFormatted = formatPatternData.value(accompData.flatten, measureLen); dUnit = 8.reciprocal; 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})})) \bus, ~busses[m].index ) }) ++ accompDataFormatted[measure].collect({arg musData, m; //"--------".postln; 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] * 0.9 * dUnit), \bout, Pseq(musData[4] + 6) ) }) ++ [ 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 ) ] ) }); }; //~~~~gen music /* ~genPatterns = {arg partStarSeqIn, accompLowSeqIn, partISeqIn, sectionSeqIn, beatFrac = 1/8; var calcSustains, genSectionSec, sectionLimits, measureCount; //~~~~helper sus function calcSustains = {arg stringSeq, durSeq; var res = []; stringSeq.size.do({arg index; var curString, dur, count; if(stringSeq[index].isRest.not, { curString = stringSeq[index]; dur = durSeq[index]; count = 1; while({(stringSeq[(index + count).clip(0, stringSeq.size - 1)] != curString) && (dur < 16) && (count < 100)}, { dur = dur + durSeq[(index + count).clip(0, durSeq.size - 1)]; count = count + 1; }); res = res.add(dur.clip(0, 16)); }, { res.add(Rest()); }); }); res }; genSectionSec = {arg seq, startTime, endTime, type; var durSum, resSeqs, inSecs, mult; durSum = 0; resSeqs = []; seq.do({arg item; if((durSum >= startTime) && (durSum < endTime), { var dur = durSum - startTime; if((resSeqs.size == 0) && (dur > 0), { switch(type, 0, {resSeqs = resSeqs.add([Rest(-1), Rest(-1), dur])}, 1, {resSeqs = resSeqs.add([Rest(-1), Rest(-1), dur])}, 2, {resSeqs = resSeqs.add([Rest(-1), dur, dur])}) }); resSeqs = resSeqs.add(item); }); durSum = durSum + if(type == 2, {item[1]}, {item[2]}); }); resSeqs }; measureCount = 0; sectionLimits = []; sectionSeqIn.slice(nil, 0).add(100000).doAdjacentPairs({arg a, b; sectionLimits = sectionLimits.add([a, b])}); ~sectionStartMeasure = []; sectionLimits.collect({arg timePair, secIndex; var startTime, endTime, beatLength, beatSeq, measureSeq, partStarSecSeq, accompLowSecSeq, partISecSeq, stringSeq, fretSeq, harmLimit, freqSeq, durSeq, susSeq, trigSeq, openStrings, pattern; startTime = timePair[0]; endTime = timePair[1]; 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; ~sectionStartMeasure = ~sectionStartMeasure.add(measureCount + 1); measureCount = measureSeq.last; beatSeq = beatSeq.flat; measureSeq = measureSeq.add(0); beatSeq = beatSeq.add(0); partStarSecSeq = genSectionSec.value(partStarSeqIn, startTime, endTime, 0); accompLowSecSeq = genSectionSec.value(accompLowSeqIn, startTime, endTime, 1); partISecSeq = genSectionSec.value(partISeqIn, startTime, endTime, 2); if(partISecSeq == [], {partISecSeq = [[Rest(-1), 1, 0], [Rest(-1), 1, 0]]}); openStrings = [1/1, 3/2, 2/1, 5/2, 35/12, 7/2]; harmLimit = [9, 8, 7, 6, 5, 4]; stringSeq = partStarSecSeq.slice(nil, 0); fretSeq = partStarSecSeq.slice(nil, 1); durSeq = partStarSecSeq.slice(nil, 2); susSeq = calcSustains.value(stringSeq, durSeq); freqSeq = stringSeq.collect({arg string, index; if(string.isRest, {Rest()}, { var midi, freq; //this is transposed up because karplus-strong does not really sound correctly in the partStar range midi = (62.midicps * openStrings[string]).cpsmidi + fretSeq[index]; freq = midi.midicps * if((secIndex % 4) != 3, {1}, {[1, harmLimit[string].rand + 1].choose})}) }); pattern = EventPatternProxy.new; pattern.source = Ppar([ Pbind( \instrument, \karplus ++ ~hash, \amp, 0.3, \dur, Pseq(durSeq * beatFrac), \sustain, Pseq(susSeq * beatFrac), \freq, Pseq(freqSeq), \bus, ~partStarBus.index), if(accompLowSecSeq.size > 1, { Pmono( \accompBass ++ ~hash, \amp, 0.5, \freq1, Pseq(accompLowSecSeq.slice(nil, 0)), \freq2, Pseq(accompLowSecSeq.slice(nil, 1)), \dur, Pseq(accompLowSecSeq.slice(nil, 2)) * beatFrac, \busLower, if(secIndex % 2 == 0, {~partIIBusA.index}, {~partIIBusB.index}), \busUpper, if(secIndex % 2 == 0, {~partIIIBusA.index}, {~partIIIBusB.index})) }, { Pmono( \accompBass ++ ~hash, \amp, 0.5, \freq1, Pseq([accompLowSecSeq[0][0]]), \freq2, Pseq([accompLowSecSeq[0][1]]), \dur, Pseq([accompLowSecSeq[0][2]]) * beatFrac, \busLower, if(secIndex % 2 == 0, {~partIIBusA.index}, {~partIIBusB.index}), \busUpper, if(secIndex % 2 == 0, {~partIIIBusA.index}, {~partIIIBusB.index})) }), Pbind( \instrument, \accompTreble ++ ~hash, //\freq, Pseq(partISecSeq.slice(nil, 0)), \freq, Pseq(partISecSeq.slice(nil, 0).curdle(0.3).collect({arg item; item.cpsmidi - 0.16 + 0.32.rand}).midicps.flat), \dur, Pseq(partISecSeq.slice(nil, 1) * beatFrac), \sustain, Pseq(partISecSeq.slice(nil, 2) * beatFrac), \amp, 0.5, \bus, ~partIBus.index), Pbind( \instrument, \transport ++ ~hash, \measure, Pseq(measureSeq), \beat, Pseq(beatSeq), \dur, beatFrac * 8 ), Pbind( \instrument, \click ++ ~hash, \beat, Pseq(beatSeq.drop(-1)), \dur, beatFrac * 8 ) ]); pattern }); }; */ )