initial commit of pifcamp 2023 workshop notes
commit
de0984ce6d
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
|
||||||
|
# CAPACITIVE COLLABORATIVE
|
||||||
|
- INSTRUMENT BUILDING WORKSHOP
|
||||||
|
- PIFCAMP 2023
|
||||||
|
|
||||||
|
## DEPENDENCIES
|
||||||
|
|
||||||
|
- pyserial - sudo apt install python3-serial
|
||||||
|
|
||||||
|
- ARDUINO 2.1.1
|
||||||
|
|
||||||
|
- esp boards for arduino
|
||||||
|
|
||||||
|
grep doit ./Arduino/hardware/espressif/esp32/boards.txt
|
||||||
|
|
||||||
|
modify boards.txt to allow large partition with no OTA
|
||||||
|
=
|
||||||
|
esp32doit-devkit-v1.menu.PartitionScheme.no_ota=No OTA (Large APP)
|
||||||
|
esp32doit-devkit-v1.menu.PartitionScheme.no_ota.build.partitions=no_ota
|
||||||
|
esp32doit-devkit-v1.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
|
||||||
|
|
||||||
|
- OSC by Adrian Freed
|
||||||
|
|
||||||
|
oscdump for testing - sudo apt install liblo-utils
|
||||||
|
|
||||||
|
Listen to OSC on PORT 57120
|
||||||
|
-----------------
|
||||||
|
# GPIO pin = touch input mapping
|
||||||
|
byte keys[] = {
|
||||||
|
32, // 0
|
||||||
|
33, // 1
|
||||||
|
27, // 2
|
||||||
|
14, // 3
|
||||||
|
12, // 4
|
||||||
|
13, // 5
|
||||||
|
-----------
|
||||||
|
4, // 6
|
||||||
|
15 // 7
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
# autostart file for miza installation
|
||||||
|
|
||||||
|
killall -9 /usr/lib/ardour7/ardour-7.3.0~ds0
|
||||||
|
|
||||||
|
killall -9 liquidsoap qjackctl jackd sclang scide;
|
||||||
|
|
||||||
|
barrier &
|
||||||
|
|
||||||
|
# choose audio interface
|
||||||
|
/usr/bin/jackd -aa -u -dalsa -r48000 -p256 -n3 -D -Chw:U192k -Phw:U192k &
|
||||||
|
#usr/bin/jackd -aa -u -dalsa -r48000 -p256 -n3 -D -Chw:VSL -Phw:VSL &
|
||||||
|
|
||||||
|
sleep 4;
|
||||||
|
|
||||||
|
qjackctl -a ~/spellcaster/spellcaster.xml &
|
||||||
|
|
||||||
|
sleep 2;
|
||||||
|
|
||||||
|
scide ~/pifcamp2023/sc/collaborative_capacitive.scd &
|
||||||
|
|
||||||
|
#sleep 1;
|
||||||
|
|
||||||
|
#ardour ~/spellcaster/ardour/spellcaster/spellcaster.ardour &
|
||||||
|
|
||||||
|
#sleep 1;
|
||||||
|
|
||||||
|
#liquidsoap ~/spellcaster/spellcaster.liq &
|
||||||
|
#xterm -e "liquidsoap ~/spellcaster/spellcaster.liq "
|
||||||
|
|
||||||
|
#sleep 1;
|
||||||
|
|
||||||
|
xterm; &
|
Binary file not shown.
After Width: | Height: | Size: 725 KiB |
|
@ -0,0 +1,140 @@
|
||||||
|
/*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
|
|
@ -0,0 +1,15 @@
|
||||||
|
(
|
||||||
|
Ndef(\gong, {
|
||||||
|
SinOsc.ar(75);
|
||||||
|
}).play(3);
|
||||||
|
)
|
||||||
|
s.meter
|
||||||
|
Ndef(\gong).clear
|
||||||
|
|
||||||
|
(Ndef(\mike, {
|
||||||
|
var in=SoundIn.ar(1);
|
||||||
|
Pitch.kr(in).poll;
|
||||||
|
in;
|
||||||
|
}).play(3))
|
||||||
|
FreqScope.new
|
||||||
|
s.quit
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue