/*RUN*/ s.options.numInputBusChannels = 4; s.options.numOutputBusChannels = 4; b = NetAddr.new("192.168.0.116", 8888); // create the NetAddr //b.sendMsg("/led", [0,1].choose); // send the application the message "hello" with the parameter "there" //OSCFunc.trace(true); // Turn posting on //OSCFunc.trace(false); // Turn posting off s.waitForBoot{ /////////////////////////////////////////////////////////////////////////// // set path for sample location and make dictionary of subdirectories //~samplepath = thisProcess.nowExecutingPath.dirname ++ "/samples"; ~samplepath = "/home/rob/pifcamp2023/sc/samples"; // CHANGE THIS TO YOUR OWN PATH ~smp = Dictionary.new; //~smp[\green]; PathName(~samplepath).entries.do{ arg subfolder; ~smp.add( subfolder.folderName.asSymbol -> Array.fill( subfolder.entries.size, { arg i; Buffer.read(s, subfolder.entries[i].fullPath).normalize;} ) ); }; // e.g. green sample subdirectory of ~samplepath: ~smp[\green][1] // /////////////////////////////////////////////////////////////////////// // allocate busses ~reverbBus = Bus.audio(s, 1); ~ringModBus = Bus.audio(s, 1); // create group order ~sGA = Group.new; ~sGB = Group.new; ~sGC = Group.new; ~sGD = Group.new; s.sync; //// SYNTHS ////////////////////////////////// SynthDef.new(\splay, {| out=0, bufnum=0, tpse=1, t_trig=0, amp=0.8, rate=1, atk=1, rel=1, loop=0, spos=0, gate=0, panRate=0.2, dir=1 | var env, sig; env= EnvGen.kr(Env.asr(atk,1,rel),gate, doneAction:2); sig = PlayBuf.ar(1, bufnum, rate*tpse*dir, t_trig, startPos: spos, loop:loop, doneAction: 0); sig = sig * env * amp; sig = Pan2.ar(sig, FSinOsc.kr(panRate)); Out.ar(out, sig); }).add; s.sync; ~oPA = 8.collect({ arg itt, rate=1, out=0, sdir=\bowl, amp=0.9, loop=0, panRate=rrand(0.05,0.75), group=~sGA; Synth.new(\splay, [ \bufnum, ~smp[sdir][rrand(0,~smp[sdir].size-1)], \out, out, \loop, loop, panRate: panRate], group); }); ~oPB = 8.collect({ arg itt, rate=1, out=0, sdir=\green, amp=0.5, loop=0, panRate=rrand(0.05,0.75), group=~sGB; Synth.new(\splay, [\bufnum, ~smp[sdir][rrand(0,~smp[sdir].size-1)], \out, out, \loop, loop, panRate: panRate], group); }); // RECEIVE OSC MESSAGES FROM ESP32s ~transpositionsA = 0; ~modeB = 0; ~modeC = 0; ~modeD = 0; ~shiftA = 0; // shift state ~shiftB = 0; // shift state ~shiftC = 0; // shift state ~shiftD = 0; // shift state ~ctrlA = 0; // ctrl state ~ctrlB = 0; // ctrl state ~sampleDir = [\green, \bowl, \blue, \green]; ~lsA=0; // loop state ~lsB=0; // loop state ~scaleMode = [ Scale.major, Scale.minor, Scale.melodicMinor, Scale.minorPentatonic, Scale.ionian(\pythagorean), Scale.whole, Scale.chromatic, Scale.gong, Scale.indian, Scale.egyptian, Scale.major, Scale.minor, Scale.melodicMinor, Scale.chromatic ]; ~scaleA = ~scaleMode[0]; ~scaleB = ~scaleMode[0]; ~ssA = 0; // scale index ~ssB = 0; ~psetA = Array.series(~scaleA.size, start: 0, step: 1); ~psetB = Array.series(~scaleB.size, start: 0, step: 1); ~smpA = 0; // sample bank index ~smpB = 0; ~dirStateA = [0,0,0,0,0,0,0,0]; ~dirStateB = [0,0,0,0,0,0,0,0]; //~dirState.put(3,1); //~scales[2].tuning; ~scales[2].size; ~scales[2].pitchesPerOcatave; s.sync; ~esp32Receive = { arg name ,mac; OSCdef(name, { arg msg, time; // msg[1] sender mac address // msg[2] which of the [0 - 11] sensors is touched // msg[3] is it a touch [1] or a release [0] // msg[4] which of the connected mpr121 boards is sending if (msg[1] == mac && msg[4] == 0 ) { if (msg[2] < 8) { // if sensor 0 - 7 and looper if ( msg[3]== 1 ) { postln("PITCHCLASS: " + ~psetA[msg[2]] ); b.sendMsg("/led", msg[2], ~psetA[msg[2]], msg[4]); w = case { msg[2] == 0} { ~oPA[0].set(\rate, ~scaleA[~psetA[0]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } { msg[2] == 1} { ~oPA[1].set(\rate, ~scaleA[~psetA[1]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } { msg[2] == 2} { ~oPA[2].set(\rate, ~scaleA[~psetA[2]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } { msg[2] == 3} { ~oPA[3].set(\rate, ~scaleA[~psetA[3]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } { msg[2] == 4} { ~oPA[4].set(\rate, ~scaleA[~psetA[4]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } { msg[2] == 5} { ~oPA[5].set(\rate, ~scaleA[~psetA[5]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } { msg[2] == 6} { ~oPA[6].set(\rate, ~scaleA[~psetA[6]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } // TODO: LOGIC TO FIX NEXT OCTAVE IN 7 NOTE VS OTHER NOTE LENGTH SCALES ~psetA.size // if logic below not workingif (~scaleA.size == 7 ) {t //{ msg[2] == 7} { ~oPA[7].set(\rate, ~scaleA[~psetA[7]].midiratio,\t_trig, 1, \gate, 1, \tpse, 1); } { msg[2] == 7} { if (~scaleA.size == 7 ) { ~oPA[7].set(\rate, ~scaleA[~psetA[0]].midiratio + 1 ,\t_trig, 1, \gate, 1, \tpse, 1); postln("notes in scale: " + ~scaleA );}; if (~scaleA.size == 12 ) { ~oPA[7].set(\te, ~scaleA[~psetA[0]].midiratio,\t_trig, 1, \gate, 1, \tpse, 2); postln("notes in scale: " + ~scaleA + "not>>> debug");} } } { ~dirStateA.put(msg[2],0); postln("release"); } // if first 8 sensors are released after being touched set state to }; // LOOP mode on off // GROUP ////////////////////////////// if ( msg[2] == 8 && msg[3] == 0 ) { // release 7 = toggle looping of all samplers ~lsA = (~lsA + 1)% 2; ~sGA.set(\loop, ~lsA ); // toggle this b.sendMsg("/led", msg[2], ~lsA, msg[4]); postln("LOOP: " + ~lsA ); }; // SHIFT state /////////////////////////////////// if ( msg[2] == 11 ) { if (msg[3]==1){ ~shiftA = 1; postln("shift is enabled" )} { ~shiftA = 0; postln("shift is disabled" )}; b.sendMsg("/led", msg[2], ~shiftA, msg[4]); }; // CTRL state //////////////////////////////////// if (msg[2] == 10 ) { if (msg[3]==1){ ~ctrlA = 1; postln("CTRL enabled" ); b.sendMsg("/led", msg[2], ~ctrlA, msg[4]);} { ~ctrlA = 0; postln("CTRL disabled" ); b.sendMsg("/led", msg[2], ~ctrlA, msg[4]);}; }; // SCALE CHANGER --------------------------------- if (~shiftA==1 && msg[2] == 9 && msg[3] == 1) { if (msg[3]==1){ ~ssA = (~ssA + 1) % 14; // fourteen slots for scales // use key release to ~scaleA = ~scaleMode[~ssA]; postln("SCALE: " + ~scaleA.name + " : " + ~scaleA); //b.sendMsg("/led", 9, ~ssA, msg[4]); }; // todo color code for SCALE CHANGER... red not updating b.sendMsg("/led", msg[2], ~ssA, msg[4]); }; // PITCH SET SCRAMBLER --------------------------------- if (~shiftA==0 && ~ctrlA==0 && msg[2] == 9 && msg[3] == 1) { ~psetA = Array.series(~scaleA.size+1, start: 0, step: 1).scramble; postln(~scaleA.name + " SCALE SCRAMBLED: " + ~psetA); b.sendMsg("/led", 9, ~ssA, msg[4]); }; if (~shiftA==0 && ~ctrlA==1 && msg[2] == 9 && msg[3] == 1) { ~psetA = Array.series(~scaleA.size+1, start: 0, step: 1); postln(~scaleA.name + " SCALE ORDER RESTORED: " + ~psetA); b.sendMsg("/led", 9, ~ssA, msg[4]); }; // SAMPLE DIRECTORY CHANGER --------------------------------- if (~shiftA==1 && msg[2] == 8 && msg[3] == 1) { ~smpA = (~smpA + 1) % 4; // use key release to ~sdir = ~sampleDir[~smpA]; postln("NEW SAMPLE DIRECTORY SELECTED:"+ ~sampleDir[~smpA+1] + " : " + ~sampleDir); }; // SAMPLE DIRECTORY MAPPINGS --------------------------------- if (~smpA == 0){ w = case { msg[2] == 0} { ~oPA[0].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 1} { ~oPA[1].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 2} { ~oPA[2].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 3} { ~oPA[3].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 4} { ~oPA[4].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 5} { ~oPA[5].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 6} { ~oPA[6].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 7} { ~oPA[7].set(\bufnum, ~smp[\bowl][0]); }; b.sendMsg("/led", 9, ~smpA, msg[4]); }; if (~smpA == 1){ x =~smp[\green]; w = case { msg[2] == 0} { ~oPA[0].set(\bufnum, x[0]); } { msg[2] == 1} { ~oPA[1].set(\bufnum, x[1]); } { msg[2] == 2} { ~oPA[2].set(\bufnum, x[1]); } { msg[2] == 3} { ~oPA[3].set(\bufnum, x[1]); } { msg[2] == 4} { ~oPA[4].set(\bufnum, x[2]); } { msg[2] == 5} { ~oPA[5].set(\bufnum, x[2]); } { msg[2] == 6} { ~oPA[6].set(\bufnum, x[2]); } { msg[2] == 7} { ~oPA[7].set(\bufnum, x[3]); }; b.sendMsg("/led", 9, ~smpA, msg[4]); }; if (~smpA == 2){ x =~smp[\blue]; w = case { msg[2] == 0} { ~oPA[0].set(\bufnum, x[0]); } { msg[2] == 1} { ~oPA[1].set(\bufnum, x[1]); } { msg[2] == 2} { ~oPA[2].set(\bufnum, x[1]); } { msg[2] == 3} { ~oPA[3].set(\bufnum, x[1]); } { msg[2] == 4} { ~oPA[4].set(\bufnum, x[2]); } { msg[2] == 5} { ~oPA[5].set(\bufnum, x[2]); } { msg[2] == 6} { ~oPA[6].set(\bufnum, x[2]); } { msg[2] == 7} { ~oPA[7].set(\bufnum, x[3]); }; b.sendMsg("/led", 9, ~smpA, msg[4]); }; if (~smpA == 3){ x =~smp[\red]; w = case { msg[2] == 0} { ~oPA[0].set(\bufnum, x[0]); } { msg[2] == 1} { ~oPA[1].set(\bufnum, x[1]); } { msg[2] == 2} { ~oPA[2].set(\bufnum, x[1]); } { msg[2] == 3} { ~oPA[3].set(\bufnum, x[1]); } { msg[2] == 4} { ~oPA[4].set(\bufnum, x[2]); } { msg[2] == 5} { ~oPA[5].set(\bufnum, x[2]); } { msg[2] == 6} { ~oPA[6].set(\bufnum, x[2]); } { msg[2] == 7} { ~oPA[7].set(\bufnum, x[3]); }; b.sendMsg("/led", 9, ~smpA, msg[4]); }; // REVERSE SAMPLES //////////////////////////////////////////// if (~ctrlA == 1 ) { // while control pressed if (msg[2] < 8 ){ // only applies to the first 8 sensors if (msg[3] == 1 ){ // if touched postln("reverse sample @ index: " + msg[2] ); w = case { msg[2] == 0} { ~oPA[0].set(\dir, -1, \spos, 44100); } { msg[2] == 1} { ~oPA[1].set(\dir, -1, \t_trig, 1, \gate, 1, ); } { msg[2] == 2} { ~oPA[2].set(\dir, -1 ); } { msg[2] == 3} { ~oPA[3].set(\dir, -1 ); } { msg[2] == 4} { ~oPA[4].set(\dir, -1 ); } { msg[2] == 5} { ~oPA[5].set(\dir, -1 ); } { msg[2] == 6} { ~oPA[6].set(\dir, -1 ); } { msg[2] == 7} { ~oPA[7].set(\dir, -1 ); } } { ~dirStateA.put(msg[2],1); postln("set direction state to 1 reverse magenta"); } // if not 1 (released after CTRL+touch) } // set the state for neopixel // when released }; // TRANSPOSITION MODE SETTER if (~shiftA == 1 && msg[2] == 10 ) { if (msg[3]==1){ ~transpositionsA = ~transpositionsA+1 % 6; w = case { ~transpositionsA == 0} { postln("MODE: ------> NORMAL" ); } { ~transpositionsA == 1} { postln("MODE: ------> TRANSPOSE ---- 1 8VE-DOWN" ); } { ~transpositionsA == 2} { postln("MODE: ------> TRANSPOSE ---- 2 8VE-DOWN" ); } { ~transpositionsA == 3} { postln("MODE: ------> TRANSPOSE ---- 1 8VE-UP" ); } { ~transpositionsA == 4} { postln("MODE: ------> TRANSPOSE ---- 2 8VE-UP" ); } { ~transpositionsA == 5} { postln("MODE: ------> TRANSPOSE ---- RANDOM 0.25 <-> 5" ); }; }; b.sendMsg("/led", msg[2], ~transpositionsA, msg[4]); }; // modes ---- if (~shiftA==0 && msg[3] == 1 ){ if (~transpositionsA == 0) { w = case { msg[2] == 0} { ~oPA[0].set(\tpse, 1); } { msg[2] == 1} { ~oPA[1].set(\tpse, 1 ); } { msg[2] == 2} { ~oPA[2].set(\tpse, 1 ); } { msg[2] == 3} { ~oPA[3].set(\tpse, 1 ); } { msg[2] == 4} { ~oPA[4].set(\tpse, 1 ); } { msg[2] == 5} { ~oPA[5].set(\tpse, 1 ); } { msg[2] == 6} { ~oPA[6].set(\tpse, 1 ); } { msg[2] == 7} { ~oPA[7].set(\tpse, 1 ); } }; if (~transpositionsA == 1) { w = case { msg[2] == 0} { ~oPA[0].set(\tpse, 0.5); } { msg[2] == 1} { ~oPA[1].set(\tpse, 0.5 ); } { msg[2] == 2} { ~oPA[2].set(\tpse, 0.5 ); } { msg[2] == 3} { ~oPA[3].set(\tpse, 0.5 ); } { msg[2] == 4} { ~oPA[4].set(\tpse, 0.5 ); } { msg[2] == 5} { ~oPA[5].set(\tpse, 0.5 ); } { msg[2] == 6} { ~oPA[6].set(\tpse, 0.5 ); } { msg[2] == 7} { ~oPA[7].set(\tpse, 0.5 ); } }; if (~transpositionsA == 2 ) { w = case { msg[2] == 0} { ~oPA[0].set(\tpse, [0.25].choose ); } { msg[2] == 1} { ~oPA[1].set(\tpse, [0.25].choose ); } { msg[2] == 2} { ~oPA[2].set(\tpse, [0.25].choose ); } { msg[2] == 3} { ~oPA[3].set(\tpse, [0.25].choose ); } { msg[2] == 4} { ~oPA[4].set(\tpse, [0.25].choose ); } { msg[2] == 5} { ~oPA[5].set(\tpse, [0.25].choose ); } { msg[2] == 6} { ~oPA[6].set(\tpse, [0.25].choose ); } { msg[2] == 7} { ~oPA[7].set(\tpse, [0.25].choose ); } }; if (~transpositionsA == 3 ) { w = case { msg[2] == 0} { ~oPA[0].set(\tpse, [2].choose ); } { msg[2] == 1} { ~oPA[1].set(\tpse, [2].choose ); } { msg[2] == 2} { ~oPA[2].set(\tpse, [2].choose ); } { msg[2] == 3} { ~oPA[3].set(\tpse, [2].choose ); } { msg[2] == 4} { ~oPA[4].set(\tpse, [2].choose ); } { msg[2] == 5} { ~oPA[5].set(\tpse, [2].choose ); } { msg[2] == 6} { ~oPA[6].set(\tpse, [2].choose ); } { msg[2] == 7} { ~oPA[7].set(\tpse, [2].choose ); } }; if (~transpositionsA == 4 ) { w = case { msg[2] == 0} { ~oPA[0].set(\tpse, [3].choose ); } { msg[2] == 1} { ~oPA[1].set(\tpse, [3].choose ); } { msg[2] == 2} { ~oPA[2].set(\tpse, [3].choose ); } { msg[2] == 3} { ~oPA[3].set(\tpse, [3].choose ); } { msg[2] == 4} { ~oPA[4].set(\tpse, [3].choose ); } { msg[2] == 5} { ~oPA[5].set(\tpse, [3].choose ); } { msg[2] == 6} { ~oPA[6].set(\tpse, [3].choose ); } { msg[2] == 7} { ~oPA[7].set(\tpse, [3].choose ); } }; if (~transpositionsA == 5 ) { x = [0.25, 0.5, 1, 2, 3, 4, 5]; w = case { msg[2] == 0} { ~oPA[0].set(\tpse, x.choose); } { msg[2] == 1} { ~oPA[1].set(\tpse, x.choose); } { msg[2] == 2} { ~oPA[2].set(\tpse, x.choose ); } { msg[2] == 3} { ~oPA[3].set(\tpse, x.choose ); } { msg[2] == 4} { ~oPA[4].set(\tpse, x.choose ); } { msg[2] == 5} { ~oPA[5].set(\tpse, x.choose ); } { msg[2] == 6} { ~oPA[6].set(\tpse, x.choose ); } { msg[2] == 7} { ~oPA[7].set(\tpse, x.choose ); } }; }; // UPDATE THE NEOPIXELS STATUS if (msg[2] < 8) { // when not touched turn led 0-7 black/off(12) gray/9 if (msg[1] == mac && msg[3] == 0 && msg[4] == 0 ) { // released if (~dirStateA[msg[2]] == 0){ // if the direction state is 0 (forward) b.sendMsg("/led", msg[2], 7, msg[4]); // set the neopixel to 7 (orange) } { b.sendMsg("/led", msg[2], 5, msg[4]); } // else (dirState reverse) set the neopixel to 5 (cyan) }; } {} ; }; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// // board 2 logic here if (msg[1] == mac && msg[4] == 1 ) { if (msg[2] < 8) { // if sensor 0 - 7 and looper if ( msg[3]== 1 ) { postln("PITCHCLASS: " + ~psetB[msg[2]] ); b.sendMsg("/led", msg[2], ~psetB[msg[2]], msg[4]); w = case { msg[2] == 0} { ~oPB[0].set(\rate, ~scaleB[~psetB[0]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } { msg[2] == 1} { ~oPB[1].set(\rate, ~scaleB[~psetB[1]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } { msg[2] == 2} { ~oPB[2].set(\rate, ~scaleB[~psetB[2]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } { msg[2] == 3} { ~oPB[3].set(\rate, ~scaleB[~psetB[3]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } { msg[2] == 4} { ~oPB[4].set(\rate, ~scaleB[~psetB[4]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } { msg[2] == 5} { ~oPB[5].set(\rate, ~scaleB[~psetB[5]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } { msg[2] == 6} { ~oPB[6].set(\rate, ~scaleB[~psetB[6]].midiratio, \t_trig, 1, \gate, 1, \tpse, 1, \dir, 1); } // TODO: LOGIC TO FIX NEXT OCTAVE IN 7 NOTE VS OTHER NOTE LENGTH SCALES ~psetA.size // if logic below not workingif (~scaleB.size == 7 ) {t //{ msg[2] == 7} { ~oPB[7].set(\rate, ~scaleB[~psetB[7]].midiratio,\t_trig, 1, \gate, 1, \tpse, 1); } { msg[2] == 7} { if (~scaleB.size == 7 ) { ~oPB[7].set(\rate, ~scaleB[~psetB[0]].midiratio + 1 ,\t_trig, 1, \gate, 1, \tpse, 1); postln("notes in scale: " + ~scaleB );}; if (~scaleB.size == 12 ) { ~oPB[7].set(\te, ~scaleB[~psetB[0]].midiratio,\t_trig, 1, \gate, 1, \tpse, 2); postln("notes in scale: " + ~scaleB + "not>>> debug");} } } { ~dirStateB.put(msg[2],0); postln("release"); } // if first 8 sensors are released after being touched set state to }; // LOOP mode on off // GROUP ////////////////////////////// if ( msg[2] == 8 && msg[3] == 0 ) { // release 7 = toggle looping of all samplers ~lsB = (~lsB + 1)% 2; ~sGB.set(\loop, ~lsB ); // toggle this b.sendMsg("/led", msg[2], ~lsB, msg[4]); postln("LOOP: " + ~lsB ); }; // SHIFT state /////////////////////////////////// if ( msg[2] == 11 ) { if (msg[3]==1){ ~shiftB = 1; postln("shift is enabled" )} { ~shiftB = 0; postln("shift is disabled" )}; b.sendMsg("/led", msg[2], ~shiftB, msg[4]); }; // CTRL state //////////////////////////////////// if (msg[2] == 10 ) { if (msg[3]==1){ ~ctrlB = 1; postln("CTRL enabled" ); b.sendMsg("/led", msg[2], ~ctrlB, msg[4]);} { ~ctrlB = 0; postln("CTRL disabled" ); b.sendMsg("/led", msg[2], ~ctrlB, msg[4]);}; }; // SCALE CHANGER --------------------------------- if (~shiftB==1 && msg[2] == 9 && msg[3] == 1) { if (msg[3]==1){ ~ssB = (~ssB + 1) % 14; // fourteen slots for scales // use key release to ~scaleB = ~scaleMode[~ssB]; postln("SCBLE: " + ~scaleB.name + " : " + ~scaleB); //b.sendMsg("/led", 9, ~ssB, msg[4]); }; // todo color code for SCALE CHANGER... red not updating b.sendMsg("/led", msg[2], ~ssB, msg[4]); }; // PITCH SET SCRAMBLER --------------------------------- if (~shiftB==0 && ~ctrlB==0 && msg[2] == 9 && msg[3] == 1) { ~psetB = Array.series(~scaleB.size+1, start: 0, step: 1).scramble; postln(~scaleB.name + " SCALE SCRAMBLED: " + ~psetB); b.sendMsg("/led", 9, ~ssB, msg[4]); }; if (~shiftB==0 && ~ctrlB==1 && msg[2] == 9 && msg[3] == 1) { ~psetB = Array.series(~scaleB.size+1, start: 0, step: 1); postln(~scaleB.name + " SCALE ORDER RESTORED: " + ~psetB); b.sendMsg("/led", 9, ~ssB, msg[4]); }; // SAMPLE DIRECTORY CHANGER --------------------------------- if (~shiftB==1 && msg[2] == 8 && msg[3] == 1) { ~smpB = (~smpB + 1) % 4; // use key release to ~sdir = ~sampleDir[~smpB]; postln("NEW SAMPLE DIRECTORY SELECTED:"+ ~sampleDir[~smpB+1] + " : " + ~sampleDir); }; // SAMPLE DIRECTORY MAPPINGS --------------------------------- if (~smpB == 0){ w = case { msg[2] == 0} { ~oPB[0].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 1} { ~oPB[1].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 2} { ~oPB[2].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 3} { ~oPB[3].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 4} { ~oPB[4].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 5} { ~oPB[5].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 6} { ~oPB[6].set(\bufnum, ~smp[\bowl][0]); } { msg[2] == 7} { ~oPB[7].set(\bufnum, ~smp[\bowl][0]); }; b.sendMsg("/led", 9, ~smpB, msg[4]); }; if (~smpB == 1){ x =~smp[\green]; w = case { msg[2] == 0} { ~oPB[0].set(\bufnum, x[0]); } { msg[2] == 1} { ~oPB[1].set(\bufnum, x[1]); } { msg[2] == 2} { ~oPB[2].set(\bufnum, x[1]); } { msg[2] == 3} { ~oPB[3].set(\bufnum, x[1]); } { msg[2] == 4} { ~oPB[4].set(\bufnum, x[2]); } { msg[2] == 5} { ~oPB[5].set(\bufnum, x[2]); } { msg[2] == 6} { ~oPB[6].set(\bufnum, x[2]); } { msg[2] == 7} { ~oPB[7].set(\bufnum, x[3]); }; b.sendMsg("/led", 9, ~smpB, msg[4]); }; if (~smpB == 2){ x =~smp[\blue]; w = case { msg[2] == 0} { ~oPB[0].set(\bufnum, x[0]); } { msg[2] == 1} { ~oPB[1].set(\bufnum, x[1]); } { msg[2] == 2} { ~oPB[2].set(\bufnum, x[1]); } { msg[2] == 3} { ~oPB[3].set(\bufnum, x[1]); } { msg[2] == 4} { ~oPB[4].set(\bufnum, x[2]); } { msg[2] == 5} { ~oPB[5].set(\bufnum, x[2]); } { msg[2] == 6} { ~oPB[6].set(\bufnum, x[2]); } { msg[2] == 7} { ~oPB[7].set(\bufnum, x[3]); }; b.sendMsg("/led", 9, ~smpB, msg[4]); }; if (~smpB == 3){ x =~smp[\red]; w = case { msg[2] == 0} { ~oPB[0].set(\bufnum, x[0]); } { msg[2] == 1} { ~oPB[1].set(\bufnum, x[1]); } { msg[2] == 2} { ~oPB[2].set(\bufnum, x[1]); } { msg[2] == 3} { ~oPB[3].set(\bufnum, x[1]); } { msg[2] == 4} { ~oPB[4].set(\bufnum, x[2]); } { msg[2] == 5} { ~oPB[5].set(\bufnum, x[2]); } { msg[2] == 6} { ~oPB[6].set(\bufnum, x[2]); } { msg[2] == 7} { ~oPB[7].set(\bufnum, x[3]); }; b.sendMsg("/led", 9, ~smpB, msg[4]); }; // REVERSE SAMPLES //////////////////////////////////////////// if (~ctrlB == 1 ) { // while control pressed if (msg[2] < 8 ){ // only applies to the first 8 sensors if (msg[3] == 1 ){ // if touched postln("reverse sample @ index: " + msg[2] ); w = case { msg[2] == 0} { ~oPB[0].set(\dir, -1, \spos, 44100); } { msg[2] == 1} { ~oPB[1].set(\dir, -1, \t_trig, 1, \gate, 1, ); } { msg[2] == 2} { ~oPB[2].set(\dir, -1 ); } { msg[2] == 3} { ~oPB[3].set(\dir, -1 ); } { msg[2] == 4} { ~oPB[4].set(\dir, -1 ); } { msg[2] == 5} { ~oPB[5].set(\dir, -1 ); } { msg[2] == 6} { ~oPB[6].set(\dir, -1 ); } { msg[2] == 7} { ~oPB[7].set(\dir, -1 ); } } { ~dirStateB.put(msg[2],1); postln("set direction state to 1 reverse magenta"); } // if not 1 (released after CTRL+touch) } // set the state for neopixel // when released }; // TRANSPOSITION MODE SETTER if (~shiftB == 1 && msg[2] == 10 ) { if (msg[3]==1){ ~transpositionsB = ~transpositionsB+1 % 6; w = case { ~transpositionsB == 0} { postln("MODE: ------> NORMAL" ); } { ~transpositionsB == 1} { postln("MODE: ------> TRANSPOSE ---- 1 8VE-DOWN" ); } { ~transpositionsB == 2} { postln("MODE: ------> TRANSPOSE ---- 2 8VE-DOWN" ); } { ~transpositionsB == 3} { postln("MODE: ------> TRANSPOSE ---- 1 8VE-UP" ); } { ~transpositionsB == 4} { postln("MODE: ------> TRANSPOSE ---- 2 8VE-UP" ); } { ~transpositionsB == 5} { postln("MODE: ------> TRANSPOSE ---- RANDOM 0.25 <-> 5" ); }; }; b.sendMsg("/led", msg[2], ~transpositionsB, msg[4]); }; // modes ---- if (~shiftB==0 && msg[3] == 1 ){ if (~transpositionsB == 0) { w = case { msg[2] == 0} { ~oPB[0].set(\tpse, 1); } { msg[2] == 1} { ~oPB[1].set(\tpse, 1 ); } { msg[2] == 2} { ~oPB[2].set(\tpse, 1 ); } { msg[2] == 3} { ~oPB[3].set(\tpse, 1 ); } { msg[2] == 4} { ~oPB[4].set(\tpse, 1 ); } { msg[2] == 5} { ~oPB[5].set(\tpse, 1 ); } { msg[2] == 6} { ~oPB[6].set(\tpse, 1 ); } { msg[2] == 7} { ~oPB[7].set(\tpse, 1 ); } }; if (~transpositionsB == 1) { w = case { msg[2] == 0} { ~oPB[0].set(\tpse, 0.5); } { msg[2] == 1} { ~oPB[1].set(\tpse, 0.5 ); } { msg[2] == 2} { ~oPB[2].set(\tpse, 0.5 ); } { msg[2] == 3} { ~oPB[3].set(\tpse, 0.5 ); } { msg[2] == 4} { ~oPB[4].set(\tpse, 0.5 ); } { msg[2] == 5} { ~oPB[5].set(\tpse, 0.5 ); } { msg[2] == 6} { ~oPB[6].set(\tpse, 0.5 ); } { msg[2] == 7} { ~oPB[7].set(\tpse, 0.5 ); } }; if (~transpositionsB == 2 ) { w = case { msg[2] == 0} { ~oPB[0].set(\tpse, [0.25].choose ); } { msg[2] == 1} { ~oPB[1].set(\tpse, [0.25].choose ); } { msg[2] == 2} { ~oPB[2].set(\tpse, [0.25].choose ); } { msg[2] == 3} { ~oPB[3].set(\tpse, [0.25].choose ); } { msg[2] == 4} { ~oPB[4].set(\tpse, [0.25].choose ); } { msg[2] == 5} { ~oPB[5].set(\tpse, [0.25].choose ); } { msg[2] == 6} { ~oPB[6].set(\tpse, [0.25].choose ); } { msg[2] == 7} { ~oPB[7].set(\tpse, [0.25].choose ); } }; if (~transpositionsB == 3 ) { w = case { msg[2] == 0} { ~oPB[0].set(\tpse, [2].choose ); } { msg[2] == 1} { ~oPB[1].set(\tpse, [2].choose ); } { msg[2] == 2} { ~oPB[2].set(\tpse, [2].choose ); } { msg[2] == 3} { ~oPB[3].set(\tpse, [2].choose ); } { msg[2] == 4} { ~oPB[4].set(\tpse, [2].choose ); } { msg[2] == 5} { ~oPB[5].set(\tpse, [2].choose ); } { msg[2] == 6} { ~oPB[6].set(\tpse, [2].choose ); } { msg[2] == 7} { ~oPB[7].set(\tpse, [2].choose ); } }; if (~transpositionsB == 4 ) { w = case { msg[2] == 0} { ~oPB[0].set(\tpse, [3].choose ); } { msg[2] == 1} { ~oPB[1].set(\tpse, [3].choose ); } { msg[2] == 2} { ~oPB[2].set(\tpse, [3].choose ); } { msg[2] == 3} { ~oPB[3].set(\tpse, [3].choose ); } { msg[2] == 4} { ~oPB[4].set(\tpse, [3].choose ); } { msg[2] == 5} { ~oPB[5].set(\tpse, [3].choose ); } { msg[2] == 6} { ~oPB[6].set(\tpse, [3].choose ); } { msg[2] == 7} { ~oPB[7].set(\tpse, [3].choose ); } }; if (~transpositionsB == 5 ) { x = [0.25, 0.5, 1, 2, 3, 4, 5]; w = case { msg[2] == 0} { ~oPB[0].set(\tpse, x.choose); } { msg[2] == 1} { ~oPB[1].set(\tpse, x.choose); } { msg[2] == 2} { ~oPB[2].set(\tpse, x.choose ); } { msg[2] == 3} { ~oPB[3].set(\tpse, x.choose ); } { msg[2] == 4} { ~oPB[4].set(\tpse, x.choose ); } { msg[2] == 5} { ~oPB[5].set(\tpse, x.choose ); } { msg[2] == 6} { ~oPB[6].set(\tpse, x.choose ); } { msg[2] == 7} { ~oPB[7].set(\tpse, x.choose ); } }; }; // UPDATE THE NEOPIXELS STATUS if (msg[2] < 8) { // when not touched turn led 0-7 black/off(12) gray/9 if (msg[1] == mac && msg[3] == 0 && msg[4] == 0 ) { // released if (~dirStateB[msg[2]] == 0){ // if the direction state is 0 (forward) b.sendMsg("/led", msg[2], 7, msg[4]); // set the neopixel to 7 (orange) } { b.sendMsg("/led", msg[2], 5, msg[4]); } // else (dirState reverse) set the neopixel to 5 (cyan) }; } {} ; }; ////////////////////////////////////////////////////////////////////////// },'/touch') }; s.sync; ~esp32Receive.('anything', '3C:E9:0E:AD:A5:48'); ~sG.set(\amp, 1); ~sG.set(\rate, -1); ~sGB.set(\amp, 0.2); "patch loaded and ready...".postln; };