diff options
-rw-r--r-- | contact_mic.ck | 34 | ||||
-rw-r--r-- | jack_patch.xml | 56 | ||||
-rw-r--r-- | lfo.ck | 82 | ||||
-rw-r--r-- | lib.ck | 10 | ||||
-rw-r--r-- | lib/Bus.ck | 30 | ||||
-rw-r--r-- | lib/Clipper.ck | 18 | ||||
-rw-r--r-- | lib/MIDI.ck | 18 | ||||
-rw-r--r-- | lib/Oscope.ck | 120 | ||||
-rw-r--r-- | lib/Queue.ck | 48 | ||||
-rw-r--r-- | oscilloscope.pd | 17 | ||||
-rw-r--r-- | pulse.wav | bin | 0 -> 35322 bytes | |||
-rw-r--r-- | rec.ck | 24 | ||||
-rw-r--r-- | settings.nktrl_set | bin | 0 -> 1184 bytes | |||
-rwxr-xr-x | start_chuck | 15 | ||||
-rw-r--r-- | virtualosc_obsolete.xml | 28 |
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> + @@ -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;*/ + } + } +} @@ -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 Binary files differnew file mode 100644 index 0000000..ccf7b26 --- /dev/null +++ b/pulse.wav @@ -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 Binary files differnew file mode 100644 index 0000000..14d7c64 --- /dev/null +++ b/settings.nktrl_set 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 |