2011
08.05

In part 6, we c0nstructed a simple oscillator by utilizing a monotonically growing ramp as the phase input to a trigonometric function. In practice, this is not ideal as the phase accuracy will deteriorate numerically as the ramp increases.

Periodic ramp

Since the trigonometric function is periodic, we could substitute a periodic ramp, or a phasor. This version maintains full numerical precision, no matter how long the oscillator keeps playing.

periodic-ramp(increment)
{
    ramp = z-1('0 wrap + Audio:Clock(increment))
    wrap = ramp - Truncate(ramp)
    periodic-ramp = wrap
}

sine-osc(freq)
{
    sine-osc = Crt:sin(periodic-ramp(freq) * 2 * Pi)
}

‘Truncate’ drops the fractional part of any number, with the resulting effect that ‘periodic-ramp’ is wrapped to a range between 0 and 1.

Geometric waveforms

Naive geometric oscillators can be constructed directly from the periodic ramp. These are not antialiased, so they don’t sound very good, but present an opportunity to study periodic ramps and might be useful as low frequency oscillators.

saw-osc(freq)
{
    saw-osc = 2 * periodic-ramp(freq) - 1
} 

tri-osc(freq)
{
    tri-osc = 2 * Abs(saw-osc(freq)) - 1
}

square-osc(freq)
{
    square-osc = (2 & (saw-osc(freq) > 0)) - 1
}

All these examples employ the same basic principle. Triangular waveform is derived from a sawtooth wave by absolute value, while a square is implemented by using binary logic. The comparison operator will produce either ‘TRUE’ or 0, depending on the values. Applying a bitwise and ‘&’ with 2 to this value will return 2 in the case of TRUE or 0. This is then centered by substracting 1 to create a simple square wave oscillator.

In part 8, we will learn to control audio synthesis with an OSC signal.

 

No Comment.

Add Your Comment


7 − = three