Oscillators
Overview
Synthesizers 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
Constructors and Assignment
Expression | Semantics |
---|---|
|
Default construct an |
|
Copy construct from |
|
Assign |
C++ brace initialization may also be used. |
Function Call
Expression | Semantics | Return Type |
---|---|---|
|
Generate a periodic waveform given |
|
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.
Function Call
Expression | Semantics | Return Type |
---|---|---|
|
Generate a periodic waveform given |
|
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.
Function Call
Expression | Semantics | Return Type |
---|---|---|
|
Generate a periodic waveform given |
|
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.
};
}
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.