Sequence PV_BinDelay

Hey, i was wondering i someone could help me adjusting the Code of the PV_BinDelay, so the parameters delay and feedback could be sequenced in a Pbind vs. using the GUI.
Im not sure if this is even possible and how the buffer data is handled in this case. thanks alot :slight_smile:

(
s.doWhenBooted({
	var size, fftSize, awin, delaySilder, fbSlider, maxdel, synth, cond;
	var setup, onReadyFunc, fftBuffer, delTimeBuffer, fbAmtBuffer, createGUI;

	size = 128;
	fftSize = size * 2;
	maxdel = 0.5;
	cond = Condition.new;

	SynthDef(\spectralDelay, {
		arg pan=0, amp=0.5, in=0, inMix=0, out=0, freq=150,
		fftBuf=0, delayBuf=0, fbBuf=0, maxdel=0.5;

		var sig, input, chain;
		var env = EnvGen.kr(Env.perc(0.01,1), doneAction:2);
		input = Saw.ar(freq) * env * amp;
		//input = In.ar(in, 2) * inMix;

		chain = FFT(fftBuf, input, 0.25);
		chain = PV_BinDelay(chain, maxdel, delayBuf, fbBuf, 0.25);
		sig = IFFT(chain).dup;
		Out.ar(out, sig * amp);
	}).add;

	/* Functions that allocate buffers and call onReadyFunc when done */
	setup = {
		Routine.run({
			"Allocating FFT buffer".postln;
			fftBuffer = Buffer.alloc(s, fftSize, 1);
			"Allocating DelTime buffer".postln;
			delTimeBuffer = Buffer.alloc(s, size, 1);
			"Allocating FB buffer".postln;
			fbAmtBuffer = Buffer.alloc(s, size, 1);
			s.sync(cond);
			onReadyFunc.value()
		});
	};

	createGUI = {

		awin = Window("test", Rect(200 , 450, 10 + (size * 1), 10 + (size * 2)));
		awin.view.decorator = FlowLayout(awin.view.bounds);

		delaySilder = MultiSliderView(awin, Rect(0, 0, size * 1, size * 1));
		delaySilder.action = {arg xb;
			("Deltime index: " ++ xb.index ++" value: " ++ (xb.currentvalue * maxdel)).postln;
			delTimeBuffer.set(xb.index, xb.currentvalue * maxdel)
		};

		fbSlider = MultiSliderView(awin, Rect(0, 0, size * 1, size * 1));
		fbSlider.action = {arg xb;
			("FB index: " ++ xb.index ++" value: " ++ xb.currentvalue).postln;
			fbAmtBuffer.set(xb.index, xb.currentvalue)
		};

		[delaySilder, fbSlider].do({
			arg thisSliderView;
			var initDataArray;
			initDataArray = Array.fill(size, {0.0});
			thisSliderView.value_(initDataArray);
			thisSliderView.xOffset_(5);
			thisSliderView.thumbSize_(12.0);

			// value axis size of each blip in pixels
			thisSliderView.valueThumbSize_(15.0);
			// index axis size of each blip in pixels
			thisSliderView.indexThumbSize_( thisSliderView.bounds.width / initDataArray.size );
			thisSliderView.gap = 0;
		});

		awin.front;

		awin.onClose_({
			synth.free;
			fftBuffer.free;
			fbAmtBuffer.free;
			delTimeBuffer.free;
		})
	};

	onReadyFunc = {
		createGUI.defer();

		Pbind(
			\instrument, \spectralDelay,
			//\in, ~bus[\spectral],
			\inMix, 1,

			\fftBuf, fftBuffer.bufnum,
			\delayBuf, delTimeBuffer.bufnum,
			\fbBuf, fbAmtBuffer.bufnum,

			\amp, 0.5,
			\pan, 0,
			\out, 0,
		).play;
	};

	setup.value();
})
)

Hi,
you can use .setn messages to the buffer in a Pfunc{}.

(
a=Buffer.alloc(s,1024,1);
b=Buffer.alloc(s,512,1);//delTime
c=Buffer.alloc(s,512,1);//feed
);

(
b.setn(0, Array.fill(512, { rrand(0,1.0) }));
c.setn(0, Array.fill(512, { rrand(0,1.0) }));
)

Pfunc{
b.setn(0, Array.fill(512, { rrand(0,1.0) }));
c.setn(0, Array.fill(512, { rrand(0,1.0) }));
}

1 Like

It’s a little bit hard coded, but will help you figure out what is happening without the need to figure out the GUI part:

~voice = Buffer.read(s,Platform.resourceDir +/+ "sounds/a11wlk01.wav");


(
~size = 256;
~fftSize = ~size * 2;
~maxdel = 1.0;

~fftBuffer = Buffer.alloc(s, ~fftSize, 1);
~delTimeBuffer = Buffer.alloc(s, ~size, 1);
~fbAmtBuffer = Buffer.alloc(s, ~size, 1);

~liveInputMix = 0.0; // change to 1 to hear sound from live input, otherwise, an Impulse

)



SynthDef(\helpBinDelay, { arg inbus=0, inMix = 0.0, out=0, fftBuf=0, delayBuf=0, fbBuf=0;
	var in, chain;
	in = (PlayBuf.ar(1,~voice, loop:1,doneAction: 0) * (1.0 - inMix)) + (In.ar(inbus, 1) * inMix);
	//chain = FFT(fftBuf, in, 0.25);
	chain = FFT(LocalBuf(~fftSize), in, 0.25);
	chain = PV_BinDelay(chain, ~maxdel, delayBuf, fbBuf, 0.25);
	Out.ar(out,
		[IFFT(chain), in] * -12.dbamp// inverse FFT
	);
}).add;



(
p = Pmono(\helpBinDelay, \inbus, s.options.numOutputBusChannels,
	\inMix, ~liveInputMix,
	\out, 0,
	\fftBuf, ~fftBuffer.bufnum,
	\delayBuf, ~delTimeBuffer.bufnum,
	\fbBuf, ~fbAmtBuffer.bufnum,
	\dur, 2,
	\bufferFilling, Pfunc{
		~delTimeBuffer.setn(0, {exprand(0.1, 0.2)}!256);
		~fbAmtBuffer.setn(0, {exprand(0.1, 0.9)}!256);
	}
).play;
)
p.stop;

@jamshark70 Is it possible to use .setn inside a Pbind to fill a buffer using List Patterns ?

For instance, at each \dur, 1second setn a Buffer with size 256 using Pseries ?
time 0 → [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6,…]

time 1 → [ 0.1, 0.3, 0.5, 0.7, 0.9, 1.1, …]

time 2 → [ 0.1, 0.5, 0.9, 1.3, 1.7, 2.1, …]

I would just use Pfunc for this.

hjh

1 Like

thanks alot :slight_smile:

this works perfect.

i was using it on a DynKlank instrument and was wondering if instead of ~delTimeBuffer.setn(0, {exprand(0.1, 0.2)}!256); i could write “interesting” functions to the buffers maybe derived from physical modelling if that makes any sense. any ideas?

1 Like