Server.supernova;
s.boot;
MIDIClient.init;
MIDIIn.connectAll;

// Set list
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-Acheinu_Kol_Beit_Israel.wav");
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/02-Cantor_Mordechai_Hershman_Baruch_Hashem_Bayom.wav");
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/03-Cantor_Samual_Malavsky_Shomea_Kol_Bichios.wav");
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/05-Cantor_Zavel_Kwartin_Ribono_Shel_Olam.wav");
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/06-Cantor_Zevulun_Zavel_Kwartin_sings_Tiher.wav");
b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/07-Izak_Algazi_Efendi_Kamti_Be_ashmoret.wav");





(
// ========== Spectral SynthDef with expanded modulation ==========
SynthDef(\pv16knob, {
	arg bufnum, fftSize = 1024,
		amp = 0.3, delTime = 0.3, delFeedback = 0.4, verbMix = 0.2, transpose = 1.0;

	var in, chain, lfo, dry, fx, delay, verb;
	var wipe, trig;

	// Audio input and bitcrushing
	in = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum) * transpose, loop: 1);



	// FFT
	chain = FFT(LocalBuf(fftSize), in);


	// Layer 1 combos: structure

	// wipe = SinOsc.kr(0.1).range(0.1, 0.9);
	wipe = Lag.kr(TRand.kr(0.0, 1.0, Impulse.kr(0.2)), 1.0);
	trig = Impulse.kr(SinOsc.kr(0.1).range(1, 10));


	chain = PV_RandComb(chain, wipe, trig);
	chain = PV_BrickWall(chain);



/*	chain = PV_RandComb(chain, wipe, trig);
	chain = PV_BinShift(chain, stretch, shift, interp);

	chain = PV_MagFreeze(chain, freeze);
	chain = PV_BrickWall(chain, wipe);

	chain = PV_MaxMagN(chain, numbins);
	chain = PV_MagSmooth(chain, factor);

	chain = PV_PhaseShift90(chain, buffer);
	chain = PV_Diffuser(chain, trig);


	// Layer 2 combos: texture

	chain = PV_RandComb(chain);
	chain = PV_BinScramble(chain);
	chain = PV_BinWipe(chain);

	chain = PV_RandComb(chain);
	chain = PV_BinShift(chain);
	chain = PV_Diffuser(chain);

	chain = PV_MagFreeze(chain);
	chain = PV_BinWipe(chain);

	chain = PV_BrickWall(chain);
	chain = PV_MagSmooth(chain);*/



	// Select
	// chain = SelectX.kr(pvRouting.clip(0, 4), [chain0, chain1]);
	dry = IFFT(chain);

	// FX
	delay = CombC.ar(dry, 1, delTime, delFeedback);
	verb = FreeVerb.ar(dry, verbMix, 0.8, 0.3);

	// Mix and output
	fx = Mix([dry, delay, verb]);
	Out.ar(0, fx.dup * amp);
}).add;
)

(
// ========== Spectral SynthDef with expanded modulation ==========
SynthDef(\pv16knob_1, {
	arg bufnum, fftSize = 1024,
		amp = 0.3, delTime = 0.3, delFeedback = 0.4, verbMix = 0.2, transpose = 1.0;

	var in, chain, lfo, dry, fx, delay, verb;
	var wipe, trig;

	// Audio input and bitcrushing
	in = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum) * transpose, loop: 1);


	// FFT
	chain = FFT(LocalBuf(fftSize), in);


	// Layer 1 combos: structure

	// wipe = SinOsc.kr(0.1).range(0.1, 0.9);
	wipe = Lag.kr(TRand.kr(0.0, 1.0, Impulse.kr(0.2)), 1.0);
	trig = Impulse.kr(SinOsc.kr(0.1).range(1, 10));

/*	chain = PV_RandComb(chain, wipe, trig);
	chain = PV_BrickWall(chain);*/

	chain = PV_RandComb(chain, wipe, trig);
	chain = PV_BinScramble(chain, wipe, 0.2, trig);
	chain = PV_BinWipe(chain, chain, wipe);




/*	chain = PV_RandComb(chain, wipe, trig);
	chain = PV_BinShift(chain, stretch, shift, interp);

	chain = PV_MagFreeze(chain, freeze);
	chain = PV_BrickWall(chain, wipe);

	chain = PV_MaxMagN(chain, numbins);
	chain = PV_MagSmooth(chain, factor);

	chain = PV_PhaseShift90(chain, buffer);
	chain = PV_Diffuser(chain, trig);


	// Layer 2 combos: texture

	chain = PV_RandComb(chain);
	chain = PV_BinScramble(chain);
	chain = PV_BinWipe(chain);

	chain = PV_RandComb(chain);
	chain = PV_BinShift(chain);
	chain = PV_Diffuser(chain);

	chain = PV_MagFreeze(chain);
	chain = PV_BinWipe(chain);

	chain = PV_BrickWall(chain);
	chain = PV_MagSmooth(chain);*/



	// Select
	// chain = SelectX.kr(pvRouting.clip(0, 4), [chain0, chain1]);
	dry = IFFT(chain);

	// FX
	delay = CombC.ar(dry, 1, delTime, delFeedback);
	verb = FreeVerb.ar(dry, verbMix, 0.8, 0.3);

	// Mix and output
	fx = Mix([dry, delay, verb]);
	Out.ar(0, fx.dup * amp);
}).add;
)



(
// ========== Instantiate synth ==========
~pvSynth = Synth(\pv16knob, [\bufnum, b, \amp, 0.1]);
~pvSynth = Synth(\pv16knob_1, [\bufnum, b, \amp, 0.1]);
)


(
// it needs a control for mixing between the original and the granular, try adding the Dust & Impulse switch first

// ========== MIDI CC Mapping (channel 2) ==========
[
// remember to make the signal flow conventional
// what are other ways I can rhythmically distort this? Pulsar? FM?

	[\amp, 0, 0.0, 1.5], // keep
	// add tr08 mix control
	[\grainSize, 5, 0.01, 0.2], // yes, maybe add a switch for impulse or dust

	[\smearAmt, 1, 1, 40], // don't know
	[\randRate, 2, 0.5, 20], // don't know
	[\binScrambleAmt, 3, 0.0, 1.0], // don't know
	[\pvRouting, 4, 0, 4], // don't know
	[\delFeedback, 7, 0.0, 0.95], // don't know

	[\delTime, 6, 0.05, 1.0], // yes, but more


	[\verbMix, 8, 0.0, 1.0], // yes, but convolution and maybe switches for types
	[\lfoFreq, 9, 0.01, 5.0], // yes
	[\bitcrushAmt, 10, 0.0, 1.0],
	[\distAmt, 11, 0.5, 10.0], // yes, but varied forms
	// needs splay control

	[\ringFreq, 12, 50, 2000], // yes, but more
	[\freezeAmt, 13, 0.0, 1.0],
	[\transpose, 14, 0.25, 2.0], // not working
	[\filterCutoff, 15, 100, 15000] // yes, more filters, add type switch
	// needs to be a resonance control here
].do { |spec|
	var param, cc, min, max;
	#param, cc, min, max = spec;

	MIDIdef.cc(param.asSymbol, { |val, num, chan, src|
		if(chan == 2) {
			var mapped = val.linlin(0, 127, min, max);
			~pvSynth.set(param, mapped);
		}
	}, cc);
};
)




(
// it needs a control for mixing between the original and the granular, try adding the Dust & Impulse switch first

// ========== MIDI CC Mapping (channel 2) ==========
[
// remember to make the signal flow conventional
// what are other ways I can rhythmically distort this? Pulsar? FM?

	[\amp, 0, 0.0, 1.5], // keep
	// add tr08 mix control

	[\layer1_amp],
	[\layer1_index],
	[\layer2_amp],
	[\layer2_index],

	[\filt1_crf],
	[\filt2_res],
	[\filt1_crf],
	[\filt2_res],

	[\verb],
	[\comb],
	[\fold],
	[\splay],



].do { |spec|
	var param, cc, min, max;
	#param, cc, min, max = spec;

	MIDIdef.cc(param.asSymbol, { |val, num, chan, src|
		if(chan == 2) {
			var mapped = val.linlin(0, 127, min, max);
			~pvSynth.set(param, mapped);
		}
	}, cc);
};
)




