Best way to change different parameters at different "rates" on a pattern?


#1

Hello !

Let’s take a simple SynthDef with a frequency for a note, and a frequency for the filter

(
SynthDef(\test, { |out=0, gate=1, freq=440, filterFreq=440|
	var sig;
	sig = VarSaw.ar(freq);
	sig = DFM1.ar(sig, filterFreq, 0.5);
	sig = EnvGen.kr(Env.asr, gate, doneAction: Done.freeSelf) * sig;
	sig = Out.ar(out, sig);
}).add;
)

What would be the best way to have a pattern where the note changes every beat, and the filter frequency changes two times per beat ?

I’ve tried to chain two Pbinds but it does not work, the frequency changes twice per beat.

(
a = Pbind(*[
	instrument: \test,
	filterFreq: Pseq([400, 1000], inf),
	dur: 0.5
]) <>
Pbind(*[
	instrument: \test,
	freq: Pwhite(400, 2000, inf),
	dur: 1
]);

a.play;
)

Any clue ?

Thanks !


#2

Check the repetition patterns. Maybe Pgate:

(
a = Pbind(*[
	instrument: \test,
	step: Pseq([false, true],inf),
	filterFreq: Pseq([400, 1000], inf),
	dur: 0.5,
	freq: Pgate(Pwhite(400, 2000), inf, \step),
]);

a.play;
)

#3

Thanks for your quick answer !
This is clever, but I’m wondering if there’s a more idiomatic solution because I can only use Pgate if the second duration is a multiple of the first duration (it would not work if filterFreq would change every 0.3 seconds and freq would change every second).
But thanks !


#4

As part of his miSCellaneous_lib, Daniel Mayer wrote a useful tutorial about Event patterns and LFOs.html which I think would be useful to read in the context of this question.


#5

Thanks @shiihs

I found a solution, using Event type “bus” :slight_smile:

I can have a pattern outputting values to a bus, at any rate, and then reuse these values in another pattern with bus.asMap

An example

(
SynthDef(\test, { |out=0, gate=1, freq=440, filterFreq=440|
	var sig;
	sig = VarSaw.ar(freq);
	sig = DFM1.ar(sig, filterFreq, 0.5);
	sig = EnvGen.kr(Env.asr, gate, doneAction: Done.freeSelf) * sig;
	sig = Out.ar(out, sig * -12.dbamp);
}).add;
)

~filterFreqBus = Bus.control(s, 1);

(
Pbind(*[
	type: \bus,
	out: ~filterFreqBus,
	array: Pseq([400, 1000], inf),
	dur: 0.4
]).play;
)

~filterFreqBus.plot(1); // seems to work

(
Pbind(*[
	instrument: \test,
	freq: Pwhite(400, 2000, inf),
	filterFreq: ~filterFreqBus.asMap,
	dur: 2,
	legato: 2
]).play;
)

BTW, I would have expected that using Pseg would work

(
Pbind(*[
	instrument: \test,
	freq: Pwhite(400, 2000, inf),
	filterFreq: Pseg(Pseq([400, 1000], inf), Pseq([0.4, 0.4], inf), \step),
	dur: 2,
	legato: 2
]).play;
)

but unfortunately, it would not (I guess this is because the dur at the pbind level is bigger than the duration inside the Pseg ?)


#6

(I guess this is because the dur at the pbind level is bigger than the duration inside the Pseg ?)

Actually you can easily verify this to be the case by adding some calls to trace and watching the post window.

(
Pbind(*[
	instrument: \test,
	freq: Pwhite(400, 2000, inf),
	filterFreq: Pseg(Pseq([400, 1000], inf), Pseq([0.4, 0.4], inf), \step).trace,
    dur: Pseq([2],inf).trace,
	legato: 2
]).play;
)