Tracking the wrap-around (1 → 0) of a Phasor.ar

Hi all,

I’m trying to find a reliable way to detect when a Phasor.ar wraps from 1 back to 0. Essentially, I want to track the moment when it resets after reaching its end value.
Ideally, I’d get a 1 or a trigger-like signal exactly at that wrap-around moment, and 0 otherwise.
With this trigger i want to set a variable to a defined value.
What would be the best approach here?

Greetings,
PvN

hey, to derive a trigger from a linear ramp between 0 and 1 you can calculate the absolute Delta (current sample - last sample).abs and compare that with a threshold of 0.5. This will work for upward and downward ramps. But with this setup you wont get an initial trigger and when you manually reset your phasor in the first half of the Duty cycle you also wouldnt get a trigger, because the Delta isnt big enough. A more reliable trigger detection is based on calculating the Delta and the Sum and get the proportional Change, If the Change was big you get a trigger. Check out the rampToTrig function in my Collection of functions for sub-sample accurate Granulation here: A collection of functions for sub-sample accurate granulation

For my presentation at NOTAM I have prepared a Guide for phasor based scheduling, you can find that here: NOTAM Meetups: Spring 2025 - #9 by dietcv

2 Likes

If it’s an upward ramp, check for a negative delta: HPZ1.ar(phasor) < 0.

hjh

1 Like

Yes, Then you would probably want to add Impulse.ar(0) for an initial trigger.

Thanks all!

Looking at your SC Code is helping me getting used to this syntax and how things are done in SC. I’m missing ternary operator for this :smiling_face_with_tear:

If you are just interested in when the phase is a certain value you can also directly query it and derive a trigger from it:

(
(
{
	var phaseDur = 1 * s.sampleRate;
	var phase = Phasor.ar(Impulse.ar(0), 1, 0, phaseDur);
	var trig = phase |==| 0;
	// var trig = phase |==| (phaseDur - 1);
	var env = Env.perc().ar(2, trig);
	var sig = LFSaw.ar(110) * 0.1;
	sig = sig * env
}.play
)

Now, if you need to derive intersample triggers, that’s where it get’s more complex and this is the stuff which @dietcv has been working on mainly (to my understanding).

hey, to derive a trigger from a ramp i would go for:

1.) delta < 0 for upward ramps (no initial trigger)
2.) delta > 0.5 for upward and downward ramps (no initial trigger and no trigger on phase reset during the first half of the duty cycle
3.) delta / sum (initial trigger with 1-sample delay and trigger on phase reset during the first half of the duty cycle)

You can calculate these manually by using Delay1 or use HPZ1. phase |==| 0 doesnt give you a reliable trigger detection.

The triggers are still happening at sample boundaries, but you calculate the sub-sample offset from the scheduling phasor to add that to the derived phase on phase reset (thats like: what current value would my derived ramp have, if it would have been reset at the ideal phasors wrap in the middle of the current sample, instead of a reset at sample boundaries). Thats similiar but different from using a continuous signal and trying to derive an inter-sample trigger for a phase reset of a scheduling phase signal. We are not changing the location of the trigger itself here, but add an offset to the phase we are interested in.