From 90b4ca66b5d34e429fa5d502e3bf9e459c4c4e30 Mon Sep 17 00:00:00 2001 From: Leo Coogan Date: Tue, 8 Apr 2025 01:45:36 -0400 Subject: [PATCH 1/7] successgit status --- dubecho.scd | 24 ++++++ padsynth practice EF-edit.scd | 42 ++++++--- padsynth practice.scd | 156 ++++++++++++++++++++++++++++++---- saw pad.scd | 76 +++++++++++++++++ 4 files changed, 267 insertions(+), 31 deletions(-) create mode 100644 dubecho.scd create mode 100644 saw pad.scd diff --git a/dubecho.scd b/dubecho.scd new file mode 100644 index 0000000..489fb26 --- /dev/null +++ b/dubecho.scd @@ -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); diff --git a/padsynth practice EF-edit.scd b/padsynth practice EF-edit.scd index 0f83d62..574248f 100644 --- a/padsynth practice EF-edit.scd +++ b/padsynth practice EF-edit.scd @@ -6,40 +6,42 @@ 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| + |freq = 440, gate = 1, cutoff = 1e4, rq = 0.3, amp = 0.05, modDepth = 0.3, modDepth2 = 0.5, noiseLevel = 0.8, ringFreq = 80, detune = 0| 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 + osc1 = LFTri.ar(freq + detune); + osc2 = Pulse.ar(freq + detune); + // osc1 = LFTri.ar((freq + detune) * 1); + // osc2 = Pulse.ar((freq + detune)* 0.5); 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); + lfo = LFNoise2.kr(20).range(1 - modDepth, 1 + modDepth); + lfo2 = LFNoise2.kr(1).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); + filt2 = RLPF.ar(osc2, cutoff * lfo, rq); + filt3 = RLPF.ar(osc3, cutoff * lfo2, rq); // ADSR Envelope - env = EnvGen.kr(Env.adsr(0.0, 0.3, 0.3, 0.1), gate, doneAction: 2); + env = EnvGen.kr(Env.adsr(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 + // sig2 = GVerb.ar(sig2, 299, 4); // 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, sig2!2); }).add; ) @@ -59,7 +61,7 @@ Pbind( // \dur, 0.5, // Duration of each chord \amp, 0.08, // Volume // \cutoff, 1200, - \detune, 0, // Slight detune + \detune, -2, // Slight detune \pan, Pwhite(-0.3, 0.3), // Random stereo width ).play; ) @@ -75,21 +77,33 @@ Pbind( MIDIdef.noteOn(\noteOnTest, { arg vel, nn, chan, src; - [vel, nn].postln; + // [vel, nn].postln; ~notes[nn] = Synth.new( \rhubarb, [ \freq, nn.midicps, \amp, vel.linexp(1,127,0.01,0.3), \gate, 1, + \detune, 2, + \cutoff, 400, + \rq, 0.5, ] ); }); MIDIdef.noteOff(\noteOffTest, { arg vel, nn; - [vel, nn].postln; + // [vel, nn].postln; ~notes[nn].set(\gate, 0); ~notes[nn] = nil; }); -) \ No newline at end of file +) + + + + + + + + + diff --git a/padsynth practice.scd b/padsynth practice.scd index cfb0f6d..7511558 100644 --- a/padsynth practice.scd +++ b/padsynth practice.scd @@ -4,16 +4,16 @@ 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| + |freq = 440, gate = 1, cutoff = 1e4, rq = 0.3, amp = 0.3, modDepth = 0.3, modDepth2 = 0.5, noiseLevel = 0.8, ringFreq = 80, detune = 0| 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 + osc1 = SinOsc.ar(freq + detune); + osc2 = SinOsc.ar(freq + detune * 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); + lfo = LFDNoise3.kr(4).range(1 - modDepth, 1 + modDepth); lfo2 = LFNoise2.kr(4).range(1 - modDepth, 1 + modDepth); // lfo2 = noise; @@ -24,7 +24,7 @@ SynthDef(\rhubarb, { // ADSR Envelope - env = EnvGen.kr(Env.adsr(0.0, 0.3, 0.3, 0.1), gate, doneAction: 2); + env = EnvGen.kr(Env.adsr(1, 3, 0.3, 0.1), gate, doneAction: 2); // Panning and Mixing sig1 = Pan2.ar(filt1 * env * amp, -0.3); @@ -32,6 +32,8 @@ SynthDef(\rhubarb, { sig3 = Pan2.ar(filt3 * env * amp, 0); mix = sig1 + sig2; // Mix main signals + + // mix = mix.blend(GVerb.ar(mix.sum, 299, 4), 0.15); // mix = mix + (noise * env * noiseLevel); // Add noise with envelope control // mix = DelayC.ar(mix, maxdelaytime: 0.2, delaytime: 0.3); @@ -41,26 +43,77 @@ SynthDef(\rhubarb, { }).add; ) +( +SynthDef(\rhubarb, { + |freq = 440, gate = 1, cutoff = 1e4, rq = 0.3, amp = 0.1, modDepth = 0.3, modDepth2 = 0.5, noiseLevel = 0.8, ringFreq = 80, detune = 0| + var env, osc1, osc2, osc3, filt1, filt2, filt3, lfo, lfo2, noise, noiseFilt, sig1, sig2, sig3, mix, chorus, chorusDepth = 20, chorusRate = 80, chorusedSignal; + + // Slightly Different Oscillators + osc1 = SinOsc.ar(freq + detune); + osc2 = SinOsc.ar(freq + detune * 0.5); // Slight detune for variation + osc3 = SawDPW.ar(freq * 2); + + // LFO to Modulate Filter Frequency + lfo = LFDNoise3.kr(4).range(1 - modDepth, 1 + modDepth); + lfo2 = LFNoise2.kr(4).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); + + // 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 + + // Chorusing effect using CombN (no delay added, just detuned voices) + chorusDepth = LFDNoise3.kr(0.2).range(0.01, 0.05); // Depth of modulation + chorusRate = LFDNoise3.kr(0.2).range(0.1, 0.3); // Rate of modulation + + // Apply CombN for chorusing + chorusedSignal = CombN.ar(mix, maxdelaytime: 0.01, decaytime: chorusDepth, feedback: chorusRate); + + // Output + Out.ar(0, chorusedSignal); // Send the chorused signal to the output +}).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, 7, 12], [1, 5, 9], [4, 7, 11], [5, 9, 8], + // [2, 7, 11], [1, 5, 9], [3, 9], [1,3,5] + ], inf), // Chord progression + // \degree, Pseq([], inf), // \degree, Pseq([2, 4, 11,], inf), - // \dur, 0.5, // Duration of each chord - \amp, 0.08, // Volume - // \cutoff, 1200, - \detune, 0, // Slight detune + \dur, 4, // Duration of each chord + \amp, 0.06, // Volume + \cutoff, 1200, + \rq, 0.6, + \detune, Pseq([4.1, 4], inf), // Slight detune \pan, Pwhite(-0.3, 0.3), // Random stereo width ).play; ) +( +MIDIClient.init; +MIDIIn.connectAll; +) + + ( ~notes = Array.newClear(128); @@ -69,21 +122,90 @@ Pbind( 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, + + + // \instrument, \rhubarb, + // \degree, Pseq([], inf), + // \degree, Pseq([2, 4, 11,], inf), + \dur, 2 , // Duration of each chord + \amp, 0.06, // Volume + \cutoff, 800, + \rq, 0.2, + \detune, Pseq([4.1, 4], inf), // Slight detune + \pan, Pwhite(-0.3, 0.3), // Random stereo width ] ); }); MIDIdef.noteOff(\noteOffTest, { arg vel, nn; - [vel, nn].postln; + // [vel, nn].postln; ~notes[nn].set(\gate, 0); ~notes[nn] = nil; }); -) \ No newline at end of file +) + + + + + +( +~notes = Array.newClear(128); + +// MIDI definitions +MIDIdef.noteOn(\noteOnTest, { + arg vel, nn, chan, src; + // [vel, nn].postln; // Uncomment to debug + + // Create the first instrument (rhubarb) + ~notes[nn] = Synth.new( + \rhubarb, + [ + \freq, nn.midicps, + \amp, vel.linexp(1, 127, 0.01, 0.3), + \gate, 1, + \dur, 2, // Duration of each chord + \amp, 0.06, // Volume + \cutoff, 800, + \rq, 0.8, + \detune, Pseq([4.1, 4], inf), // Slight detune + \pan, Pwhite(-0.3, 0.3), // Random stereo width + ] + ); + + // Create the second instrument (rhubarb2) with the same parameters + ~notes[nn] = Synth.new( + \rhubarb2, + [ + \freq, nn.midicps, + \amp, vel.linexp(1, 127, 0.01, 0.3), + \gate, 1, + \dur, 2, // Duration of each chord + \amp, 0.06, // Volume + \cutoff, 400, + \rq, 0.1, + \detune, Pseq([4.1, 4], inf), // Slight detune + \pan, Pwhite(-0.3, 0.3), // Random stereo width + ] + ); +}); + +MIDIdef.noteOff(\noteOffTest, { + arg vel, nn; + // [vel, nn].postln; // Uncomment to debug + + // Stop both instruments + ~notes[nn].set(\gate, 0); + ~notes[nn] = nil; + + // For the second instrument (rhubarb2), clear the reference as well + ~notes[nn] = nil; +}); +) diff --git a/saw pad.scd b/saw pad.scd new file mode 100644 index 0000000..a9fced1 --- /dev/null +++ b/saw pad.scd @@ -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; +}); +) From 83118dcbbb759cb1c501ebc21a7bd22fd060a122 Mon Sep 17 00:00:00 2001 From: Leo Coogan Date: Tue, 8 Apr 2025 06:00:46 -0400 Subject: [PATCH 2/7] i feel like death --- omnichord.scd | 20 +++++ pads/mel.scd | 27 ++++-- padsynth practice.scd | 192 ++++-------------------------------------- 3 files changed, 56 insertions(+), 183 deletions(-) create mode 100644 omnichord.scd diff --git a/omnichord.scd b/omnichord.scd new file mode 100644 index 0000000..2fc7c87 --- /dev/null +++ b/omnichord.scd @@ -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; +) \ No newline at end of file diff --git a/pads/mel.scd b/pads/mel.scd index ce1678b..6138f13 100644 --- a/pads/mel.scd +++ b/pads/mel.scd @@ -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; ) diff --git a/padsynth practice.scd b/padsynth practice.scd index 7511558..5787573 100644 --- a/padsynth practice.scd +++ b/padsynth practice.scd @@ -1,125 +1,13 @@ MIDIClient.init; MIDIIn.connectAll; -MIDIClient.sources.do; - -( -SynthDef(\rhubarb, { - |freq = 440, gate = 1, cutoff = 1e4, rq = 0.3, amp = 0.3, modDepth = 0.3, modDepth2 = 0.5, noiseLevel = 0.8, ringFreq = 80, detune = 0| - var env, osc1, osc2, osc3, filt1, filt2, filt3, lfo, lfo2, noise, noiseFilt, sig1, sig2, sig3, mix; - - // Slightly Different Oscillators - osc1 = SinOsc.ar(freq + detune); - osc2 = SinOsc.ar(freq + detune * 0.5); // Slight detune for variation - osc3 = SawDPW.ar(freq * 2); - - // LFO to Modulate Filter Frequency - lfo = LFDNoise3.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(1, 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.blend(GVerb.ar(mix.sum, 299, 4), 0.15); - // 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; -) - -( -SynthDef(\rhubarb, { - |freq = 440, gate = 1, cutoff = 1e4, rq = 0.3, amp = 0.1, modDepth = 0.3, modDepth2 = 0.5, noiseLevel = 0.8, ringFreq = 80, detune = 0| - var env, osc1, osc2, osc3, filt1, filt2, filt3, lfo, lfo2, noise, noiseFilt, sig1, sig2, sig3, mix, chorus, chorusDepth = 20, chorusRate = 80, chorusedSignal; - - // Slightly Different Oscillators - osc1 = SinOsc.ar(freq + detune); - osc2 = SinOsc.ar(freq + detune * 0.5); // Slight detune for variation - osc3 = SawDPW.ar(freq * 2); - - // LFO to Modulate Filter Frequency - lfo = LFDNoise3.kr(4).range(1 - modDepth, 1 + modDepth); - lfo2 = LFNoise2.kr(4).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); - - // 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 - - // Chorusing effect using CombN (no delay added, just detuned voices) - chorusDepth = LFDNoise3.kr(0.2).range(0.01, 0.05); // Depth of modulation - chorusRate = LFDNoise3.kr(0.2).range(0.1, 0.3); // Rate of modulation - - // Apply CombN for chorusing - chorusedSignal = CombN.ar(mix, maxdelaytime: 0.01, decaytime: chorusDepth, feedback: chorusRate); - - // Output - Out.ar(0, chorusedSignal); // Send the chorused signal to the output -}).add; -) - - - - -( -// Test pattern - -Pbind( - \instrument, \rhubarb, - \degree, Pseq([ - [2, 4, 7, 12], [1, 5, 9], [4, 7, 11], [5, 9, 8], - // [2, 7, 11], [1, 5, 9], [3, 9], [1,3,5] - ], inf), // Chord progression - // \degree, Pseq([], inf), - // \degree, Pseq([2, 4, 11,], inf), - \dur, 4, // Duration of each chord - \amp, 0.06, // Volume - \cutoff, 1200, - \rq, 0.6, - \detune, Pseq([4.1, 4], inf), // Slight detune - \pan, Pwhite(-0.3, 0.3), // Random stereo width -).play; -) - - -( -MIDIClient.init; -MIDIIn.connectAll; -) ( +// 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; @@ -129,17 +17,9 @@ MIDIdef.noteOn(\noteOnTest, { \freq, nn.midicps, \amp, vel.linexp(1,127,0.01,0.3), \gate, 1, - - - // \instrument, \rhubarb, - // \degree, Pseq([], inf), - // \degree, Pseq([2, 4, 11,], inf), - \dur, 2 , // Duration of each chord - \amp, 0.06, // Volume - \cutoff, 800, - \rq, 0.2, - \detune, Pseq([4.1, 4], inf), // Slight detune - \pan, Pwhite(-0.3, 0.3), // Random stereo width + \detune, 2, + \cutoff, 400, + \rq, 0.7, ] ); }); @@ -156,56 +36,18 @@ MIDIdef.noteOff(\noteOffTest, { -( -~notes = Array.newClear(128); - -// MIDI definitions -MIDIdef.noteOn(\noteOnTest, { - arg vel, nn, chan, src; - // [vel, nn].postln; // Uncomment to debug - - // Create the first instrument (rhubarb) - ~notes[nn] = Synth.new( - \rhubarb, - [ - \freq, nn.midicps, - \amp, vel.linexp(1, 127, 0.01, 0.3), - \gate, 1, - \dur, 2, // Duration of each chord - \amp, 0.06, // Volume - \cutoff, 800, - \rq, 0.8, - \detune, Pseq([4.1, 4], inf), // Slight detune - \pan, Pwhite(-0.3, 0.3), // Random stereo width - ] - ); - // Create the second instrument (rhubarb2) with the same parameters - ~notes[nn] = Synth.new( - \rhubarb2, - [ - \freq, nn.midicps, - \amp, vel.linexp(1, 127, 0.01, 0.3), - \gate, 1, - \dur, 2, // Duration of each chord - \amp, 0.06, // Volume - \cutoff, 400, - \rq, 0.1, - \detune, Pseq([4.1, 4], inf), // Slight detune - \pan, Pwhite(-0.3, 0.3), // Random stereo width - ] - ); -}); - -MIDIdef.noteOff(\noteOffTest, { - arg vel, nn; - // [vel, nn].postln; // Uncomment to debug +( +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; - // Stop both instruments - ~notes[nn].set(\gate, 0); - ~notes[nn] = nil; + 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; - // For the second instrument (rhubarb2), clear the reference as well - ~notes[nn] = nil; -}); -) + Out.ar(0, sig!2); +}).add; +) \ No newline at end of file From 5f146987f6ddf1be32496e92c03ab85ae2c07003 Mon Sep 17 00:00:00 2001 From: Leo Coogan Date: Tue, 8 Apr 2025 07:46:08 -0400 Subject: [PATCH 3/7] Cleaning --- padsynth practice EF-edit.scd | 52 +++++------------------------------ 1 file changed, 7 insertions(+), 45 deletions(-) diff --git a/padsynth practice EF-edit.scd b/padsynth practice EF-edit.scd index 574248f..d2aedcf 100644 --- a/padsynth practice EF-edit.scd +++ b/padsynth practice EF-edit.scd @@ -6,66 +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, detune = 0| - 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 = LFTri.ar(freq + detune); osc2 = Pulse.ar(freq + detune); - // osc1 = LFTri.ar((freq + detune) * 1); - // osc2 = Pulse.ar((freq + detune)* 0.5); - osc3 = SawDPW.ar(freq * 2); - // LFO to Modulate Filter Frequency lfo = LFNoise2.kr(20).range(1 - modDepth, 1 + modDepth); - lfo2 = LFNoise2.kr(1).range(1 - modDepth, 1 + modDepth); - // lfo2 = noise; - // Apply Different Filters to Each Oscillator filt1 = SVF.ar(osc1, cutoff * lfo, rq); filt2 = RLPF.ar(osc2, cutoff * lfo, rq); - filt3 = RLPF.ar(osc3, cutoff * lfo2, rq); - - // ADSR Envelope env = EnvGen.kr(Env.adsr(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); - - // sig2 = GVerb.ar(sig2, 299, 4); - // mix = mix + (noise * env * noiseLevel); // Add noise with envelope control + sig1 = Pan2.ar(filt1 * amp * env, -0.3); + sig2 = Pan2.ar(filt2 * amp * env, 0.3); - // mix = DelayC.ar(mix, maxdelaytime: 0.2, delaytime: 0.3); + sig = sig1 + sig2; - // Output - Out.ar(0, sig2!2); + 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, -2, // Slight detune - \pan, Pwhite(-0.3, 0.3), // Random stereo width -).play; -) - @@ -84,7 +46,7 @@ MIDIdef.noteOn(\noteOnTest, { \freq, nn.midicps, \amp, vel.linexp(1,127,0.01,0.3), \gate, 1, - \detune, 2, + \detune, 0, \cutoff, 400, \rq, 0.5, ] From 2e38f0ed7e5741ec7856a2ff120d7176ad1ab251 Mon Sep 17 00:00:00 2001 From: Leo Coogan Date: Wed, 9 Apr 2025 11:13:38 -0400 Subject: [PATCH 4/7] becoming satisfactory, missing the right noise blend --- aphex_twin_rhubarb_EF.scd | 93 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 aphex_twin_rhubarb_EF.scd diff --git a/aphex_twin_rhubarb_EF.scd b/aphex_twin_rhubarb_EF.scd new file mode 100644 index 0000000..183e72b --- /dev/null +++ b/aphex_twin_rhubarb_EF.scd @@ -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, 400).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; +) \ No newline at end of file From 091379583479b7439bf9f9c4dfb17f9b6825b85c Mon Sep 17 00:00:00 2001 From: Leo Coogan Date: Wed, 9 Apr 2025 11:14:07 -0400 Subject: [PATCH 5/7] set correct chan --- live/tr08 EF-edit.scd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/live/tr08 EF-edit.scd b/live/tr08 EF-edit.scd index 40bbe19..2d3d649 100644 --- a/live/tr08 EF-edit.scd +++ b/live/tr08 EF-edit.scd @@ -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) \ No newline at end of file From 3ff392c6efb32444fb8843589a1dc523d38ea695 Mon Sep 17 00:00:00 2001 From: Leo Coogan Date: Wed, 9 Apr 2025 11:14:45 -0400 Subject: [PATCH 6/7] set right chan --- padsynth practice EF-edit.scd | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/padsynth practice EF-edit.scd b/padsynth practice EF-edit.scd index d2aedcf..dbee357 100644 --- a/padsynth practice EF-edit.scd +++ b/padsynth practice EF-edit.scd @@ -40,24 +40,30 @@ SynthDef(\rhubarb, { 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, - \detune, 0, - \cutoff, 400, - \rq, 0.5, - ] - ); + + 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; + arg vel, nn, chan; // [vel, nn].postln; - ~notes[nn].set(\gate, 0); - ~notes[nn] = nil; + + if (chan == 0, { + ~notes[nn].set(\gate, 0); + ~notes[nn] = nil; + }); }); ) From 59fd31103f6ac37d3489d46743012c81a333609e Mon Sep 17 00:00:00 2001 From: Leo Coogan Date: Wed, 9 Apr 2025 14:11:22 -0400 Subject: [PATCH 7/7] changed crf to 600, still missing the right blend of noise and tape distortion --- aphex_twin_rhubarb_EF.scd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aphex_twin_rhubarb_EF.scd b/aphex_twin_rhubarb_EF.scd index 183e72b..4e99d34 100644 --- a/aphex_twin_rhubarb_EF.scd +++ b/aphex_twin_rhubarb_EF.scd @@ -13,7 +13,7 @@ s.waitForBoot({ 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, 400).tanh(20) * 0.12; + 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);