Initial phase in Saw

Why does the LFSaw has a initial phase parameter, but Saw doesn’t?

Saw is bandlimited, but LFSaw is not. Their outputs are calculated differently. You could fake phase offset with one of the Delay Ugens

whats the relation btwn non-band-limitation and phase?

There isn’t one, necessarily. It’s just the way that the UGen is calculated. The saw UGen requires an initial phase value of 0. LFSaw is calculated in a different way. Saw needs an initial phase of 0 for its calculation function. LFSaw doesn’t. It takes the initial phase value from an input. You can look at supercollider/server/plugins at develop · supercollider/supercollider · GitHub if you’re curious about how they work.

They’re in the LFUGens and OscUGens C++ files.

phase and frequency are relatives. for an oscillator to be band limited, it has to make sure to stay below nyquist frequency no matter what. i guess if the phase argument would be available this probably wont be possible when phase modulation comes into play. but i think some other people here can give way more insight.

1 Like

Two things:

The reason to use a phase offset is because you want the oscillator to start at a value other than 0.

A band-limited saw can’t really start at any value other than 0, because if it did, it would start with a transient with infinite frequency, and that wouldn’t be bandlimited. Instead, what you get is something like this:

So, in other words, it isn’t capable of having a true phase offset, so the option just isn’t available in that implementation.

Sam

1 Like

Great! Could you elaborate a bit on what a transient with infinite freq is?

So it is called non-band-limited because it can start at any phase other than 0, causing transients with infinite frequencies?

There are some inaccuracies in this thread. The lack of phase argument is entirely due to an oversight in Saw. It is possible to implement an antialiased sawtooth with arbitrary initial phase control, it was simply forgotten for Saw. This is quite annoying for detuned pads because you can hear the phase relationships pretty easily. SawDPW fixes this.

1 Like

Saw, IIRC, uses the BLIT (Band Limited Impulse Train) technique. I’m a bit out of my depth here (I never delved deeply into DSP loops) but Stilson and (the Julius O.) Smith say that the band limited impulses can be generated by a discrete summation formula, where the main input is time (which could also be a phase angle). In that case, indeed, there’s no reason why “time” could not be offset by an initial phase.

The rest of BLIT sawtooth is to remove DC offset from the impulse train, and then integrate. This might produce DC offset in the end result, depending on that initial phase offset. E.g.:

// SC has a bandlimited impulse UGen: sample it
{ Blip.ar(SampleRate.ir * 0.01, numharm: 45) }.getToFloatArray(0.01, action: { |data| d = data });

d.plot;  // yep, bandlimited pulses

d = d - d.mean;  // remove DC

// yep, bandlimited saw
// but showing a large DC offset
// and a gradual slide down
// probably bc the original sample wasn't *exactly* an integer number of cycles
d.integrate.plot;

// DC offset is different depending on starting phase
[d.integrate, d.rotate(d.size div: 4).integrate].lace(d.size * 2).plot(numChannels: 2, minval: -1, maxval: 1);

One possible reason, then, not to include that initial phase is to simplify the control over the DC offset that results from integrating.

That has nothing to do with it.

Watch this video: Xiph.Org Video Presentations: Digital Show & Tell – really. It will help you understand the fundamental concepts, by showing them in action.

hjh

2 Likes