-// connect synth to midi-keyboard
-KeySynth {
+// connect synth to midi-controller
+MidiSynth {
var <midihandler, <>synthName, <>bendRadius, <>panAcross, <>params, <>amp, <>group;
- var <bend, <notes, madeNewGroup;
+ var <bend, madeNewGroup;
+
+ midiInit {
+ bend = 0;
+ group = group ?? {madeNewGroup = true; Group.new()};
+ params = params ? ();
+ }
+
+ makePanParam {|n|
+ var panParam=#[];
+ if (panAcross) {
+ panParam = [\pan, n.bilin(63, 0, 127, 0, -0.7, 0.7)];
+ };
+ ^panParam;
+ }
+
+ free {
+ if (madeNewGroup) {
+ group.free;
+ };
+ }
+
+}
+
+//=============================================================================
+
+// connect synth to midi-keyboard
+KeySynth : MidiSynth {
+ var <notes;
*new {|midihandler, synthName=\default, bendRadius=1, panAcross=false, params=nil, amp=1.0, group=nil|
- ^super.newCopyArgs(midihandler, synthName, bendRadius, panAcross, params, amp, group).allInit;
+ ^super.newCopyArgs(midihandler, synthName, bendRadius, panAcross, params, amp, group).midiInit.keyInit;
}
- allInit {
- bend = 0;
+ keyInit {
notes = Array.newClear(128);
- group = group ?? {madeNewGroup = true; Group.new()};
- params = params ? ();
midihandler.key_{|d, v, n|
- var panParam=#[];
if (d) {
- if (panAcross) {
- panParam = [\pan, n.bilin(63, 0, 127, 0, -0.7, 0.7)];
- };
notes[n] = Synth(synthName, params.value.asPairs++[
\gate, 1,
\freq, n.midicps,
\amp, amp * v,
- ]++panParam, group);
+ ]++this.makePanParam(n), group);
} {
notes[n].set(\gate, 0);
notes[n] = nil;
notes.do{|item|
item.free;
};
- if (madeNewGroup) {
- group.free;
- };
midihandler.key = nil;
midihandler.bend = nil;
+ super.free;
}
}
//=============================================================================
// connect synth to pads
-PadSynth {
- var <midihandler, <>synthName, <>bendRadius, <>panAcross, <>params, <>amp, <>group;
- var <bend, <notes, <amps, madeNewGroup;
+PadSynth : KeySynth {
+ var <amps;
*new {|midihandler, synthName=\default, bendRadius=1, panAcross=false, params=nil, amp=1.0, group=nil|
- ^super.newCopyArgs(midihandler, synthName, bendRadius, panAcross, params, amp, group).allInit;
+ ^super.newCopyArgs(midihandler, synthName, bendRadius, panAcross, params, amp, group).keyInit.padInit;
}
- allInit {
- bend = 0;
- notes = Array.newClear(128);
+ padInit {
amps = Array.fill(128, 0);
- group = group ?? {madeNewGroup = true; Group.new()};
- params = params ? ();
+
+ midihandler.key = nil;
midihandler.pad_{|d, v, col, row|
var freq, midinote;
- var panParam=#[];
freq = Scale.major.degreeToFreq(col, 0.midicps, row+1);
midinote = freq.cpsmidi.asInteger;
if (d) {
- if (panAcross) {
- panParam = [\pan, midinote.bilin(63, 0, 127, 0, -0.7, 0.7)];
- };
midihandler.ledPad(row, col, 2, 1, 1);
notes[midinote] = Synth(synthName, params.value.asPairs++[
\gate, 1,
\freq, freq,
\amp, amp * v,
- ]++panParam, group);
+ ]++this.makePanParam(midinote), group);
amps[midinote] = amp * v;
} {
midihandler.ledPad(row, col, 0, 1, 1);
});
});
};
-
-
-
- midihandler.bend_{|v|
- bend = v * bendRadius;
- notes.do{|item, i|
- item.set(\freq, (i+bend).midicps);
- };
- };
}
free {
- notes.do{|item|
- item.free;
- };
- if (madeNewGroup) {
- group.free;
- };
- midihandler.key = nil;
- midihandler.bend = nil;
+ midihandler.pad = nil;
+ midihandler.press = nil;
+ super.free;
}
}
//=============================================================================
+// connect synth to midi-keyboard, play only one note at a time
+KeySynthMono : MidiSynth {
+ var <note, <midinote;
+
+ *new {|midihandler, synthName=\default, bendRadius=1, panAcross=false, params=nil, amp=1.0, group=nil|
+ ^super.newCopyArgs(midihandler, synthName, bendRadius, panAcross, params, amp, group).midiInit.keyInit;
+ }
+
+ keyInit {
+ note = nil;
+ midinote = -1;
+
+ midihandler.key_{|d, v, n|
+ if (d) {
+ if (note.notNil) {
+ note.set(\gate, 0);
+ };
+ midinote = n;
+ note = Synth(synthName, params.value.asPairs++[
+ \gate, 1,
+ \freq, n.midicps,
+ \amp, amp * v,
+ ]++this.makePanParam(n), group);
+ } {
+ if (n == midinote) {
+ note.set(\gate, 0);
+ note = nil;
+ };
+ };
+ };
+
+ midihandler.bend_{|v|
+ bend = v * bendRadius;
+ if (note.notNil) {
+ note.set(\freq, (midinote+bend).midicps);
+ };
+ };
+ }
+
+ free {
+ note.free;
+ midihandler.key = nil;
+ midihandler.bend = nil;
+ super.free;
+ }
+}
+
+//=============================================================================
+
+// connect synth to midi-keyboard, play only one note at a time, relative keys
+KeySynthRelative : KeySynthMono {
+ var <>centerKey, <>intervals, keyNote;
+
+ *new {|midihandler, synthName=\default, bendRadius=1, panAcross=false, params=nil, amp=1.0, group=nil, centerKey=60, intervals=#[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]|
+ ^super.newCopyArgs(
+ midihandler, synthName, bendRadius, panAcross, params, amp, group
+ ).midiInit.keyInit.relInit(centerKey, intervals);
+ }
+
+ relInit {|c, i|
+ centerKey = c;
+ intervals = i;
+ keyNote = -1;
+ midinote = 60;
+ midihandler.key_{|d, v, n|
+ if (d) {
+ if (note.notNil) {
+ note.set(\gate, 0);
+ };
+ keyNote = n;
+ midinote = case
+ { (n-centerKey) == 0 } {
+ midinote;
+ }
+ { (n-centerKey) > 0 } {
+ midinote + intervals[n-centerKey-1];
+ }
+ { (n-centerKey) < 0 } {
+ midinote - intervals[centerKey-n-1];
+ };
+ midinote.postln;
+ note = Synth(synthName, params.value.asPairs++[
+ \gate, 1,
+ \freq, midinote.midicps,
+ \amp, amp * v,
+ ]++this.makePanParam(midinote), group);
+ } {
+ if (n == keyNote) {
+ note.set(\gate, 0);
+ note = nil;
+ keyNote = -1;
+ };
+ };
+ };
+ }
+}
+
+//=============================================================================
+
// connect sampler to pedals + push
MidiSampler {
var <push, <pedals, <sampler, <>tuneSound;
--- /dev/null
+~push = MidiPush();
+~push.midiout.latency_(0.2);
+
+~kedi = MidiRemote25SL();
+
+(
+~kedi.tempo_{|v|
+ TempoClock.tempo = v / 60;
+ v.postln;
+};
+
+TempoClock.play({|beats, time, clock|
+ ~push.syncTempo_(true);
+}, 1);
+)
+
+// infinite pattern
+// ###
+// ###
+(
+~screen = Array2D.new(8, 8);
+8.do{|i|
+ 8.do{|j|
+ ~screen[i, j] = 1.rand;
+ };
+};
+
+~draw = {|arr|
+ 8.do{|i|
+ 8.do{|j|
+ ~push.ledPad(i, j, arr[i, j]*3);
+ }
+ };
+};
+)
+
+~draw.value(~screen);
+
+(
+~conway = IdentityDictionary[
+ \arr -> Array2D.new(8, 8),
+ \time -> 0,
+ \init -> {|zi|
+ 8.do{|i|
+ 8.do{|j|
+ zi.arr[i, j] = 0;
+ };
+ };
+ },
+ \get -> {|zi, i, j|
+ i = i % 8;
+ j = j % 8;
+ zi.arr[i, j];
+ },
+ \nextGen -> {|zi|
+ var arrcopy = zi.arr.deepCopy;
+ 8.do{|i|
+ 8.do{|j|
+ var cur, sum;
+ cur = zi.get(i, j);
+ sum = 0;
+ (-1..1).do{|k|
+ (-1..1).do{|l|
+ sum = sum + zi.get(i+k, j+l);
+ };
+ };
+ sum = sum - cur;
+ if (cur == 1) {
+ if ((sum < 2) || (sum > 3)) {
+ arrcopy[i, j] = 0;
+ };
+ } {
+ if (sum == 3) {
+ arrcopy[i, j] = 1;
+ };
+ };
+ };
+ };
+ zi.arr = arrcopy;
+ zi.time = zi.time + 1;
+ }
+];
+~conway.know = true;
+~conway.init;
+)
+
+~conway.arr[1, 1] = 1;
+~conway.arr[2, 2] = 1;
+~conway.arr[1, 2] = 1;
+~conway.arr.postln;
+~conway.nextGen;
+
+(
+~eventGen = {|i, j, sum|
+ var ev = nil;
+ if (7.rand < 2) {
+ ev = (
+ instrument: [\dyti].choose,
+ midinote: 24+(i*5)+(j*2),
+ amp: 3/sum/(i+5),
+ legato: 0.2,
+ timingOffset: 3.rand/3// + 0.15
+ )
+ };
+ ev;
+};
+)
+
+~sum = 0;
+
+~routine.stop;
+
+(
+~conway.init;
+~conway.arr[2, 0] = 1;
+~conway.arr[2, 1] = 1;
+~conway.arr[2, 2] = 1;
+~conway.arr[3, 2] = 1;
+~conway.arr[3, 3] = 1;
+~conway.arr[3, 4] = 1;
+/*
+8.do{|i|
+8.do{|j|
+~conway.arr[i, j] = 2.rand;
+};
+};
+*/
+~routine = {
+ true.while{
+ ~sum = ~conway.arr.sum;
+ ~draw.value(~conway.arr);
+ 8.do{|i|
+ 8.do{|j|
+ if (~conway.arr[i, j] == 1) {
+ ~eventGen.value(i, j, ~sum).play;
+ };
+ };
+ };
+ 1.wait;
+ ~conway.nextGen;
+ };
+}.fork(quant: 1);
+)
+
+(
+~push.pad_{|d, v, c, r|
+ ~conway.arr[r, c] = 1;
+ ~push.ledPad(r, c, ~conway.arr[r, c]*3);
+};
+)
+
+~push.ledButton(\play, \brightBlink);
+
+(
+Pdef(\ritm, Pmono(\liwe, *[
+ dur: Pwrand([
+ Pseq([1, 1, 1, 1].normalizeSum*4, 1),
+ Pseq([1, 1, 1, 1, 1, 1, 1, 1].normalizeSum*4, 1),
+ Pseq([2, 2, 1, 1, 1, 1].normalizeSum*4, 1),
+ Pseq([4, 2, 2, 2, 2, 1, 1, 1, 1].normalizeSum*4, 1),
+ Pseq([3, 3, 2, 3, 2, 3].normalizeSum*4, 1),
+ Pseq([3, 3, 2, 2, 3, 3].normalizeSum*4, 1),
+ Pseq([3, 3, 2, 3, 3, 2].normalizeSum*4, 1),
+ Pseq([2, 1, 2, 1, 4, 2, 2, 2].normalizeSum*4, 1),
+ Pseq([3, 3, 2, 2, 1, 1, 1/2, 1/2, 1/2, 1/2, 2].normalizeSum*4, 1),
+ ], [5, 2, 1, 1, 2, 2, 2, 1, 1].normalizeSum, inf),
+ db: -21,
+ pan: Pwhite(-0.5, 0.5),
+ t_trig: Pwrand([1, 0], [15, 1], inf),
+ tension: 0.006/(Pkey(\dur)**0.4)*Pwhite(0.95, 1.05),
+ loss: Plprand(0.9999, 0.99995, inf),
+])).quant_(4).stop;
+)
+
+(
+Pdef(\ritm2, Pmono(\qoba, *[
+ dur: Pwrand([
+ Pseq([1, 1, 1, 1].normalizeSum*4, 1),
+ Pseq([1, 1, 1, 1, 1, 1, 1, 1].normalizeSum*4, 1),
+ Pseq([2, 2, 1, 1, 1, 1].normalizeSum*4, 1),
+ Pseq([4, 2, 2, 2, 2, 1, 1, 1, 1].normalizeSum*4, 1),
+ Pseq([3, 3, 2, 3, 2, 3].normalizeSum*4, 1),
+ Pseq([3, 3, 2, 2, 3, 3].normalizeSum*4, 1),
+ Pseq([3, 3, 2, 3, 3, 2].normalizeSum*4, 1),
+ Pseq([2, 1, 2, 1, 4, 2, 2, 2].normalizeSum*4, 1),
+ Pseq([3, 3, 2, 2, 1, 1, 1/2, 1/2, 1/2, 1/2, 2].normalizeSum*4, 1),
+ ], [5, 2, 1, 1, 2, 2, 2, 1, 1].normalizeSum, inf),
+ db: 15,
+ pan: Pwhite(-0.5, 0.5),
+ trig: Pwrand([1, 0], [15, 1], inf),
+ accent: 0.3,
+ freq: Pexprand(40, 80),
+ tone: 0.01,
+ decay: 0.2,
+ attackfm: 0.15,
+ selffm: 0.6,
+])).quant_(4).stop;
+)
+
+(
+Pdef(\ritm3, Pmono(\buti, *[
+ dur: Pwrand([
+ Pseq([1, 1, 1, 1].normalizeSum*4, 1),
+ Pseq([1, 1, 1, 1, 1, 1, 1, 1].normalizeSum*4, 1),
+ Pseq([2, 2, 1, 1, 1, 1].normalizeSum*4, 1),
+ Pseq([4, 2, 2, 2, 2, 1, 1, 1, 1].normalizeSum*4, 1),
+ Pseq([3, 3, 2, 3, 2, 3].normalizeSum*4, 1),
+ Pseq([3, 3, 2, 2, 3, 3].normalizeSum*4, 1),
+ Pseq([3, 3, 2, 3, 3, 2].normalizeSum*4, 1),
+ Pseq([2, 1, 2, 1, 4, 2, 2, 2].normalizeSum*4, 1),
+ Pseq([3, 3, 2, 2, 1, 1, 1/2, 1/2, 1/2, 1/2, 2].normalizeSum*4, 1),
+ ], [5, 2, 1, 1, 2, 2, 2, 1, 1].normalizeSum, inf),
+ timingOffset: 1/2,
+ db: -20,
+ pan: Pwhite(-0.5, 0.5),
+ trig: Pwrand([1, 0], [15, 1], inf),
+ accent: 0.5,
+ freq: Pexprand(40, 160),
+ tone: 0.1,
+ decay: Pwhite(0.1, 0.5),
+ snappy: Pwhite(0.1, 0.9),
+])).quant_(4).stop;
+)