diff --git a/aphex_twin_rhubarb_EF.scd b/aphex_twin_rhubarb_EF.scd new file mode 100644 index 0000000..4e99d34 --- /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, 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; +) \ No newline at end of file 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/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 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 EF-edit.scd b/padsynth practice EF-edit.scd index 0f83d62..dbee357 100644 --- a/padsynth practice EF-edit.scd +++ b/padsynth practice EF-edit.scd @@ -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; + }); }); -) \ No newline at end of file +) + + + + + + + + + diff --git a/padsynth practice.scd b/padsynth practice.scd index cfb0f6d..5787573 100644 --- a/padsynth practice.scd +++ b/padsynth practice.scd @@ -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; ) \ No newline at end of file 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; +}); +)