diff --git a/supercollider/tkam_gui.scd b/supercollider/tkam_gui.scd index 3351a5d..f2d7abf 100644 --- a/supercollider/tkam_gui.scd +++ b/supercollider/tkam_gui.scd @@ -110,7 +110,27 @@ buildTransport = {arg win, view, clock, metronome; Button(view).states_([["play", Color.black], ["stop", Color.black, Color.grey]]).action_({arg pState; if(pState.value == 1, { player = { - ~patternProxy.source = Pseq(~patterns, 1, ~sectionNavDict[[currentSection, currentSubsection]] - 1); + ~patternProxy.source = Ppar( + [Pseq(~patterns[0], 1, ~sectionNavDict[[currentSection, currentSubsection]] - 1)] ++ + + ~patterns[2].collect({arg pattern, p; + Pmono(\amp_curve_ ++ ~hash, + \amp, Pseg(Pseq(pattern.slice(nil, 0), 1, (~sectionNavDict[[currentSection, currentSubsection]] - 1) * 4), 4 * ~dUnit), + \dur, 4 * ~dUnit, + \bus, ~preampBusses[p].index + ) + }) ++ + + ~patterns[1].collect({arg pattern, p; + Pmono(\bass_mono_ ++ ~hash, + \freq, Pseq(pattern.slice(nil, 0), 1, (~sectionNavDict[[currentSection, currentSubsection]] - 1) * 4), + \dur, 4 * ~dUnit, + \ampBus, ~preampBusses[p + 1].index, + \bus, ~postampBusses[4].index + ) + }) + + ); Pbind(\instrument, \click_ ++ ~hash, \beat, Pseq([1, 2, 1, 2]), \dur, 1).play(~tempoClock, quant: 0); [1, 2, 1, 2].do({arg beat; { diff --git a/supercollider/tkam_main.scd b/supercollider/tkam_main.scd index e796fa3..e998495 100644 --- a/supercollider/tkam_main.scd +++ b/supercollider/tkam_main.scd @@ -21,9 +21,11 @@ s.waitForBoot({ ~dUnit = 8.reciprocal; ~musicData = ~genMusicData.value(seed); ~scoreData = ~genScoreData.value(~musicData[0]); - ~sectionData = ~musicData[2]; - ~patterns = ~genPatterns.value(~musicData[0], ~musicData[1], ~musicData[3], ~sectionData); - ~sectionNavDict = ~musicData[4].postln; + ~sectionData = ~musicData[4]; + "sdasfsdfsdaf".postln; + ~patterns = ~genPatterns.value(~musicData[0], ~musicData[1], ~musicData[2], ~musicData[3], ~sectionData); + "sdasfsdfsdaf".postln; + ~sectionNavDict = ~musicData[5].postln; ~isPlaying = false; }; @@ -34,7 +36,7 @@ s.waitForBoot({ "loading app".postln; ~genAll.value(19800725); ~play = Synth.new(\masterPlayerControl_ ++ ~hash); - 4.collect({arg p; Synth.new(\clip_ ++ ~hash, [\bin, p + 6, \bus, ~busses[5].index])}); + 4.collect({arg p; Synth.new(\clip_ ++ ~hash, [\bin, p + 6, \bus, ~postampBusses[5].index])}); ~generateGUI.value; "ready".postln; diff --git a/supercollider/tkam_musical_data_generator.scd b/supercollider/tkam_musical_data_generator.scd index e41a6c8..f80c7fe 100644 --- a/supercollider/tkam_musical_data_generator.scd +++ b/supercollider/tkam_musical_data_generator.scd @@ -4,7 +4,7 @@ genMode, hdChoose, wchooseDict, collectRoots, initModeState, advanceMode, initTemporalState, genTemporalData, initPartStates, distributeRoots, -genEnsemblePart, genAccompPart, genBassPart, genMusicData, genScoreData, genPatterns; +genEnsemblePart, genAccompPart, genBassPart, genAmpCurve, genMusicData, genScoreData, genPatterns; //~~~~~~~~~~~~FREQUENCY RATIO MATH FUNCTIONS~~~~~~~~~~~~ @@ -391,7 +391,7 @@ genBassPart = {arg root, temporalData1, temporalData2, offset1, offset2, hi; offset1 + temporalData1[0].size, (attacksMin + offset2) - (offset1 + temporalData1[0].size), // + ((temporalData2.size - temporalData2.indexOf(1)) * 1/6), attacksMax - attacksMin, - temporalData2.size - attacksMax, + temporalData2[0].size - attacksMax, 1 ].postln }, { @@ -414,13 +414,55 @@ genBassPart = {arg root, temporalData1, temporalData2, offset1, offset2, hi; ] }; +//~~~~~~~~~~~~GENERATE ELECTRONIC BASS~~~~~~~~~~~~ +genBassPart = {arg root, ampCurve, hi; + var freq; + freq = if(hi, + {36.midicps * frToFloat.value(frCollapse.value(frAdd.value(root, [[3], [2]])))}, + {36.midicps * frToFloat.value(root)}); + + //freq.postln; + ampCurve.collect({arg sec, iter; [freq, sec[1]]}) +}; + +//~~~~~~~~~~~~GENERATE AMP CURVES~~~~~~~~~~~~ +genAmpCurve = {arg temporalData1, temporalData2, offset1, offset2, type; + var firsts1, firsts2, delay, attack, decay, release, min, env; + firsts1 = temporalData1.collect({arg ptd; ptd.indexOf(1)}); + firsts2 = temporalData2.collect({arg ptd; ptd.indexOf(1)}); + delay = switch(type) + {0} {0} + {1} {0} + {2} {firsts1.minItem}; + attack = switch(type) + {0} {offset2 - offset1} + {1} {offset2 - temporalData2[0].size + firsts2.minItem - offset1} + {2} {firsts1.maxItem - firsts1.minItem}; + decay = switch(type) + {0} {0} + {1} {firsts2.maxItem - firsts2.minItem} + {2} {temporalData1[0].size - firsts1.maxItem}; + release = switch(type) + {0} {0} + {1} {temporalData2[0].size.postln - firsts2.maxItem} + {2} {(offset2 - temporalData2[0].size) - offset1} ; + min = switch(type) + {0} {0.25} + {1} {0} + {2} {0} ; + + env = Env.dadsr(delay, attack, decay, 0.25, release, curve: \cub).range(min); + + ((delay.postln + attack.postln + decay.postln + release.postln).postln / 4).asInteger.collect({arg iter; [env.at(iter * 4), offset1 + (iter * 4)]}) +}; + //~~~~~~~~~~~~GENERATE ALL MUSIC DATA~~~~~~~~~~~~ ~genMusicData = {arg seed; var totalDur, section1Dur, dUnit, totalLen, section1Len, curLen, cadence, - modeState, temporalState, partStates, lastCadenceTemporalData, lastCadenceState, lastCadencePoint, - ensData, accompData, bassData, sectionData, + modeState, temporalState, partStates, lastCadenceTemporalData, lastCadenceState, lastSectionPoint, + ensData, accompData, bassData, ampData, sectionData, roots, lastRoots, sectionCount, subsectionCount, sectionNavDict; thisThread.randSeed = seed; @@ -439,11 +481,12 @@ genBassPart = {arg root, temporalData1, temporalData2, offset1, offset2, hi; partStates = initPartStates.value; lastCadenceTemporalData = nil; lastCadenceState = modeState.deepCopy; - lastCadencePoint = 0; + lastSectionPoint = 0; ensData = 4.collect({[]}); - bassData = 3.collect({[]}); + bassData = 2.collect({[]}); accompData = 4.collect({6.collect({[]})}); + ampData = 3.collect({[]}); sectionData = Dictionary.new; //Dictionary.with(*[0->4]); sectionNavDict = Dictionary.new; //Dictionary.with(*[[[1], [1]]->1]); @@ -471,10 +514,6 @@ genBassPart = {arg root, temporalData1, temporalData2, offset1, offset2, hi; ensData[part] = ensData[part] ++ musicData; partStates[part] = partState; - //if(collectRoots.value(modeState).size == 1, { - // if(part != 0, {bassData[part - 1] = bassData[part - 1] ++ genBassPart.value(roots[2][0], curLen)}); - //}); - thisThread.randSeed = Date.seed; 6.do({arg register; musicData = genAccompPart.value(modeState, temporalData[part], curLen, pow(2, part + register), part, register); @@ -486,50 +525,47 @@ genBassPart = {arg root, temporalData1, temporalData2, offset1, offset2, hi; subsectionCount = subsectionCount + 1; thisThread.randSeed = (seed + (sectionCount * 100) + subsectionCount); + if(curLen == 0, { + lastCadenceTemporalData = temporalData; + lastSectionPoint = curLen; + }); + + curLen = curLen + temporalData[0].size; + if(curLen > section1Len, { if(collectRoots.value(modeState).size == 1, { - + var ampDataTmp; "asdfasfdsf".postln; - - if(sectionCount > 1, { - bassData[0] = bassData[0] ++ - genBassPart.value(collectRoots.value(lastCadenceState).asList[0], - lastCadenceTemporalData, temporalData, lastCadencePoint, curLen, false); - }); - - if(sectionCount > 0, { - bassData[0] = bassData[0] ++ - genBassPart.value(collectRoots.value(modeState).asList[0], - lastCadenceTemporalData, temporalData, lastCadencePoint, curLen, true); + //sectionCount.postln; + + ampData[0] = ampData[0] ++ genAmpCurve.value(lastCadenceTemporalData, temporalData, lastSectionPoint, curLen, 0); + ampDataTmp = genAmpCurve.value(lastCadenceTemporalData, temporalData, lastSectionPoint, curLen, 1); + ampData[1] = ampData[1] ++ ampDataTmp; + bassData[0] = bassData[0] ++ genBassPart.value(collectRoots.value(modeState).asList[0], ampDataTmp, true); + + if(sectionCount == 1, { + ampData[2] = ampData[2] ++ ((curLen - temporalData[0].size) / 4).asInteger.collect({arg iter; [0, iter * 4]}); + bassData[1] = bassData[1] ++ ((curLen - temporalData[0].size) / 4).asInteger.collect({arg iter; [0, iter * 4]}) + }, { + ampDataTmp = genAmpCurve.value(lastCadenceTemporalData, temporalData, lastSectionPoint, curLen, 2); + ampData[2] = ampData[2] ++ ampDataTmp; + bassData[1] = bassData[1] ++ genBassPart.value(collectRoots.value(lastCadenceState).asList[0], ampDataTmp, false); }); - //bassData[0] = bassData[0] ++ genBassPart.value(roots[0][0].postln, curLen); - - //lastCadenceState = modeState; sectionCount = sectionCount + 1; subsectionCount = 1; - //lastCadenceTemporalData = temporalData[0]; - //lastCadencePoint = curLen; - //cadence = true; - //lastCadencePoint.postln; - lastCadenceState = modeState; lastCadenceTemporalData = temporalData; - lastCadencePoint = curLen; + lastSectionPoint = curLen; cadence = true; }, {cadence = false}); modeState = advanceMode.value(modeState, lastCadenceState); }); - if(curLen == 0, { - lastCadenceTemporalData = temporalData[0]; - lastCadencePoint = curLen; - }); - curLen = curLen + temporalData[0].size; }); - [ensData, accompData, sectionData, bassData, sectionNavDict] + [ensData, accompData, bassData, ampData, sectionData, sectionNavDict] }; //~genMusicData.value(100) ) diff --git a/supercollider/tkam_sonifier.scd b/supercollider/tkam_sonifier.scd index 9fc5f41..c21e0a8 100644 --- a/supercollider/tkam_sonifier.scd +++ b/supercollider/tkam_sonifier.scd @@ -9,12 +9,13 @@ var formatPatternData; ~accompBus = Bus.audio(s, 1); ~clickBus = Bus.audio(s, 1); -~busses = 7.collect({Bus.audio(s, 1)}); +~postampBusses = 7.collect({Bus.audio(s, 1)}); +~preampBusses = 7.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)}); + 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); @@ -35,18 +36,22 @@ SynthDef(\transport_ ++ ~hash, {arg measure = 0, beat = 0, section = 0, subsecti SynthDef(\click_ ++ ~hash, {arg beat = 0, gate = 1, dur = 1; - Out.ar(~busses[6], 10 * BPF.ar(WhiteNoise.ar * EnvGen.kr(Env.perc(0.01, 0.1), gate), 440 * ((beat <= 1) + 1), 0.02)); + 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(\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)) +SynthDef(\amp_curve_ ++ ~hash, {arg amp = 0, dur = 0.1, gate = 1, bus = 0; + Out.kr(bus, amp) }).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)) +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; @@ -58,6 +63,10 @@ SynthDef(\bass_ ++ ~hash, {arg freq = 440, amp = 1, dur = 1, attack = 1, decay = Out.ar(bus, (SinOsc.ar(freq) * 0.3 * amp * EnvGen.kr(Env.adsr(attack, decay, 0.5, release, curve: \sqr), gate, doneAction: 2))) }).add; +SynthDef(\bass_mono_ ++ ~hash, {arg freq = 440, ampBus = 0, bus = 0; + Out.ar(bus, (SinOsc.ar(freq.poll) * 0.4 * In.kr(ampBus))) +}).add; + // group data by measures for navigation formatPatternData = {arg musData, measureLen; @@ -78,9 +87,11 @@ formatPatternData = {arg musData, measureLen; //~~~~~~~~~~~~GENERATE PATTERNS~~~~~~~~~~~~ -~genPatterns = {arg ensData, accompData, bassData, sectionData; - var measureLen, ensDataFormatted, accompDataFormatted, bassDataFormatted, dUnit, section, subsection; +~genPatterns = {arg ensData, accompData, bassData, ampData, sectionData; + var measureLen, ensDataFormatted, accompDataFormatted, bassDataFormatted, ampDataFormatted, + dUnit, section, subsection, patterns; + "here5".postln; measureLen = (( ensData.collect({arg partData; partData.last[1]}) ++ accompData.flatten.collect({arg partData; partData.last[1]}) @@ -88,10 +99,12 @@ formatPatternData = {arg musData, measureLen; ensDataFormatted = formatPatternData.value(ensData, measureLen); accompDataFormatted = formatPatternData.value(accompData.flatten, measureLen); - bassDataFormatted = formatPatternData.value(bassData[..0], measureLen); + //bassDataFormatted = formatPatternData.value(bassData[..0], measureLen); + //ampDataFormatted = formatPatternData.value([ampData, ampData, ampData, ampData].postln, measureLen); + "here6".postln; dUnit = 8.reciprocal; - measureLen.collect({arg measure; + patterns = measureLen.collect({arg measure; if(sectionData[measure * 4] != nil, { section = sectionData[measure * 4][2]; subsection = sectionData[measure * 4][3]; @@ -106,7 +119,8 @@ formatPatternData = {arg musData, measureLen; \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 + \ampBus, ~preampBusses[0].index, + \bus, ~postampBusses[m].index ) }) ++ accompDataFormatted[measure].collect({arg musData, m; @@ -119,9 +133,11 @@ formatPatternData = {arg musData, measureLen; \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] + 6) ) }) ++ + /* bassDataFormatted[measure][..0].postln.collect({arg musData, m; Pbind( \instrument, \bass_ ++ ~hash, @@ -134,9 +150,19 @@ formatPatternData = {arg musData, measureLen; \amp, 1, //\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[4].index + \bus, ~postampBusses[4].index ) }) ++ + ampDataFormatted[measure].collect({arg musData, m; + Pbind( + \instrument, \amp_curve_ ++ ~hash, + \amp, Pseq(musData[0]), + \dur, Pseq(musData[1].replace(0, Rest(0)) * dUnit), + \bus, ~preampBusses[m].index + ) + }) ++ + */ + [ Pbind( \instrument, \transport_ ++ ~hash, @@ -154,6 +180,7 @@ formatPatternData = {arg musData, measureLen; ] ) }); + [patterns, bassData, ampData] };