summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contact_mic.ck34
-rw-r--r--jack_patch.xml56
-rw-r--r--lfo.ck82
-rw-r--r--lib.ck10
-rw-r--r--lib/Bus.ck30
-rw-r--r--lib/Clipper.ck18
-rw-r--r--lib/MIDI.ck18
-rw-r--r--lib/Oscope.ck120
-rw-r--r--lib/Queue.ck48
-rw-r--r--oscilloscope.pd17
-rw-r--r--pulse.wavbin0 -> 35322 bytes
-rw-r--r--rec.ck24
-rw-r--r--settings.nktrl_setbin0 -> 1184 bytes
-rwxr-xr-xstart_chuck15
-rw-r--r--virtualosc_obsolete.xml28
15 files changed, 500 insertions, 0 deletions
diff --git a/contact_mic.ck b/contact_mic.ck
new file mode 100644
index 0000000..12999b0
--- /dev/null
+++ b/contact_mic.ck
@@ -0,0 +1,34 @@
+/*
+ * contact mic
+ * digital feedback loop
+ */
+Clipper clipper;
+adc.chan(0) => Gain pregain => Echo echo => Gain amp => clipper.input;
+clipper.output => Bus.out_left;
+clipper.output => Bus.out_right;
+clipper.output => Delay del => amp;
+
+// mic pre-amplification - don't contribute to feedback loop
+6 => pregain.gain;
+
+1::second => echo.max;
+100::ms => echo.delay;
+0.8 => echo.mix;
+
+// feedback loop amp
+3 => amp.gain;
+
+// delay line: delay influences feedback pitch
+1::second => del.max;
+1::ms => del.delay;
+
+// simulate speaker<->mic distance
+0.324 => del.gain;
+
+/*
+ * record player
+ */
+adc.chan(1) => Bus.out_left;
+adc.chan(1) => Bus.out_right;
+
+while (day => now);
diff --git a/jack_patch.xml b/jack_patch.xml
new file mode 100644
index 0000000..6497036
--- /dev/null
+++ b/jack_patch.xml
@@ -0,0 +1,56 @@
+<!DOCTYPE patchbay>
+<patchbay version="0.3.4" name="jack_patch">
+ <output-sockets>
+ <socket exclusive="off" client="ChucK" type="audio" name="Chuck Out 1">
+ <plug>outport 0</plug>
+ <plug>outport 1</plug>
+ </socket>
+ <socket exclusive="off" client="ChucK" type="audio" name="Chuck Out 2">
+ <plug>outport 2</plug>
+ <plug>outport 3</plug>
+ </socket>
+ <socket exclusive="off" client="ChucK" type="audio" name="Chuck Out 3">
+ <plug>outport 4</plug>
+ <plug>outport 5</plug>
+ <plug>outport 6</plug>
+ </socket>
+ <socket exclusive="off" client="system" type="audio" name="ALSA hw:0 Out">
+ <plug>capture_1</plug>
+ <plug>capture_2</plug>
+ </socket>
+ <socket exclusive="off" client="alsa_in" type="audio" name="ALSA hw:default Out">
+ <plug>capture_1</plug>
+ </socket>
+ </output-sockets>
+ <input-sockets>
+ <socket exclusive="off" client="system" type="audio" name="ALSA hw:0 In">
+ <plug>playback_1</plug>
+ <plug>playback_2</plug>
+ </socket>
+ <socket exclusive="off" client="alsa_out" type="audio" name="ALSA hw:default In">
+ <plug>playback_1</plug>
+ <plug>playback_2</plug>
+ </socket>
+ <socket exclusive="off" client="jack\.scope-[0-9]+" type="audio" name="Oscilloscope In">
+ <plug>in_1</plug>
+ <plug>in_2</plug>
+ <plug>in_3</plug>
+ </socket>
+ <socket exclusive="off" client="ChucK" type="audio" name="Chuck In 1">
+ <plug>inport 0</plug>
+ <plug>inport 1</plug>
+ </socket>
+ <socket exclusive="off" client="ChucK" type="audio" name="Chuck In 2">
+ <plug>inport 2</plug>
+ </socket>
+ </input-sockets>
+ <slots/>
+ <cables>
+ <cable output="Chuck Out 1" input="ALSA hw:0 In"/>
+ <cable output="Chuck Out 2" input="ALSA hw:default In"/>
+ <cable output="Chuck Out 3" input="Oscilloscope In"/>
+ <cable output="ALSA hw:0 Out" input="Chuck In 1"/>
+ <cable output="ALSA hw:default Out" input="Chuck In 2"/>
+ </cables>
+</patchbay>
+
diff --git a/lfo.ck b/lfo.ck
new file mode 100644
index 0000000..a988dc0
--- /dev/null
+++ b/lfo.ck
@@ -0,0 +1,82 @@
+/*
+ * Configurable LFOs
+ */
+UGen @lfo[2]; // FIXME: ChucK bug prevents elegant initialization
+new SinOsc @=> lfo[0];
+new PulseOsc @=> lfo[1];
+
+Step lfo_freq;
+for (0 => int i; i < lfo.cap(); i++)
+ lfo_freq => lfo[i];
+
+0 => int cur_lfo;
+
+/* s.freq = lfo.freq*lfo.gain + base.value */
+lfo[cur_lfo] => Gain lfo_gain => SawOsc s => JCRev rev => Bus.out_left;
+rev => Bus.out_right;
+Step base => s;
+
+//50::ms => echo.delay;
+//.3 => echo.mix;
+
+0.1 => rev.mix;
+0.2 => rev.gain;
+
+10 => lfo_freq.next;
+400 => base.next;
+80 => lfo_gain.gain;
+
+//10 => lfo.harmonics;
+
+fun void
+change_lfo(int new_lfo)
+{
+ /* unchuck lfo */
+ lfo[cur_lfo] =< lfo_gain;
+ /* rechuck lfo */
+ lfo[new_lfo => cur_lfo] => lfo_gain;
+}
+
+/*
+ * LFO configuration via MIDI (Channel/Scene 0)
+ */
+/* FIXME: custom nanoKONTROL events */
+if (me.args() > 1)
+ me.exit();
+
+1 => int device;
+if (me.args() == 1)
+ me.arg(0) => Std.atoi => device;
+
+MidiIn min;
+
+if (!min.open(device))
+ me.exit();
+<<< "MIDI device:", min.num(), " -> ", min.name() >>>;
+
+while (min => now) {
+ while (MidiMsg msg => min.recv) {
+ msg.data1 & 0x0F => int channel;
+ msg.data1 & 0xF0 => int cmd;
+ (msg.data3 $ float)/127 => float value;
+
+ if (channel == 0 && cmd == 0xB0) {
+ <<< "Channel:", channel, "Command:", cmd, "Controller:", msg.data2, "Value:", value >>>;
+
+ if (msg.data2 == 22)
+ value => rev.gain;
+ else if (msg.data2 == 13)
+ 100 + value*900 => base.next;
+ else if (msg.data2 == 12)
+ value*100 => lfo_gain.gain;
+ else if (msg.data2 == 21)
+ value*20 => lfo_freq.next;
+ else if (msg.data2 == 31)
+ change_lfo(0);
+ else if (msg.data2 == 41)
+ change_lfo(1);
+ /*else if (msg.data2 == 9)
+ value $ int => lfo.harmonics;*/
+ }
+ }
+}
diff --git a/lib.ck b/lib.ck
new file mode 100644
index 0000000..b6f8809
--- /dev/null
+++ b/lib.ck
@@ -0,0 +1,10 @@
+/* Includes */
+Machine.add("lib/Clipper.ck");
+Machine.add("lib/MIDI.ck");
+Machine.add("lib/Queue.ck");
+
+Machine.add("lib/Bus.ck");
+
+Machine.add("lib/Oscope.ck");
+
+<<< "Channels: ", adc.channels() >>>;
diff --git a/lib/Bus.ck b/lib/Bus.ck
new file mode 100644
index 0000000..fbbca74
--- /dev/null
+++ b/lib/Bus.ck
@@ -0,0 +1,30 @@
+/*
+ * Public data bus
+ */
+public class Bus {
+ static Gain @out_left;
+ static Gain @out_right;
+
+ /* chucked in Oscope.ck */
+ static Gain @oscope[];
+
+ static Gain @channels[];
+}
+/* initialization */
+new Gain @=> Bus.out_left;
+new Gain @=> Bus.out_right;
+new Gain[3] @=> Bus.oscope;
+new Gain[8] @=> Bus.channels;
+
+/* limiting and clipping for main stereo outputs */
+Clipper clipper1;
+Bus.out_left => Dyno dyn1 => clipper1.input;
+clipper1.output => dac.chan(0);
+dyn1.limit();
+
+Clipper clipper2;
+Bus.out_right => Dyno dyn2 => clipper2.input;
+clipper2.output => dac.chan(1);
+dyn2.limit();
+
+while (day => now);
diff --git a/lib/Clipper.ck b/lib/Clipper.ck
new file mode 100644
index 0000000..c11d3c2
--- /dev/null
+++ b/lib/Clipper.ck
@@ -0,0 +1,18 @@
+/*
+ * clip signal within -1 to 1 with simple UGens
+ */
+public class Clipper {
+ Gain input; // chuck input signal to this
+ Gain output; // chuck this out to have the result
+
+ Step one; 1 => one.next;
+ input => HalfRect a;
+ one => a; // calculate a from HalfRect(input + 1)
+ one => Gain two; 2 => two.gain;
+ -1 => a.gain;
+ a => HalfRect b;
+ two => b; // calculate b from HalfRect(2 - HalfRect(input + 1))
+ -1 => b.gain;
+ one => output;
+ b => output; // the result we want: 1 - HalfRect(2 - HalfRect(input + 1))
+}
diff --git a/lib/MIDI.ck b/lib/MIDI.ck
new file mode 100644
index 0000000..be808db
--- /dev/null
+++ b/lib/MIDI.ck
@@ -0,0 +1,18 @@
+/*
+ * Global MIDI tools
+ */
+public class MIDI {
+ static int channels;
+
+ static int noteOff;
+ static int noteOn;
+
+ fun static int
+ isCmd(int data, int cmd)
+ {
+ return data >= cmd && data < cmd + channels;
+ }
+}
+0x10 => MIDI.channels;
+0x80 => MIDI.noteOff;
+0x90 => MIDI.noteOn;
diff --git a/lib/Oscope.ck b/lib/Oscope.ck
new file mode 100644
index 0000000..5849b3f
--- /dev/null
+++ b/lib/Oscope.ck
@@ -0,0 +1,120 @@
+/*
+ * Oscilloscope (jack.scope) helpers
+ */
+public class Oscope {
+ static OscSend @jack_scope;
+
+ /*
+ * "signal" or "embed"
+ */
+ fun static void
+ mode(string m)
+ {
+ jack_scope.startMsg("/mode", "s");
+ m => jack_scope.addString;
+ }
+
+ /*
+ * "dot", "fill" or "line"
+ */
+ fun static void
+ style(string s)
+ {
+ jack_scope.startMsg("/style", "s");
+ s => jack_scope.addString;
+ }
+
+ fun static void
+ frames(dur f)
+ {
+ // <<< "set frame size:", (f / samp) $ int >>>;
+ jack_scope.startMsg("/frames", "i");
+ (f / samp) $ int => jack_scope.addInt;
+ }
+
+ fun static void
+ delay(dur d)
+ {
+ // <<< "set delay length:", d / ms >>>;
+ jack_scope.startMsg("/delay", "f");
+ d / ms => jack_scope.addFloat;
+ }
+
+ /*
+ * "sample delay" in "embed" mode
+ * Can this be a ChucK duration???
+ */
+ fun static void
+ embed(int em)
+ {
+ jack_scope.startMsg("/embed", "i");
+ em => jack_scope.addInt;
+ }
+
+ fun static void
+ incr(float i)
+ {
+ jack_scope.startMsg("/incr", "f");
+ i => jack_scope.addFloat;
+ }
+}
+/* initialization */
+new OscSend @=> Oscope.jack_scope;
+Oscope.jack_scope.setHost("localhost", 57140);
+
+"signal" => Oscope.mode;
+"line" => Oscope.style;
+512::samp => Oscope.frames;
+100::ms => Oscope.delay;
+
+/*
+ * connect oscilloscope Bus channels to dedicated output ports that are patched
+ * to jack.scope
+ */
+for (0 => int i; i < Bus.oscope.cap(); i++)
+ Bus.oscope[i] => dac.chan(4 + i);
+
+/*
+ * jack.scope configuration via MIDI (Channel/Scene 1)
+ */
+/* FIXME: custom nanoKONTROL events */
+if (me.args() > 1)
+ me.exit();
+
+1 => int device;
+if (me.args() == 1)
+ me.arg(0) => Std.atoi => device;
+
+MidiIn min;
+
+if (!min.open(device))
+ me.exit();
+<<< "MIDI device:", min.num(), " -> ", min.name() >>>;
+
+while (min => now) {
+ while (MidiMsg msg => min.recv) {
+ msg.data1 & 0x0F => int channel;
+ msg.data1 & 0xF0 => int cmd;
+ (msg.data3 $ float)/127 => float value;
+
+ if (channel == 1 && cmd == 0xB0) {
+ <<< "Channel:", channel, "Command:", cmd, "Controller:", msg.data2, "Value:", value >>>;
+
+ if (msg.data2 == 67) {
+ if (value $ int)
+ "embed" => Oscope.mode;
+ else
+ "signal" => Oscope.mode;
+ } else if (msg.data2 == 76) {
+ if (value $ int)
+ "fill" => Oscope.style;
+ else
+ "line" => Oscope.style;
+ } else if (msg.data2 == 42) {
+ 512::samp + value*2::second => Oscope.frames;
+ } else if (msg.data2 == 57) {
+ 50::ms + value*second => Oscope.delay;
+ }
+ }
+ }
+}
diff --git a/lib/Queue.ck b/lib/Queue.ck
new file mode 100644
index 0000000..f05ae5e
--- /dev/null
+++ b/lib/Queue.ck
@@ -0,0 +1,48 @@
+/*
+ * Queue data structure
+ */
+public class Queue {
+ class Element {
+ Element @next;
+ Object @payload;
+ }
+ Element head @=> Element @tail;
+
+ fun void
+ push(Object @data)
+ {
+ new Element @=> tail.next @=> tail;
+ data @=> tail.payload;
+ }
+
+ fun Object @
+ peek()
+ {
+ if (head.next == null)
+ /* empty */
+ return null;
+ else
+ return head.next.payload;
+ }
+
+ fun Object @
+ pop()
+ {
+ head.next @=> Element @el;
+ if (el == null)
+ /* empty */
+ return null;
+
+ el.next @=> head.next;
+ if (el == tail)
+ /* but now it's empty! */
+ head @=> tail;
+ return el.payload;
+ }
+
+ fun void
+ flush()
+ {
+ while (pop() != null);
+ }
+}
diff --git a/oscilloscope.pd b/oscilloscope.pd
new file mode 100644
index 0000000..daac5e9
--- /dev/null
+++ b/oscilloscope.pd
@@ -0,0 +1,17 @@
+#N canvas 764 391 486 417 10;
+#X obj 9 351 adc~;
+#X obj 10 392 tabwrite~ oscilloscope;
+#N canvas 0 0 450 300 (subpatch) 0;
+#X array oscilloscope 4410 float 0;
+#X coords 0 100 4409 -100 400 280 1;
+#X restore 3 14 graph;
+#X obj 62 303 loadbang;
+#X msg 144 348 \; pd dsp 1;
+#X msg 19 302 bang;
+#X obj 62 348 metro 100;
+#X connect 0 0 1 0;
+#X connect 3 0 4 0;
+#X connect 3 0 6 0;
+#X connect 5 0 1 0;
+#X connect 5 0 6 0;
+#X connect 6 0 1 0;
diff --git a/pulse.wav b/pulse.wav
new file mode 100644
index 0000000..ccf7b26
--- /dev/null
+++ b/pulse.wav
Binary files differ
diff --git a/rec.ck b/rec.ck
new file mode 100644
index 0000000..1a30a5f
--- /dev/null
+++ b/rec.ck
@@ -0,0 +1,24 @@
+// chuck this with other shreds to record to file
+// example> chuck foo.ck bar.ck rec (see also rec2.ck)
+
+// FIXME: stereo recording
+
+// arguments: rec:<filename>
+
+// get name
+me.arg(0) => string filename;
+if (!filename.length())
+ "foo.wav" => filename;
+
+// pull samples from the dac
+dac => Gain g => WvOut w => blackhole;
+// this is the output file name
+filename => w.wavFilename;
+<<<"writing to file:", "'" + w.filename() + "'">>>;
+
+// any gain you want for the output
+//.5 => g.gain;
+
+// infinite time loop...
+// ctrl-c will stop it, or modify to desired duration
+while (day => now);
diff --git a/settings.nktrl_set b/settings.nktrl_set
new file mode 100644
index 0000000..14d7c64
--- /dev/null
+++ b/settings.nktrl_set
Binary files differ
diff --git a/start_chuck b/start_chuck
new file mode 100755
index 0000000..af8273e
--- /dev/null
+++ b/start_chuck
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# USB sound card JACK ports
+alsa_in -d hw:default -c 1 -q 0 >/dev/null &
+alsa_out -d hw:default -c 2 -q 0 >/dev/null &
+
+# Jack Oscilloscope (Bus.oscope[] in ChucK)
+# NOTE: frame size given here limits the frame size that can be set later on
+# currently the MIDI slider can set from 512 to (512::samp + 2::second)/samp
+jack.scope -n 3 -w 512 -b 96512 >/dev/null &
+
+# ChucK server
+# NOTE: Last three output ports are for jack.scope
+chuck --in3 --out7 --loop lib.ck
+
diff --git a/virtualosc_obsolete.xml b/virtualosc_obsolete.xml
new file mode 100644
index 0000000..09f539c
--- /dev/null
+++ b/virtualosc_obsolete.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<interface>
+ <tab label="Oscillator">
+ <slider label="Freq (Hz)"
+ type="set" geo="9.76 16.67 3.91 66.67"
+ color="white" max="20" showValue="true"
+ OSCAddress="/osc/freq">10</slider>
+
+ <slider label="Pitch (Hz)"
+ type="relative" geo="19.53 16.67 3.91 66.67"
+ color="blue red" min="100" max="1000" showValue="true"
+ OSCAddress="/osc/pitch">400</slider>
+
+ <slider label="Range (Hz)"
+ type="relative" geo="29.3 16.67 3.91 66.67"
+ color="white" max="100" showValue="true"
+ OSCAddress="/osc/range">80</slider>
+
+ <slider geo="39.06 16.67 6 53" color="red green"
+ min="20" max="200" step="5" label="VOL (db)" showValue="true"
+ OSCAddress="/osc/volume">100</slider>
+
+ <switch geo="39.06 73 6 10" label="MUTE"
+ OSCAddress="/osc/mute">true</switch>
+
+ </tab>
+</interface> \ No newline at end of file