/*RUN*/ //supercollider file for spellcaster s.options.numInputBusChannels = 4; s.options.numOutputBusChannels = 4; OSCFunc.trace(true); // Turn posting on OSCFunc.trace(false); // Turn posting off //s.boot; //( s.waitForBoot{ /////////////////////////////////////////////////////////////////////////// // set path for sample location and make dictionary of subdirectories //~samplepath = thisProcess.nowExecutingPath.dirname ++ "/samples"; ~samplepath = "/home/rizoma/pifcamp2023/sc/samples"; // CHANGE THIS TO YOUR OWN PATH ~smp = Dictionary.new; 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 ~smpGrp = Group.new; // 4 BUFFERS ALLOCATED ... ~b1 = Buffer.alloc(s, s.sampleRate * 10, 1); // Allocate a 10 second mono buffer ~b0 = Buffer.alloc(s, s.sampleRate * 4, 1); // //~b1 = Buffer.alloc(s, s.sampleRate * 4, 1); // ~b2 = Buffer.alloc(s, s.sampleRate * 4, 1); // ~b3 = Buffer.alloc(s, s.sampleRate * 4, 1); // //////////////////////////////////////////////////////////// // function to save audio recordings to timestamped wav files // make the MIZA directory manually for now and store audio recording archive there // this gets triggered by the osc responder below // ~archiveInputs.value(~b0); ~path = thisProcess.platform.recordingsDir +/+ "MIZA/"; ~archiveInputs = { | buf| buf.write( path: ~path ++ "MIZA_" ++ Date.localtime.stamp ++ ".wav", headerFormat: "wav", sampleFormat: 'int16'); }; // load archive directories into array and scramble ~archiveDir = PathName.new(~path).files.scramble.copyFromStart(5); ~archiveDir[0]; // get a random file from archive s.sync; //// SYNTHS ////////////////////////////////// SynthDef.new(\splay, {| out = 0, bufnum = 0, trig = 1, amp = 1, rate=1, atk=1, rel=1, loop=0, spos=0, gate=1 | var env, sig; env= EnvGen.kr(Env.asr(atk,1,rel),gate, doneAction:2); sig = PlayBuf.ar(1, bufnum, //BufRateScale.kr(bufnum) * rate, trig, startPos: spos, loop:loop, doneAction: Done.freeSelf); sig = sig * env * amp; Out.ar(out, sig); }).add; //////////////////////////////////////////////////////// s.sync; ~oscPlay = { arg chan=1, rates=1, sdir=\bowl, amp=0.5, loop=0, group=~smpGrp; Synth(\splay, [\bufnum, ~smp[sdir][rrand(0,~smp[sdir].size)], \out, rrand(0,1), \rate, rates, \amp, rrand(0.4, 0.8), \loop, loop], group); // recorder postln("chan:" + chan + "rates: " + rates + "sdir:" + sdir.asString + "amp: " + amp ); }; // 'A8:42:E3:4B:10:AC' ~ls0=1; //loop state /////////////////////////////////////////////////////////////////// s.sync; // RECEIVE OSC MESSAGES FROM ESP32s ~esp32Receive = { arg name ,mac; OSCdef(name, { arg msg, time; /* postln("from esp32: " + mac + " name: " + name + " sensor: " + msg[2] ); // which ESP instrument and sensor is message coming from "~esp32Receive function declared".postln;*/ if (msg[1] == mac) { // use esp32 mac address to determine source of msg postln("from esp32: " + mac + " name: " + name + " sensor: " + msg[2] ); // which ESP instrument and sensor is message coming from w = case { msg[2] == 0} { ~oscPlay.value( chan: rrand(0,1), rates:[0.125, 0.5,1].choose + 0.1, sdir: \green, amp:rrand(0.4, 0.8), loop:0, group:~smpGrp ); } { msg[2] == 1} { ~oscPlay.value( chan: rrand(0,1), rates:[8,16,24].choose + 0.2, sdir: \bowl, amp:rrand(0.4, 0.8), loop:1, group:~smpGrp ); } { msg[2] == 2} { ~oscPlay.value( chan: rrand(0,1), rates:[0.125, 0.5, 1].choose + 0.3, sdir: \bowl, amp:rrand(0.4, 0.8), loop:0, group:~smpGrp ); } { msg[2] == 3} { ~oscPlay.value( chan: rrand(0,1), rates:[0.5, 1,2,3].choose + 0.5, sdir: \bowl, amp:rrand(0.4, 0.8), loop:0, group:~smpGrp ); } { msg[2] == 4} { ~oscPlay.value( chan: rrand(0,1), rates:[0.5, 1,2,3].choose + 0.8, sdir: \bowl, amp:rrand(0.4, 0.8), loop:0, group:~smpGrp ); } { msg[2] == 5} { ~oscPlay.value( chan: rrand(0,1), rates:[0.5, 1,2,3].choose + 1.3, sdir: \bowl, amp:rrand(0.4, 0.8), loop:0, group:~smpGrp ); } { msg[2] == 6} { ~oscPlay.value( chan: rrand(0,1), rates:[0.5, 1,2,3].choose + 2.1, sdir: \bowl, amp:rrand(0.4, 0.8), loop:0, group:~smpGrp ); } // touch 7 = toggle looping of all samplers { msg[2] == 7} { ~ls0 = (~ls0 + 1)% 2; ~smpGrp.set(\loop, ~ls0 ); // toggle this postln("loop state set as:" + ~ls0 + " 7 " + msg[2] ); }; } },'/touch') } ; s.sync; "asdfasdfasdf".postln; ~esp32Receive.('bendy_wires', 'A8:42:E3:4B:10:AC'); ~esp32Receive.('tetractys', '48:E7:29:C3:EF:BC'); ~esp32Receive.('roger', '48:E7:29:C3:EF:BC'); ~esp32Receive.('robbie', 'A8:42:E3:57:A1:38'); ~esp32Receive.('tina', 'A8:42:E3:47:5E:3C '); }; //} /// mesages from tetractys esp32 // 3C:E9:0E:AD:E5:00 - general // 48:E7:29:C3:EF:BC - tetractys // A0:B7:65:4A:AB:40 // white clip // A8:42:E3:4B:10:AC // testing thin case