Changed Ugen and Pitch.kr

Hi everyone !

I have a basic question but I can’t find the answer…
I try to code a trigger wich react when the values of the Pitch Ugen change.

I am surprise that this synthdef is not working, the Changed Ugen output is always zero and yet react strangely…

Any help is appreciated, thanks a lot !

(
SynthDef(\harmo, {
	var pitchtrig, pitch, sig;
	pitch = Pitch.kr(SoundIn.ar(0, 1), minFreq:30 );
	pitchtrig = Changed.kr(pitch[0]);
	pitchtrig.poll;
	sig = SinOsc.ar(pitch);
	sig = Pan2.ar(sig, 0, 0.2);
	Out.ar(0, sig);
}).add;
)

One possible issue here is that poll, by default, samples its input signal 10 times per second (every 100 ms) and prints that. If it’s nonzero between polling cycles, but 0 when being polled, then you wouldn’t see the nonzero values.

You could try polling the peak value instead?

But more to the point: Pitch.kr should be changing pretty much all the time. Pitch detection is likely to hover around the true pitch but fluctuate. So it is surprising that it’s reporting 0 change.

What type of sound material is coming in via SoundIn? (Is perhaps the mic signal not actually reaching SC? E.g. on my laptop, I can use a headset mic connected to the built in jack but I’ve had no luck with the mic built into the laptop screen.)

hjh

Hey jamshark,

Thanks a lot for your answer.

The reason I don’t want to use the peak value is because I want to trigger things depending of the ambitus of glissandi.

I think you are right and this is a problem of polling cycles.

The strange behavior i noticed was because of the constant fluctuations of the Pitch Ugen. To compensate those fluctuations I tried to round the values of Pitch and find a good spot between gain, and peakthreshold. It worked better but it’s really unstable when the pitch is between two rounded values…

I was using a microphone with my voice and I assume it will work better with more stable instruments.

If someone have a better idea than round the values I’ll take it ! I used this formula to receive a trigger for each semitone:
Pitch.kr(in).cpsmidi.round(1)

Thank you all !

To go back to my comment: “You could try polling the peak value instead.”

This doesn’t say “use the peak value for everything.” I only suggested to use the peak value for polling, to avoid the problem of instantaneous polling overlooking nonzero data between triggers. You could still trigger using whatever data you want. (That’s actually what I meant.)

Also try polling HPZ1. Changed is based on HPZ1 and flattens it to a Boolean 1 or 0 IIRC. HPZ1 gives you the amount of change directly (half the difference between successive samples).

This is a constant problem of all kinds of thresholding analysis: extraneous events when the value is hovering around the edge.

If you’re deriving triggers from the rounded values, a Schmitt trigger (misspelled in SC as Schmidt) doesn’t reset instantaneously and can eliminate some of the extra triggers. For transitions between semitones, perhaps the rule could be related to the absolute difference between the raw pitch and the fixed semitone. A Schmitt trigger fires when the value > upper threshold, but here you want to fire when it’s “close enough” to the semitone, which is the opposite. The maximum error in semitones would be 0.5, so maybe subtract the absdif from that. Then you’d have a value that rises as you get closer to a fixed semitone, and will be very small when the measured pitch is in the middle… and then you would tune the trigger for how close is close enough (which I can’t decide for you).

var midi = pitch[0].cpsmidi;
var rounded = midi.round;
var closeness = 0.5 - (midi absdif: rounded);

I’m sure this isn’t a complete solution (it won’t detect a sudden jump of a large interval, if this “closeness” value is similar for both pitches) but it could be a useful supplement to other logic.

hjh