Merge remote-tracking branch 'refs/remotes/origin/master'

master
Leo Coogan 9 months ago
commit 8db232edf7
Signed by: lcoogan
GPG Key ID: 54DBD17B0D75ABB0

@ -0,0 +1,93 @@
(
s.waitForBoot({
s.newBusAllocators;
~revbus = Bus.audio(s, 2);
SynthDef(\rhubarb, {
var bn, pn, osc, sig, env, freq = \freq.ir(440);
bn = Crackle.ar(1!4);
bn = LPF.ar(bn, 10); // Low-pass filter to reduce high frequencies
bn = GlitchBPF.ar(bn, freq * {Rand(-0.1, 0.1).midiratio}.dup(4), \rq.ir(0.01), 24);
osc = LFSaw.ar(freq * {Rand(-0.1, 0.1).midiratio}.dup(4), {Rand(0.48, 0.52)}.dup(4));
osc = LPF.ar(osc, (freq * 2).clip(20, 20000));
osc = osc * LFDNoise3.kr(0.1!4).exprange(1.1, 1.5);
osc = Fold.ar(osc, -20, 20);
osc = LPF.ar(osc, 600).tanh(20) * 0.12;
env = Env.asr(\atk.kr(0.35), \dec.kr(3), \sus.kr(1), \rel.kr(2), \crv.ir(-2)).ar(2, \gate.kr(1));
sig = bn + osc + PinkNoise.ar(0.015!4 * LFDNoise3.kr(1).exprange(0.35, 1));
sig = sig * LFDNoise3.kr(0.1!4).exprange(1.1, 1.2);
sig = Splay.ar(sig, spread:10);
sig = sig.tanh * \amp.ir(0.25);
/*sig = sig + BPF.ar(sig, 400, 0.3, 1, 0);
sig = sig + GlitchBPF.ar(sig, 400, 1, 1, 0) * 0.1;*/
sig = sig + CombL.ar(sig, maxdelaytime:0.2, delaytime:0.2, decaytime: 1.0) * 0.4;
sig = sig * env;
Out.ar(\out.ir(0), sig);
}).add;
SynthDef(\reverb, {
var sig, verb;
sig = In.ar(\in.ir(~revbus), 2);
verb = GVerb.ar(sig.sum, 299, 1);
// verb = JPverb.ar(verb, 299, 1);
verb = JPverb.ar(verb, t60: 2.0, damp: 0.0, size: 3.0, earlyDiff: 0.1, modDepth: 0, modFreq: 1.0, low: 1.0, mid: 1.0, high: 1.0, lowcut: 500.0, highcut: 2000.0);
verb = LPF.ar(verb, \lpf.ir(12500), \amp.ir(0.2));
sig = sig.blend(verb, \mix.kr(0.8));
Out.ar(\out.ir(0), sig);
}).add;
s.sync;
~rev = Synth(\reverb, [in: ~revbus, out: 0], s, \addAfter);
t = TempoClock(86/60);
p = Pbind(
\instrument, \rhubarb,
\dur, Pseq([ 1.5, 4.5, 1.5, 1.5, 5 ], inf),
\sustain, Pkey(\dur),
\midinote, Pseq([
[ 57, 62, 66 ],
[ 54, 57, 61 ],
[ 57, 61, 64 ],
[ 52, 56, 59 ],
Prand([[ 33, 50, 54, 57], [ 50, 54, 57 ]], 1),
], inf),
\amp, 1,
\atk, Pwhite(0.2, 0.5),
\rel, Pexprand(1.2, 2.5),
\out, ~revbus
).play(t)
});
)
(
SynthDef(\rhubarb, {
var bn, pn, osc, sig, env, freq = \freq.ir(440);
bn = BrownNoise.ar(0.02); // Subtle noise for warmth
bn = BPF.ar(bn, freq * {Rand(-0.1, 0.1).midiratio}.dup(4), \rq.ir(0.01), 8);
osc = LFSaw.ar([freq, freq * 1.01, freq * 0.99], {Rand(0.48, 0.52)}.dup(3)); // Multiple detuned oscillators
// Removed aggressive band-limiting for more high-end content
osc = osc * LFDNoise3.kr(0.1!4).exprange(1.1, 1.5);
osc = Fold.ar(osc, -1, 1);
osc = LPF.ar(osc, 2000, 0.4); // Analog-style low-pass filter with resonance
env = Env.asr(\atk.kr(0.1), \sus.kr(1), \rel.kr(2), \crv.ir(-2)).ar(2, \gate.kr(1));
sig = bn + osc + PinkNoise.ar(0.015!4 * LFDNoise3.kr(1).exprange(0.35, 1));
sig = sig * LFDNoise3.kr(0.1!4).exprange(1.1, 1.2);
sig = Splay.ar(sig);
sig = sig.tanh * 0.15; // Subtle distortion for warmth
sig = sig * env;
Out.ar(\out.ir(0), sig);
}).add;
)

@ -0,0 +1,24 @@
(
SynthDef(\dubecho,{|length = 1, fb = 0.8, sep = 0.012|
var input = In.ar(0, 2);
var output = input + Fb({
arg feedback; // this will contain the delayed output from the Fb unit
var left,right;
var magic = LeakDC.ar(feedback*fb + input);
magic = HPF.ar(magic, 400); // filter's on the feedback path
magic = LPF.ar(magic, 5000);
magic = magic.tanh; // and some more non-linearity in the form of distortion
#left, right = magic; // let's have named variables for the left and right channels
magic = [DelayC.ar(left, 1, LFNoise2.ar(12).range(0,sep)), DelayC.ar(right, 1, LFNoise2.ar(12).range(sep,0))]; // In addition to the main delay handled by the feedback quark, this adds separately modulated delays to the left and right channels, which with a small "sep" value creates a bit of spatialization
},length);
ReplaceOut.ar(0, output);
}).store;
)
// Example Usage
~echo = Synth(\dubecho, [\length, TempoClock.default.tempo*(3/8), \fb, 0.1, \sep, 0.0014], addAction: \addToTail);
~echo.free;
~echo.set(\gate, 0);

@ -62,7 +62,7 @@ SynthDef(\sampleTrigger, { |buf, ampin = 0|
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
Out.ar(0, sound!2); // Send to audio output
}).add;
)
@ -137,7 +137,7 @@ MIDIdef.noteOn('808trig', { |vel, nn|
{75} {
Synth(\sampleTrigger, [buf: ~sample.cl, ampin: ~clampbus]);
}
}, noteNum: [36, 38, 39, 42, 43, 46, 47, 49, 50, 56, 62, 63, 64, 70, 75], chan: [0]);
}, noteNum: [36, 38, 39, 42, 43, 46, 47, 49, 50, 56, 62, 63, 64, 70, 75], chan: [1]);
MIDIdef.cc('808amp', { |val, num|
switch(num)
@ -153,6 +153,6 @@ MIDIdef.cc('808amp', { |val, num|
{85} {~cyampbus.value = val / 127}
{88} {~cbampbus.value = val / 127};
}, ccNum: [24, 29, 48, 51, 54, 57, 60, 63, 82, 85, 88], chan: [0]);
}, ccNum: [24, 29, 48, 51, 54, 57, 60, 63, 82, 85, 88], chan: [1]);
)
MIDIFunc.trace(true)

@ -0,0 +1,20 @@
(
SynthDef(\omnichord, {
arg freq = 440, amp = 0.3, releaseTime = 2.0, fmIndex = 1.0, fmRatio = 2, gate = 1;
var sig, env, osc1, osc2;
osc1 = Saw.ar(freq);
osc1 = RLPF.ar(osc1, 1200, 0.1);
osc2 = SinOsc.ar(freq * fmRatio, 0, fmIndex);
sig = osc1 + osc2;
env = EnvGen.ar(Env.adsr(attackTime: 0.01, decayTime: 0.3, sustainLevel: 0.5, releaseTime: 0), gate, doneAction: 2);
sig = sig * env * amp;
Out.ar(0, sig!2);
}).add;
)

@ -8,8 +8,8 @@ SynthDef(\mellotron, {
vibrato = SinOsc.kr(vibratoRate, 0, vibratoDepth).range(0.98, 1.02);
freq1 = freq * (0.99);
freq2 = freq * (1.01);
freq1 = (freq * (0.99))/4;
freq2 = (freq * (1.01))/2;
osc1 = Mix([
LFTri.ar(freq1 * vibrato),
@ -40,15 +40,26 @@ SynthDef(\mellotron, {
}).add;
)
(
Pbind(
\instrument, \mellotron,
\freq, Pseq([
[48, 20, 53], [10, 58, 60], [10, 55, 63], [12, 55, 58],
[48, 20, 53], [10, 58, 60], [55, 72, 74], [10, 63, 70],
].midicps, inf),
\dur, 2,
\freq, Pseq([
// [65, 69, 71], // F Major (F, A, C)
[80, 75,],
[90, 70],
[90, 70],
[80, 65]
].midicps, inf), // Use MIDI note numbers for frequencies
\dur, Pseq([2, 0.5, 0.5, 1],inf),
\vibratoRate, 5, // Adding more vibrato (changeable)
\vibratoDepth, 0.15, // Keep vibrato depth as is
\lpfFreq, 1200, // LPF for smoothing
\lpfLfoRate, 0.1, // Slow LFO modulation for LPF
\lpfLfoDepth, 100, // Depth of LPF modulation
// \detune, -12, // Slight detuning for realism
\pan, Pseq([0.5, -0.5], inf), // Panning left and right for stereo spread
).play;
)

@ -6,64 +6,28 @@ 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;
|freq = 440, gate = 1, cutoff = 1e4, rq = 0.3, amp = 0.05, modDepth = 0.3, detune = 0|
var env, osc1, osc2, filt1, filt2, lfo, sig, sig1, sig2;
// Slightly Different Oscillators
osc1 = SinOsc.ar(freq);
osc2 = SinOsc.ar(freq * 0.5); // Slight detune for variation
osc3 = SawDPW.ar(freq * 2);
osc1 = LFTri.ar(freq + detune);
osc2 = Pulse.ar(freq + detune);
// 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;
lfo = LFNoise2.kr(20).range(1 - modDepth, 1 + modDepth);
// 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);
filt2 = RLPF.ar(osc2, cutoff * lfo, rq);
env = EnvGen.kr(Env.adsr(0, 0.3, 0.3, 0.1), gate, doneAction: 2);
// ADSR Envelope
env = EnvGen.kr(Env.adsr(0.0, 0.3, 0.3, 0.1), gate, doneAction: 2);
sig1 = Pan2.ar(filt1 * amp * env, -0.3);
sig2 = Pan2.ar(filt2 * amp * env, 0.3);
// 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);
sig = sig1 + sig2;
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);
Out.ar(0, sig);
}).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;
)
@ -75,21 +39,39 @@ Pbind(
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,
]
);
// [vel, nn].postln;
if (chan == 0, {
~notes[nn] = Synth.new(
\rhubarb,
[
\freq, nn.midicps,
\amp, vel.linexp(1,127,0.01,0.3),
\gate, 1,
\detune, 0,
\cutoff, 400,
\rq, 0.5,
]
);
});
});
MIDIdef.noteOff(\noteOffTest, {
arg vel, nn;
[vel, nn].postln;
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
arg vel, nn, chan;
// [vel, nn].postln;
if (chan == 0, {
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
});
});
)

@ -1,89 +1,53 @@
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;
)
(
// 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);
// MIDI
MIDIdef.noteOn(\noteOnTest, {
arg vel, nn, chan, src;
[vel, nn].postln;
// [vel, nn].postln;
~notes[nn] = Synth.new(
\mellotronFlute,
\rhubarb,
[
\freq, nn.midicps,
\amp, vel.linexp(1,127,0.01,0.3),
\gate, 1,
\detune, 2,
\cutoff, 400,
\rq, 0.7,
]
);
});
MIDIdef.noteOff(\noteOffTest, {
arg vel, nn;
[vel, nn].postln;
// [vel, nn].postln;
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
});
)
(
SynthDef(\rhubarb, {
|freq = 440, gate = 1, cutoff = 1e4, rq = 0.3, amp = 0.3, modDepth = 0.3, detune = 0|
var env, osc, osc2, filt, lfo, lfo2, sig;
sig = Pulse.ar(freq + detune);
env = EnvGen.kr(Env.adsr(0.1, 0.3, 0.3, 0.1), gate, doneAction: 2);
lfo = LFNoise2.kr(20).range(1 - modDepth, 1 + modDepth);
filt = RLPF.ar(sig, cutoff * lfo, rq);
sig = filt * env * amp;
Out.ar(0, sig!2);
}).add;
)

@ -0,0 +1,76 @@
(
SynthDef(\pad, {
arg amp = 0.3, freq = 440, octave = 0, gate = 0;
var sig, osc1, osc2, env, lfo, noise;
freq = freq * (2 ** octave);
osc1 = LFSaw.ar(freq + 1.01) * 2;
osc2 = SawDPW.ar(freq + 0.99) * 3;
noise = WhiteNoise.ar(2);
lfo = SinOsc.kr(3.1).range(0.5, 1.5);
sig = osc1 + osc2;
sig = RLPF.ar(sig, 800 * lfo);
// sig = BPF.ar(sig, 40 * lfo, 0.8);
env = EnvGen.ar(Env.adsr(attackTime: 0.3, decayTime: 0.5, sustainLevel: 0.2, releaseTime: 0.05), gate, doneAction: 2);
// env = EnvGen.kr(Env.adsr(0.2, 3, 1, 1), gate, doneAction: 2);
// sig = CombL.ar(sig, 0.2, 0.2, 1.0);
// sig = DiodeRingMod.ar(sig);
// sig = sig.blend(GVerb.ar(sig, 299, 4), 0.15);
// sig = sig.blend(GVerb.ar(sig.sum, 299, 4), 0.15);
sig = CombL.ar(sig, 0.5, 1/[36.7, 37.3], 1, 0.2);
// sig = sig.blend(PF.ar(sig, 1500, 0.5), 0.9);
// Ideas
// chorusing (through J Concepts arrays), reverb, spatialization, distortion. See: Presence by Basic Channel
// dub echo
// band pan -- what was that AFX demo rack effect?
// multi-band strum
sig = sig!2 * amp * env;
Out.ar(0, sig);
}).add;
)
x = Synth(\pad, [\freq, 60.midicps]);
MIDIClient.init;
MIDIIn.connectAll;
(
~notes = Array.newClear(128);
// MIDI
MIDIdef.noteOn(\noteOnTest, {
arg vel, nn, chan, src;
// [vel, nn].postln;
~notes[nn] = Synth.new(
\pad,
[
\freq, nn.midicps,
\amp, vel.linexp(1,127,0.01,0.3),
\gate, 1,
\octave, 0
]
);
});
MIDIdef.noteOff(\noteOffTest, {
arg vel, nn;
// [vel, nn].postln;
~notes[nn].set(\gate, 0);
~notes[nn] = nil;
});
)
Loading…
Cancel
Save