miniDSP
A small C library for audio DSP
Loading...
Searching...
No Matches
minidsp_generators.c File Reference

Signal generators: sine, white noise, impulse, chirps, square, sawtooth waves, and Shepard tone. More...

#include "minidsp.h"
Include dependency graph for minidsp_generators.c:

Go to the source code of this file.

Functions

void MD_sine_wave (double *output, unsigned N, double amplitude, double freq, double sample_rate)
 Generate a sine wave.
 
void MD_white_noise (double *output, unsigned N, double amplitude, unsigned seed)
 Generate Gaussian white noise.
 
void MD_impulse (double *output, unsigned N, double amplitude, unsigned position)
 Generate a discrete impulse (Kronecker delta).
 
void MD_chirp_linear (double *output, unsigned N, double amplitude, double f_start, double f_end, double sample_rate)
 Generate a linear chirp (swept sine with linearly increasing frequency).
 
void MD_chirp_log (double *output, unsigned N, double amplitude, double f_start, double f_end, double sample_rate)
 Generate a logarithmic chirp (swept sine with exponentially increasing frequency).
 
void MD_square_wave (double *output, unsigned N, double amplitude, double freq, double sample_rate)
 Generate a square wave.
 
void MD_sawtooth_wave (double *output, unsigned N, double amplitude, double freq, double sample_rate)
 Generate a sawtooth wave.
 
void MD_shepard_tone (double *output, unsigned N, double amplitude, double base_freq, double sample_rate, double rate_octaves_per_sec, unsigned num_octaves)
 Generate a Shepard tone — the auditory illusion of endlessly rising or falling pitch.
 

Detailed Description

Signal generators: sine, white noise, impulse, chirps, square, sawtooth waves, and Shepard tone.

Author
Chuck Wooters woote.nosp@m.rs@h.nosp@m.ey.co.nosp@m.m

Definition in file minidsp_generators.c.

Function Documentation

◆ MD_chirp_linear()

void MD_chirp_linear ( double *  output,
unsigned  N,
double  amplitude,
double  f_start,
double  f_end,
double  sample_rate 
)

Generate a linear chirp (swept sine with linearly increasing frequency).

The instantaneous frequency sweeps linearly from f_start to f_end over N samples:

f(t) = f_start + (f_end - f_start) * t / T

where T = (N-1) / sample_rate is the sweep duration. The output is:

output[i] = amplitude * sin(2*pi * (f_start*t + 0.5*chirp_rate*t^2))

A linear chirp is the standard test signal for spectrograms – its instantaneous frequency traces a straight diagonal line in the time-frequency plane.

Parameters
outputOutput buffer of length N (caller-allocated).
NNumber of samples to generate. Must be > 0.
amplitudePeak amplitude of the chirp (e.g. 1.0).
f_startStarting frequency in Hz.
f_endEnding frequency in Hz.
sample_rateSampling rate in Hz. Must be > 0.
double sig[16000];
// 1-second linear chirp from 200 Hz to 4000 Hz at 16 kHz sample rate
MD_chirp_linear(sig, 16000, 1.0, 200.0, 4000.0, 16000.0);
void MD_chirp_linear(double *output, unsigned N, double amplitude, double f_start, double f_end, double sample_rate)
Generate a linear chirp (swept sine with linearly increasing frequency).

Definition at line 77 of file minidsp_generators.c.

◆ MD_chirp_log()

void MD_chirp_log ( double *  output,
unsigned  N,
double  amplitude,
double  f_start,
double  f_end,
double  sample_rate 
)

Generate a logarithmic chirp (swept sine with exponentially increasing frequency).

The instantaneous frequency sweeps exponentially from f_start to f_end over N samples:

f(t) = f_start * (f_end / f_start)^(t / T)

where T = (N-1) / sample_rate is the sweep duration. The output is:

output[i] = amplitude * sin(2*pi * f_start * T * (r^(t/T) - 1) / ln(r))

where r = f_end / f_start.

A logarithmic chirp spends equal time per octave, making it ideal for measuring systems whose behaviour is best described on a log-frequency axis (e.g. audio equaliser response).

Parameters
outputOutput buffer of length N (caller-allocated).
NNumber of samples to generate. Must be > 0.
amplitudePeak amplitude of the chirp (e.g. 1.0).
f_startStarting frequency in Hz. Must be > 0.
f_endEnding frequency in Hz. Must be > 0 and != f_start.
sample_rateSampling rate in Hz. Must be > 0.
double sig[44100];
// 1-second log chirp from 20 Hz to 20 kHz at 44.1 kHz sample rate
MD_chirp_log(sig, 44100, 1.0, 20.0, 20000.0, 44100.0);
void MD_chirp_log(double *output, unsigned N, double amplitude, double f_start, double f_end, double sample_rate)
Generate a logarithmic chirp (swept sine with exponentially increasing frequency).

Definition at line 99 of file minidsp_generators.c.

◆ MD_impulse()

void MD_impulse ( double *  output,
unsigned  N,
double  amplitude,
unsigned  position 
)

Generate a discrete impulse (Kronecker delta).

Fills the output buffer with zeros except at position, where the value is set to amplitude. A unit impulse (amplitude 1.0 at position 0) is the identity element of convolution and has a perfectly flat magnitude spectrum.

Common uses:

  • Measure a system's impulse response by feeding it through a filter.
  • Verify that MD_magnitude_spectrum() returns a flat spectrum.
  • Create delayed spikes for testing convolution and delay estimation.
Parameters
outputOutput buffer of length N (caller-allocated).
NNumber of samples to generate. Must be > 0.
amplitudeValue of the impulse spike (e.g. 1.0 for unit impulse).
positionSample index of the spike (0-based). Must be < N.
double sig[1024];
MD_impulse(sig, 1024, 1.0, 0); // unit impulse at sample 0
void MD_impulse(double *output, unsigned N, double amplitude, unsigned position)
Generate a discrete impulse (Kronecker delta).

Definition at line 68 of file minidsp_generators.c.

◆ MD_sawtooth_wave()

void MD_sawtooth_wave ( double *  output,
unsigned  N,
double  amplitude,
double  freq,
double  sample_rate 
)

Generate a sawtooth wave.

Fills the output buffer with a sawtooth wave that ramps linearly from −amplitude to +amplitude over each period:

\[ x[n] = A \left(\frac{\phi}{\pi} - 1\right) \]

where \(\phi = 2\pi f n / f_s \pmod{2\pi}\).

A sawtooth wave contains all integer harmonics (1f, 2f, 3f, …) whose amplitudes decay as 1/k — useful for demonstrating richer harmonic content compared to the square wave's odd-only series.

Parameters
outputOutput buffer of length N (caller-allocated).
NNumber of samples to generate. Must be > 0.
amplitudePeak amplitude of the sawtooth wave (e.g. 1.0).
freqFrequency in Hz.
sample_rateSampling rate in Hz. Must be > 0.
double sig[1024];
MD_sawtooth_wave(sig, 1024, 1.0, 440.0, 44100.0);
void MD_sawtooth_wave(double *output, unsigned N, double amplitude, double freq, double sample_rate)
Generate a sawtooth wave.

Definition at line 145 of file minidsp_generators.c.

◆ MD_shepard_tone()

void MD_shepard_tone ( double *  output,
unsigned  N,
double  amplitude,
double  base_freq,
double  sample_rate,
double  rate_octaves_per_sec,
unsigned  num_octaves 
)

Generate a Shepard tone — the auditory illusion of endlessly rising or falling pitch.

A Shepard tone superimposes several sine waves spaced one octave apart. Each tone glides continuously upward (or downward) in pitch while a Gaussian spectral envelope — fixed in log-frequency space — fades tones in at one end and out at the other. The result is a sound that seems to rise (or fall) forever without ever actually leaving its frequency range.

Signal model. At time \(t = n / f_s\) the output sample is:

\[ x[n] \;=\; A_\mathrm{norm}\!\sum_k \underbrace{ \exp\!\Bigl(-\frac{d_k(t)^2}{2\sigma^2}\Bigr) }_{\text{Gaussian envelope}} \;\sin\!\bigl(\varphi_k(n)\bigr) \]

where the octave distance from the Gaussian centre is

\[ d_k(t) = k - c + R\,t, \qquad c = \frac{L-1}{2}, \qquad \sigma = \frac{L}{4} \]

and the instantaneous frequency of layer \(k\) is \(f_k(t) = f_\text{base}\cdot 2^{d_k(t)}\). The phase \(\varphi_k\) is accumulated sample-by-sample from \(f_k\) so that each tone glides smoothly. \(R\) is rate_octaves_per_sec and \(L\) is num_octaves. \(A_\mathrm{norm}\) scales the peak to amplitude.

The sum ranges over all integer indices \(k\) for which \(|d_k(t)|\) is within \(5\sigma\) at some point during the signal, ensuring enough layers are present to sustain the illusion for the full duration.

Parameters
outputOutput buffer of length N (caller-allocated).
NNumber of samples to generate. Must be > 0.
amplitudePeak amplitude of the output signal.
base_freqCentre frequency of the Gaussian envelope in Hz. Typical values: 200–600 Hz.
sample_rateSampling rate in Hz. Must be > 0.
rate_octaves_per_secGlissando rate in octaves per second. Positive = rising, negative = falling, 0 = static chord.
num_octavesNumber of audible octave layers (width of the Gaussian bell). Typical values: 6–10. Must be > 0.
// 5 seconds of endlessly rising Shepard tone at 44.1 kHz
unsigned N = 5 * 44100;
double *sig = malloc(N * sizeof(double));
MD_shepard_tone(sig, N, 0.8, 440.0, 44100.0, 0.5, 8);
// sig[] now sounds like it rises forever
free(sig);
void MD_shepard_tone(double *output, unsigned N, double amplitude, double base_freq, double sample_rate, double rate_octaves_per_sec, unsigned num_octaves)
Generate a Shepard tone — the auditory illusion of endlessly rising or falling pitch.

Definition at line 159 of file minidsp_generators.c.

◆ MD_sine_wave()

void MD_sine_wave ( double *  output,
unsigned  N,
double  amplitude,
double  freq,
double  sample_rate 
)

Generate a sine wave.

Fills output[i] = amplitude * sin(2π * freq * i / sample_rate) for i in [0, N).

This is the simplest test signal in DSP — a pure tone at a single frequency. Use it to verify filter responses, check FFT bin alignment, or provide a clean input for any processing chain.

Parameters
outputOutput buffer of length N (caller-allocated).
NNumber of samples to generate. Must be > 0.
amplitudePeak amplitude of the sine wave (e.g. 1.0).
freqFrequency in Hz.
sample_rateSampling rate in Hz. Must be > 0.
double sig[1024];
MD_sine_wave(sig, 1024, 1.0, 440.0, 44100.0); // 440 Hz A4 tone
void MD_sine_wave(double *output, unsigned N, double amplitude, double freq, double sample_rate)
Generate a sine wave.

Definition at line 15 of file minidsp_generators.c.

◆ MD_square_wave()

void MD_square_wave ( double *  output,
unsigned  N,
double  amplitude,
double  freq,
double  sample_rate 
)

Generate a square wave.

Fills the output buffer with a bipolar square wave that alternates between +amplitude and −amplitude at the given frequency:

\[ x[n] = \begin{cases} +A & 0 < \phi < \pi \\ -A & \pi < \phi < 2\pi \\ 0 & \phi = 0 \text{ or } \phi = \pi \end{cases} \]

where \(\phi = 2\pi f n / f_s \pmod{2\pi}\).

A square wave contains only odd harmonics (1f, 3f, 5f, …) whose amplitudes decay as 1/k — a classic demonstration of the Fourier series and the Gibbs phenomenon.

Parameters
outputOutput buffer of length N (caller-allocated).
NNumber of samples to generate. Must be > 0.
amplitudePeak amplitude of the square wave (e.g. 1.0).
freqFrequency in Hz.
sample_rateSampling rate in Hz. Must be > 0.
double sig[1024];
MD_square_wave(sig, 1024, 1.0, 440.0, 44100.0);
void MD_square_wave(double *output, unsigned N, double amplitude, double freq, double sample_rate)
Generate a square wave.

Definition at line 126 of file minidsp_generators.c.

◆ MD_white_noise()

void MD_white_noise ( double *  output,
unsigned  N,
double  amplitude,
unsigned  seed 
)

Generate Gaussian white noise.

Fills output with normally distributed random samples (mean 0, standard deviation amplitude) using the Box-Muller transform. White noise has equal energy at all frequencies – its power spectral density is approximately flat.

Use white noise to test filters, measure impulse responses, or as an additive noise source for SNR experiments.

Parameters
outputOutput buffer of length N (caller-allocated).
NNumber of samples to generate. Must be > 0.
amplitudeStandard deviation of the noise (e.g. 1.0).
seedSeed for the random number generator. Using the same seed produces the same output sequence, which is useful for reproducible tests.
double noise[4096];
MD_white_noise(noise, 4096, 1.0, 42); // reproducible Gaussian noise
void MD_white_noise(double *output, unsigned N, double amplitude, unsigned seed)
Generate Gaussian white noise.

Definition at line 26 of file minidsp_generators.c.