show prep wip

master
Leo Coogan 9 months ago
parent 33e6cc729e
commit 0aed7d5205
Signed by: lcoogan
SSH Key Fingerprint: SHA256:vnrR5ilHkdr6L4t2yOMUMINFPpxEh+53N3nMel66mCw

@ -9,22 +9,22 @@ MIDIIn.connectAll;
~sampleDir = PathName("~/snd/samples/808/").fullPath; ~sampleDir = PathName("~/snd/samples/808/").fullPath;
~samples = ( ~samples = (
42: Buffer.read(s, ~sampleDir +/+ "Cls'dHihat.wav"), 42: Buffer.read(s, ~sampleDir +/+ "ch.wav"),
46: Buffer.read(s, ~sampleDir +/+ "OpenHiHat.wav"), 46: Buffer.read(s, ~sampleDir +/+ "oh.wav"),
49: Buffer.read(s, ~sampleDir +/+ "CYmbal.wav"), 49: Buffer.read(s, ~sampleDir +/+ "cy.wav"),
56: Buffer.read(s, ~sampleDir +/+ "CowBell.wav"), 56: Buffer.read(s, ~sampleDir +/+ "cb.wav"),
39: Buffer.read(s, ~sampleDir +/+ "handClaP.wav"), 39: Buffer.read(s, ~sampleDir +/+ "cp.wav"),
37: Buffer.read(s, ~sampleDir +/+ "RimShot.wav"), 37: Buffer.read(s, ~sampleDir +/+ "rs.wav"),
50: Buffer.read(s, ~sampleDir +/+ "HiTom.wav"), 50: Buffer.read(s, ~sampleDir +/+ "ht.wav"),
47: Buffer.read(s, ~sampleDir +/+ "MidTom.wav"), 47: Buffer.read(s, ~sampleDir +/+ "mt.wav"),
43: Buffer.read(s, ~sampleDir +/+ "LowTom.wav"), 43: Buffer.read(s, ~sampleDir +/+ "lt.wav"),
38: Buffer.read(s, ~sampleDir +/+ "SnareDrum.wav"), 38: Buffer.read(s, ~sampleDir +/+ "sd.wav"),
36: Buffer.read(s, ~sampleDir +/+ "BassDrum.wav"), 36: Buffer.read(s, ~sampleDir +/+ "bd.wav"),
70: Buffer.read(s, ~sampleDir +/+ "MAracas.wav"), 70: Buffer.read(s, ~sampleDir +/+ "ma.wav"),
75: Buffer.read(s, ~sampleDir +/+ "CLaves.wav"), 75: Buffer.read(s, ~sampleDir +/+ "cl.wav"),
62: Buffer.read(s, ~sampleDir +/+ "HiConga.wav"), 62: Buffer.read(s, ~sampleDir +/+ "hc.wav"),
63: Buffer.read(s, ~sampleDir +/+ "MidConga.wav"), 63: Buffer.read(s, ~sampleDir +/+ "mc.wav"),
64: Buffer.read(s, ~sampleDir +/+ "LowConga.wav") 64: Buffer.read(s, ~sampleDir +/+ "lc.wav")
); );
); );

@ -0,0 +1,3 @@
// var ir = Buffer.read(s, "/home/lcoogan/snd/ir/ForestScaleModel/ForestScaleModel/IR_ScaleModel/S1R1_ScaleModel.wav"); // Load an impulse response file
// sig = Convolution2.ar(sig, ir, 512) * 0.5; // Apply convolution reverb with buffer size 512'''

@ -0,0 +1,78 @@
// Don't touch!
~klezmer = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Acheinu_Kol_Beit_Israel.wav", channels:[0]);
b = Buffer.read(s,"/Users/eli/Sounds/scaudio/groh/metal/metalPipe/metalPipeLow02.aiff");
(
x = {
var sig;
sig = GrainBuf.ar(
numChannels: 2,
trigger: Impulse.kr(2),
dur: 1,
sndbuf: b,
rate: \trnsp.kr(0).midiratio,
pos: 0.1,
interp: 2,
pan: 0,
envbufnum: -1,
maxGrains: 512
);
// sig = sig * 10;
}.play;
)
x.set(\trnsp, 12)
x.free;
(
{
var sig;
sig = GrainBuf.ar(
1,
Dust.ar(40),
0.8,
~klezmer,
1,
1.25,
2,
0,
-1,
512
);
sig = sig!2;
}.play;
)
~klezmer = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Acheinu_Kol_Beit_Israel.wav", channels:[0]);
~klezmer = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Cantor_Samuel_Malavsky_Zechor.wav", channels:[0]);
~klezmer = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/yiddish_chuasdel.wav", channels:[0]);
(
// MIDI sequencing by MIDI file
var m1, m2, x1, x2;
// Read each MIDI file separately
m1 = SimpleMIDIFile.read("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-borrowed flesh/midi/fuzzy gameboy.mid");
m2 = SimpleMIDIFile.read("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-borrowed flesh/midi/pad organ.mid");
// Play both MIDI sequences simultaneously
x1 = m1.p(\granular).play;
x2 = m2.p(\granular).play;
// Store them in a global variable so you can stop them later
~midiPlayers = [x1, x2];
)

@ -0,0 +1,16 @@
(
x = {
var sig = WhiteNoise.ar(1!2);
sig = CombL.ar(sig, 0.05, 1/[36.7, 37.3], 1, 0.2);
sig = sig.blend(BPF.ar(sig, 1500, 0.5), 0.9);
}.play(fadeTime: 2);
)
x.release;

@ -0,0 +1,114 @@
// Granular leftovers from granular_EF-edit.scd
// Transposition. Doesn't sound good, not readily controllable from an artistic perspective.
~klezmer = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Acheinu_Kol_Beit_Israel.wav", channels:[0]);
(
x = {
arg amp = 0.1;
var sig;
sig = GrainBuf.ar(
numChannels: 2,
trigger: Impulse.kr(1),
dur: 1,
sndbuf: ~klezmer,
rate: \trnsp.kr(0).midiratio,
pos: 0.1,
interp: 2,
pan: 0,
envbufnum: -1,
maxGrains: 512
);
sig = sig;
}.play;
)
x.set(\trnsp, 20)
x.free;
(
// MIDI
MIDIClient.init;
MIDIIn.connectAll;
)
(
~notes = Array.newClear(128);
// Handle MIDI note on (when a note is pressed)
MIDIdef.noteOn(\noteOnTest, {
arg vel, nn, chan, src;
// Post the velocity and note for debugging
// [vel, nn].postln;
// Create a Synth for the note with the correct argument names
~notes[nn] = Synth.new(
\granular,
[
\note, nn, // Use \note, not \freq
\amp, vel.linexp(1, 127, 0.01, 0.3), // Map velocity to amplitude
\gate, 1, // Trigger the envelope
]
);
});
// Handle MIDI note off (when a note is released)
MIDIdef.noteOff(\noteOffTest, {
arg vel, nn;
// Set gate to 0 to stop the sound
~notes[nn].set(\gate, 0);
// Clear the reference to the Synth object for the note
~notes[nn] = nil;
});
)
(
~granularSynth = Synth(\granular, [
\note, 60, // C4
// \dur, 1,
\pan, 0
]);
)
(
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Cantor_Samuel_Malavsky_Zechor.wav");
(
SynthDef(\cantorial_tremolo, {
|out, pan = 0, dur = 0.1, atk=0.3, dec=0.4, sus=0.1, rel=0, amp=1, crf=1200|
var sig, rate, env, filter;
env = EnvGen.ar(
Env.new(
[0, 1, 1, 0],
[atk, dec, sus, rel],
),
gate: 1,
doneAction: 2
);
sig = GrainBuf.ar(
numChannels: 2,
trigger: Impulse.kr(10),
dur: dur,
sndbuf: b,
rate: 1,
pos: 0.1,
interp: 2,
pan: pan,
envbufnum: -1,
maxGrains: 512
);
sig = sig * env * amp;
filter = MoogVCF.ar(sig, crf, 0.3);
Out.ar(out, filter);
}).play;
)
)

@ -0,0 +1,159 @@
~klezmer = "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Acheinu_Kol_Beit_Israel.wav"
(
{
var sig;
sig = GrainBuf.ar(
1,
Impulse.ar(2),
1,
~klezmer,
1,
1.2,
1,
0,
-1,
512
);
sig = sig!2;
}.play;
)
(
{
var sig;
sig = GrainBuf.ar(
1,
Dust.ar(40),
0.8,
~klezmer,
1,
1.25,
2,
0,
-1,
512
);
sig = sig!2;
}.play;
)
~organ = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Cantor_Samuel_Malavsky_Zechor.wav");
(
{
var sig;
sig = TGrains2
})
~klezmer = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Acheinu_Kol_Beit_Israel.wav", channels:[0]);
~klezmer = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Cantor_Samuel_Malavsky_Zechor.wav", channels:[0]);
~klezmer = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/yiddish_chuasdel.wav", channels:[0]);
(
SynthDef(\granular, {
arg freq = 410, amp = 4, pan = 0, gate = 1, baseFreq = 600, lpfFreq = 8000, rq = 0.3, drive = 1, pitchRatio = 1;
var sig, env, trig, waveshapedSig, filteredSig, shiftedSig;
trig = Impulse.kr(10, 0.5, 1.0, 0.0) + Dust.kr(1); // Regular grain trigger
env = EnvGen.kr(Env.adsr(0, 0.2, 0.4, 1), gate, doneAction: 2);
// Random panning for each grain
pan = 0;
// Granular synthesis without internal rate control (rate = 1)
sig = GrainBuf.ar(
1,
trig,
0.8,
~klezmer,
1,
1.25,
2,
0,
-1,
512
) * env;
// Apply pitch shifting externally
shiftedSig = PitchShift.ar(sig, 0.2, 580 / baseFreq); // Shifting the pitch after the grain is generated
// Apply waveshaper: Tanh saturation (soft clipping)
waveshapedSig = (shiftedSig * drive).tanh;
// Apply a resonant low-pass filter
filteredSig = SVF.ar(waveshapedSig, lpfFreq, rq);
// Apply panning and amplitude
filteredSig = Pan2.ar(filteredSig, pan) * amp;
// Output the final signal
Out.ar(0, filteredSig);
}).play;
)
(
SynthDef(\granular, {
arg freq = 400, amp = 1, pan = 8, gate = 1, baseFreq = 600;
var sig, env, trig, rate;
trig = Impulse.kr(10); // Regular grain trigger
env = EnvGen.kr(Env.adsr(0, 0.4, 0.8, 1), gate, doneAction: 2);
// Rate scales playback relative to a known base frequency of the buffer
rate = freq / baseFreq;
// Random panning for each grain
pan = LFNoise1.kr(8);
sig = GrainBuf.ar(
1,
trig,
0.8,
~klezmer,
rate, // Control pitch via rate
1.25,
2,
0,
-1,
512
) * amp * env;
sig = Pan2.ar(sig, pan);
Out.ar(0, sig);
}).play;
)
(
// MIDI sequencing by MIDI file
var m1, m2, x1, x2;
// Read each MIDI file separately
m1 = SimpleMIDIFile.read("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-borrowed flesh/midi/fuzzy gameboy.mid");
m2 = SimpleMIDIFile.read("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-borrowed flesh/midi/pad organ.mid");
// Play both MIDI sequences simultaneously
x1 = m1.p(\granular).play;
x2 = m2.p(\granular).play;
// Store them in a global variable so you can stop them later
~midiPlayers = [x1, x2];
)

@ -0,0 +1,34 @@
(
SynthDef(\junoPad, {
arg gate=1, freq=220, atk=4, sus=2, rel=6, amp=0.3;
var sig, env, freqs, lfo, chorus, modRate, modDepth;
// Slightly detuned saw waves
freqs = freq * [1, 1.01, 0.99]; // Small detune
sig = Mix(Saw.ar(freqs)); // Stack saw waves
// LFO to slowly move filter cutoff
lfo = SinOsc.kr(0.1).range(500, 2000);
sig = RLPF.ar(sig, lfo, 0.3); // Low-pass filter with modulation
.
// Envelope for smooth rise
env = EnvGen.kr(Env.asr(atk, 1, rel), gate, doneAction:2);
sig = sig * env * amp;
// Chorus effect (emulates Juno-chorus)
modRate = [0.3, 0.4]; // Two different modulation rates
modDepth = 0.01; // Small pitch variation
chorus = sig + DelayC.ar(sig, 0.02, SinOsc.kr(modRate).range(0, modDepth));
// Reverb for space
// sig = FreeVerb.ar(chorus, mix: 0.5, room: 0.8, damp: 0.5);
sig = sig * chorus;
Out.ar(0, sig);
}).play;
)

@ -0,0 +1,77 @@
(
SynthDef(\add_do, {
arg freq = 440, amp = 0.5, out = 0;
var sig = 0, freqs = Array.series(15, 1, 2);
freqs.do({ |f, i|
var pulse;
pulse = Pulse.ar(
freq * f * ExpRand(0.91, 0.90),
mul: i.linexp(0, freqs.size - 1, 1, 0.0001)
);
pulse = Pan2.ar(pulse, Rand(-0.9, 0.9));
sig = sig + pulse;
});
sig = sig * Env([0, 1, 0], [5, 5], [1, -2]).kr(2);
sig = sig.blend(GVerb.ar(sig.sum, 100, 4), 0.15);
sig = LPF.ar(sig, (freq.midicps * XLine.kr(2, 10, 16)).clip(20, 20000));
sig = Splay.ar(sig.scramble, 0.5);
sig = sig * 0.1 * amp;
Out.ar(out, sig);
}).add;
)
// We can use iteration to create multiple Synths. Because of the randomness (ExpRand) applied to the frequencies of the sine waves, we'll hear beating patterns.
23.do({ Synth(\add_do, [freq: 40.midicps]) });
(
[38, 50, 57, 59, 66].do({ |note, index|
3.do({
Synth(
\add_do, [
freq: note.midicps,
amp: index.linexp(0, 4, 0.6, 0.2),
]
)
});
});
)
(
SynthDef(\add_do, {
arg freq = 440, amp = 0.1, out = 0;
var sig = 0, freqs = Array.series(15, 1, 2);
freqs.do({ |f, i|
var osc;
osc = PulseDPW.ar(
freq * f * ExpRand(0.99, 1.01),
mul: i.linexp(0, freqs.size - 1, 1, 0.0001)
);
osc = Pan2.ar(osc, Rand(-0.9, 0.9));
sig = sig + osc;
});
sig = sig * Env([0, 1, 0], [5, 5], [1, -2]).kr(2);
sig = sig * amp;
Out.ar(out, sig);
}).play;
)
(
SynthDef(\add_do, {
arg freq = 440, amp = 0.1, out = 0;
var sig = 0, freqs = Array.series(15, 1, 2);
sig = Pulse.ar(freq)!2;
sig = sig * amp;
Out.ar(out,sig);
}).play;
)
3.do({ Synth(\add_do, [freq: 64.midicps]) });

@ -0,0 +1,113 @@
// TODO: connect MIDI CC knobs to an array of defined pos, also connect amp, possibly rate though probably not
(
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Cantor_Samuel_Malavsky_Zechor.wav");
(
SynthDef(\cantorial_tremolo, { |out, pan = 0, dur = 0.1, atk=0.3, dec=0.4, sus=0.1, rel=0, amp=1, crf=1100|
var sig, rate, env, filter;
env = EnvGen.ar(
Env.new(
[0, 1, 1, 0],
[atk, dec, sus, rel],
),
gate: 1,
doneAction: 2
);
sig = GrainBuf.ar(
numChannels: 2,
trigger: Impulse.kr(10),
dur: dur,
sndbuf: b,
rate: 1,
pos: 0.1,
interp: 2,
pan: pan,
envbufnum: -1,
maxGrains: 512
);
sig = sig * env * amp;
filter = MoogVCF.ar(sig, crf, 0.3);
Out.ar(out, filter);
}).play;
)
)
(
// Becoming satisfactory granular synth
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Cantor_Samuel_Malavsky_Zechor.wav");
(
SynthDef(\cantorial_trill, { |out, pan = 0, dur = 0.5, atk=0.3, dec=0.4, sus=0.1, rel=0, amp=1, crf=1000, grainRate=5|
var sig, rate, env, filt;
env = EnvGen.ar(
Env.new(
[0, 1, 1, 0],
[atk, dec, sus, rel],
),
gate: 1,
doneAction: 2
);
rate = (note.midicps / 60.midicps);
sig = GrainBuf.ar(
numChannels: 2,
trigger: Impulse.kr(grainRate),
dur: dur,
sndbuf: b,
rate: rate,
pos: 0.01,
interp: 2,
pan: pan,
envbufnum: -1,
maxGrains: 512
);
sig = sig * env * amp;
sig = LPF.ar(sig, crf);
Out.ar(out, sig);
}).play;
)
)
(
// IMPORTANT!
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Acheinu_Kol_Beit_Israel.wav");
(
SynthDef(\cantorial_reed ,
{
arg amp = 0.3, pan = 0;
var sig;
sig = GrainBuf.ar(
numChannels: 2,
trigger: Dust.ar(40),
dur: 0.8,
sndbuf: b,
rate: 1,
pos: 1.25, // 1.25, 1.20
interp: 2,
pan: pan,
envbufnum: -1,
maxGrains: 512
);
sig = sig * amp;
Out.ar(0, sig);
}).play;
)
)

@ -0,0 +1,19 @@
(
{
var sig, nn = 39.6, seq;
seq = Demand.kr(
trig: Impulse.kr(0.21) + Impulse.kr(0.105, 5/8),
reset: 0,
// demandUGens: Dseq([[0, 12, 16, 19], [2, 14, 18, 21], [-3, 13, 16, 21]], inf);
demandUGens: Dseq([[0, 12, 16, 21], [2, 20], [-4, 12, 24], [30, 40], [23, 38]], inf);
);
nn = nn * LFDNoise3.kr(LFNoise0.kr(8).exprange(1, 4)).bipolar(0.06).midiratio;
sig = Saw.ar((seq + nn).midicps);
sig = LPF.ar(sig, (nn.midicps * XLine.kr(2, 10, 16)).clip(20, 20000));
sig = BLowShelf.ar(sig, 300, 0.5, 9);
sig = Splay.ar(sig.scramble, 0.5);
sig = sig * LFDNoise0.kr(LFNoise2.kr(8).exprange(1, 30)).exprange(0.6, 1).lag(0.1);
sig = sig.blend(GVerb.ar(sig.sum, 299, 4), 0.15);
sig = sig * 0.15;
}.play;
)

@ -0,0 +1,160 @@
MIDIClient.init;
MIDIIn.connectAll;
MIDIdef.noteOn(\noteOnTest, {"key down".postln});
// Print MIDI debug info
(
MIDIdef.noteOn(\noteOnTest, {
arg nn, chan, src;
[nn, chan, src].postln;
});
MIDIdef.cc(\ccTest, {
arg val, num, chan, src;
["CC:", num, "Value:", val, "Channel:", chan, "Source:", src].postln;
});
)
// Load samples
(
~sampleDir = PathName("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-borrowed flesh/seq/808").fullPath;
~samples = Dictionary.newFrom(
(
42: "ch.wav", 46: "oh.wav", 49: "cy.wav",
56: "cb.wav", 39: "cp.wav", 37: "rs.wav",
50: "ht.wav", 47: "mt.wav", 43: "lt.wav",
38: "sd.wav", 36: "bd.wav", 70: "ma.wav",
75: "cl.wav", 62: "hc.wav", 63: "mc.wav",
64: "lc.wav"
).collect { |file, key|
key -> Buffer.read(s, ~sampleDir +/+ file)
}
);
)
~samples.class
~samples[39].class
~samples[39].
(
~sampleDir = PathName("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-borrowed flesh/seq/808");
~sample = ();
~sampleDir.entries.do({ |pn|
var sym;
sym = pn.fileNameWithoutExtension.asSymbol;
~sample[sym] = Buffer.read(s, pn.fullPath);
});
)
(
// Define the Synth for sample triggering (if not defined already)
SynthDef(\sampleTrigger, { |buf, ampin = 0|
var sound, amp;
amp = In.kr(ampin, 1);
sound = PlayBuf.ar(1, buf, BufRateScale.ir(buf), doneAction: 2); // doneAction: 2 will free the synth when it's done
sound = sound * amp;
Out.ar(0, sound); // Send to audio output
}).add;
)
/*
75: "cl.wav", 62: "hc.wav", 63: "mc.wav",
64: "lc.wav"*/
(
s.newBusAllocators;
~bdampbus = Bus.control(s, 1);
// ~bdampbus.value = 0.8;
~sdampbus = Bus.control(s, 1);
~ltampbus = Bus.control(s, 1);
~mtampbus = Bus.control(s, 1);
~htampbus = Bus.control(s, 1);
~rsampbus = Bus.control(s, 1);
~cpampbus = Bus.control(s, 1);
~champbus = Bus.control(s, 1);
~ohampbus = Bus.control(s, 1);
~cyampbus = Bus.control(s, 1);
~cbampbus = Bus.control(s, 1);
MIDIIn.connectAll;
MIDIdef.noteOn('808trig', { |vel, nn|
// nn.postln;
switch(nn)
{36} {
Synth(\sampleTrigger, [buf: ~sample.bd, ampin: ~bdampbus]);
}
{37} {
Synth(\sampleTrigger, [buf: ~sample.rs, ampin: ~rsampbus]);
}
{38} {
Synth(\sampleTrigger, [buf: ~sample.sd, ampin: ~sdampbus]);
}
{39} {
Synth(\sampleTrigger, [buf: ~sample.cp, ampin: ~cpampbus]);
}
{42} {
Synth(\sampleTrigger, [buf: ~sample.ch, ampin: ~champbus]);
}
{43} {
Synth(\sampleTrigger, [buf: ~sample.lt, ampin: ~ltampbus]);
}
{46} {
Synth(\sampleTrigger, [buf: ~sample.oh, ampin: ~ohampbus]);
}
{47} {
Synth(\sampleTrigger, [buf: ~sample.mt, ampin: ~mtampbus]);
}
{49} {
Synth(\sampleTrigger, [buf: ~sample.cy, ampin: ~cyampbus]);
}
{50} {
Synth(\sampleTrigger, [buf: ~sample.ht, ampin: ~htampbus]);
}
{56} {
Synth(\sampleTrigger, [buf: ~sample.cb, ampin: ~cbampbus]);
}
{62} {
Synth(\sampleTrigger, [buf: ~sample.hc, ampin: ~hcampbus]);
}
{63} {
Synth(\sampleTrigger, [buf: ~sample.mc, ampin: ~mcampbus]);
}
{64} {
Synth(\sampleTrigger, [buf: ~sample.lc, ampin: ~lcampbus]);
}
{70} {
Synth(\sampleTrigger, [buf: ~sample.ma, ampin: ~maampbus]);
}
{75} {
Synth(\sampleTrigger, [buf: ~sample.cl, ampin: ~clampbus]);
}
}, noteNum: [36, 38, 39, 42, 46, 49], chan: [9]);
MIDIdef.cc('808amp', { |val, num|
switch(num)
{24} {~bdampbus.value = val / 127}
{29} {~sdampbus.value = val / 127}
{48} {~ltampbus.value = val / 127}
{51} {~mtampbus.value = val / 127}
{54} {~htampbus.value = val / 127}
{57} {~rsampbus.value = val / 127}
{60} {~cpampbus.value = val / 127}
{63} {~champbus.value = val / 127}
{82} {~ohampbus.value = val / 127}
{85} {~cyampbus.value = val / 127}
{88} {~cbampbus.value = val / 127};
}, ccNum: [24, 29, 48, 51, 54, 57, 60, 63, 82, 85, 88], chan: [9]);
)
MIDIFunc.trace(false)

@ -0,0 +1,77 @@
(
SynthDef(\rhubarb, {
|freq = 440, gate = 1, cutoff = 600, rq = 0.3, amp = 4, modDepth = 0.3, modDepth2 = 0.5, noiseLevel = 0.8, ringFreq = 400|
var env, sig1, sig2, sig3, filt1, filt2, filt3, lfo, lfo2, pan1, pan2, pan3, mix, saturatedSig;
// Using GrainBuf for granular synthesis
var grainBuf1, grainBuf2, grainBuf3;
// Grains for the three channels, modulating playback speed for pitch control
grainBuf1 = GrainBuf.ar(
2,
Impulse.ar(10), // Control grain density
0.1, // Grain duration
~klezmer, // Sound source buffer
2, // Pitch shift factor
1.19, // Frequency modulation
2, // Grain density variation
0, // Start position (set dynamically for random play)
-1, // Reverse playback (for added texture)
512 // Buffer size
);
grainBuf2 = GrainBuf.ar(
2,
Dust.ar(10),
0.08,
~klezmer,
-2, // Different pitch for variety
1.25,
2,
0,
-1,
512
);
grainBuf3 = GrainBuf.ar(
2,
Dust.ar(10),
0.8,
~klezmer,
2, // Higher pitch for more brightness
1.25,
2,
0,
-1,
512
);
// LFO to modulate filter frequency (similar to previous LFO setup)
lfo = LFNoise0.kr(10).range(1 - modDepth, 1 + modDepth);
lfo2 = LFNoise2.kr(4).range(1 - modDepth, 1 + modDepth);
// Apply Different Filters to Each GrainBuf Signal
filt1 = SVF.ar(grainBuf1, cutoff * lfo, rq);
filt2 = LPF.ar(grainBuf2, 400 * lfo, rq);
filt3 = HPF.ar(grainBuf3, cutoff * lfo2, rq);
// ADSR Envelope for modulation
env = EnvGen.kr(Env.adsr(0.0, 0.3, 0.3, 0.1), gate, doneAction: 2);
// Panning each signal for stereo effect
pan1 = Pan2.ar(filt1 * env * amp, -0.3); // Slightly left
pan2 = Pan2.ar(filt2 * env * amp, 0.3); // Slightly right
pan3 = Pan2.ar(filt3 * env * amp, 0); // Centered
// Mixing the signals together
mix = pan1 + pan2 + pan3; // Add all three signals
saturatedSig = mix.tanh;
// Output the final mixed signal
Out.ar(0, saturatedSig);
}).play;
)

@ -0,0 +1,95 @@
s.boot;
MIDIClient.init;
MIDIIn.connectAll;
MIDIClient.sources.do;
(
SynthDef(\rhubarb, {
|freq = 440, gate = 1, cutoff = 1e4, rq = 0.3, amp = 0.05, modDepth = 0.3, modDepth2 = 0.5, noiseLevel = 0.8, ringFreq = 80|
var env, osc1, osc2, osc3, filt1, filt2, filt3, lfo, lfo2, noise, noiseFilt, sig1, sig2, sig3, mix;
// Slightly Different Oscillators
osc1 = SinOsc.ar(freq);
osc2 = SinOsc.ar(freq * 0.5); // Slight detune for variation
osc3 = SawDPW.ar(freq * 2);
// LFO to Modulate Filter Frequency
lfo = LFNoise0.kr(4).range(1 - modDepth, 1 + modDepth);
lfo2 = LFNoise2.kr(4).range(1 - modDepth, 1 + modDepth);
// lfo2 = noise;
// Apply Different Filters to Each Oscillator
filt1 = SVF.ar(osc1, cutoff * lfo, rq);
filt2 = LPF.ar(osc2, cutoff * lfo, rq);
filt3 = BPF.ar(osc3, cutoff * lfo2, rq);
// ADSR Envelope
env = EnvGen.kr(Env.adsr(0.0, 0.3, 0.3, 0.1), gate, doneAction: 2);
// Panning and Mixing
sig1 = Pan2.ar(filt1 * env * amp, -0.3);
sig2 = Pan2.ar(filt2 * env * amp, 0.3);
sig3 = Pan2.ar(filt3 * env * amp, 0);
mix = sig1 + sig2; // Mix main signals
// mix = mix + (noise * env * noiseLevel); // Add noise with envelope control
// mix = DelayC.ar(mix, maxdelaytime: 0.2, delaytime: 0.3);
// Output
Out.ar(0, mix);
}).add;
)
Synth(\rhubarb)
(
// Test pattern
Pbind(
\instrument, \rhubarb,
/*\degree, Pseq([
[2, 4, 7, 12], [1, 5, 9], [4, 7, 11], [5, 9, 8]
], inf), // Chord progression*/
\degree, Pseq([[2, 7, 11], [1, 5, 9], [3, 9], [1,3,5]], inf),
// \degree, Pseq([2, 4, 11,], inf),
// \dur, 0.5, // Duration of each chord
\amp, 0.08, // Volume
// \cutoff, 1200,
\detune, 0, // Slight detune
\pan, Pwhite(-0.3, 0.3), // Random stereo width
).play;
)
(
// MIDI
// EMF: one major issue here is that ~notes is never actually initialized as an array, so it's nil. when you try to store a Synth at index nn, SC throws an error, because you can't put an item into nil. So, we first initialize ~notes as an array of size 128. After I add this line, your polyphonic MIDI code seems to work fine (no stuck notes)
~notes = Array.newClear(128);
MIDIdef.noteOn(\noteOnTest, {
arg vel, nn, chan, src;
[vel, nn].postln;
~notes[nn] = Synth.new(
\rhubarb,
[
\freq, nn.midicps,
\amp, vel.linexp(1,127,0.01,0.3),
\gate, 1,
]
);
});
MIDIdef.noteOff(\noteOffTest, {
arg vel, nn;
[vel, nn].postln;
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
});
)

@ -1,87 +1,7 @@
(
SynthDef(\junoPad, {
arg gate=1, freq=220, atk=4, sus=2, rel=6, amp=0.3;
var sig, env, freqs, lfo, chorus, modRate, modDepth;
// Slightly detuned saw waves
freqs = freq * [1, 1.01, 0.99]; // Small detune
sig = Mix(Saw.ar(freqs)); // Stack saw waves
// LFO to slowly move filter cutoff
lfo = SinOsc.kr(0.1).range(500, 2000);
sig = RLPF.ar(sig, lfo, 0.3); // Low-pass filter with modulation
// Envelope for smooth rise
env = EnvGen.kr(Env.asr(atk, 1, rel), gate, doneAction:2);
sig = sig * env * amp;
// Chorus effect (emulates Juno-chorus)
modRate = [0.3, 0.4]; // Two different modulation rates
modDepth = 0.01; // Small pitch variation
chorus = sig + DelayC.ar(sig, 0.02, SinOsc.kr(modRate).range(0, modDepth));
// Reverb for space
// sig = FreeVerb.ar(chorus, mix: 0.5, room: 0.8, damp: 0.5);
sig = sig * chorus;
Out.ar(0, sig);
}).play;
)
(
x = {
var sig = WhiteNoise.ar(1!2);
sig = CombL.ar(sig, 0.05, 1/[36.7, 37.3], 1, 0.2);
sig = sig.blend(BPF.ar(sig, 1500, 0.5), 0.9);
}.play(fadeTime: 2);
)
x.release;
MIDIClient.init; MIDIClient.init;
MIDIIn.connectAll;
MIDIClient.sources.do; MIDIClient.sources.do;
(
SynthDef(\rhubarb, {
|freq = 440, gate = 1, cutoff = 1000, rq = 0.3, amp = 0.05, modDepth = 1, noiseLevel = 0.05|
var env, osc, filt, lfo, noise, sig;
// Single Sawtooth Oscillator
osc = SinOsc.ar(freq);
osc2 = SinOsc.ar(freq);
// Subtle Noise Layer
// noise = PinkNoise.ar(noiseLevel);
// LFO to Modulate Filter
lfo = LFNoise0.kr(4).range(1 - modDepth, 1 + modDepth); // Triangle LFO at 2.94 Hz
// Low-pass filter modulated by LFO
filt = SVF.ar(osc, cutoff * lfo, rq);u
filt2 = BMoog.ar(osc, freq * lfo, rq);
// ADSR Envelope with Long Attack & Release
env = EnvGen.kr(Env.adsr(0.0, 0.3, 0.8, 2.0), gate, doneAction: 2);
sig = Pan2.ar(filt * env * amp, 0);
sig2 = Pan2.ar(filt * env * amp, 0);
// Output
Out.ar(0, sig);
}).add;
)
( (
SynthDef(\rhubarb, { SynthDef(\rhubarb, {
|freq = 440, gate = 1, cutoff = 1e4, rq = 0.3, amp = 0.05, modDepth = 0.3, modDepth2 = 0.5, noiseLevel = 0.8, ringFreq = 80| |freq = 440, gate = 1, cutoff = 1e4, rq = 0.3, amp = 0.05, modDepth = 0.3, modDepth2 = 0.5, noiseLevel = 0.8, ringFreq = 80|
@ -119,28 +39,19 @@ SynthDef(\rhubarb, {
// Output // Output
Out.ar(0, mix); Out.ar(0, mix);
}).add; }).add;
~synths = Dictionary.new; // Store active notes
MIDIFunc.noteOn({ |vel, num, chan, src|
var freq = num.midicps; // Convert MIDI note to Hz
var amp = vel.linexp(1, 127, 0.05, 0.5); // Velocity mapping
~synths[num] = Synth(\rhubarb, [\freq, freq, \amp, amp]); // Store synth instance
});
) )
( (
// Test pattern
Pbind( Pbind(
\instrument, \rhubarb, \instrument, \rhubarb,
/*\degree, Pseq([ /*\degree, Pseq([
[2, 4, 7, 12], [1, 5, 9], [4, 7, 11], [5, 9, 8] [2, 4, 7, 12], [1, 5, 9], [4, 7, 11], [5, 9, 8]
], inf), // Chord progression*/ ], inf), // Chord progression*/
// \degree, Pseq([[2, 7, 11], [1, 5, 9], [3, 9], [1,3,5]], inf), \degree, Pseq([[2, 7, 11], [1, 5, 9], [3, 9], [1,3,5]], inf),
\degree, Pseq([2, 4, 11,], inf), // \degree, Pseq([2, 4, 11,], inf),
// \dur, 0.5, // Duration of each chord // \dur, 0.5, // Duration of each chord
\amp, 0.08, // Volume \amp, 0.08, // Volume
// \cutoff, 1200, // \cutoff, 1200,
@ -151,13 +62,28 @@ Pbind(
( (
SynthDef(\pad, {
var sig;
sig = Mix( ~notes = Array.newClear(128);
// MIDI
MIDIdef.noteOn(\noteOnTest, {
arg vel, nn, chan, src;
[vel, nn].postln;
~notes[nn] = Synth.new(
\rhubarb,
[
\freq, nn.midicps,
\amp, vel.linexp(1,127,0.01,0.3),
\gate, 1,
]
);
});
Out.ar(0, sig); MIDIdef.noteOff(\noteOffTest, {
}).play; arg vel, nn;
[vel, nn].postln;
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
});
) )

@ -0,0 +1,7 @@
(
SynthDef( "organ", { |freq = 440, sustain = 1, amp = 0.03|
var sig;
sig = LFPar.ar( freq * [1,2,3,5], 0, amp/[2,4,5,7] );
Out.ar( 0, Env([0,1,1,0], [0.025,sustain,0.025]).kr(2) * sig.dup )
}).add;
);

@ -0,0 +1,26 @@
// src: https://tranceaddict.com/forums/showthread.php?threadid=361228
(
// select everything between the two parentheses
{
CombN.ar(
SinOsc.ar(
LFNoise1.kr(
1, // LFO
24, // range in MIDI
LFSaw.kr(
[8,7.23],//second LFO
0,
3, // range in MIDI
80 // offset in MIDI
)
).midicps,
0,
0.04
),
0.2, // max delay
0.2, // actual delay
4 // decay
)
}.play
)

@ -0,0 +1,95 @@
MIDIClient.init;
MIDIIn.connectAll;
MIDIdef.noteOn(\noteOnTest, {"key down".postln});
// Print MIDI debug info
(
MIDIdef.noteOn(\noteOnTest, {
arg nn, chan, src;
[nn, chan, src].postln;
});
MIDIdef.cc(\ccTest, {
arg val, num, chan, src;
["CC:", num, "Value:", val, "Channel:", chan, "Source:", src].postln;
});
)
// Load samples
(
~sampleDir = PathName("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-borrowed flesh/seq/808/").fullPath;
~samples = Dictionary.newFrom(
(
42: "ch.wav", 46: "oh.wav", 49: "cy.wav",
56: "cb.wav", 39: "cp.wav", 37: "rs.wav",
50: "ht.wav", 47: "mt.wav", 43: "lt.wav",
38: "sd.wav", 36: "bd.wav", 70: "ma.wav",
75: "cl.wav", 62: "hc.wav", 63: "mc.wav",
64: "lc.wav"
).collect { |file, key|
key -> Buffer.read(s, ~sampleDir +/+ file)
}
);
)
// Testing ~samples
(
// For some reason, nn and vel are swapped on the tr-08 MIDIIn
// if vel isn't in the enclosure, then nn doesn't work
// still figuring out how to do polyphony
// set it to if == 9 when everything else is working
MIDIdef.noteOn(\noteOnTest, {|vel, nn|
[nn].postln;
Synth(\sampleTrigger, [\buf, ~samples[nn]]);
});
)
(
// Define the Synth for sample triggering (if not defined already)
SynthDef(\sampleTrigger, { |buf|
var sound;
sound = PlayBuf.ar(1, buf, doneAction: 2); // doneAction: 2 will free the synth when it's done
Out.ar(0, sound); // Send to audio output
}).add;
)
// Manually trigger a sample for note number 42
(
var noteNumber = 39; // The MIDI note number to play
if (~samples.includesKey(noteNumber), {
("Triggering sample for note: " + noteNumber).postln;
Synth(\sampleTrigger, [\buf, ~samples[noteNumber]]);
}, {
("No sample found for note: " + noteNumber).postln;
});
)
MIDIFunc.trace;
Loading…
Cancel
Save