You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
5.5 KiB
Plaintext
212 lines
5.5 KiB
Plaintext
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;
|
|
)
|
|
|
|
|
|
(
|
|
|
|
~notes = Array.newClear(128);
|
|
|
|
// MIDI
|
|
|
|
MIDIdef.noteOn(\noteOnTest, {
|
|
arg vel, nn, chan, src;
|
|
// [vel, nn].postln;
|
|
~notes[nn] = Synth.new(
|
|
\rhubarb,
|
|
[
|
|
\freq, nn.midicps,
|
|
\amp, vel.linexp(1,127,0.01,0.3),
|
|
\gate, 1,
|
|
|
|
|
|
// \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;
|
|
~notes[nn].set(\gate, 0);
|
|
~notes[nn] = nil;
|
|
});
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
(
|
|
~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;
|
|
});
|
|
)
|