Controlling Pattern params via DetectSilence


#1

Hi SCers,

I’m trying to write a pattern for a PlayBuf-based synth that switches buffers when the buffer being played reaches a silent moment.

I’m stuck on how to get the 1/0 from the DetectSilence into a form that my Pbindef can use:

(
~dsbus = Bus.audio(s, 2);
~silentbus = Bus.control(s, 1);
~dssynth = SynthDef(\silent,
{var ds;
ds = DetectSilence.kr(A2K.kr(In.ar(~dsbus)), 0.001);
Out.kr(~silentbus, ds)
}).play;

~silent = Task({inf.do({
~silentbus.getSynchronous;
0.1.wait;
}).play;
)

And, the relevant bits of the Pbindef, fwiw:

Pbindef(\bp2, \bufnum, Pgate(Pseq([153, 19], inf), inf, Pfunc{~silent == 1} ), \out, [0, ~dsbus]).play;

Thanks in advance!


#2

You need the assignment

~silent = ~silentbus.getSynchronous;

in the Task. However, if there’s no other reason to employ a Task, you can do that in the Pbind/Pbindef

Pfunc { ~silentbus.getSynchronous }


#3

Thank you, Daniel. I had actually tried your suggestion as well, but getting confirmation from you helps me to understand that there is some other issue at play here. When I run the code below, the Pseq inside the Pgate doesn’t advance even when the DetectSilence is sending 1. I tried tracing the Pfunc to see what’s going on, but apparently .trace doesn’t work on Pfunc(?).
I also tried using Pfunc{~silentbus.getSynchronous ==1} just to see whether the gate needed to be explicitly converted to a Boolean inside the function, but that didn’t make any difference.

Polling the DetectSilence and .trace-ing the Pgate yields the following in the post window:

UGen(DetectSilence): 0
152
152
152
152
152
152
152
UGen(DetectSilence): 1//\bufnum should change to 19 here, but remains 152
152
152
152
152
152
152
152
152

~dsbus = Bus.audio(s, 2);
~silentbus = Bus.control(s, 1);
~dssynth = SynthDef(\silent,
{var ds;
ds = DetectSilence.kr(A2K.kr(In.ar(~dsbus)), 0.01).poll;
Out.kr(~silentbus, ds);
}).play;

Pbindef(\bp2, \bufnum, Pgate(Pseq([152, 19], inf), inf, Pfunc{~silentbus.getSynchronous}).trace, \out, [0, ~dsbus]).play;


#4

Yes, I didn’t see it at first, Pgate’s third argument should be a key, the referred Pattern should give Booleans.

~silentbus = 1

(
Pbindef(\t,
	\busValue, Pfunc{ ~silentbus == 1 },
	\x, Pgate(
		Pseq([152, 19], inf), 
		inf, 
		\busValue
	).trace, 
	\out, 0
).play;
)

~silentbus = 0

BTW if you post code please enclose it with three backticks, this causes indentation and makes it better readable.


#5

Thanks very much, Daniel, that did the trick. And thanks for the tip regarding the three backticks.