// Load buffer first
b = Buffer.read(s, "/Users/lcoogan/snd/samples/scarlett/listen to my voice.wav");
b = Buffer.read(s, "/Users/lcoogan/snd/samples/scarlett/vocal backing.wav");
b = Buffer.read(s, "/Users/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/acheinu.wav");

b = Buffer.read(s, "/Users/lcoogan/Music/Musicians/My Bloody Valentine/Loveless/05 When You Sleep.opus");
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/04-Cantor_Samuel_Malavsky_Zechor.wav");
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/zechor.wav");

b = Buffer.read(s,"/Users/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/crawling-stems/lead.const.wav");

b = Buffer.read(s, "/Users/lcoogan/snd/releases/desolation-mountain/demos/boc.mp3");
b = Buffer.read(s, "/Users/lcoogan/snd/releases/desolation-mountain/demos/room-02.wav");
b.free;

// ============================
// SynthDefs (Generative / Self-contained)
// ============================

(
// PV_BrickWall + PV_RectComb
SynthDef(\pv_brickwall, { |amp = 0.5|
    var sig = PlayBuf.ar(1, b, BufRateScale.kr(b), loop: 1);
    var chain = FFT(LocalBuf(2048), sig);

    var mod1 = LFNoise1.kr(0.05).range(5, 40);
    var mod2 = LFNoise1.kr(0.1).range(0.01, 0.3);
    var mod3 = LFNoise1.kr(0.07).range(1, 10);
    var mod4 = LFNoise1.kr(0.05).range(0.1, 0.8);
    var mod5 = LFNoise1.kr(0.03).range(0.01, 0.4);

    chain = PV_BrickWall(chain, SinOsc.ar(mod1) + SinOsc.kr(mod2));
    chain = PV_RectComb(chain, mod3, mod4, mod5);
    sig = IFFT(chain.dup);
    Out.ar(0, sig * amp);
}).add;

// PV_RectComb only
SynthDef(\pv_rectcomb, { |amp = 0.5|
    var sig = PlayBuf.ar(1, b, BufRateScale.kr(b), loop: 1);
    var chain = FFT(LocalBuf(2048), sig);

    var mod1 = LFNoise1.kr(0.08).range(2, 12);
    var mod2 = LFNoise1.kr(0.07).range(0.05, 0.6);
    var mod3 = LFNoise1.kr(0.05).range(0.1, 0.5);

    chain = PV_RectComb(chain, mod1, mod2, mod3);
    Out.ar(0, IFFT(chain).dup * amp);
}).add;

// PV_MagSmear only
SynthDef(\pv_magsmear, { |amp = 0.5|
	var sig = PlayBuf.ar(1, b, rate:0.5, loop: 1);
    var chain = FFT(LocalBuf(1024), sig);
    var smearAmt = LFNoise2.kr(0.1).range(5, 50);

    chain = PV_MagSmear(chain, smearAmt);
    Out.ar(0, IFFT(chain).dup * amp);
}).add;

// PV_Freeze
SynthDef(\pv_freeze, { |amp = 0.5|
    var sig = PlayBuf.ar(1, b, BufRateScale.kr(b), loop: 1);
    var chain = FFT(LocalBuf(1024), sig);
    var freezeTrig = LFNoise0.kr(0.05).range(0.05, 1.0);

    chain = PV_Freeze(chain, SinOsc.kr(freezeTrig) > 0.5);
    Out.ar(0, IFFT(chain).dup * amp);
}).add;

// PV_MagGate + PV_MagShift
SynthDef(\pv_maggate, { |amp = 0.5|
    var sig = PlayBuf.ar(1, b, BufRateScale.kr(b), loop: 1);
    var chain = FFT(LocalBuf(1024), sig);

    var thresh = LFNoise1.kr(0.09).range(20, 80);
    var floor = LFNoise1.kr(0.07).range(0.2, 1.0);
    var shift = LFNoise1.kr(0.04).range(-0.4, 0.4);

    chain = PV_MagGate(chain, thresh, floor);
    chain = PV_MagShift(chain, 1, shift);

    Out.ar(0, IFFT(chain).dup * amp);
}).add;
)

// ============================
// Spawn Generative Instances
// ============================

(
Synth(\pv_brickwall);
Synth(\pv_rectcomb);
// Synth(\pv_magsmear);
// Synth(\pv_freeze);
)



// ============================
// Generative Patterns for Parameters
// ============================

// Pattern for randomly varying synth parameters over time
(
Pbind(
    \instrument, \pv_brickwall,      // Choose SynthDef
	// \amp, Pwhite(0.2, 0.8, inf),     // Random amplitude (0.2 to 0.8)
	\amp, 1,
    \mod1, Pwhite(5, 40, inf),       // Random mod1 value (5 to 40)
    \mod2, Pwhite(0.01, 0.3, inf),   // Random mod2 value (0.01 to 0.3)
    \mod3, Pwhite(1, 10, inf),       // Random mod3 value (1 to 10)
    \mod4, Pwhite(0.1, 0.8, inf),    // Random mod4 value (0.1 to 0.8)
    \mod5, Pwhite(0.01, 0.4, inf),   // Random mod5 value (0.01 to 0.4)
    \dur, Pseq([2, 4, 1, 3], inf)    // Sequence of durations
).play;
)

// You can create a similar pattern for other synths:

// Pattern for PV_RectComb
(
Pbind(
    \instrument, \pv_rectcomb,
    \amp, Pwhite(0.3, 0.7, inf),
    \mod1, Pwhite(2, 12, inf),
    \mod2, Pwhite(0.05, 0.6, inf),
    \mod3, Pwhite(0.1, 0.5, inf),
    \dur, Pseq([3, 1, 2], inf)
).play;
)

// Pattern for PV_MagSmear
(
Pbind(
    \instrument, \pv_magsmear,
    \amp, Pwhite(0.2, 0.5, inf),
    \mod1, Pwhite(5, 50, inf),
    \dur, Pseq([4, 6, 2], inf)
).play;
)


(
// hell yeah
Routine({
    loop {
        // Random parameter values
        var mod1 = Pwhite(5, 40).next;   // Random mod1 value (5 to 40)
        var mod2 = Pwhite(0.01, 0.3).next; // Random mod2 value (0.01 to 0.3)
        var mod3 = Pwhite(1, 10).next;   // Random mod3 value (1 to 10)
        var mod4 = Pwhite(0.1, 0.8).next; // Random mod4 value (0.1 to 0.8)
        var mod5 = Pwhite(0.01, 0.4).next; // Random mod5 value (0.01 to 0.4)
        var dur = Pseq([2, 4, 1, 3], inf).next; // Duration pattern

        // Create synth
        Synth(\pv_magsmear, [
			\amp, 1.5,
            \mod1, mod1,
            \mod2, mod2,
            \mod3, mod3,
            \mod4, mod4,
            \mod5, mod5
        ]);

		Synth(\pv_brickwall, [
			\amp, 4.5,
			\mod1, mod1,
			\mod2, mod2,
			\mod3, mod3,
			\mod4, mod4,
			\mod5, mod5
		]);

		Synth(\pv_rectcomb, [
			\amp, 0.5,
			\mod1, mod1,
			\mod2, mod2,
			\mod3, mod3,
			\mod4, mod4,
		]);

        // Wait for the duration
        20.wait; // Wait 1 second before the next iteration
	}
}).play;
)

(
SynthDef(\pv_brickwall, { |amp = 0.5|
	var sig = PlayBuf.ar(1, b, rate:0.5, loop: 1);
    var chain = FFT(LocalBuf(2048), sig);
    chain = PV_BrickWall(chain, SinOsc.ar(5) + SinOsc.kr(0.1));
    sig = IFFT(chain.dup);
    Out.ar(0, sig * amp);
}).add;
)



(
SynthDef(\pv_distorted_bass, { |amp = 0.5|
    var sig = PlayBuf.ar(1, b, BufRateScale.kr(b), loop: 1);
    var chain = FFT(LocalBuf(2048), sig);
    chain = PV_BrickWall(chain, SinOsc.ar(5) + SinOsc.kr(0.1));
    chain = PV_Mul(chain, SinOsc.kr(0.5, 0, 0.1)); // Adding more randomness
    chain = PV_BrickWall(chain, SinOsc.kr(0.3, 0, 0.2)); // Distortion Layer
    sig = IFFT(chain.dup);
    Out.ar(0, sig * amp);
}).add;
)

(
// PV_BrickWall + PV_RectComb with evolving complexity
SynthDef(\pv_brickwall, { |amp = 80|
	var sig = PlayBuf.ar(1, b, rate:0.1, loop: 1);
    var chain = FFT(LocalBuf(2048), sig);

    // Modulation sources for evolving behavior
    var mod1 = LFNoise1.kr(0.05).range(5, 40);
    var mod2 = LFNoise1.kr(0.1).range(0.01, 0.3);
    var mod3 = LFNoise1.kr(0.07).range(1, 10);
    var mod4 = LFNoise1.kr(0.05).range(0.1, 0.8);
    var mod5 = LFNoise1.kr(0.03).range(0.01, 0.4);

	var randomMod;

    // Applying PV effects with evolving modulations
    chain = PV_BrickWall(chain, SinOsc.ar(mod1) + SinOsc.kr(mod2));
    chain = PV_RectComb(chain, mod3, mod4, mod5);

    // Adding some additional time-varying effects or randomization
    randomMod = LFNoise1.kr(0.02).range(0.1, 1);
    chain = PV_BrickWall(chain, SinOsc.ar(mod1 + randomMod) + SinOsc.kr(mod2 + randomMod));

    sig = IFFT(chain.dup);
    Out.ar(0, sig * amp);
}).add;
)

(
// PV_BrickWall + PV_RectComb + PV_MagShift + PV_Freeze
SynthDef(\pv_complex_fx, { |amp = 200, freeze = 0, shiftAmt = 0.2|
	var sig = PlayBuf.ar(1, b, rate:0.5, loop: 1);
    var chain = FFT(LocalBuf(2048), sig);

    // Modulation sources
    var mod1 = LFNoise1.kr(0.05).range(5, 40);
    var mod2 = LFNoise1.kr(0.1).range(0.01, 0.3);
    var mod3 = LFNoise1.kr(0.07).range(1, 10);
    var mod4 = LFNoise1.kr(0.05).range(0.1, 0.8);
    var mod5 = LFNoise1.kr(0.03).range(0.01, 0.4);
    var randomMod = LFNoise1.kr(0.02).range(0.1, 1);

    // Apply effects
    chain = PV_BrickWall(chain, SinOsc.ar(mod1) + SinOsc.kr(mod2));
    chain = PV_RectComb(chain, mod3, mod4, mod5);
    chain = PV_BrickWall(chain, SinOsc.ar(mod1 + randomMod) + SinOsc.kr(mod2 + randomMod));
    chain = PV_MagShift(chain, shiftAmt); // pitch shifting
    chain = PV_Freeze(chain, freeze);     // freeze toggle

    sig = IFFT(chain.dup);
    Out.ar(0, sig * amp);
}).add;
)




(
Routine({
    var amp = 5; // Start with a moderate amplitude
    Synth(\pv_brickwall, [\amp, amp]);
    0.5.wait;
    amp = amp * 5; // Decrease amplitude gradually
	Synth(\pv_distorted_bass, [\amp, amp]);
    1.wait;
	amp = amp * 5; // Increase amplitude
	Synth(\pv_brickwall, [\amp, amp]);
	0.1.wait;
    Synth(\pv_complex_fx, [\amp, amp]); // Lower volume for variation
}).play;
)

