MIDIClient.init;
MIDIIn.connectAll;

(
SynthDef(\rhubarb, {
    |freq = 440, gate = 1, cutoff = 1000, rq = 0.3, amp = 0.05, modDepth = 0.3, noiseLevel = 0.05|
    var env, osc, filt, lfo, noise, sig;

    // Single Sawtooth Oscillator
	osc = SinOsc.ar(freq);

    // Subtle Noise Layer
	// noise = PinkNoise.ar(noiseLevel);

    // LFO to Modulate Filter
    lfo = LFNoise0.kr(4).range(1 - modDepth, 1 + modDepth); // Triangle LFO at 2.94 Hz

    // Low-pass filter modulated by LFO
    filt = RLPF.ar(osc, cutoff * lfo, rq);

    // ADSR Envelope with Long Attack & Release
    env = EnvGen.kr(Env.adsr(0.0, 0.3, 0.8, 2.0), gate, doneAction: 2);

	sig = Pan2.ar(filt * env * amp, 0);

    // Output
    Out.ar(0, sig);
}).add;
)


(
~midiNotes = Dictionary.new; // Store active notes

MIDIdef.noteOn(\rhubarb_on, { |vel, num, chan, src|
    var freq = num.midicps; // Convert MIDI note to frequency
    var amp = vel / 127; // Normalize velocity (0 to 1)

    // Create the synth and store it in a dictionary
    ~midiNotes[num] = Synth(\rhubarb, [
        \freq, freq,
        \amp, amp * 0.1, // Adjust for a reasonable volume
        \cutoff, 1200
    ]);
});

MIDIdef.noteOff(\rhubarb_off, { |vel, num, chan, src|
    ~midiNotes[num].set(\gate, 0); // Release the synth
    ~midiNotes.remove(num); // Remove from dictionary
});
)



(
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),
    \dur, 0.5,       // Duration of each chord
    \amp, 0.08,     // Volume
	\cutoff, 1200,
	//\cutoff, Pseq([400, 600, 800]), // Filter cutoff frequency
	\detune, 12,  // Slight detune
    \pan, Pwhite(-0.3, 0.3), // Random stereo width
).play;
)

