Phasor gotcha

[email protected] Tue, 14 Jan 2020 19:50:24 -0500
Newsgroups gmane.comp.audio.supercollider.devel
Message-ID <CAPjq8bTG=BCORKunF6gYPgNrtO3WFpAtzJkV-wap4Ostcdh44w@mail.gmail.com>
Hey dev list,

I just spent a good bit trying to track down the source of some strange
behavior, turns out it was this gotcha with Phasor....

( // L and R are equivalent, as they should be
{
  var freq = 100;
  var phase = Phasor.ar(0, freq / SampleRate.ir, 0, 1) * 2pi;
  [SinOsc.ar(0, phase), SinOsc.ar(freq)] * 0.16;
}.play
)

( // suddenly weird distortion in L
{
  var mod = SinOsc.ar(300).exprange(0.5, 2);
  var freq = 100 * mod;
  var phase = Phasor.ar(0, freq / SampleRate.ir, 0, 1) * 2pi;
  [SinOsc.ar(0, phase), SinOsc.ar(freq)] * 0.16;
}.play
)

The culprit is how Phasor is constructed:
(starting line 1533 of server/plugins/TriggerUGens.cpp)
void Phasor_Ctor(Phasor* unit) {
    if (unit->mCalcRate == calc_FullRate) {
        if (INRATE(0) == calc_FullRate) {
            if (INRATE(1) == calc_FullRate) {
                SETCALC(Phasor_next_aa);
            } else {
                SETCALC(Phasor_next_ak);
            }
        } else {
            SETCALC(Phasor_next_kk);
        }
    } else {
        SETCALC(Phasor_next_ak);
    }

    unit->m_previn = ZIN0(0);
    ZOUT0(0) = unit->mLevel = ZIN0(2);
}

Which means Phasor doesn't consider the possibility that rate input might
be audio rate if trig input is control rate. So, obviously the immediate
solution to my problem is:

(
{
  var mod = SinOsc.ar(300).exprange(0.5, 2);
  var freq = 100 * mod;
  var phase = Phasor.ar(DC.ar(0), freq / SampleRate.ir, 0, 1) * 2pi;
  [SinOsc.ar(0, phase), SinOsc.ar(freq)] * 0.16;
}.play
)

But, I feel like either this should be documented in the helpfile, or (more
to my liking) adding a Phasor_next_ka calc function to allow for control
rate trigs with audio rate rates. Is there a reason not to do the latter? I
can't imagine anyone is depending on the current behavior....

Also, am I reading this correctly to see that if you use Phasor.kr you are
automatically getting Phasor_next_ak (audio rate trigger, control rate
rate) as your calc function?

If these things seem like real bugs I'd be happy to work on fixing them...

Best,
E