= Saw-Tooth Wave Oscillator

include::../../common.adoc[]

== Overview

image:saw.svg[alt="Saw-Tooth Wave", width=300, role=right]

The saw-tooth wave oscillator programmatically generates the waveform. The result is basically just the phase, centered around zero, producing an amplitude of ±1.0. The `basic_saw_osc` is not bandwidth limited, while `saw_osc` is, using a technique called "PolyBLEP" to reduce aliasing artifacts that can occur when generating the waveform with a sharp discontinuity as the signal transitions from -1.0 to 1.0.

PolyBLEP works by precalculating a correction function that subtracts the waveform's high-frequency components at discontinuities. This correction function is then applied to the generated waveform, effectively removing frequencies above the waveform's Nyquist frequency to avoid aliasing artifacts.

== Include

```c++
#include <q/synth/saw_osc.hpp>
```

== Declaration

```c++
struct basic_saw_osc
{
    constexpr float operator()(phase p) const;
    constexpr float operator()(phase_iterator i) const;
};

constexpr auto basic_saw = basic_saw_osc{};

struct saw_osc
{
    constexpr float operator()(phase p, phase dt) const;
    constexpr float operator()(phase_iterator i) const;
};

constexpr auto saw = saw_osc{};
```

== Expressions

`basic_saw_osc` is a model of `{basic_osc}` and implements all valid expressions of `{basic_osc}`. `saw_osc` is a model of `{bandlimited_osc}` and implements all valid expressions of `{bandlimited_osc}`.

`basic_saw_osc` and  `saw_osc` are stateless. The global instances `basic_saw` and `saw` can be used anywhere without needing to be placed in a class or struct. They are semantically equivalent to global functions.


