( s.reboot{ s.options.numBuffers = 1024 * 256; // increase this if you need to load more samples s.options.sampleRate = 44100; // also tried with 44000 value s.options.memSize = 8192 * 32; // increase this if you get "alloc failed" messages s.options.numWireBufs = 64; // increase this if you get "exceeded number of interconnect buffers" messages s.options.maxNodes = 1024 * 32; // increase this if you are getting drop outs and the message "too many nodes" s.options.numInputBusChannels = 4; s.options.numOutputBusChannels = 4; } ) // RUNME 0 ========================================= s.boot(); // RUNME 1 ========================================= // ------------------------------------------------- ( // SETUP ----------------------------------------- - // --------------------------------------------------- // Allocate a 4 second mono buffer b = Buffer.alloc(s, s.sampleRate * 4.0, 1); // load a test file f = Buffer.read(s, thisProcess.nowExecutingPath.dirname +/+ "sounds/Front_Left.wav"); // Open port 57121 for ESP32 UDP OSC thisProcess.openUDPPort(57121); ); // RUNME 2 ========================================== // ------------------------------------------------- ( // DEFINE SYNTHS --------------------------------- <-- // ------------------------------------------------- ( // direct signal + reverb ------------------------- SynthDef("dryIn", { arg in=0, instrPanModeIndex=0, out=0, sensorInstrPan=0; var signal, dry, wet, instrPan, instrPanMode0, instrPanMode1, instrPanMode2, instrPanMode3, instrPanMode4, instrPanMode5; instrPanMode0 = 0; //LFNoise1.kr(100).range(-0.2, 0.2); instrPanMode1 = 1; //LFNoise1.kr(100).range(-0.2, 0.2); instrPanMode2 = SinOsc.kr(0.33).range(-0.2, 0.2); instrPanMode3 = LFNoise1.kr(10).range(-0.2, 0.2); instrPanMode4 = LFSaw.kr(0.33).bipolar.range(-1,1); instrPanMode5 = LFNoise1.kr(10).range(-1, 1); instrPan = Select.kr(instrPanModeIndex, [instrPanMode0, instrPanMode1, instrPanMode2, instrPanMode3, instrPanMode4, instrPanMode5, sensorInstrPan]); signal = SoundIn.ar(in); //wet = FreeVerb.ar(dry, mix:0.4, room:0.55, damp:0); signal = PanAz.ar(4, signal, instrPan); signal = signal * 0.9; Out.ar(0, signal); }).add; ); ( // mono buffer recorder ---------------------------- // with loop and overdub modes ///////////////////// // make record togglable between looping, direct or onset detection trigger SynthDef("recBuf",{ arg in=0, out=0, bufnum=0, t_trig=0, l=0, overdub=0; var sig, chain, onsets; sig = SoundIn.ar(in); // Onsets chain = FFT(LocalBuf(512), sig); onsets = Onsets.kr(chain, MouseX.kr(0,1), \rcomplex); RecordBuf.ar(sig, bufnum, loop:l, preLevel: overdub, doneAction: 0, trigger:t_trig,); }).add; ); // ---------~positionmode = 1; ------------------------------------------- ( // Granulator -------------------------------------- // ---------------------------------------------------- // a custom envelope //var winenv; //winenv = Env([0, 1, 0], [0.5, 0.5], [8, -8]); //z = Buffer.sendCollection(s, winenv.discretize, 1); // ~rndpos = LFNoise2.kr(0.1).range(0, 1); SynthDef(\buf_grain, { | out, gate = 1, amp = 0.5, sndbuf, envbuf, pan=0, imp=50, pitchmodeindex=0, sensorpitch=1, sensorgdur=0.1, sensorgpan=0, positionmodeindex=0, gdurmodeindex=0, gpanmodeindex=0, sensorposition=0, impulsemodeindex=0, sensorimpulse=0, signalChannelIndex=1, dseqarrayIndex=1, rlow= -1, rhigh=10 | var signal, env, freqdev, pos, pitchmode0, pitchmode1, pitchmode2,pitchmode3,pitchmode4,pitchmode5, pitchmode6, pitch, gdurmode0, gdurmode1, gdurmode2, gdurmode3, gdurmode4, gdurmode5, gdurmode6, gdur, gpanmode0, gpanmode1, gpanmode2, gpan, positionmode0, positionmode1, positionmode2, positionmode3, position, impulsemode0, impulsemode1, impulse, xdseq, dseq_array1, dseq_array2, dseq_array3, dseq_array4, dseq_array5, dseq_array6, stereosignal, quadsignalL, quadsignalR, quadsignal, signalchannels; // grain duration mode -untransposed, random, or sensor controlled gdurmode0 = 0.2; gdurmode1 = 0.5; gdurmode2 = LFNoise1.kr.range(0.1, 0.3); gdurmode3 = LFNoise1.kr.range(0.1, 0.6); gdurmode4 = LFNoise1.kr.range(0.6, 0.6); gdurmode5 = LFNoise1.kr.range(0.1, 2.6); gdurmode6 = LFNoise1.kr.range(0.01, 4); gdur = Select.kr(gdurmodeindex, [gdurmode0, gdurmode1, gdurmode2, gdurmode3, gdurmode4, gdurmode5, gdurmode6, sensorgdur]); // grain pan mode STEREO, QUAD, ROTATING gpanmode0 = LFNoise1.kr(100).range(-0.2, 0.2); gpanmode1 = LFSaw.kr(0.33).bipolar.range(-1,1); gpanmode2 = LFNoise1.kr(100).range(-1, 1); gpan = Select.kr(gpanmodeindex, [gpanmode0, gpanmode1, gpanmode2, sensorgpan]); // grain pitch mode -untransposed, random, or sensor controlled Scale.minor.degrees.midiratio; dseq_array1 = Dseq([1,-1, 2, 1, -1.5, 1, 1.33, 1, -0.5, 1, 3, 1, 2.37, 1, -0.33, 1], inf); dseq_array2 = Dseq([1,-1, -0.5, 1, 1.33, 1], inf); dseq_array3 = Drand([(1..5).mirror.midiratio], inf); dseq_array4 = Drand(Scale.minor.degrees.midiratio, inf); dseq_array5 = Dseq([1,-1, -0.5, 1, 1.33, 1], inf); // // // xdseq = [dseq_array1, dseq_array2,dseq_array3, dseq_array4, dseq_array5]; dseqarrayIndex =1; pitchmode0 = 1; pitchmode1 = Demand.kr(Impulse.kr(imp), 0, Dseq([1,-1, 2, 1, -1.5, 1, 1.33, 1, -0.5, 1, 3, 1, 2.37, 1, -0.33, 1], inf)); pitchmode2 = Demand.kr(Impulse.kr(imp), 0, Drand(Scale.minor.degrees.midiratio, inf) * Drand([0.5, 0.25,1,2], inf)); pitchmode3 = Demand.kr(Impulse.kr(imp), 0, Dseq([1,-1, -0.5, 1, 1.33, 1], inf)); pitchmode4 = Demand.kr(Impulse.kr(imp), 0, Drand([0.5, 0.25,1,2], inf)); pitchmode5 = Demand.kr(Impulse.kr(imp), 0, Drand(Scale.diminished.degrees.midiratio, inf)); pitchmode6 = LFNoise1.kr(imp).range(rlow, rhigh); pitch = Select.kr(pitchmodeindex, [pitchmode0, sensorpitch, pitchmode1, pitchmode2 ,pitchmode3, pitchmode4, pitchmode5, pitchmode6]); // granular playhead mode - fixed random or sensor controlled positionmode0 = 0.2; positionmode1 = (Phasor.ar(0.01, 1 * BufRateScale.ir(b), 0, BufSamples.ir(b)) + LFNoise1.ar(100).bipolar(0.1 * SampleRate.ir) ) / BufSamples.ir(b); positionmode2 = LFNoise1.kr.range(0.05, (BufSamples.ir(b)-1) - 1000 ); positionmode3 = LFNoise1.kr.range(0.1, 3.8 ); position = Select.kr(positionmodeindex, [positionmode0, positionmode1, positionmode2, positionmode3, sensorposition]); // grain impulse frequency mode - random, metric or sensor based impulse modes impulsemode0 = Impulse.kr(imp); impulsemode1 = Dust.kr(imp); impulse = Select.kr(impulsemodeindex, [impulsemode0, impulsemode1, sensorimpulse]); env = EnvGen.kr( Env([0, 1, 0], [1, 1], \sin, 1), gate, levelScale: amp, doneAction: 2); signal = TGrains.ar(4, impulse, b, pitch, position, gdur, gpan, amp, 4) * env; Out.ar(0, signal); }).add; ); ) // RUNME 3 ========================================== // ---------------------------------------------------- (( // START SYNTHS --------------------------------- // ---------------------------------------------------- // TODO NO EPRAND IN INSTR! r = Synth(\recBuf, [\in, 0, \out, 0, \bufnum, b, \t_trig, 0]); // recorder ~g1 = Synth(\buf_grain, [\sndbuf, b, \amp, 0.5, \envbuf, -1, \gate, 1, doneAction: 2]); // granulate ~gtrIn = Synth(\dryIn); // dry audio signaL )); // RUNME 4 ========================================== // ---------------------------------------------------- (( // OSC Receivers // ENABLE SENSOR AND SWITCH VALUES <-- // ---------------------------------------------------- ~pitchmode = 0; ~positionmode = 0; ~impulsemode = 1; ~gdurmode=0; ~gpanmode=0; ~channelmode=0; ~instrPanMode=0; ~btnstate = []; ~btnsA = []; ~btnsB = []; ~btnsC = []; ~btn0val = -1; ~btn1val = -1; ~btn2val = -1; ~btn3val = -1; ~btn4val = -1; ~btn5val = -1; ~btn6val = -1; ~btn7val = -1; ~btn8val = -1; // shift buttons ~btn9val = -1; ~btn10val = -1; ~btn11val = -1; ~btn12val = -1; ~btn13val = -1; ~btn14val = -1; ~btn15val = -1; ~btn16val = -1; ( // accel gyro quaternion mapping /////////////////// // msg[1] msg[2] msg[3] X Y Z ==> ROLL, PITCH, YAW o = OSCdef(\test, { arg msg, time, addr, recvPort, rlow, rhigh; // PAN ------- X Roll ~g1.set(\pan, msg[1].linlin(-0.3, 0.3, -1, 1)); ~g1.set(\gpanmodeindex, ~gpanmode ); // PITCH ------- Y Pitch ~g1.set(\sensorpitch, ( msg[3] * 5 ) + 1 ); ~g1.set(\pitchmodeindex, ~pitchmode ); // POSITION ------- Z Yaw ~g1.set(\sensorposition, msg[2].linlin(-1, 1, 0.05, 3.99)); ~g1.set(\positionmodeindex, ~positionmode ); // RATE ------- X (roll [with PAN]) ~g1.set(\sensorimpulse, msg[2].linlin(-1, 1, 5, 50)); ~g1.set(\impulsemodeindex, ~impulsemode ); ~g1.set(\sensorgdur, msg[2].linlin(-1, 1, 0.1, 1)); ~g1.set(\gdurmodeindex, ~gdurmode ); ~g1.set(\sensorgpan, msg[2]); ~g1.set(\gpanmodeindex, ~gpanmode ); //~g1.set(\sensorgpan, msg[2].linlin(-1, 1, -1, 1)); //~g1.set(\signalChannelIndex, ~channelmode ); ~gtrIn.set(\sensorInstrPan, msg[2].wrap(0, 5).linlin(0, 5, -1, 1)); ~gtrIn.set(\instrPanModeIndex, ~instrPanMode); //msg.postln; }; , '/euler'); ); // ---------------------------------------------------- // send message back to nodejs m = NetAddr("127.0.0.1", 57100); // on off osconoff accelerometer data m.sendMsg("/xyzc", 1); m.sendMsg("/xyzc", 0); // ---------------------------------------------------- // button press mapping /////////////////////////////// // ---------------------------------------------------- p = OSCdef(\keys, { arg msg, time, addr, recvPort; ~btnsA[~btn2val, ~btn3val]; ~btnsB[~btn4val, ~btn5val, ~btn6val, ~btn7val]; ~btnsC[~btn5val]; ~btnstate = [~btnsA, ~btnsB, ~btnsC]; if (msg[9] == 1 && msg[10] == 1, {~btnstate.postln;}); //msg.println; // ============================== // BUTTON MAPPING // ============================== // TRIGGER BUTTONS (3) ------------------------------ // if SHIFT key is 0: if (msg[9] == 0, { // BUTTON X ----- TRIGGER ONESHOT BUFFER RECORD if (msg[10] == 1, { r.set( \in, 0, \l, 0, \t_trig, 1); "/////////// SAMPLING!".postln }, {}); // BUTTON X ----> LOOP RECORDING MODE ON/OFF if (msg[11]==1, { ( ~btn2val = (~btn2val + 1) % 3 ) ; switch( ~btn2val, 0, { r.set(\l, 0); "RECORD LOOPING OFF".postln; }, 1, { r.set(\l, 1); "RECORD LOOPING ON".postln; }, 2, { r.set(\l, 1); "RECORDING ONSET DETECTION ON".postln; }, //todo ); }); // BUTTON X ----> OVERDUB RECORDING MODE ON/OFF if (msg[12]==1, { ( ~btn3val = (~btn3val + 1) % 5 ) ; switch( ~btn3val, 0, { r.set(\overdub, 0); "SAMPLE OVERDUB OFF".postln; }, 1, { r.set(\overdub, 0.5); "SAMPLE OVERDUB ON 50%".postln; }, 2, { r.set(\overdub, 0.75); "SAMPLE OVERDUB ON 75%".postln; }, 3, { r.set(\overdub, 0.90); "SAMPLE OVERDUB ON 90%".postln; }, 4, { r.set(\overdub, 1); "SAMPLE OVERDUB ON 100%".postln; }, ) }); //TODO btn7 repeated counter fix /////////////////// RESET RANDOM PITCH TO FIXED PITCH IN ONE TAP if (msg[14]==1, { ( ~btn5val = (~btn5val + 1) % 2 ) ; switch( ~btn5val, 0, { ~pitchmode = 0; "PITCH RESET TO UNTRANSPOSED MODE".postln; }, 1, { ~pitchmode = 1; "PITCH IN SENSOR MODE".postln; } ); }); // INCREASE IMPULSE RATE --------------------------------------- if (msg[15]==1, { ( ~btn6val = (~btn6val + 1) % 8 ) ; switch(~btn6val, 0, { ~g1.set(\imp, 1); "IMPULSE = 1".postln; }, 1, { ~g1.set(\imp, 2); "IMPULSE = 2".postln; }, 2, { ~g1.set(\imp, 4); "IMPULSE = 4".postln; }, 3, { ~g1.set(\imp, 8); "IMPULSE = 8".postln; }, 4, { ~g1.set(\imp, 16); "IMPULSE = 16".postln; }, 5, { ~g1.set(\imp, 32); "IMPULSE = 32".postln; }, 6, { ~g1.set(\imp, 64); "IMPULSE = 64".postln; }, 7, { ~g1.set(\imp, 128); "IMPULSE = 128".postln; }, ) }); // BUTTON X ----- G PANNING MODE if (msg[16]==1, { ( ~btn7val = (~btn7val + 1) % 3 ) ; switch( ~btn7val, 0, { ~gpanmode = 0 ; "PAN STEREO".postln; }, 1, { ~gpanmode = 1 ; "PAN QUAD ROTATIONS".postln; }, 2, { ~gpanmode = 2 ; "PAN RANDOM QUAD".postln; }, ) }); }, /// SHIFT 0 LOGIC ENDS HERE -------------------------------------------- { // SHIFT IN STATE 1 ======================= .......................... // GTR INPUT ======================= if (msg[11]==1, { ( ~btn10val = (~btn10val + 1) % 9 ) ; switch(~btn10val, 0, { ~gtrIn.set(\in, 1 ); "DRY SIGNAL OFF".postln; }, 1, { ~gtrIn.set(\in, 0 ); ~instrPanMode=0; "DRY FRONT {STERE0}".postln; }, 2, { ~gtrIn.set(\in, 0 ); ~instrPanMode=1; "DRY BACK {STERE0}".postln; }, 3, { ~gtrIn.set(\in, 0 ); ~instrPanMode=2; "DRY RaND {STEREO}".postln; }, 4, { ~gtrIn.set(\in, 0 ); ~instrPanMode=3; "DRY L/R PAN {STEREO}".postln; }, 5, { ~gtrIn.set(\in, 0 ); ~instrPanMode=4; "DRY ROTATE {QUAD}".postln; }, 6, { ~gtrIn.set(\in, 0 ); ~instrPanMode=5; "DRY RaND {QUAD}".postln; }, 7, { ~gtrIn.set(\in, 0 ); ~instrPanMode=6; "DRY SENSOR {QUAD}".postln; }, 8, { ~gtrIn.set(\in, 0 ); ~instrPanMode=7; "DRY SENSOR {QUAD}".postln; }, ) }); // BUTTON X && X RESET/ZERO SENSORS [in firmware just here for notificaton] if (msg[12] == 1, { " ===== EULER ZEROED! =====".postln }, {}); // BUTTON X ----- GRANULAR POSITION MODE if (msg[13]==1, { ( ~btn12val = (~btn12val + 1) % 5 ) ; switch(~btn12val, 0, { ~positionmode = 0; "POSITION MODE FIXED".postln; }, 1, { ~positionmode = 1; "POSITION MODE LOOPING".postln; }, 2, { ~positionmode = 2; "POSITION MODE RANDOM".postln; }, 3, { ~positionmode = 3; "POSITION CONSTRAINED RND".postln; }, 4, { ~positionmode = 4; "POSITION MODE SENSOR".postln; }, ) }); // BUTTON X ----- GRANULAR PITCH MODE if (msg[14]==1, { ( ~btn13val = (~btn13val + 1) % 8 ) ; switch(~btn13val, 0, { ~pitchmode = 2; "pitch array 0".postln; }, 1, { ~pitchmode = 3; "pitch array 1".postln; }, 2, { ~pitchmode = 4; "pitch array 2".postln; }, 3, { ~pitchmode = 5; "pitch array 3".postln; }, 4, { ~pitchmode = 6; "pitch array 4".postln; }, 5, { ~pitchmode = 7; ~g1.set(\rlow, -0.8 ); ~g1.set(\rhigh, 1.5); "PITCH MODE RANDOM 4".postln; }, 6, { ~pitchmode = 7; ~g1.set(\rlow, -3 ); ~g1.set(\rhigh, 3); "PITCH MODE RANDOM 5".postln; }, 7, { ~pitchmode = 7; ~g1.set(\rlow, -8 ); ~g1.set(\rhigh, 8); "PITCH MODE RANDOM 6".postln; }, ) }); // BUTTON X ----- GRAIN DURATION MODE if (msg[15]==1, { ( ~btn14val = (~btn14val + 1) % 7 ) ; switch(~btn14val, 0, { ~gdurmode = 0; ~g1.set(\imp, 64); "DURATION MODE 0".postln; }, 1, { ~gdurmode = 1; ~g1.set(\imp, 30); "DURATION MODE 1".postln; }, 2, { ~gdurmode = 2; ~g1.set(\imp, 20); "DURATION MODE 2".postln; }, 3, { ~gdurmode = 3; ~g1.set(\imp, 15); "DURATION MODE 3".postln; }, 4, { ~gdurmode = 4; ~g1.set(\imp, 10); "DURATION MODE 4".postln; }, 5, { ~gdurmode = 5; ~g1.set(\imp, 5); "DURATION MODE 5".postln; }, 6, { ~gdurmode = 6; ~g1.set(\imp, 3); "DURATION MODE 6".postln; }, ) }); // BUTTON X ----- GRANULAR IMPULSE MODE if (msg[16]==1, { ( ~btn15val = (~btn15val + 1) % 3 ) ; switch( ~btn15val, 0, { ~g1.set(\impulsemodeindex, 0 ); "IMPULSE MODE FIXED".postln; }, 1, { ~g1.set(\impulsemodeindex, 1 ); "IMPULSE MODE DUST".postln; }, 2, { ~g1.set(\impulsemodeindex, 2 ); "IMPULSE MODE SENSOR".postln; }, ) }); }); // SHIFT ONE LOGIC ENDS HERE ================ } , '/keys'); )); // ---------------------------------------------------- // PERFORMABLE PARAMETERS ///////////////////////////// // ---------------------------------------------------- // start recording (without button) r.set(\in, 0, \l, 0, \t_trig, 1); // set recorder loop and overdub modes r.set(\l, 1); // looping record on - MAPPED TO SWITCH 3 r.set(\l, 0); // off r.set(\overdub, 1); // overdub mode on - MAPPED TO SWITCH 4 r.set(\overdub, 0); // off /// random pitch/rate low and high values ~g1.set(\rlow, 1); ~g1.set(\rlow, 0.2); ~g1.set(\rhigh, 2); ~g1.set(\rhigh, 1); 1.midiratio; 33.midiratio; ~impulsemode = 0; // impulse ~impulsemode = 1; // dust ~impulsemode = 2; // sensor ~pitchmode = 0; // no transpose ~pitchmode = 1; // sensor (pitch) input ~pitchmode = 2; // random2 ~pitchmode = 3; // random3 ~pitchmode = 4; // random4 ~pitchmode = 5; // random5 ~pitchmode = 6; // ~positionmode = 0; // middle of sample ~positionmode = 1; // random position ~positionmode = 2; // sensor (position) input ~gdurmode = 0 ; // random position ~gdurmode = 1 ; // random position ~gdurmode = 2 ; // random position ~gdurmode = 3 ; // random position ~gdurmode = 4 ; // random position ~gdurmode = 5 ; // random position ~gdurmode = 6 ; // random position ~gpanmode = 0 ; // random position ~gpanmode = 1 ; // random position ~gpanmode = 2 ; // random position ~gpanmode = 3 ; // random position ~dseqarrayIndex=0; ~g1.set(\dseqarrayIndex, 0); ~g1.set(\gpan, -1 ); ~channelmode = 1; // set grain impulse rate ~g1.set(\imp, 10); // fix doneaction ~g1.set(\gate, 1); // granulator on ~g1.set(\gate, 0); // granulator off ~g1.set(\amp, 0.5); // granulator off a = Scale.major; ///////////////////////////////////////////////// // ----------------------------------------------- // ----------------------------------------------- // ----------------------------------------------- // list all open ports // ----------------------------------------------- // CODE DUMP ZONE /////////////////////////////// // switch to the custom env //~g1.set(\envbuf, z); //~g1.set(\envbuf, -1); //n = NetAddr("127.0.0.1", NetAddr.langPort); //n = NetAddr.new("224.0.1.9", 6696);