diff --git a/README.md b/README.md index 1a6be7f..296c1df 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,8 @@ GPIO: momentary switchs +on diagram (0,1,2,3) + 4 TOUCH0 - SHIFT KEY 0 TOUCH1 - record to buffer 0 @@ -56,7 +58,7 @@ momentary switchs 15 TOUCH3 -toggle switchs +on diagram (4,5,6,7) 13 TOUCH4 diff --git a/gtr.scd b/gtr.scd index 5a0892d..d4d0fc2 100644 --- a/gtr.scd +++ b/gtr.scd @@ -68,7 +68,7 @@ SynthDef("recBuf",{ arg in=0, out=0, bufnum=0, t_trig=0, l=0, overdub=0; }).add; ); -// ---------------------------------------------------- +// ---------~positionmode = 1; ------------------------------------------- ( // Granulator -------------------------------------- // ---------------------------------------------------- @@ -81,16 +81,30 @@ SynthDef("recBuf",{ arg in=0, out=0, bufnum=0, t_trig=0, l=0, overdub=0; SynthDef(\buf_grain, { | out, gate = 1, amp = 1, sndbuf, envbuf, pan=0, imp=50, - pitchmodeindex=0, sensorpitch=1, - positionmodeindex=0, sensorposition=0, - impulsemodeindex=0, sensorimpulse=0, + pitchmodeindex=0, sensorpitch=1, sensorgdur=0.1, sensorgpan=0, + positionmodeindex=0, gdurmodeindex=0, gpanmodeindex=0, + sensorposition=0, impulsemodeindex=0, sensorimpulse=0, rlow= -1, rhigh=1 | var signal, env, freqdev, pos, pitchmode0, pitchmode1, pitch, + gdurmode0, gdurmode1, gdur, + gpanmode0, gpanmode1, gpan, positionmode0, positionmode1, position, impulsemode0, impulsemode1, impulse; + // grain duration mode -untransposed, random, or sensor controlled + gdurmode0 = 0.1; + gdurmode1 = LFNoise1.kr.range(0.2, 3.3); + gdur = Select.kr(gdurmodeindex, + [gdurmode0, gdurmode1, sensorgdur]); + + // grain pan mode -untransposed, random, or sensor controlled + gpanmode0 = 0.1; + gpanmode1 = LFNoise1.kr.range(0.1, 10.3); + gpan = Select.kr(gpanmodeindex, + [gpanmode0, gpanmode1, sensorgpan]); + // grain pitch mode -untransposed, random, or sensor controlled pitchmode0 = 1; pitchmode1 = LFNoise1.kr.range(rlow, rhigh); @@ -113,7 +127,7 @@ SynthDef(\buf_grain, { | out, gate = 1, amp = 1, Env([0, 1, 0], [1, 1], \sin, 1), gate, levelScale: amp, doneAction: 2); signal = GrainBuf.ar(2, impulse, // selectable between impulse.kr and dust.kr - 0.1, sndbuf, pitch, position, 2, pan, envbuf); + gdur, sndbuf, pitch, position, 2, gpan, envbuf); signal = FreeVerb2.ar(signal[0], signal[1], mix:0.4, room:0.5, damp:0 ); @@ -142,8 +156,7 @@ SynthDef(\buf_grain, { | out, gate = 1, amp = 1, // ---------------------------------------------------- (( // OSC Receivers // ENABLE SENSOR AND SWITCH VALUES <-- // ---------------------------------------------------- - -~pitchmode = 0; ~positionmode = 2; ~impulsemode = 0; +~pitchmode = 0; ~positionmode = 2; ~impulsemode = 0; ~gdurmode=0; ~gpanmode=0; ( // accel gyro quaternion mapping /////////////////// // msg[1] msg[2] msg[3] X Y Z ==> ROLL, PITCH, YAW @@ -152,6 +165,7 @@ o = OSCdef(\test, { arg msg, time, addr, recvPort, rlow, rhigh; // PAN ------- X Roll ~granulator1.set(\pan, msg[1].linlin(-0.3, 0.3, -1, 1)); + ~granulator1.set(\panmodeindex, ~panmode ); // PITCH ------- Y Pitch ~granulator1.set(\sensorpitch, msg[3].linlin(-1, 1, 0, 4)); @@ -164,7 +178,14 @@ o = OSCdef(\test, { arg msg, time, addr, recvPort, rlow, rhigh; // RATE ------- X (roll [with PAN]) ~granulator1.set(\sensorimpulse, msg[2].linlin(-1, 1, 5, 50)); ~granulator1.set(\impulsemodeindex, ~impulsemode ); - //msg.postln; + + ~granulator1.set(\sensorgdur, msg[2].linlin(-1, 1, 0.1, 1)); + ~granulator1.set(\gdurmodeindex, ~gdurmode ); + + ~granulator1.set(\sensorgpan, msg[2].linlin(-1, 1, -1, 1)); + ~granulator1.set(\gpanmodeindex, ~gpanmode ); + + //msg.postln; }; , '/euler'); ); @@ -173,26 +194,35 @@ o = OSCdef(\test, { arg msg, time, addr, recvPort, rlow, rhigh; // button press mapping /////////////////////////////// // ---------------------------------------------------- -p = OSCdef(\keys, { arg msg, time, addr, recvPort; +~btn2val = 0; +p = OSCdef(\keys, { arg msg, time, addr, recvPort; + //msg.println; // ============================== // BUTTON MAPPING // ============================== - // BUTTON X && X RESET/ZERO SENSORS [in firmware] - - if (msg[9] == 1 && msg[10] == 1, - { " ===== EULER ZEROED! =====".postln }, - {}); - // TRIGGER BUTTONS (3) ------------------------------ - // BUTTON X ----- TRIGGER ONESHOT BUFFER RECORD + // 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 }, {}); - ~btn2val; + + + if (msg[16]==1, + { + ( ~btn2val = (~btn2val + 1) % 3 ) ; + + switch(~btn2val, + 0, { ~positionmode = 0; "TEST MODE FIXED".postln; }, + 1, { ~positionmode = 1; "POSITION MODE RANDOM".postln; }, + 2, { ~positionmode = 2; "POSITION MODE SENSOR".postln; }, + ) + }); // BUTTON X ----- GRANULAR POSITION MODE @@ -201,15 +231,15 @@ p = OSCdef(\keys, { arg msg, time, addr, recvPort; ( ~btn2val = (~btn2val + 1) % 3 ) ; switch(~btn2val, - 0, { ~granulator1.set(\positionmodeindex, 0 ); "POSITION MODE FIXED".postln; }, - 1, { ~granulator1.set(\positionmodeindex, 1 ); "POSITION MODE RANDOM".postln; }, - 2, { ~granulator1.set(\positionmodeindex, 2 ); "POSITION MODE SENSOR".postln; }, + 0, { ~positionmode = 0; "POSITION MODE FIXED".postln; }, + 1, { ~positionmode = 1; "POSITION MODE RANDOM".postln; }, + 2, { ~positionmode = 2; "POSITION MODE SENSOR".postln; }, ) }); // BUTTON X ----- GRANULAR PITCH MODE - if (msg[12]==1, + if (msg[15]==1, { ( ~btn2val = (~btn2val + 1) % 3 ) ; @@ -237,6 +267,7 @@ p = OSCdef(\keys, { arg msg, time, addr, recvPort; // BUTTON X ----> LOOP RECORDING MODE ON/OFF + if (msg[13]==1, { ( ~btn2val = (~btn2val + 1) % 2 ) ; @@ -261,6 +292,21 @@ p = OSCdef(\keys, { arg msg, time, addr, recvPort; }; ); + }, /// SHIFT 0 LOGIC ENDS HERE + + { // SHIFT IN STATE 1 ======================= + + // BUTTON X && X RESET/ZERO SENSORS [in firmware] + + if (msg[11] == 1, + { " ===== EULER ZEROED! =====".postln }, + {}); + + + } // SHIFT ONE LOGIC ENDS HERE ================ + + ); /// closes SHIFT 1 + } , '/keys'); ); @@ -284,9 +330,9 @@ r.set(\overdub, 0); // off /// random pitch/rate low and high values ~granulator1.set(\rlow, 0); -~granulator1.set(\rlow, -10); +~granulator1.set(\rlow, -1); ~granulator1.set(\rhigh, 1); -~granulator1.set(\rhigh, 10); +~granulator1.set(\rhigh, 3); ~impulsemode = 0; // impulse ~impulsemode = 1; // dust @@ -300,6 +346,14 @@ r.set(\overdub, 0); // off ~positionmode = 1; // random position ~positionmode = 2; // sensor (position) input +~gdurmode = 0 ; // random position +~gdurmode = 1 ; // random position +~gdurmode = 2 ; // random position + +~gpanmode = 0 ; // random position +~gpanmode = 1 ; // random position +~gpanmode = 2 ; // random position + // set grain impulse rate ~granulator1.set(\imp, 50); diff --git a/osc32final/osc32final.ino b/osc32final/osc32final.ino index 6b44b58..50763e5 100644 --- a/osc32final/osc32final.ino +++ b/osc32final/osc32final.ino @@ -130,7 +130,11 @@ float GyX, GyY, GyZ; // Keys //byte keys[] = {16, 17, 5, 18}; + +// noise on byte keys[] = {4, 0, 2, 15, 13, 14, 12, 27}; // TOUCH0 - TOUCH7 +//byte keys[] = {33, 0, 2, 15, 13, 14, 12, 27}; // TOUCH8, TOUCH1 - TOUCH7 + byte pressed[] = {0, 0, 0, 0, 0, 0, 0, 0}; byte KEYLEN = 8; diff --git a/wavey-wind/server.js b/wavey-wind/server.js index d6f071c..be5481f 100644 --- a/wavey-wind/server.js +++ b/wavey-wind/server.js @@ -35,8 +35,8 @@ const DEBUG = true // Odprti serijski OSC link let scon = null -let buttonHeld = [false, false, false, false] -let buttonValue = [false, false, false, false] +let buttonHeld = [false, false, false, false, false, false, false, false] +let buttonValue = [false, false, false, false, false, false, false, false] let switchHeld = [false, false, false, false] let switchValue = [false, false, false, false] @@ -183,63 +183,86 @@ function eulerFromQuaternion(quaternion) { } -var threshold = 20; +var threshold = 15; +var thresholds = [15,15,15,15,15,15,15,15]; +var floatthresholds = [15,15,15,15,15,15,15,15]; +var threshdiff = 4; +var touchvalue = [40,40,40,40,40,40,40,40]; +var touchcount = [0,0,0,0,0,0,0,0]; const sendAll = (msg, info, oscWS, osclients) => { if (msg.address == '/keys') { - // keys 0 + 3 = euler reset - if (msg.args[0] <= threshold && msg.args[3] <= threshold ) { - eulerRotation = [0, 0, 0]; - console.log("EULER ROTATION RESET"); - } - } - var waiting = false; - - function waitFalse() { - waiting = false; - } - - - function wait4Second() { - waiting = true; - setTimeout(waitFalse, 1000); + console.log("TOUCH MSG",msg.args); + + for (let i = 1; i < 8; i++) { + touchvalue[i]=msg.args[i]; + } + touchvalue[0]=msg.args[0]; + // LOW PASS FILTER BUTTON 0 + // touchvalue[0]=touchvalue[0]*0.95+msg.args[0]*0.05; + //console.log("TOUCH VAL",touchvalue); + + // SELF-CALIBRATING TOUCH THRESHOLDS + for (let i = 0; i < 8; i++) { + if (floatthresholds[i]==15) thresholds[i]=floatthresholds[i]=msg.args[i]-threshdiff; + + if (msg.args[i]>(thresholds[i]+(threshdiff/2))) { + floatthresholds[i]=0.99 * floatthresholds[i] + 0.01*(msg.args[i]-threshdiff); + thresholds[i]=Math.round(floatthresholds[i]); + } + } + console.log("TOUCH FLTHR ",floatthresholds); + console.log("TOUCH THR ",thresholds); - } - - // LOGIC FOR SHIFT BUTTON 0 - for (let i = 0; i < 1; i++) { - // momentary state between 0 and 1 - if (msg.address == '/keys') { - if (msg.args[i] <= threshold ) { +/* // LOGIC FOR SHIFT BUTTON 0 + for (let i = 0; i < 1; i++) { + // momentary state between 0 and 1 + if (msg.args[i] <= thresholds[i] ) { buttonValue[i] = 1; } else { buttonValue[i] = 0; } - msg.args.push(buttonValue[i] ? 1 : 0) - } - } - - // LOGIC FOR MOMENTARY BUTTONS (1 - 3) - for (let i = 1; i < 8; i++) { + msg.args.push(buttonValue[i]) + } +*/ + // LOGIC FOR MOMENTARY BUTTONS (1 - 3) + for (let i = 0; i < 8; i++) { // momentary state between 0 and 1 - if (msg.address == '/keys') { - buttonValue[i] = 0; - if (msg.args[i] <= threshold ) { - if (buttonHeld[i] == false) { + + buttonValue[i] = 0; + if (touchvalue[i] <= thresholds[i] ) { + if (buttonHeld[i] == false) { + if (i!=0 || touchcount[i]) { buttonHeld[i] = true - buttonValue[i] = 1; + buttonValue[i] = 1; + console.log("TOUCH PRESS ",i,touchvalue[i],msg.args[i],thresholds[i],floatthresholds[i]); } - } else if (msg.args[i] >= threshold+5) { - buttonHeld[i] = false; } - msg.args.push(buttonValue[i] ? 1 : 0) - } + touchcount[i]++; + } else if (touchvalue[i] > thresholds[i]+(threshdiff/2)) { + if (buttonHeld[i]) console.log("TOUCH PRESS RELEASE ",i,touchvalue[i],msg.args[i],thresholds[i],floatthresholds[i],touchcount[i]); + buttonHeld[i] = false; + touchcount[i]=0; + } + + //0 IS SHIFT KEY, SENDS 1 ALL TIME WHEN HELD + if (i==0 && buttonHeld[0]) buttonValue[0]=1; + + msg.args.push(buttonValue[i]) + } + // keys 0 + 3 = euler reset + if (buttonHeld[0] && buttonHeld[3]) { + eulerRotation = [0, 0, 0]; + console.log("EULER ROTATION RESET"); + } + + // LOGIC FOR TOGGLE SWITCHES (4-7) // for (let i = 4; i < 8; i++) { @@ -260,7 +283,9 @@ const sendAll = (msg, info, oscWS, osclients) => { // } // } //------------------------------------------------ - + + } + // Convert quaternion diff to euler angle diff if (msg.address == '/quaternionDiff') { const euler = eulerFromQuaternion(msg.args, 'XYZ');