Merge remote-tracking branch 'refs/remotes/origin/master'
commit
505fa4d4bb
@ -0,0 +1,40 @@
|
||||
// Define the bass synth
|
||||
(
|
||||
SynthDef(\boC_bass, {
|
||||
arg freq = 440, detune = 1.001, amp = 0.4, cutoff = 1000, attack = 0.5, decay = 1;
|
||||
|
||||
var osc1, osc2, mix, filter, env;
|
||||
|
||||
// Two sawtooth oscillators detuned slightly
|
||||
osc1 = Pulse.ar(freq, amp); // First oscillator, base frequency
|
||||
osc2 = Pulse.ar(freq * detune, amp); // Second oscillator, slightly detuned
|
||||
|
||||
// Mix both oscillators
|
||||
mix = osc1 + osc2;
|
||||
|
||||
// Apply a low-pass filter to smooth the high frequencies
|
||||
filter = LPF.ar(mix, cutoff); // Low-pass filter with customizable cutoff
|
||||
|
||||
// Envelope for shaping the sound
|
||||
env = EnvGen.kr(Env.perc(attack, decay), doneAction: 2); // Short attack and decay
|
||||
|
||||
// Apply envelope to the filter and mix the result
|
||||
filter = filter * env;
|
||||
|
||||
// Output the final sound to both left and right channels
|
||||
Out.ar(0, filter.dup);
|
||||
}).add;
|
||||
)
|
||||
|
||||
// Play the synth with default values
|
||||
x = Synth(\boC_bass, [\freq, 30.midicps]);
|
||||
|
||||
// You can also play the synth with custom arguments
|
||||
x = Synth(\boC_bass, [
|
||||
\freq, 220, // Set frequency
|
||||
\detune, 1.005, // Slightly different detune
|
||||
\amp, 0.5, // Amp (volume)
|
||||
\cutoff, 400, // Filter cutoff frequency
|
||||
\attack, 0.05, // Attack time
|
||||
\decay, 0.3 // Decay time
|
||||
]);
|
||||
@ -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,13 @@
|
||||
DRC
|
||||
|
||||
1 OSC Square Wave dropped one octave
|
||||
2 OSC same volume, same octave, square wave, fine detuning (right),
|
||||
|
||||
1 EG slowish attack, normal ds, raise release a little bit
|
||||
2 EG increase modulation a little bit
|
||||
2 EG raise attack to half, bring decay to maximum, sustain to half, raise release a little bit
|
||||
|
||||
chorus: low rate, norma depth, no feedback
|
||||
lpf: 800, subtle resonance
|
||||
|
||||
reverb: loads of decay and a nice amount
|
||||
@ -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,92 @@
|
||||
(
|
||||
SynthDef(\boc_pad, {
|
||||
arg freq = 210, amp = 0.1, att = 2, dec = 3, sus = 0.1, rel = 0, detune = -8,
|
||||
lpfFreq = 800, rq = 0.3, revMix = 0.5, revSize = 20, revDamping = 0.5,
|
||||
tremRate = 10, tremDepth = 0.8; // Tremolo parameters
|
||||
|
||||
var osc1, osc2, env, sig, filt, chorus, reverb, tremolo;
|
||||
|
||||
osc1 = SinOsc.ar(freq, 0.5);
|
||||
osc2 = Saw.ar(freq * (1 + detune), 0.5);
|
||||
sig = Mix([osc1, osc2]) * 0.5;
|
||||
env = EnvGen.kr(Env.adsr(att, dec, sus, rel), doneAction: 2);
|
||||
filt = RLPF.ar(sig, lpfFreq, rq);
|
||||
chorus = CombL.ar(filt, 0.01, LFDNoise3.kr(2).range(0.005, 0.01), 0.3);
|
||||
|
||||
// Reverb
|
||||
reverb = GVerb.ar(chorus, revSize, revDamping, mul: revMix);
|
||||
|
||||
// Tremolo (amplitude modulation)
|
||||
tremolo = SinOsc.kr(tremRate).range(1 - tremDepth, 1);
|
||||
|
||||
Out.ar(0, reverb * tremolo * env * amp);
|
||||
}).add;
|
||||
)
|
||||
|
||||
(
|
||||
Pbind(
|
||||
\instrument, \boc_pad,
|
||||
\freq, Pseq([
|
||||
[60, 64, 67].midicps, // C major
|
||||
[62, 65, 69].midicps, // D minor
|
||||
[57, 60, 64].midicps, // A minor
|
||||
[55, 59, 62].midicps // G major
|
||||
], inf), // Infinite loop
|
||||
\dur, 1, // Each chord lasts 2 beats
|
||||
\amp, 0.1
|
||||
).play;
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(
|
||||
Pbind(
|
||||
\instrument, \boc_pad,
|
||||
\freq, Pseq([
|
||||
[40, 50, 59].midicps,
|
||||
[62, 65, 67].midicps,
|
||||
[50, 58, 64].midicps
|
||||
], inf), // Infinite loop
|
||||
\dur, 2, // Each chord lasts 2 beats
|
||||
\amp, 0.008
|
||||
).play;
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(
|
||||
SynthDef(\boc_pad, {
|
||||
arg freq = 210, amp = 0.1, att = 0.3, dec = 0.3, sus = 0.1, rel = 0, detune = 0.1,
|
||||
lpfFreq = 2000, rq = 2, revMix = 0.5, revSize = 20, revDamping = 0.5,
|
||||
tremRate = 3, tremDepth = 0.1; // Tremolo parameters
|
||||
|
||||
var osc1, osc2, env, sig, filt, chorus, tremolo, panLeft, panRight;
|
||||
|
||||
// Generate two oscillators
|
||||
osc1 = Pulse.ar(freq, 0.5);
|
||||
osc2 = Pulse.ar(freq * (1 + detune), 0.5);
|
||||
sig = Mix([osc1, osc2]) * 0.5;
|
||||
env = EnvGen.kr(Env.adsr(att, dec, sus, rel), doneAction: 2);
|
||||
|
||||
// Lowpass filter
|
||||
filt = LPF.ar(sig, lpfFreq, rq);
|
||||
|
||||
// Apply a chorus to create stereo width
|
||||
chorus = CombL.ar(filt, 0.01, LFDNoise3.kr(1).range(0.008, 0.1), 0.3);
|
||||
|
||||
// Apply tremolo for amplitude modulation
|
||||
tremolo = SinOsc.kr(tremRate).range(1 - tremDepth, 1);
|
||||
|
||||
// Split the signal into two channels and pan them
|
||||
panLeft = chorus * tremolo * env * amp * 0.5; // Left channel
|
||||
panRight = chorus * tremolo * env * amp * 0.5; // Right channel
|
||||
|
||||
// Slightly pan the signals to create a stereo image
|
||||
Out.ar(0, [panLeft, panRight]); // Send to both left and right channels
|
||||
}).add;
|
||||
)
|
||||
@ -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,222 @@
|
||||
// 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
|
||||
);
|
||||
|
||||
filter = MoogVCF.ar(sig, crf, 0.3);
|
||||
|
||||
sig = sig * env * amp * filter;
|
||||
|
||||
Out.ar(out, sig);
|
||||
}).add;
|
||||
)
|
||||
)
|
||||
|
||||
(
|
||||
Ppar([
|
||||
Pbind(
|
||||
\instrument, \cantorial_trill,
|
||||
\dur, 0.1, // Adjust as needed
|
||||
\amp, 0.5, // Amplitude (adjust as needed)
|
||||
\pan, 0, // Pan position
|
||||
),
|
||||
Pbind(
|
||||
\instrument, \cantorial_tremolo,
|
||||
\dur, 0.1, // Adjust as needed
|
||||
\amp, 1, // Amplitude (adjust as needed)
|
||||
\pan, 0, // Pan position for the second synth (can be changed)
|
||||
)
|
||||
]).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
|
||||
);
|
||||
|
||||
sig = GrainBuf.ar(
|
||||
numChannels: 2,
|
||||
trigger: Impulse.kr(grainRate),
|
||||
dur: dur,
|
||||
sndbuf: b,
|
||||
rate: 1,
|
||||
pos: 0.02,
|
||||
interp: 2,
|
||||
pan: pan,
|
||||
envbufnum: -1,
|
||||
maxGrains: 512
|
||||
);
|
||||
|
||||
sig = sig * env * amp;
|
||||
|
||||
sig = LPF.ar(sig, crf);
|
||||
|
||||
Out.ar(out, sig);
|
||||
}).add;
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(
|
||||
// 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, pos = 0;
|
||||
var sig;
|
||||
sig = GrainBuf.ar(
|
||||
numChannels: 2,
|
||||
trigger: Dust.ar(40),
|
||||
dur: 0.8,
|
||||
sndbuf: b,
|
||||
rate: 1,
|
||||
pos: 0.25, //.20
|
||||
interp: 2,
|
||||
pan: pan,
|
||||
envbufnum: -1,
|
||||
maxGrains: 512
|
||||
);
|
||||
|
||||
sig = sig * amp;
|
||||
Out.ar(0, sig);
|
||||
}).play;
|
||||
)
|
||||
)
|
||||
|
||||
Synth(\cantorial_reed);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Acheinu_Kol_Beit_Israel.wav");
|
||||
c = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Cantor_Samuel_Malavsky_Zechor.wav");
|
||||
|
||||
SynthDef(\cantorial_reed,
|
||||
{
|
||||
arg amp = 0.3, pan = 0, pos = 0, bufSwitch = 0;
|
||||
var sig, buf;
|
||||
|
||||
// Choose buffer based on bufSwitch (0 or 1)
|
||||
buf = Select.kr(bufSwitch, [b, c]);
|
||||
|
||||
sig = GrainBuf.ar(
|
||||
numChannels: 2,
|
||||
trigger: Dust.ar(40),
|
||||
dur: 0.8,
|
||||
sndbuf: buf, // Dynamically selected buffer
|
||||
rate: 1,
|
||||
pos: 0.25,
|
||||
interp: 2,
|
||||
pan: pan,
|
||||
envbufnum: -1,
|
||||
maxGrains: 512
|
||||
);
|
||||
|
||||
sig = sig * amp;
|
||||
Out.ar(0, sig);
|
||||
}).add;
|
||||
|
||||
|
||||
// Example: Play the synth and switch between buffers
|
||||
x = Synth(\cantorial_reed, [\bufSwitch, 0]); // Starts with b1
|
||||
x.set(\bufSwitch, 1); // Switches to b2
|
||||
|
||||
|
||||
|
||||
(
|
||||
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Acheinu_Kol_Beit_Israel.wav");
|
||||
c = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Cantor_Samuel_Malavsky_Zechor.wav");
|
||||
|
||||
SynthDef(\cantorial_reed,
|
||||
{
|
||||
arg amp = 0.3, pan = 0, pos = 0, xfade = 0; // 'xfade' controls blending (0 = only b, 1 = only c)
|
||||
var sig1, sig2, sig;
|
||||
|
||||
sig1 = GrainBuf.ar(
|
||||
numChannels: 2,
|
||||
trigger: Dust.ar(40),
|
||||
dur: 0.8,
|
||||
sndbuf: b,
|
||||
rate: 1,
|
||||
pos: 0.25,
|
||||
interp: 2,
|
||||
pan: pan,
|
||||
envbufnum: -1,
|
||||
maxGrains: 512
|
||||
);
|
||||
|
||||
sig2 = GrainBuf.ar(
|
||||
numChannels: 2,
|
||||
trigger: Dust.ar(40),
|
||||
dur: 0.8,
|
||||
sndbuf: c,
|
||||
rate: 1,
|
||||
pos: 0.25,
|
||||
interp: 2,
|
||||
pan: pan,
|
||||
envbufnum: -1,
|
||||
maxGrains: 512
|
||||
);
|
||||
|
||||
// Crossfade between the two signals
|
||||
sig = XFade2.ar(sig1, sig2, (xfade * 2) - 1); // -1 = sig1, 1 = sig2
|
||||
|
||||
sig = sig * amp;
|
||||
Out.ar(0, sig);
|
||||
}).add;
|
||||
)
|
||||
|
||||
// Play and smoothly fade between buffers
|
||||
x = Synth(\cantorial_reed, [\xfade, 0]); // Start with buffer b
|
||||
x.set(\xfade, 0.5); // Midpoint mix
|
||||
x.set(\xfade, 0); // Fully buffer c
|
||||
x.free;
|
||||
|
||||
@ -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,158 @@
|
||||
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
|
||||
|
||||
(
|
||||
~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); // adding .value(0.5) sets an initial of 0.5
|
||||
~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: [0]);
|
||||
|
||||
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: [0]);
|
||||
)
|
||||
MIDIFunc.trace(true)
|
||||
@ -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,79 @@
|
||||
(
|
||||
SynthDef(\mellotronFlute, {
|
||||
arg freq = 440, amp = 0.3, gate = 1, pan = 0, vibratoRate = 1, vibratoDepth = 0.15,
|
||||
noiseLevel = 0.2, ringModFreq = 3, lpfFreq = 1200, res = 0.8, lpfLfoRate = 1, lpfLfoDepth = 80,
|
||||
detune = 0.005; // Detune amount (in ratio)
|
||||
|
||||
var sig, osc1, osc2, vibrato, noise, env, lpfMod, freq1, freq2;
|
||||
|
||||
// Natural vibrato (LFO)
|
||||
vibrato = SinOsc.kr(vibratoRate, 0, vibratoDepth).range(0.98, 1.02);
|
||||
|
||||
// Detuned frequencies (slight offsets)
|
||||
freq1 = freq * (1.01); // Slightly sharp
|
||||
freq2 = freq * (1.01); // Slightly flat
|
||||
|
||||
// 1st Oscillator: Triangle waves with vibrato
|
||||
osc1 = Mix([
|
||||
LFTri.ar(freq1 * vibrato),
|
||||
LFTri.ar(freq2 * vibrato)
|
||||
]) * 0.5; // Mix detuned voices
|
||||
|
||||
// Pink noise mixed into the first oscillator for breathiness
|
||||
noise = PinkNoise.ar(noiseLevel);
|
||||
osc1 = Mix([osc1, noise * 0.5]); // Blend noise into osc1
|
||||
|
||||
// 2nd Oscillator: Detuned ring modulation for a natural tone
|
||||
osc2 = Mix([
|
||||
Saw.ar(freq1 * ringModFreq),
|
||||
SinOscFB.ar(freq2 * ringModFreq)
|
||||
]) * 0.5 * osc1; // Ring-modulated with detuned pair
|
||||
|
||||
// Mix oscillators together
|
||||
sig = Mix([ osc1, osc2 * 0.5]);
|
||||
|
||||
// LFO for filter frequency modulation
|
||||
lpfMod = SinOsc.kr(lpfLfoRate).range(lpfFreq - lpfLfoDepth, lpfFreq + lpfLfoDepth);
|
||||
|
||||
// Low-pass filter with LFO modulation and slight resonance
|
||||
sig = RLPF.ar(sig, lpfMod, res);
|
||||
|
||||
// Envelope (slow attack for a natural swell)
|
||||
env = EnvGen.kr(Env.adsr(0.2, 3, 1, 1), gate, doneAction: 2);
|
||||
|
||||
|
||||
// Apply envelope and amp
|
||||
sig = sig * env * amp;
|
||||
|
||||
// sig = sig.tanh(8);
|
||||
sig = BLowShelf.ar(sig, 200, 0.5, 9);
|
||||
// sig = sig.blend(GVerb.ar(sig, 200, 4), 0.15);
|
||||
|
||||
|
||||
|
||||
|
||||
// sig = sig.blend(BPF.ar(sig, 800, 0.5), 0.9);
|
||||
// Output with panning
|
||||
Out.ar(0, Pan2.ar(sig, pan));
|
||||
}).add;
|
||||
)
|
||||
|
||||
// Play the flute synth
|
||||
x = Synth(\mellotronFlute, [\freq, 53.midicps, \detune, 0.1]); // Slight detune for a richer sound
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
(
|
||||
|
||||
Pbind(
|
||||
\instrument, \mellotronFlute, // Use your SynthDef
|
||||
// \freq, Pseq([40, 37, 38, 30, 45, 30].midicps, inf), // Sequence of MIDI notes converted to Hz
|
||||
\freq, Pseq([[48, 20, 53], [10, 58, 60], [10, 55, 63], [12, 55, 58]].midicps, inf), // Sequence of MIDI notes converted to Hz
|
||||
// \freq, Pseq([[50, 65], [55, 72], [72, 74], [48, 20]].midicps, inf), // Sequence of MIDI notes converted to Hz
|
||||
\detune, Pseq([0.2], inf), // Varying detune values
|
||||
\dur, Pseq([2], inf), // Duration per note
|
||||
// \amp, 0.02;
|
||||
).play;
|
||||
)
|
||||
@ -0,0 +1,54 @@
|
||||
(
|
||||
SynthDef(\mellotron, {
|
||||
arg freq = 440, amp = 0.8, gate = 1, pan = 0, vibratoRate = 1, vibratoDepth = 0.15,
|
||||
noiseLevel = 0.2, ringModFreq = 3, lpfFreq = 2000, res = 0.8, lpfLfoRate = 1, lpfLfoDepth = 100,
|
||||
detune = 0.005;
|
||||
|
||||
var sig, osc1, osc2, vibrato, noise, env, lpfMod, freq1, freq2;
|
||||
|
||||
vibrato = SinOsc.kr(vibratoRate, 0, vibratoDepth).range(0.98, 1.02);
|
||||
|
||||
freq1 = freq * (0.99);
|
||||
freq2 = freq * (1.01);
|
||||
|
||||
osc1 = Mix([
|
||||
LFTri.ar(freq1 * vibrato),
|
||||
LFTri.ar(freq2 * vibrato)
|
||||
]) * 0.5;
|
||||
|
||||
noise = WhiteNoise.ar(noiseLevel);
|
||||
osc1 = Mix([osc1, noise * 0.5]);
|
||||
|
||||
osc2 = Mix([
|
||||
Saw.ar(freq1 * ringModFreq),
|
||||
SinOscFB.ar(freq2 * ringModFreq)
|
||||
]) * 0.5 * osc1;
|
||||
|
||||
sig = Mix([ osc1, osc2 * 0.5]);
|
||||
|
||||
lpfMod = SinOsc.kr(lpfLfoRate).range(lpfFreq - lpfLfoDepth, lpfFreq + lpfLfoDepth);
|
||||
sig = RLPF.ar(sig, lpfMod, res);
|
||||
|
||||
env = EnvGen.kr(Env.adsr(0.2, 3, 1, 2), gate, doneAction: 2);
|
||||
|
||||
sig = sig * env * amp;
|
||||
|
||||
sig = sig.tanh(8);
|
||||
sig = BLowShelf.ar(sig, 200, 0.5, 9);
|
||||
|
||||
Out.ar(0, Pan2.ar(sig, pan));
|
||||
}).add;
|
||||
)
|
||||
|
||||
|
||||
(
|
||||
Pbind(
|
||||
\instrument, \mellotron,
|
||||
\freq, Pseq([
|
||||
[48, 20, 53], [10, 58, 60], [55, 72, 74], [10, 63, 70],
|
||||
[48, 20, 53], [10, 58, 60], [10, 55, 63], [12, 55, 58]
|
||||
].midicps, inf),
|
||||
\dur, 2,
|
||||
).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;
|
||||
});
|
||||
)
|
||||
@ -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…
Reference in New Issue