~klezmer = "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Acheinu_Kol_Beit_Israel.wav"

(
{
	var sig;
	sig = GrainBuf.ar(
		1,
		Impulse.ar(2),
		1,
		~klezmer,
		1,
		1.2,
		1,
		0,
		-1,
		512
	);

	sig = sig!2;
}.play;
)

(
{
	var sig;
	sig = GrainBuf.ar(
		1,
		Dust.ar(40),
		0.8,
		~klezmer,
		1,
		1.25,
		2,
		0,
		-1,
		512
	);

	sig = sig!2;
}.play;
)



~organ = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Cantor_Samuel_Malavsky_Zechor.wav");

(
{
	var sig;
	sig = TGrains2
})






~klezmer = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Acheinu_Kol_Beit_Israel.wav", channels:[0]);
~klezmer = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/Cantorial/Cantor_Samuel_Malavsky_Zechor.wav", channels:[0]);
~klezmer = Buffer.readChannel(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/granular/yiddish_chuasdel.wav", channels:[0]);


(
SynthDef(\granular, {
	arg freq = 410, amp = 4, pan = 0, gate = 1, baseFreq = 600, lpfFreq = 8000, rq = 0.3, drive = 1, pitchRatio = 1;
	var sig, env, trig, waveshapedSig, filteredSig, shiftedSig;

	trig = Impulse.kr(10, 0.5, 1.0, 0.0) + Dust.kr(1); // Regular grain trigger
	env = EnvGen.kr(Env.adsr(0, 0.2, 0.4, 1), gate, doneAction: 2);

	// Random panning for each grain
	pan = 0;

	// Granular synthesis without internal rate control (rate = 1)
	sig = GrainBuf.ar(
		1,
		trig,
		0.8,
		~klezmer,
		1,
		1.25,
		2,
		0,
		-1,
		512
	) * env;

	// Apply pitch shifting externally
	shiftedSig = PitchShift.ar(sig, 0.2, 580 / baseFreq); // Shifting the pitch after the grain is generated

	// Apply waveshaper: Tanh saturation (soft clipping)
	waveshapedSig = (shiftedSig * drive).tanh;

	// Apply a resonant low-pass filter
	filteredSig = SVF.ar(waveshapedSig, lpfFreq, rq);

	// Apply panning and amplitude
	filteredSig = Pan2.ar(filteredSig, pan) * amp;

	// Output the final signal
	Out.ar(0, filteredSig);
}).play;
)





(
SynthDef(\granular, {
	arg freq = 400, amp = 1, pan = 8, gate = 1, baseFreq = 600;
	var sig, env, trig, rate;

	trig = Impulse.kr(10); // Regular grain trigger
	env = EnvGen.kr(Env.adsr(0, 0.4, 0.8, 1), gate, doneAction: 2);

	// Rate scales playback relative to a known base frequency of the buffer
	rate = freq / baseFreq;

	// Random panning for each grain
	pan = LFNoise1.kr(8);

	sig = GrainBuf.ar(
		1,
		trig,
		0.8,
		~klezmer,
		rate,   // Control pitch via rate
		1.25,
		2,
		0,
		-1,
		512
	) * amp * env;

	sig = Pan2.ar(sig, pan);

	Out.ar(0, sig);
}).play;
)



(
// MIDI sequencing by MIDI file

var m1, m2, x1, x2;

// Read each MIDI file separately
m1 = SimpleMIDIFile.read("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-borrowed flesh/midi/fuzzy gameboy.mid");
m2 = SimpleMIDIFile.read("/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-borrowed flesh/midi/pad organ.mid");

// Play both MIDI sequences simultaneously
x1 = m1.p(\granular).play;
x2 = m2.p(\granular).play;

// Store them in a global variable so you can stop them later
~midiPlayers = [x1, x2];
)