X.poll differs from SendTrig x value

Hello,

I was wondering how come that average.poll returns slightly different values than the SendTrig in the SendFreqAverage def . And how can I possibly retrieve the last value that comes out of the average, if that is not the one that I am currently getting?

Here is the def in question:

(
SynthDef(\SendFreqAverage,{
	arg buffer;
	var  amp, trig, freq, hasFreq, average, player, pass;
	player = PlayBuf.ar(2,buffer,1,1,5,0,2);
	# freq, hasFreq = Pitch.kr(player, initFreq: 0, minFreq: 20.0, maxFreq: 20000.0, execFreq: 100.0, maxBinsPerOctave: 16, median: 1, ampThreshold: 0.01, peakThreshold: 0.5, downSample: 1, clar: 0);
	pass = freq[0] * freq[1];
	Out.ar(0,player);
	average = AverageOutput.kr(pass , trig: 0.0, mul: 1.0, add: 0.0);
	average.poll;
	DetectSilence.ar(player,0.1, 1,2);
	SendTrig.kr(Changed.kr(average),1, average);
}).add)

Here is the rest, if perhaps relevant:

//defs
(
(
SynthDef(\RecordBuf, { arg out = 0, bufnum = 0;
    var signal;
	signal = SoundIn.ar()!2;
	RecordBuf.ar(signal, bufnum,recLevel: 1,preLevel: 0, run: DetectSilence.ar(signal,0.1, 0.5,doneAction:  2).range(1,0),loop: 0);
}).add;
);

(
SynthDef(\SendFreqAverage,{
	arg buffer;
	var  amp, trig, freq, hasFreq, average, player, pass;
	player = PlayBuf.ar(2,buffer,1,1,5,0,2);
	# freq, hasFreq = Pitch.kr(player, initFreq: 0, minFreq: 20.0, maxFreq: 20000.0, execFreq: 100.0, maxBinsPerOctave: 16, median: 1, ampThreshold: 0.01, peakThreshold: 0.5, downSample: 1, clar: 0);
	pass = freq[0] * freq[1];
	Out.ar(0,player);
	average = AverageOutput.kr(pass , trig: 0.0, mul: 1.0, add: 0.0);
	average.poll;
	DetectSilence.ar(player,0.1, 1,2);
	SendTrig.kr(Changed.kr(average),1, average);
}).add);

OSCdef(\test,{ arg msg;
	var trig;
	msg.postln;
	//trig = if(msg.at(3) > 0, {trig = 1},{trig = 0});
	//~average = trig;
	//~trigr1.postln;
},'/tr', s.addr);
)

OSCdef(\test).enable;

OSCdef(\test).clear;

//allocate
~b1 = Buffer.alloc(s, s.sampleRate * 10, 2);

//record
Synth(\RecordBuf, [\bufnum, ~b1])

//play & get average
Synth(\SendFreqAverage, [\buffer, ~b1])

Thank you for any thoughts on this !

Changed as a trigger might not be doing what you thought. By definition, a trigger is “signal was <= 0, is now > 0.” For Changed, that translates to “signal was not changing, but has just started changing” – this is the only way to get a trigger from Changed. (If the signal is continuously changing, then Changed is continuously > 0, which does not mean “continuously triggering” – it means one trigger at the start of that span.)

Pitch.kr output tends to fluctuate, so I think what’s happening is that it’s always changing, hence never triggering.

Not sure what you mean by this… the last value for the Synth instance, or…? Last value for which span of time?

Are you sure about this? Left channel frequency * right channel frequency?

hjh

Thank you for your input yet again. I really appreciate it !

The Changed actually does output something it just does not completely match the poll values
average.poll:

UGen(AverageOutput): 0
UGen(AverageOutput): 0
UGen(AverageOutput): 2606.21
UGen(AverageOutput): 3444.53
UGen(AverageOutput): 3444.53
UGen(AverageOutput): 3458.28
UGen(AverageOutput): 3462.78
UGen(AverageOutput): 3671.23
UGen(AverageOutput): 3671.23
UGen(AverageOutput): 3683.41
UGen(AverageOutput): 3683.41
UGen(AverageOutput): 3698.57
UGen(AverageOutput): 3706.39
UGen(AverageOutput): 3706.39
UGen(AverageOutput): 3715.55
UGen(AverageOutput): 3725.16
UGen(AverageOutput): 3725.98
UGen(AverageOutput): 3729.43
UGen(AverageOutput): 3729.43
UGen(AverageOutput): 3729.47
UGen(AverageOutput): 3729.68
UGen(AverageOutput): 3729.68
UGen(AverageOutput): 3729.68
UGen(AverageOutput): 3729.68
UGen(AverageOutput): 3729.68

OSCdef messages:

0.0
33.697986602783
319.82040405273
3444.9294433594
3460.1313476563
3461.1232910156
3484.3449707031
3672.5532226563
3684.3825683594
3698.4597167969
3699.1940917969
3701.2150878906
3706.6557617188
3710.2219238281
3725.5703125
3728.1645507813
3729.0515136719
3729.4516601563

Just now I have realized that there seems to be 6 more of the OSC messages than there are average.poll values for this particular recorded sound. Perhaps the rate of the .poll is not as fast ? And from the OSC I am getting the value that I want.

My ultimate goal in this is to get the average frequency of the whole recorded sound before DetectSilence free’s the synth. So if I understand what I did correctly then the very last value coming out of the average variable should be the total average. For the synth instance, yes !

It is kind of strange the freq[0] is giving what seems like to be the frequency and freq[1] would be the 0 or 1. Same goes for the hasFreq[0],hasFreq[1]. In the documentation it says that the freq should give the frequency and the hasFreq would be the 1 if there is a new frequency and 0 if there is none. So in the end I am basically doing pass = freq * hasFreq. Maybe I need to do something about the # freq, hasFreq = Pitch.kr, however I just followed the examples. And this seemed to work so I just went with it.

The poll trigger is totally different from Changed, so you couldn’t expect them to match.

If you want them to match, use the same trigger for both.

Then Changed isn’t exactly that meaning.

Maybe this?

(
SynthDef(\SendFreqAverage,{
	arg buffer;
	var  amp, trig, freq, hasFreq, average, player, pass;
	var done;
	// if you are stopping based on DetectSilence below
	// then it is redundant to set doneAction here
	// that's quite important because stopping the synth here
	// means that DetectSilence never fires
	player = PlayBuf.ar(2, buffer, 1, 1, 5, 0, 0);
	// adding '.sum' here because you don't need two pitch detectors
	# freq, hasFreq = Pitch.kr(player.sum, initFreq: 0, minFreq: 20.0, maxFreq: 20000.0, execFreq: 100.0, maxBinsPerOctave: 16, median: 1, ampThreshold: 0.01, peakThreshold: 0.5, downSample: 1, clar: 0);
	pass = freq * hasFreq;
	Out.ar(0, player);
	average = AverageOutput.kr(pass, trig: 0.0, mul: 1.0, add: 0.0);
	done = DetectSilence.ar(player, 0.1, 1, 2);
	average = K2A.ar(average);
	SendTrig.ar(done, 1, average);
	average.poll(done);
}).add;

OSCdef(\test,{ arg msg;
	msg.postln;
}, '/tr', s.addr);
);

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

x = Synth(\SendFreqAverage, [buffer: b]);

// same trigger, poll + osc match
UGen(K2A): 642.722
[ /tr, 1004, 1, 642.72247314453 ]

hjh

Awesome, I see there were many things I have overlooked ! Also the freq * hasFreq is not making any sense because then I am feeding extra zeroes into the average.

Thank you for walking me trough this !

Now I have just noticed that the AverageOutput class does not seem to be working, the number only rises… but that is for another thread

Hm, I don’t get that result.

(
a = {
	var sig = Line.kr(100, 0, 10, doneAction: 2),
	avg = AverageOutput.kr(sig);
	avg.poll(2);
	Silent.ar(1)
}.play;
)

UGen(AverageOutput): 99.9855
UGen(AverageOutput): 97.4823
UGen(AverageOutput): 94.9792
UGen(AverageOutput): 92.4832
... etc

hjh

But, if hasFreq == 0 and you’re feeding frequencies into the average anyway, then it’s garbage data.

Since AverageOutput doesn’t give you control over the sum and count, you could calculate the average yourself. Integrator is a running sum. For the count, you could integrate 1.0 when hasFreq > 0 and 0.0 otherwise (so, when hasFreq == 0, neither the sum nor the count are increasing, and the average should effectively pause until pitch is detected again).

(
a = {
	var sig = SoundIn.ar(0),
	freq, hasFreq, sum, count, mean;
	#freq, hasFreq = Pitch.kr(sig);
	hasFreq = hasFreq > 0;
	sum = Integrator.kr(freq * hasFreq);
	// adds 1 per control block, when freq is detected
	count = Integrator.kr(hasFreq);
	mean = sum / max(count, 1);  // prevent /0
	mean.poll(2);
	Silent.ar(1)
}.play;
)

hjh

2 Likes

Sorry for the late reply !

Yes, that is exactly what I meant.

Perfect ! I could not figure it myself so I was about to just use the freq values, but this resolves everything then. Even this “bug” with only rising values

I get these values using your example code

UGen(AverageOutput): 99.9855
UGen(AverageOutput): 637.489
UGen(AverageOutput): 701.58
UGen(AverageOutput): 736.966
UGen(AverageOutput): 760.715
... etc

I have tried to redownload, reinstall everything and using older versions. I have no idea what might be the cause. It could be that I am doing something wrong with the plugins installation (i had just put the plugins folder into the sc extensions folder) Good, that I do not have to worry about it anymore though !!!

Thank you!

Unfortunately it looks like the latest release does not include a later code fix to AverageOutput.

I’ve filed an issue requesting a new release.

hjh

1 Like