Oscillators

Overview

Keith Emerson Modular MoogSynthesizers are one of the most engaging parts of any DSP library, as they involve the actual creation of sounds. What makes synthesizers so engaging is the level of control they offer over sound creation. A synthesizer allows a user to shape and mold a sound by adjusting parameters such as waveform shape, frequency, amplitude, and filter settings. This level of control enables users to create expressive and unique sounds that can be used in a variety of contexts, ranging from music production to sound design for film and video games.

The advancements in DSP technology have made synthesizers even more powerful and flexible. Users can now create sounds that were previously impossible to achieve with traditional analog synthesizers. The Q DSP library provides some common synthesisers such as sine-wave, square, pulse, triangle and saw-tooth, as well as various generators for sculpting the sound envelopes with controls for attack, decay, hold sustain and release. These are designed as moduler building blocks that are combined to form more complex synthesisers.

Oscillator

Oscillator is a concept representation of an oscillator that generates periodic waveforms.

Oscillators are function objects that take in a phase_iterator: an iterator over the phase. The output is typically a floating point value.

Declaration

namespace cycfi::q::concepts
{
   template <typename T>
   concept Oscillator =
      std::copy_constructible<T> &&
      std::assignable_from<T&, T> &&
      std::default_initializable<T> &&
      requires(T o, T a, T b, phase_iterator pi)
   {
      o(pi);            // Generate a periodic waveform given `{phase_iterator}`, `pi`.
   };
}

Expressions

Notation

o, a, b

Instances of types that conform to Oscillator.

pi

Object of type phase_iterator.

Constructors and Assignment

Expression Semantics

Oscillator()

Default construct an Oscillator.

Oscillator(o)

Copy construct from o.

a = b

Assign b to a.

C++ brace initialization may also be used.

Function Call

Expression Semantics Return Type

o(pi)

Generate a periodic waveform given phase_iterator, pi.

decltype(o(pi))

BasicOscillator

BasicOscillator is a refinement of the Oscillator concept. BasicOscillator is not bandwidth limited. This is is suitable in certain cases. Moreover, some oscillators are inherently bandwidth limited.

Declaration

namespace cycfi::q::concepts
{
   template <typename T>
   concept BasicOscillator =
      Oscillator<T> &&
      requires(T o, phase ph)
   {
      o(ph);            // Generate a periodic waveform given `{phase}`, `pi`.
   };
}

Expressions

In addition to valid expressions for Oscillator, BasicOscillator allows these expressions.

Notation

o

Instance of a type that conforms to BasicOscillator.

ph

Object of type phase.

Function Call

Expression Semantics Return Type

o(ph)

Generate a periodic waveform given phase, ph.

decltype(o(ph))

BandwidthLimitedOscillator

Waveforms with hard discontinuities such as sawtooth and square waves can generate harmonics that extend beyond the Nyquist frequency range or half the sampling rate. Oscillators may be bandwidth limited to ensure that the harmonics generated fall within the Nyquist frequency range to prevent aliasing, which causes unwanted spectral artifacts in the signal.

BandwidthLimitedOscillator is a refinement of the Oscillator concept. These oscillators are bandwidth limited.

Declaration

namespace cycfi::q::concepts
{
   template <typename T>
   concept BandwidthLimitedOscillator =
      Oscillator<T> &&
      requires(T o, phase ph, phase dt)
   {
      o(ph, dt);        // Generate a periodic waveform given `{phase}`, `pi`
                        // and another `{phase}`, `dt` representing the delta
                        // phase between two samples of the waveform (this is
                        // equivalent to the `_step` member function of the
                        // `{phase_iterator}`). (ph))`
   };
}

Expressions

In addition to valid expressions for Oscillator, BandwidthLimitedOscillator allows these expressions.

Notation

o

Instance of a type that conforms to BasicOscillator.

ph, dt

Object of type phase.

Function Call

Expression Semantics Return Type

o(ph, dt)

Generate a periodic waveform given phase, ph and another phase, dt representing the delta phase between two samples of the waveform (this is equivalent to the _step member function of the phase_iterator).

decltype(o(ph))

Generator

Generator is a concept representation of a generator. Generators are function objects that take no function arguments and return an output that is typically a floating point value. Generators are typically non-periodic. Generators are useful for constructing complex signals, envelopes and tapers (also known as window functions).

Declaration

namespace cycfi::q::concepts
{
    template <typename T>
    concept Generator = requires(T v, T o, T a, T b, phase_iterator pi)
    {
        T(o);             // Copy construct from `o`.
        a = b;            // Assign `b` to `a`.
        v();              // Generate a signal.
    };
}

Expressions

Notation

g, a, b

Instances of types that conform to Generator.

Constructors and Assignment

Expression Semantics

Generator(g)

Copy construct from g.

a = b

Assign b to a.

C++ brace initialization may also be used.

Function Call

Expression Semantics Return Type

g()

Generate a signal.

decltype(g(pi))

Ramp

Ramp is a concept representation of a generator that generates non-periodic signals from 0.0 to 1.0 or from 1.0 to 0.0. It is a refinement of the Generator concept. Ramp(s) are suitable for generating envelopes. A Ramp represents a segment of an envelope. Essentially, an envelope comprises two or more upward and downward `Ramp`s.

Declaration

namespace cycfi::q::concepts
{
   template <typename T>
   concept Ramp =
      Generator<T> &&
      requires(T v, duration w, float sps)
   {
      T(w, sps);        // Construct a Ramp given duration, w, and sps.
      v.reset();        // Reset the Ramp to the start.
      v.config(w, sps); // Configure a Ramp given duration, w, and sps.
   };
}

Expressions

In addition to valid expressions for Generator, Ramp allows these expressions.

Notation

r

Instance of a type that conforms to Ramp.

w

Object of type duration.

sps

Floating point value representing samples per second.

Constructors and Assignment

Expression Semantics

Ramp(w, sps)

Construct a Ramp given duration, w, and sps.

C++ brace initialization may also be used.

Mutators

Expression Semantics

r.reset()

Reset the Ramp to the start.

v.config(w, sps)

Configure a Ramp given duration, w, and sps.