|
miniDSP
A small C library for audio DSP
|
A mini library of DSP (Digital Signal Processing) routines. More...
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include <stdbool.h>#include <float.h>#include <complex.h>#include <fftw3.h>Go to the source code of this file.
Data Structures | |
| struct | MD_DTMFTone |
| A single detected DTMF tone with timing information. More... | |
| struct | MD_vad_params |
| Parameters for the VAD detector. More... | |
| struct | MD_vad_state |
| Internal state for the VAD detector. More... | |
Macros | |
| #define | MINIDSP_VERSION_MAJOR 0 |
| #define | MINIDSP_VERSION_MINOR 0 |
| #define | MINIDSP_VERSION_PATCH 0 |
| #define | MINIDSP_VERSION "0.0.0" |
| #define | M_PI 3.14159265358979323846 |
| #define | MD_STEG_LSB 0 |
| Steganography method: least-significant-bit encoding. | |
| #define | MD_STEG_FREQ_BAND 1 |
| Steganography method: near-ultrasonic frequency-band modulation (BFSK). | |
| #define | MD_STEG_SPECTEXT 2 |
| Steganography method: hybrid LSB + spectrogram text art. | |
| #define | MD_STEG_TYPE_TEXT 0 |
| Payload type flag: text (null-terminated string). | |
| #define | MD_STEG_TYPE_BINARY 1 |
| Payload type flag: binary (raw byte buffer). | |
VAD feature indices | |
| #define | MD_VAD_FEAT_ENERGY 0 |
| Frame energy. | |
| #define | MD_VAD_FEAT_ZCR 1 |
| Zero-crossing rate. | |
| #define | MD_VAD_FEAT_SPECTRAL_ENTROPY 2 |
| Spectral entropy. | |
| #define | MD_VAD_FEAT_SPECTRAL_FLATNESS 3 |
| Spectral flatness. | |
| #define | MD_VAD_FEAT_BAND_ENERGY_RATIO 4 |
| Band energy ratio. | |
| #define | MD_VAD_NUM_FEATURES 5 |
| Total number of features. | |
Typedefs | |
| typedef void(* | MD_ErrorHandler) (MD_ErrorCode code, const char *func_name, const char *message) |
| Signature for a user-installed error handler. | |
Enumerations | |
| enum | MD_ErrorCode { MD_ERR_NULL_POINTER = 1 , MD_ERR_INVALID_SIZE = 2 , MD_ERR_INVALID_RANGE = 3 , MD_ERR_ALLOC_FAILED = 4 } |
| Error codes reported by miniDSP when a precondition is violated. More... | |
| enum | MD_GCC_WEIGHTING_TYPE { SIMP , PHAT } |
| Weighting types for Generalized Cross-Correlation. More... | |
Functions | |
| void | MD_set_error_handler (MD_ErrorHandler handler) |
| Install a custom error handler. | |
| double | MD_dot (const double *a, const double *b, unsigned N) |
| Compute the dot product of two vectors. | |
| double | MD_entropy (const double *a, unsigned N, bool clip) |
| Compute the normalized entropy of a distribution. | |
| double | MD_energy (const double *a, unsigned N) |
| Compute signal energy: sum of squared samples. | |
| double | MD_power (const double *a, unsigned N) |
| Compute signal power: energy divided by the number of samples. | |
| double | MD_power_db (const double *a, unsigned N) |
| Compute signal power in decibels: 10 * log10(power). | |
| double | MD_rms (const double *a, unsigned N) |
| Compute the root mean square (RMS) of a signal. | |
| double | MD_zero_crossing_rate (const double *a, unsigned N) |
| Compute the zero-crossing rate of a signal. | |
| void | MD_autocorrelation (const double *a, unsigned N, double *out, unsigned max_lag) |
| Compute the normalised autocorrelation of a signal. | |
| void | MD_peak_detect (const double *a, unsigned N, double threshold, unsigned min_distance, unsigned *peaks_out, unsigned *num_peaks_out) |
| Detect peaks (local maxima) in a signal. | |
| double | MD_f0_autocorrelation (const double *signal, unsigned N, double sample_rate, double min_freq_hz, double max_freq_hz) |
| Estimate the fundamental frequency (F0) using autocorrelation. | |
| double | MD_f0_fft (const double *signal, unsigned N, double sample_rate, double min_freq_hz, double max_freq_hz) |
| Estimate the fundamental frequency (F0) using FFT peak picking. | |
| void | MD_mix (const double *a, const double *b, double *out, unsigned N, double w_a, double w_b) |
| Mix (weighted sum) two signals. | |
| void | MD_delay_echo (const double *in, double *out, unsigned N, unsigned delay_samples, double feedback, double dry, double wet) |
| Delay line / echo effect using a circular buffer with feedback. | |
| void | MD_tremolo (const double *in, double *out, unsigned N, double rate_hz, double depth, double sample_rate) |
| Tremolo effect (amplitude modulation by a sinusoidal LFO). | |
| void | MD_comb_reverb (const double *in, double *out, unsigned N, unsigned delay_samples, double feedback, double dry, double wet) |
| Comb-filter reverb (feedback comb filter with dry/wet mix). | |
| unsigned | MD_convolution_num_samples (unsigned signal_len, unsigned kernel_len) |
| Compute the output length of a full linear convolution. | |
| void | MD_convolution_time (const double *signal, unsigned signal_len, const double *kernel, unsigned kernel_len, double *out) |
| Time-domain full linear convolution (direct sum-of-products). | |
| void | MD_moving_average (const double *signal, unsigned signal_len, unsigned window_len, double *out) |
| Causal moving-average FIR filter with zero-padded startup. | |
| void | MD_fir_filter (const double *signal, unsigned signal_len, const double *coeffs, unsigned num_taps, double *out) |
| Apply a causal FIR filter with arbitrary coefficients. | |
| void | MD_convolution_fft_ola (const double *signal, unsigned signal_len, const double *kernel, unsigned kernel_len, double *out) |
| Full linear convolution using FFT overlap-add (offline). | |
| void | MD_design_lowpass_fir (double *coeffs, unsigned num_taps, double cutoff_freq, double sample_rate, double kaiser_beta) |
| Design a Kaiser-windowed sinc lowpass FIR filter. | |
| double | MD_scale (double in, double oldmin, double oldmax, double newmin, double newmax) |
| Map a single value from one range to another. | |
| void | MD_scale_vec (double *in, double *out, unsigned N, double oldmin, double oldmax, double newmin, double newmax) |
| Map every element of a vector from one range to another. | |
| void | MD_fit_within_range (double *in, double *out, unsigned N, double newmin, double newmax) |
| Fit values within [newmin, newmax]. | |
| void | MD_adjust_dblevel (const double *in, double *out, unsigned N, double dblevel) |
| Automatic Gain Control: scale a signal so its power matches the requested dB level, then clip to [-1, 1]. | |
| void | MD_magnitude_spectrum (const double *signal, unsigned N, double *mag_out) |
| Compute the magnitude spectrum of a real-valued signal. | |
| void | MD_power_spectral_density (const double *signal, unsigned N, double *psd_out) |
| Compute the power spectral density (PSD) of a real-valued signal. | |
| void | MD_phase_spectrum (const double *signal, unsigned N, double *phase_out) |
| Compute the one-sided phase spectrum of a real signal. | |
| unsigned | MD_stft_num_frames (unsigned signal_len, unsigned N, unsigned hop) |
| Compute the number of STFT frames for the given signal length and parameters. | |
| void | MD_stft (const double *signal, unsigned signal_len, unsigned N, unsigned hop, double *mag_out) |
| Compute the Short-Time Fourier Transform (STFT) of a real-valued signal. | |
| void | MD_mel_filterbank (unsigned N, double sample_rate, unsigned num_mels, double min_freq_hz, double max_freq_hz, double *filterbank_out) |
| Build a mel-spaced triangular filterbank matrix. | |
| void | MD_mel_energies (const double *signal, unsigned N, double sample_rate, unsigned num_mels, double min_freq_hz, double max_freq_hz, double *mel_out) |
| Compute mel-band energies from a single frame. | |
| void | MD_mfcc (const double *signal, unsigned N, double sample_rate, unsigned num_mels, unsigned num_coeffs, double min_freq_hz, double max_freq_hz, double *mfcc_out) |
| Compute mel-frequency cepstral coefficients (MFCCs) from a single frame. | |
| void | MD_lowpass_brickwall (double *signal, unsigned len, double cutoff_hz, double sample_rate) |
| Apply a brickwall lowpass filter to a signal in-place. | |
| double | MD_bessel_i0 (double x) |
| Zeroth-order modified Bessel function of the first kind, \(I_0(x)\). | |
| double | MD_sinc (double x) |
| Normalized sinc function: \(\mathrm{sinc}(x) = \sin(\pi x)/(\pi x)\). | |
| void | MD_Gen_Hann_Win (double *out, unsigned n) |
| Generate a Hanning (Hann) window of length n. | |
| void | MD_Gen_Hamming_Win (double *out, unsigned n) |
| Generate a Hamming window of length n. | |
| void | MD_Gen_Blackman_Win (double *out, unsigned n) |
| Generate a Blackman window of length n. | |
| void | MD_Gen_Rect_Win (double *out, unsigned n) |
| Generate a rectangular window of length n (all ones). | |
| void | MD_Gen_Kaiser_Win (double *out, unsigned n, double beta) |
| Generate a Kaiser window of length n with shape parameter beta. | |
| 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. | |
| unsigned | MD_dtmf_detect (const double *signal, unsigned signal_len, double sample_rate, MD_DTMFTone *tones_out, unsigned max_tones) |
| Detect DTMF tones in an audio signal. | |
| void | MD_dtmf_generate (double *output, const char *digits, double sample_rate, unsigned tone_ms, unsigned pause_ms) |
| Generate a DTMF tone sequence. | |
| unsigned | MD_dtmf_signal_length (unsigned num_digits, double sample_rate, unsigned tone_ms, unsigned pause_ms) |
| Calculate the number of samples needed for MD_dtmf_generate(). | |
| void | MD_shutdown (void) |
| Free all internally cached FFT plans and buffers. | |
| void | MD_get_multiple_delays (const double **sigs, unsigned M, unsigned N, unsigned margin, int weightfunc, int *outdelays) |
| Estimate delays between a reference signal and M-1 other signals. | |
| int | MD_get_delay (const double *siga, const double *sigb, unsigned N, double *ent, unsigned margin, int weightfunc) |
| Estimate the delay between two signals. | |
| void | MD_gcc (const double *siga, const double *sigb, unsigned N, double *lagvals, int weightfunc) |
| Compute the full generalized cross-correlation between two signals. | |
| unsigned | MD_spectrogram_text (double *output, unsigned max_len, const char *text, double freq_lo, double freq_hi, double duration_sec, double sample_rate) |
| Synthesise audio that displays readable text in a spectrogram. | |
| unsigned | MD_steg_capacity (unsigned signal_len, double sample_rate, int method) |
| Compute the maximum message length (in bytes) that can be hidden. | |
| unsigned | MD_steg_encode (const double *host, double *output, unsigned signal_len, double sample_rate, const char *message, int method) |
| Encode a secret message into a host audio signal. | |
| unsigned | MD_steg_decode (const double *stego, unsigned signal_len, double sample_rate, char *message_out, unsigned max_msg_len, int method) |
| Decode a secret message from a stego audio signal. | |
| unsigned | MD_steg_encode_bytes (const double *host, double *output, unsigned signal_len, double sample_rate, const unsigned char *data, unsigned data_len, int method) |
| Encode arbitrary binary data into a host audio signal. | |
| unsigned | MD_steg_decode_bytes (const double *stego, unsigned signal_len, double sample_rate, unsigned char *data_out, unsigned max_len, int method) |
| Decode binary data from a stego audio signal. | |
| int | MD_steg_detect (const double *signal, unsigned signal_len, double sample_rate, int *payload_type_out) |
| Detect which steganography method (if any) was used to encode a signal. | |
| unsigned | MD_resample_output_len (unsigned input_len, double in_rate, double out_rate) |
| Compute the output buffer size needed for resampling. | |
| unsigned | MD_resample (const double *input, unsigned input_len, double *output, unsigned max_output_len, double in_rate, double out_rate, unsigned num_zero_crossings, double kaiser_beta) |
| Resample a signal from one sample rate to another using polyphase sinc interpolation. | |
| void | MD_vad_default_params (MD_vad_params *params) |
| Populate a VAD params struct with optimized defaults. | |
| void | MD_vad_init (MD_vad_state *state, const MD_vad_params *params) |
| Initialize VAD state from params. | |
| void | MD_vad_calibrate (MD_vad_state *state, const double *signal, unsigned N, double sample_rate) |
| Feed a known-silence frame to seed the adaptive normalization. | |
| int | MD_vad_process_frame (MD_vad_state *state, const double *signal, unsigned N, double sample_rate, double *score_out, double *features_out) |
| Process one audio frame and return a binary speech decision. | |
A mini library of DSP (Digital Signal Processing) routines.
This header declares functions for:
These are the kinds of building blocks you'd use in an audio processing pipeline – for example, estimating which direction a sound came from using a pair of microphones.
Definition in file minidsp.h.
| #define MD_STEG_FREQ_BAND 1 |
| #define MD_STEG_LSB 0 |
| #define MD_STEG_SPECTEXT 2 |
Steganography method: hybrid LSB + spectrogram text art.
Encodes the message via LSB (machine-readable round-trip) and simultaneously renders it as text in a spectrogram using sine tones in the 18–23.5 kHz ultrasonic band (human-readable visual watermark).
The host signal is automatically upsampled to 48 kHz if its sample rate is below 48 kHz, so the output buffer must be sized for MD_resample_output_len(signal_len, sample_rate, 48000.0) samples when the input rate is less than 48 kHz.
Visual capacity is limited by host duration: each character occupies 240 ms (8 bitmap columns at 30 ms each). Messages longer than the visual capacity are truncated for the spectrogram art, but the full message is always recoverable via the LSB data channel.
| #define MD_STEG_TYPE_BINARY 1 |
| #define MD_STEG_TYPE_TEXT 0 |
| #define MD_VAD_FEAT_BAND_ENERGY_RATIO 4 |
| #define MD_VAD_FEAT_SPECTRAL_FLATNESS 3 |
| typedef void(* MD_ErrorHandler) (MD_ErrorCode code, const char *func_name, const char *message) |
Signature for a user-installed error handler.
| code | One of the MD_ERR_* error codes. |
| func_name | Name of the library function that detected the error. |
| message | Human-readable description of the violation. |
The handler may log, count, or even call abort() — the library itself never terminates the process.
| enum MD_ErrorCode |
Error codes reported by miniDSP when a precondition is violated.
These codes are passed to the active error handler. Zero is reserved for "no error"; all defined codes are positive.
| void MD_adjust_dblevel | ( | const double * | in, |
| double * | out, | ||
| unsigned | N, | ||
| double | dblevel ) |
Automatic Gain Control: scale a signal so its power matches the requested dB level, then clip to [-1, 1].
Automatic Gain Control: scale a signal so its power matches the requested dB level, then clip to [-1, 1].
The input signal is assumed to be in the range [-1.0, 1.0]. The function computes a gain factor so that the output signal has the desired power level (in dB), then clips to [-1.0, 1.0] if any sample exceeds that range.
Based on Jaydeep Dhole's AGC implementation for MATLAB.
Definition at line 166 of file minidsp_core.c.
| void MD_autocorrelation | ( | const double * | a, |
| unsigned | N, | ||
| double * | out, | ||
| unsigned | max_lag ) |
Compute the normalised autocorrelation of a signal.
The autocorrelation measures the similarity between a signal and a delayed copy of itself. This function computes the normalised (biased) autocorrelation for lags 0 through max_lag-1:
\[R[\tau] = \frac{1}{R[0]} \sum_{n=0}^{N-1-\tau} x[n]\,x[n+\tau] \]
where \(R[0] = \sum x[n]^2\) is the signal energy. The output satisfies out[0] = 1.0 and |out[tau]| <= 1.0. A silent signal (all zeros) produces all-zero output.
| a | Input signal of length N. |
| N | Number of samples. Must be > 0. |
| out | Output array of length max_lag (caller-allocated). |
| max_lag | Number of lag values to compute. Must be > 0 and < N. |
Compute the normalised autocorrelation of a signal.
out[tau] = (1/R[0]) * sum_{n=0}^{N-1-tau} x[n] * x[n+tau]
Reuses MD_dot() for the inner product. Silent signals (R[0]=0) produce all-zero output.
Definition at line 321 of file minidsp_core.c.
| double MD_bessel_i0 | ( | double | x | ) |
Zeroth-order modified Bessel function of the first kind, \(I_0(x)\).
Computed via the power series:
\[ I_0(x) = \sum_{k=0}^{\infty} \left[\frac{(x/2)^k}{k!}\right]^2 \]
Converges until the term is below \(10^{-15}\) relative tolerance.
| x | Input value (any real number). |
Zeroth-order modified Bessel function of the first kind, \(I_0(x)\).
Uses the power series: I₀(x) = Σ [(x/2)^k / k!]² Converges until the term is below 1e-15 * sum (relative tolerance).
Definition at line 532 of file minidsp_core.c.
| 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.
| output | Output buffer of length N (caller-allocated). |
| N | Number of samples to generate. Must be > 0. |
| amplitude | Peak amplitude of the chirp (e.g. 1.0). |
| f_start | Starting frequency in Hz. |
| f_end | Ending frequency in Hz. |
| sample_rate | Sampling rate in Hz. Must be > 0. |
Definition at line 78 of file minidsp_generators.c.
| 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).
| output | Output buffer of length N (caller-allocated). |
| N | Number of samples to generate. Must be > 0. |
| amplitude | Peak amplitude of the chirp (e.g. 1.0). |
| f_start | Starting frequency in Hz. Must be > 0. |
| f_end | Ending frequency in Hz. Must be > 0 and != f_start. |
| sample_rate | Sampling rate in Hz. Must be > 0. |
Definition at line 100 of file minidsp_generators.c.
| void MD_comb_reverb | ( | const double * | in, |
| double * | out, | ||
| unsigned | N, | ||
| unsigned | delay_samples, | ||
| double | feedback, | ||
| double | dry, | ||
| double | wet ) |
Comb-filter reverb (feedback comb filter with dry/wet mix).
Internal comb section:
\[c[n] = x[n] + feedback \cdot c[n-D] \]
Final output:
\[y[n] = dry \cdot x[n] + wet \cdot c[n] \]
where \(D\) is delay_samples. In-place safe: out may alias in.
| in | Input signal of length N. |
| out | Output signal of length N (caller-allocated). |
| N | Number of samples. |
| delay_samples | Comb delay in samples (must be > 0). |
| feedback | Feedback gain (must satisfy |feedback| < 1). |
| dry | Dry (original) mix weight. |
| wet | Wet (comb output) mix weight. |
Definition at line 495 of file minidsp_core.c.
| void MD_convolution_fft_ola | ( | const double * | signal, |
| unsigned | signal_len, | ||
| const double * | kernel, | ||
| unsigned | kernel_len, | ||
| double * | out ) |
Full linear convolution using FFT overlap-add (offline).
Produces the same output as MD_convolution_time() but is faster for longer kernels by processing blocks in the frequency domain.
| signal | Input signal of length signal_len. |
| signal_len | Number of input samples (must be > 0). |
| kernel | FIR kernel of length kernel_len. |
| kernel_len | Number of FIR taps (must be > 0). |
| out | Output buffer of length signal_len + kernel_len - 1. |
Definition at line 124 of file minidsp_fir.c.
| unsigned MD_convolution_num_samples | ( | unsigned | signal_len, |
| unsigned | kernel_len ) |
Compute the output length of a full linear convolution.
For input length N and kernel length M, full convolution length is N+M-1.
Definition at line 18 of file minidsp_fir.c.
| void MD_convolution_time | ( | const double * | signal, |
| unsigned | signal_len, | ||
| const double * | kernel, | ||
| unsigned | kernel_len, | ||
| double * | out ) |
Time-domain full linear convolution (direct sum-of-products).
Computes: out[n] = sum_{k=0}^{kernel_len-1} signal[n-k] * kernel[k] with out-of-range signal samples treated as zero.
| signal | Input signal of length signal_len. |
| signal_len | Number of input samples (must be > 0). |
| kernel | FIR kernel of length kernel_len. |
| kernel_len | Number of FIR taps (must be > 0). |
| out | Output buffer of length signal_len + kernel_len - 1. |
Definition at line 25 of file minidsp_fir.c.
| void MD_delay_echo | ( | const double * | in, |
| double * | out, | ||
| unsigned | N, | ||
| unsigned | delay_samples, | ||
| double | feedback, | ||
| double | dry, | ||
| double | wet ) |
Delay line / echo effect using a circular buffer with feedback.
Let D = delay_samples. The internal delay state follows:
\[s[n] = x[n] + feedback \cdot s[n-D] \]
and output is:
\[y[n] = dry \cdot x[n] + wet \cdot s[n-D] \]
This creates repeating echoes decaying geometrically when \(|feedback| < 1\). In-place safe: out may alias in.
| in | Input signal of length N. |
| out | Output signal of length N (caller-allocated). |
| N | Number of samples. |
| delay_samples | Delay length in samples (must be > 0). |
| feedback | Echo feedback gain (must satisfy |feedback| < 1). |
| dry | Dry (original) mix weight. |
| wet | Wet (delayed) mix weight. |
Definition at line 451 of file minidsp_core.c.
| void MD_design_lowpass_fir | ( | double * | coeffs, |
| unsigned | num_taps, | ||
| double | cutoff_freq, | ||
| double | sample_rate, | ||
| double | kaiser_beta ) |
Design a Kaiser-windowed sinc lowpass FIR filter.
Generates a linear-phase lowpass filter with the specified cutoff frequency and Kaiser window shape. The coefficients are normalized to unity DC gain (they sum to 1.0).
\[ h[i] = 2\,f_c\;\mathrm{sinc}\!\bigl(2\,f_c\,(i - (N-1)/2)\bigr) \;\cdot\; w_{\mathrm{Kaiser}}[i] \]
where \(f_c = \mathrm{cutoff\_freq} / \mathrm{sample\_rate}\).
| coeffs | Output buffer of length num_taps (caller-allocated). |
| num_taps | Filter length (must be > 0). |
| cutoff_freq | -6 dB cutoff frequency in Hz (must be > 0 and < sample_rate / 2). |
| sample_rate | Sampling rate in Hz (must be > 0). |
| kaiser_beta | Kaiser window \(\beta\) parameter (e.g. 10.0). |
Definition at line 88 of file minidsp_fir.c.
| double MD_dot | ( | const double * | a, |
| const double * | b, | ||
| unsigned | N ) |
Compute the dot product of two vectors.
The dot product is the sum of element-wise products: a[0]*b[0] + a[1]*b[1] + ...
Compute the dot product of two vectors.
dot = a[0]*b[0] + a[1]*b[1] + ... + a[N-1]*b[N-1]
This is one of the most fundamental operations in DSP. The dot product measures how "similar" two signals are – if they are identical the result is large; if they are unrelated it is near zero.
Definition at line 26 of file minidsp_core.c.
| unsigned MD_dtmf_detect | ( | const double * | signal, |
| unsigned | signal_len, | ||
| double | sample_rate, | ||
| MD_DTMFTone * | tones_out, | ||
| unsigned | max_tones ) |
Detect DTMF tones in an audio signal.
Slides a Hanning-windowed FFT frame across the signal and checks each frame for a valid row + column frequency pair. A tone is reported only after it persists for at least 40 ms (ITU-T Q.24), and a new tone is not accepted until at least 40 ms of silence separates it from the previous one.
The FFT size is the largest power of two whose window fits within 35 ms, keeping it shorter than the 40 ms Q.24 minimum pause so the state machine can resolve inter-digit gaps. The hop size is N/4 (75 % overlap).
| signal | Audio samples (mono). |
| signal_len | Number of samples. Must be > 0. |
| sample_rate | Sampling rate in Hz. Must be >= 4000 (Nyquist for the highest DTMF frequency, 1633 Hz). |
| tones_out | Output array for detected tones (caller-allocated). |
| max_tones | Size of tones_out. Must be > 0. |
max_tones).Definition at line 139 of file minidsp_dtmf.c.
| void MD_dtmf_generate | ( | double * | output, |
| const char * | digits, | ||
| double | sample_rate, | ||
| unsigned | tone_ms, | ||
| unsigned | pause_ms ) |
Generate a DTMF tone sequence.
Each digit is rendered as the sum of its row and column sinusoids, each at amplitude 0.5 (peak sum = 1.0). Digits are separated by silent gaps. Use MD_dtmf_signal_length() to pre-compute the required output buffer size.
Timing constraints follow ITU-T Q.24:
tone_ms >= 40 (minimum recognisable tone)pause_ms >= 40 (minimum inter-digit pause)| output | Output buffer (caller-allocated, length from MD_dtmf_signal_length()). |
| digits | Null-terminated string of valid DTMF characters: '0'–'9', 'A'–'D' (case-insensitive), '*', '#'. An invalid character triggers an assertion failure. |
| sample_rate | Sampling rate in Hz. Must be > 0. |
| tone_ms | Duration of each tone in milliseconds (>= 40). |
| pause_ms | Duration of silence between tones in ms (>= 40). |
Definition at line 325 of file minidsp_dtmf.c.
| unsigned MD_dtmf_signal_length | ( | unsigned | num_digits, |
| double | sample_rate, | ||
| unsigned | tone_ms, | ||
| unsigned | pause_ms ) |
Calculate the number of samples needed for MD_dtmf_generate().
\[N = D \cdot \left\lfloor \frac{t_{\text{tone}} \cdot f_s}{1000} \right\rfloor + (D - 1) \cdot \left\lfloor \frac{t_{\text{pause}} \cdot f_s}{1000} \right\rfloor \]
where \(D\) is the number of digits.
| num_digits | Number of digits in the sequence. |
| sample_rate | Sampling rate in Hz. Must be > 0. |
| tone_ms | Tone duration in milliseconds. |
| pause_ms | Pause duration in milliseconds. |
Definition at line 367 of file minidsp_dtmf.c.
| double MD_energy | ( | const double * | a, |
| unsigned | N ) |
Compute signal energy: sum of squared samples.
Compute signal energy: sum of squared samples.
N-1
E = SUM a[n]^2 n=0
Energy tells you "how loud" a signal is overall. A silent signal has zero energy; a loud one has high energy. Notice that squaring makes all values positive, so negative samples contribute too.
Definition at line 46 of file minidsp_core.c.
| double MD_entropy | ( | const double * | a, |
| unsigned | N, | ||
| bool | clip ) |
Compute the normalized entropy of a distribution.
Returns a value between 0.0 (all energy concentrated in one bin) and 1.0 (energy spread equally across all bins).
| clip | If true, ignore negative values. If false, square all values first. |
Compute the normalized entropy of a distribution.
Entropy measures how "spread out" a distribution is:
The Shannon entropy formula is: H = -SUM( p_i * log2(p_i) ) We normalise by dividing by log2(N) so the result is always in [0, 1].
| a | Array of values representing the distribution. |
| N | Length of the array. |
| clip | If true, ignore negative values (treat them as 0). If false, use a[i]^2 so all values become non-negative. |
Definition at line 218 of file minidsp_core.c.
| double MD_f0_autocorrelation | ( | const double * | signal, |
| unsigned | N, | ||
| double | sample_rate, | ||
| double | min_freq_hz, | ||
| double | max_freq_hz ) |
Estimate the fundamental frequency (F0) using autocorrelation.
This method searches for the strongest local peak in the normalised autocorrelation sequence over lags corresponding to the requested frequency range:
\[f_0 = \frac{f_s}{\tau_\text{peak}} \]
where \(\tau_\text{peak}\) is the selected lag and \(f_s\) is the sample rate.
| signal | Input signal of length N. |
| N | Number of samples (must be >= 2). |
| sample_rate | Sampling rate in Hz (must be > 0). |
| min_freq_hz | Minimum search frequency in Hz (must be > 0). |
| max_freq_hz | Maximum search frequency in Hz (must be > min_freq_hz). |
Definition at line 372 of file minidsp_core.c.
| double MD_f0_fft | ( | const double * | signal, |
| unsigned | N, | ||
| double | sample_rate, | ||
| double | min_freq_hz, | ||
| double | max_freq_hz ) |
Estimate the fundamental frequency (F0) using FFT peak picking.
The signal is internally Hann-windowed, transformed with a one-sided FFT, then the dominant magnitude peak in the requested frequency range is mapped back to Hz:
\[f_0 = \frac{k_\text{peak} f_s}{N} \]
where \(k_\text{peak}\) is the selected FFT bin.
This method is simple and fast but generally less robust than MD_f0_autocorrelation() for noisy or strongly harmonic signals.
| signal | Input signal of length N. |
| N | Number of samples (must be >= 2). |
| sample_rate | Sampling rate in Hz (must be > 0). |
| min_freq_hz | Minimum search frequency in Hz (must be > 0). |
| max_freq_hz | Maximum search frequency in Hz (must be > min_freq_hz). |
Definition at line 379 of file minidsp_spectrum.c.
| void MD_fir_filter | ( | const double * | signal, |
| unsigned | signal_len, | ||
| const double * | coeffs, | ||
| unsigned | num_taps, | ||
| double * | out ) |
Apply a causal FIR filter with arbitrary coefficients.
Computes: out[n] = sum_{k=0}^{num_taps-1} coeffs[k] * signal[n-k] with out-of-range signal samples treated as zero.
| signal | Input signal of length signal_len. |
| signal_len | Number of input samples (must be > 0). |
| coeffs | FIR coefficients of length num_taps. |
| num_taps | Number of FIR taps (must be > 0). |
| out | Output buffer of length signal_len. |
Definition at line 68 of file minidsp_fir.c.
| void MD_fit_within_range | ( | double * | in, |
| double * | out, | ||
| unsigned | N, | ||
| double | newmin, | ||
| double | newmax ) |
Fit values within [newmin, newmax].
If all values already fit, they are copied unchanged. Otherwise the entire vector is rescaled.
Fit values within [newmin, newmax].
If the input range already lies inside [newmin, newmax], the values are copied as-is (no stretching). Otherwise, the full input range is mapped onto the new range.
Definition at line 130 of file minidsp_core.c.
| void MD_gcc | ( | const double * | siga, |
| const double * | sigb, | ||
| unsigned | N, | ||
| double * | lagvals, | ||
| int | weightfunc ) |
Compute the full generalized cross-correlation between two signals.
| siga | First signal. |
| sigb | Second signal. |
| N | Length of both signals. |
| lagvals | Output array of N doubles (pre-allocated). The zero-lag value is at index ceil(N/2). |
| weightfunc | SIMP or PHAT. |
Compute the full generalized cross-correlation between two signals.
This is the core GCC-PHAT routine. It fills lagvals[] with the cross-correlation values, shifted so that the zero-lag value is at index ceil(N/2).
| siga | First signal. |
| sigb | Second signal. |
| N | Length of both signals. |
| lagvals | Output array of N doubles (pre-allocated by caller). |
| weightfunc | SIMP or PHAT. |
Definition at line 340 of file minidsp_gcc.c.
| void MD_Gen_Blackman_Win | ( | double * | out, |
| unsigned | n ) |
Generate a Blackman window of length n.
Much lower sidelobes than Hanning/Hamming, with a wider main lobe.
Generate a Blackman window of length n.
The formula is: w[i] = 0.42
Definition at line 619 of file minidsp_core.c.
| void MD_Gen_Hamming_Win | ( | double * | out, |
| unsigned | n ) |
Generate a Hamming window of length n.
Similar to Hanning, but with a slightly lower first sidelobe.
Generate a Hamming window of length n.
The formula is: w[i] = 0.54 - 0.46 * cos(2*pi*i / (n-1))
Definition at line 595 of file minidsp_core.c.
| void MD_Gen_Hann_Win | ( | double * | out, |
| unsigned | n ) |
Generate a Hanning (Hann) window of length n.
Tapers to zero at both ends and is a common default for FFT analysis.
Generate a Hanning (Hann) window of length n.
The formula is: w[i] = 0.5 * (1 - cos(2*pi*i / (n-1)))
Windowing is essential before taking an FFT because real-world signals don't start and end at exactly zero. Without a window, the abrupt edges create false high-frequency content ("spectral leakage"). The Hanning window smoothly tapers the signal to zero at both ends, reducing this artefact.
Definition at line 574 of file minidsp_core.c.
| void MD_Gen_Kaiser_Win | ( | double * | out, |
| unsigned | n, | ||
| double | beta ) |
Generate a Kaiser window of length n with shape parameter beta.
\[ w[i] = \frac{I_0\!\left(\beta\,\sqrt{1 - \left(\frac{2i}{n-1}-1\right)^2}\right)} {I_0(\beta)} \]
The \(\beta\) parameter controls the sidelobe/mainlobe tradeoff:
| out | Output buffer of length n (caller-allocated). |
| n | Window length. Must be > 0. For n == 1, outputs 1.0. |
| beta | Shape parameter (> 0 for useful windows). |
Generate a Kaiser window of length n with shape parameter beta.
The formula is: w[i] = I₀(β * sqrt(1 - ((2i/(n-1)) - 1)²)) / I₀(β)
The β parameter controls the sidelobe/mainlobe tradeoff:
Definition at line 658 of file minidsp_core.c.
| void MD_Gen_Rect_Win | ( | double * | out, |
| unsigned | n ) |
Generate a rectangular window of length n (all ones).
Useful as a baseline reference (equivalent to no tapering).
Generate a rectangular window of length n (all ones).
Definition at line 639 of file minidsp_core.c.
| int MD_get_delay | ( | const double * | siga, |
| const double * | sigb, | ||
| unsigned | N, | ||
| double * | ent, | ||
| unsigned | margin, | ||
| int | weightfunc ) |
Estimate the delay between two signals.
| siga | First signal. |
| sigb | Second signal. |
| N | Length of both signals. |
| ent | If non-null, receives the normalised entropy of the correlation peak region (closer to 1.0 = less trustworthy). |
| margin | Search +/- this many samples around zero-lag. |
| weightfunc | SIMP or PHAT. |
Estimate the delay between two signals.
The function computes the GCC between the two signals, then searches within a +/- margin window around zero-lag for the peak. The offset of that peak from zero is the estimated delay.
| siga | First signal (reference). |
| sigb | Second signal. |
| N | Length of both signals. |
| ent | If non-null, receives the normalised entropy of the lag values in the search window. High entropy (~1.0) means a flat, unreliable correlation; low entropy (~0.0) means a sharp, trustworthy peak. |
| margin | How far (in samples) to search around zero-lag. |
| weightfunc | SIMP or PHAT. |
Definition at line 290 of file minidsp_gcc.c.
| void MD_get_multiple_delays | ( | const double ** | sigs, |
| unsigned | M, | ||
| unsigned | N, | ||
| unsigned | margin, | ||
| int | weightfunc, | ||
| int * | outdelays ) |
Estimate delays between a reference signal and M-1 other signals.
| sigs | Array of M pointers to signals (sigs[0] is the reference). |
| M | Number of signals. |
| N | Length of each signal (all must be the same length). |
| margin | Search +/- this many samples around zero-lag. |
| weightfunc | SIMP or PHAT (see MD_GCC_WEIGHTING_TYPE). |
| outdelays | Output array of M-1 delay values (must be pre-allocated). |
Estimate delays between a reference signal and M-1 other signals.
This is a convenience wrapper that calls MD_get_delay() for each non-reference signal. A Hanning window is applied to all signals before computing the cross-correlation.
| sigs | Array of M pointers to signals. sigs[0] is the reference. |
| M | Number of signals (must be >= 2). |
| N | Length of every signal. |
| margin | Search +/- margin samples around zero-lag. |
| weightfunc | SIMP or PHAT. |
| outdelays | Output: M-1 delay values (pre-allocated by caller). |
Definition at line 225 of file minidsp_gcc.c.
| 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:
| output | Output buffer of length N (caller-allocated). |
| N | Number of samples to generate. Must be > 0. |
| amplitude | Value of the impulse spike (e.g. 1.0 for unit impulse). |
| position | Sample index of the spike (0-based). Must be < N. |
Definition at line 69 of file minidsp_generators.c.
| void MD_lowpass_brickwall | ( | double * | signal, |
| unsigned | len, | ||
| double | cutoff_hz, | ||
| double | sample_rate ) |
Apply a brickwall lowpass filter to a signal in-place.
Performs an FFT, zeroes all frequency bins above the cutoff frequency, and inverse-FFTs the result. This is a "brickwall" filter: it has zero transition bandwidth, meaning content at or below the cutoff is preserved exactly and content above the cutoff is eliminated completely.
The filter operation in the frequency domain:
\[ X'(k) = \begin{cases} X(k) & \text{if } k \leq \lfloor f_c \cdot N / f_s \rfloor \\ 0 & \text{otherwise} \end{cases} \]
where \(X(k)\) is the DFT of the input, \(f_c\) is the cutoff frequency, \(N\) is the signal length, and \(f_s\) is the sample rate.
| signal | Signal buffer, modified in-place (must not be NULL). |
| len | Number of samples (must be > 0). |
| cutoff_hz | Cutoff frequency in Hz (must be in (0, sample_rate/2)). |
| sample_rate | Sample rate in Hz (must be > 0). |
Definition at line 572 of file minidsp_spectrum.c.
| void MD_magnitude_spectrum | ( | const double * | signal, |
| unsigned | N, | ||
| double * | mag_out ) |
Compute the magnitude spectrum of a real-valued signal.
Given a signal of length N, this function computes the FFT and returns the magnitude |X(k)| for each frequency bin. Because the input is real-valued, the FFT output is conjugate-symmetric, so only the first N/2 + 1 bins are unique (from DC through Nyquist).
To convert bin index k to a frequency in Hz: freq_k = k * sample_rate / N
The output is not normalised by N – divide each value by N to get the "standard" DFT magnitude, or by N/2 (except DC and Nyquist) for single-sided amplitude.
| signal | Input signal of length N. |
| N | Number of samples in the signal. |
| mag_out | Output array, must be pre-allocated to at least N/2 + 1 doubles. On return, mag_out[k] = |X(k)|. |
Example:
This performs a real-to-complex FFT using FFTW, then computes the absolute value (magnitude) of each complex frequency bin.
For a real signal of length N, the FFT is conjugate-symmetric, so only the first N/2 + 1 bins are unique:
The magnitude is computed as: |X(k)| = sqrt( Re(X(k))^2 + Im(X(k))^2 )
The FFT plan is cached and reused across calls of the same length, following the same pattern as the GCC functions.
| signal | Input signal of length N. |
| N | Number of samples (must be >= 2). |
| mag_out | Output: magnitudes for bins 0..N/2. Must be pre-allocated to N/2 + 1 doubles. |
Definition at line 277 of file minidsp_spectrum.c.
| void MD_mel_energies | ( | const double * | signal, |
| unsigned | N, | ||
| double | sample_rate, | ||
| unsigned | num_mels, | ||
| double | min_freq_hz, | ||
| double | max_freq_hz, | ||
| double * | mel_out ) |
Compute mel-band energies from a single frame.
Processing steps: 1) Apply an internal Hann window. 2) Compute one-sided PSD bins via FFT: |X(k)|^2 / N. 3) Apply mel filterbank weights and sum per band.
This function uses the same internal FFT cache as MD_stft() and spectrum APIs.
| signal | Input frame of length N. |
| N | Frame length / FFT size (must be >= 2). |
| sample_rate | Sampling rate in Hz (must be > 0). |
| num_mels | Number of mel bands (must be > 0). |
| min_freq_hz | Requested lower frequency bound in Hz. |
| max_freq_hz | Requested upper frequency bound in Hz (must be > min_freq_hz). |
| mel_out | Output mel energies, caller-allocated length num_mels. |
Definition at line 532 of file minidsp_spectrum.c.
| void MD_mel_filterbank | ( | unsigned | N, |
| double | sample_rate, | ||
| unsigned | num_mels, | ||
| double | min_freq_hz, | ||
| double | max_freq_hz, | ||
| double * | filterbank_out ) |
Build a mel-spaced triangular filterbank matrix.
This function creates num_mels triangular filters over one-sided FFT bins (0..N/2), using the HTK mel mapping:
mel(f) = 2595 * log10(1 + f / 700)
The requested frequency range [min_freq_hz, max_freq_hz] is clamped at runtime to [0, sample_rate/2]. If the clamped range is empty, all output weights are zero.
Output layout is row-major: filterbank_out[m * (N/2 + 1) + k] where m is the mel band index and k is the FFT bin index.
| N | FFT size (must be >= 2). |
| sample_rate | Sampling rate in Hz (must be > 0). |
| num_mels | Number of mel filters (must be > 0). |
| min_freq_hz | Requested lower frequency bound in Hz. |
| max_freq_hz | Requested upper frequency bound in Hz (must be > min_freq_hz). |
| filterbank_out | Output matrix, caller-allocated, length num_mels * (N/2 + 1) doubles. |
Definition at line 514 of file minidsp_spectrum.c.
| void MD_mfcc | ( | const double * | signal, |
| unsigned | N, | ||
| double | sample_rate, | ||
| unsigned | num_mels, | ||
| unsigned | num_coeffs, | ||
| double | min_freq_hz, | ||
| double | max_freq_hz, | ||
| double * | mfcc_out ) |
Compute mel-frequency cepstral coefficients (MFCCs) from a single frame.
Conventions used by this API:
| signal | Input frame of length N. |
| N | Frame length / FFT size (must be >= 2). |
| sample_rate | Sampling rate in Hz (must be > 0). |
| num_mels | Number of mel bands (must be > 0). |
| num_coeffs | Number of cepstral coefficients to output (must be in [1, num_mels]). |
| min_freq_hz | Requested lower frequency bound in Hz. |
| max_freq_hz | Requested upper frequency bound in Hz (must be > min_freq_hz). |
| mfcc_out | Output array, caller-allocated length num_coeffs. |
Definition at line 622 of file minidsp_spectrum.c.
| void MD_mix | ( | const double * | a, |
| const double * | b, | ||
| double * | out, | ||
| unsigned | N, | ||
| double | w_a, | ||
| double | w_b ) |
Mix (weighted sum) two signals.
Computes the element-wise weighted sum:
\[\mathrm{out}[n] = w_a \cdot a[n] + w_b \cdot b[n] \]
In-place safe: the output buffer may alias either input.
| a | First input signal of length N. |
| b | Second input signal of length N. |
| out | Output signal of length N (caller-allocated). |
| N | Number of samples. |
| w_a | Weight for signal a. |
| w_b | Weight for signal b. |
Mix (weighted sum) two signals.
out[n] = w_a * a[n] + w_b * b[n]
In-place safe (out may alias a or b).
Definition at line 436 of file minidsp_core.c.
| void MD_moving_average | ( | const double * | signal, |
| unsigned | signal_len, | ||
| unsigned | window_len, | ||
| double * | out ) |
Causal moving-average FIR filter with zero-padded startup.
Computes: out[n] = (1/window_len) * sum_{k=0}^{window_len-1} signal[n-k] where out-of-range samples (n-k < 0) are treated as zero.
| signal | Input signal of length signal_len. |
| signal_len | Number of input samples (must be > 0). |
| window_len | Moving-average window length (must be > 0). |
| out | Output buffer of length signal_len. |
Definition at line 48 of file minidsp_fir.c.
| void MD_peak_detect | ( | const double * | a, |
| unsigned | N, | ||
| double | threshold, | ||
| unsigned | min_distance, | ||
| unsigned * | peaks_out, | ||
| unsigned * | num_peaks_out ) |
Detect peaks (local maxima) in a signal.
A sample a[i] is a peak if it is strictly greater than both immediate neighbours and above the given threshold. The min_distance parameter suppresses nearby secondary peaks: after accepting a peak at index i, any candidate within min_distance indices is skipped.
Peaks are found left-to-right (deterministic tie-breaking). Endpoint samples (i=0, i=N-1) are never peaks because they lack two neighbours.
| a | Input signal of length N. |
| N | Number of samples. |
| threshold | Minimum value for a peak. |
| min_distance | Minimum index gap between accepted peaks (>= 1). |
| peaks_out | Output array of peak indices (caller-allocated, worst case N elements). |
| num_peaks_out | Receives the number of peaks found. |
Detect peaks (local maxima) in a signal.
A sample a[i] is a peak if:
Endpoints (i=0, i=N-1) are never peaks.
Definition at line 349 of file minidsp_core.c.
| void MD_phase_spectrum | ( | const double * | signal, |
| unsigned | N, | ||
| double * | phase_out ) |
Compute the one-sided phase spectrum of a real signal.
Returns the instantaneous phase angle \(\phi(k) = \arg X(k)\) for each DFT bin using an unnormalised real-to-complex FFT (FFTW r2c). The phase is expressed in radians in the range \([-\pi,\,\pi]\).
For a real signal of length \(N\), only the first \(N/2+1\) bins carry unique information (bins \(N/2+1\ldots N-1\) are conjugate-symmetric mirrors). Accordingly, phase_out must be pre-allocated to hold at least \(N/2+1\) doubles.
Interpretation:
| [in] | signal | Input signal of length N. |
| [in] | N | Signal length (must be >= 2). |
| [out] | phase_out | Pre-allocated array of at least N/2+1 doubles that receives the phase in radians. |
Example
Compute the one-sided phase spectrum of a real signal.
The phase is the argument (angle) of each complex DFT coefficient: phi(k) = atan2(Im(X(k)), Re(X(k)))
This reuses the same FFT cache as MD_magnitude_spectrum() and MD_power_spectral_density() – no additional plan allocation.
Phase is scale-invariant (multiplying a signal by a positive constant does not change its phase), so no normalisation by N is needed.
| signal | Input signal of length N. |
| N | Number of samples (must be >= 2). |
| phase_out | Output: phase in radians for bins 0..N/2. Must be pre-allocated to N/2 + 1 doubles. |
Definition at line 357 of file minidsp_spectrum.c.
| double MD_power | ( | const double * | a, |
| unsigned | N ) |
Compute signal power: energy divided by the number of samples.
Compute signal power: energy divided by the number of samples.
P = E / N
Power is the "average energy per sample". It lets you compare signals of different lengths on an equal footing.
Definition at line 61 of file minidsp_core.c.
| double MD_power_db | ( | const double * | a, |
| unsigned | N ) |
Compute signal power in decibels: 10 * log10(power).
Compute signal power in decibels: 10 * log10(power).
P_dB = 10 * log10(P)
Decibels are a logarithmic scale commonly used in audio engineering. Every +10 dB means the power is 10x larger. A floor of 1e-10 is used to avoid log(0), which would be negative infinity.
Definition at line 77 of file minidsp_core.c.
| void MD_power_spectral_density | ( | const double * | signal, |
| unsigned | N, | ||
| double * | psd_out ) |
Compute the power spectral density (PSD) of a real-valued signal.
The PSD describes how a signal's power is distributed across frequencies. While the magnitude spectrum tells you the amplitude at each frequency, the PSD tells you the power – useful for noise analysis, SNR estimation, and comparing signals of different lengths.
This function computes the "periodogram" estimator:
PSD[k] = |X(k)|^2 / N = (Re(X(k))^2 + Im(X(k))^2) / N
where X(k) is the DFT of the input signal (unnormalised, as computed by FFTW).
Relationship to the magnitude spectrum: PSD[k] = |X(k)|^2 / N = (magnitude[k])^2 / N
Parseval's theorem (energy conservation): The one-sided PSD sums to the total signal energy: PSD[0] + 2 * sum(PSD[1..N/2-1]) + PSD[N/2] = sum(x[n]^2)
| signal | Input signal of length N. |
| N | Number of samples in the signal (must be >= 2). |
| psd_out | Output array, must be pre-allocated to at least N/2 + 1 doubles. On return, psd_out[k] = |X(k)|^2 / N. |
Example:
The PSD is the "periodogram" estimator: PSD[k] = |X(k)|^2 / N. It reuses the same FFT cache as MD_magnitude_spectrum() – both perform the same real-to-complex FFT, only the post-processing differs.
We compute |X(k)|^2 = re^2 + im^2 directly from the real and imaginary parts, rather than calling cabs() (which computes sqrt(re^2 + im^2)) and then squaring. This avoids a redundant sqrt and is both faster and more numerically precise.
| signal | Input signal of length N. |
| N | Number of samples (must be >= 2). |
| psd_out | Output: PSD for bins 0..N/2. Must be pre-allocated to N/2 + 1 doubles. |
Definition at line 315 of file minidsp_spectrum.c.
| unsigned MD_resample | ( | const double * | input, |
| unsigned | input_len, | ||
| double * | output, | ||
| unsigned | max_output_len, | ||
| double | in_rate, | ||
| double | out_rate, | ||
| unsigned | num_zero_crossings, | ||
| double | kaiser_beta ) |
Resample a signal from one sample rate to another using polyphase sinc interpolation.
Uses a fixed table of 512 sub-phases with linear interpolation and a Kaiser-windowed sinc anti-aliasing filter. Anti-aliasing cutoff is automatically set to \(\min(\mathrm{in\_rate}, \mathrm{out\_rate})/2\).
| input | Input signal of length input_len. |
| input_len | Number of input samples (must be > 0). |
| output | Output buffer (caller-allocated). Use MD_resample_output_len() to size it. |
| max_output_len | Capacity of output buffer. Must be >= MD_resample_output_len(input_len, in_rate, out_rate). |
| in_rate | Input sample rate in Hz (must be > 0). |
| out_rate | Output sample rate in Hz (must be > 0). |
| num_zero_crossings | Number of sinc zero-crossings per side. Higher = better quality. Typical: 32. |
| kaiser_beta | Kaiser window shape parameter. Typical: 10.0 for ~100 dB stopband. |
Definition at line 21 of file minidsp_resample.c.
| unsigned MD_resample_output_len | ( | unsigned | input_len, |
| double | in_rate, | ||
| double | out_rate ) |
Compute the output buffer size needed for resampling.
Returns \(\lceil \mathrm{input\_len} \times \mathrm{out\_rate} / \mathrm{in\_rate} \rceil\).
| input_len | Number of input samples (must be > 0). |
| in_rate | Input sample rate in Hz (must be > 0). |
| out_rate | Output sample rate in Hz (must be > 0). |
Definition at line 12 of file minidsp_resample.c.
| double MD_rms | ( | const double * | a, |
| unsigned | N ) |
Compute the root mean square (RMS) of a signal.
RMS is the standard measure of signal "loudness":
\[\mathrm{RMS} = \sqrt{\frac{1}{N}\sum_{n=0}^{N-1} x[n]^2} \]
Equivalently, sqrt(MD_power(a, N)). A unit-amplitude sine wave has RMS = 1/sqrt(2) ~ 0.707. A DC signal of value c has RMS = |c|.
| a | Input signal of length N. |
| N | Number of samples. Must be > 0. |
Compute the root mean square (RMS) of a signal.
RMS = sqrt(1/N * sum(x[n]^2)) = sqrt(power)
Definition at line 288 of file minidsp_core.c.
| 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.
| output | Output buffer of length N (caller-allocated). |
| N | Number of samples to generate. Must be > 0. |
| amplitude | Peak amplitude of the sawtooth wave (e.g. 1.0). |
| freq | Frequency in Hz. |
| sample_rate | Sampling rate in Hz. Must be > 0. |
Definition at line 146 of file minidsp_generators.c.
| double MD_scale | ( | double | in, |
| double | oldmin, | ||
| double | oldmax, | ||
| double | newmin, | ||
| double | newmax ) |
Map a single value from one range to another.
Example: MD_scale(5, 0, 10, 0, 100) returns 50.
Map a single value from one range to another.
Formula: out = (in - oldmin) * (newmax - newmin) / (oldmax - oldmin) + newmin
For example, mapping a value of 5 from the range [0, 10] into [0, 100] gives 50. This is sometimes called "lerp" (linear interpolation).
Definition at line 97 of file minidsp_core.c.
| void MD_scale_vec | ( | double * | in, |
| double * | out, | ||
| unsigned | N, | ||
| double | oldmin, | ||
| double | oldmax, | ||
| double | newmin, | ||
| double | newmax ) |
Map every element of a vector from one range to another.
Map every element of a vector from one range to another.
Definition at line 107 of file minidsp_core.c.
| void MD_set_error_handler | ( | MD_ErrorHandler | handler | ) |
Install a custom error handler.
When a miniDSP function detects a precondition violation (NULL pointer, invalid size, etc.) it calls the active handler instead of aborting. The default handler prints a message to stderr.
Pass NULL to restore the default handler.
Definition at line 27 of file minidsp_error.c.
| 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.
| output | Output buffer of length N (caller-allocated). |
| N | Number of samples to generate. Must be > 0. |
| amplitude | Peak amplitude of the output signal. |
| base_freq | Centre frequency of the Gaussian envelope in Hz. Typical values: 200–600 Hz. |
| sample_rate | Sampling rate in Hz. Must be > 0. |
| rate_octaves_per_sec | Glissando rate in octaves per second. Positive = rising, negative = falling, 0 = static chord. |
| num_octaves | Number of audible octave layers (width of the Gaussian bell). Typical values: 6–10. Must be > 0. |
Definition at line 160 of file minidsp_generators.c.
| void MD_shutdown | ( | void | ) |
Free all internally cached FFT plans and buffers.
Call when done.
Definition at line 238 of file minidsp_spectrum.c.
| double MD_sinc | ( | double | x | ) |
Normalized sinc function: \(\mathrm{sinc}(x) = \sin(\pi x)/(\pi x)\).
\[ \mathrm{sinc}(x) = \begin{cases} 1 & \text{if } |x| < 10^{-12} \\ \dfrac{\sin(\pi x)}{\pi x} & \text{otherwise} \end{cases} \]
| x | Input value. |
Normalized sinc function: \(\mathrm{sinc}(x) = \sin(\pi x)/(\pi x)\).
Returns 1.0 for |x| < 1e-12 to avoid division by zero.
Definition at line 552 of file minidsp_core.c.
| 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.
| output | Output buffer of length N (caller-allocated). |
| N | Number of samples to generate. Must be > 0. |
| amplitude | Peak amplitude of the sine wave (e.g. 1.0). |
| freq | Frequency in Hz. |
| sample_rate | Sampling rate in Hz. Must be > 0. |
Definition at line 16 of file minidsp_generators.c.
| unsigned MD_spectrogram_text | ( | double * | output, |
| unsigned | max_len, | ||
| const char * | text, | ||
| double | freq_lo, | ||
| double | freq_hi, | ||
| double | duration_sec, | ||
| double | sample_rate ) |
Synthesise audio that displays readable text in a spectrogram.
Given a short string, the function rasterises it with a built-in 5x7 bitmap font. Each bitmap column becomes a time slice; each "on" pixel becomes a sine wave at the corresponding frequency between freq_lo and freq_hi. A 3 ms raised-cosine crossfade suppresses clicks at column boundaries. The output is normalised to 0.9 peak amplitude.
| output | Output buffer (caller-allocated). |
| max_len | Size of output in samples (must be >= returned value). |
| text | Printable ASCII string to render (must be non-empty). |
| freq_lo | Lowest frequency in Hz (bottom of text). |
| freq_hi | Highest frequency in Hz (top of text, must be < Nyquist). |
| duration_sec | Total duration in seconds. |
| sample_rate | Sample rate in Hz. |
output.Definition at line 144 of file minidsp_spectext.c.
| 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.
| output | Output buffer of length N (caller-allocated). |
| N | Number of samples to generate. Must be > 0. |
| amplitude | Peak amplitude of the square wave (e.g. 1.0). |
| freq | Frequency in Hz. |
| sample_rate | Sampling rate in Hz. Must be > 0. |
Definition at line 127 of file minidsp_generators.c.
| unsigned MD_steg_capacity | ( | unsigned | signal_len, |
| double | sample_rate, | ||
| int | method ) |
Compute the maximum message length (in bytes) that can be hidden.
| signal_len | Length of the host signal in samples. |
| sample_rate | Sample rate in Hz. |
| method | MD_STEG_LSB, MD_STEG_FREQ_BAND, or MD_STEG_SPECTEXT. |
Definition at line 571 of file minidsp_steg.c.
| unsigned MD_steg_decode | ( | const double * | stego, |
| unsigned | signal_len, | ||
| double | sample_rate, | ||
| char * | message_out, | ||
| unsigned | max_msg_len, | ||
| int | method ) |
Decode a secret message from a stego audio signal.
Reads the 32-bit length header, then extracts message bytes using the same method that was used for encoding.
| stego | The stego signal containing the hidden message. |
| signal_len | Length of the stego signal in samples. |
| sample_rate | Sample rate in Hz. |
| message_out | Output buffer for the decoded message (caller-allocated). |
| max_msg_len | Size of message_out buffer (including null terminator). |
| method | MD_STEG_LSB, MD_STEG_FREQ_BAND, or MD_STEG_SPECTEXT. |
Definition at line 656 of file minidsp_steg.c.
| unsigned MD_steg_decode_bytes | ( | const double * | stego, |
| unsigned | signal_len, | ||
| double | sample_rate, | ||
| unsigned char * | data_out, | ||
| unsigned | max_len, | ||
| int | method ) |
Decode binary data from a stego audio signal.
Works like MD_steg_decode() but writes raw bytes without null termination, suitable for recovering binary payloads.
| stego | The stego signal containing the hidden data. |
| signal_len | Length of the stego signal in samples. |
| sample_rate | Sample rate in Hz. |
| data_out | Output buffer for the decoded bytes (caller-allocated). |
| max_len | Maximum number of bytes to write to data_out. |
| method | MD_STEG_LSB, MD_STEG_FREQ_BAND, or MD_STEG_SPECTEXT. |
Definition at line 625 of file minidsp_steg.c.
| int MD_steg_detect | ( | const double * | signal, |
| unsigned | signal_len, | ||
| double | sample_rate, | ||
| int * | payload_type_out ) |
Detect which steganography method (if any) was used to encode a signal.
Probes the signal for a valid steganographic header using both LSB and frequency-band (BFSK) methods. If a valid header is found, returns the method identifier and optionally the payload type (text or binary).
BFSK detection is only attempted when sample_rate >= 40000 Hz. If both methods appear valid, BFSK is preferred (lower false-positive rate).
| signal | The signal to inspect. |
| signal_len | Length of the signal in samples. |
| sample_rate | Sample rate in Hz. |
| payload_type_out | If non-null, receives MD_STEG_TYPE_TEXT or MD_STEG_TYPE_BINARY when a method is detected. |
Definition at line 670 of file minidsp_steg.c.
| unsigned MD_steg_encode | ( | const double * | host, |
| double * | output, | ||
| unsigned | signal_len, | ||
| double | sample_rate, | ||
| const char * | message, | ||
| int | method ) |
Encode a secret message into a host audio signal.
The host signal is copied to output, then the message is embedded using the selected method. A 32-bit length header is prepended so that MD_steg_decode() can recover the message without knowing its length in advance.
sample_rate >= 40000 Hz so the carriers remain below Nyquist.| host | Input host signal (not modified). |
| output | Output stego signal (caller-allocated; for MD_STEG_SPECTEXT with sample_rate < 48 kHz, must hold MD_resample_output_len(signal_len, sample_rate, 48000) samples). |
| signal_len | Length of host and output in samples. |
| sample_rate | Sample rate in Hz. |
| message | Null-terminated message string to hide. |
| method | MD_STEG_LSB, MD_STEG_FREQ_BAND, or MD_STEG_SPECTEXT. |
Definition at line 646 of file minidsp_steg.c.
| unsigned MD_steg_encode_bytes | ( | const double * | host, |
| double * | output, | ||
| unsigned | signal_len, | ||
| double | sample_rate, | ||
| const unsigned char * | data, | ||
| unsigned | data_len, | ||
| int | method ) |
Encode arbitrary binary data into a host audio signal.
Works like MD_steg_encode() but accepts a raw byte buffer instead of a null-terminated string, so it can embed data containing 0x00 bytes (e.g. images, compressed archives, cryptographic keys).
| host | Input host signal (not modified). |
| output | Output stego signal (caller-allocated, same length). |
| signal_len | Length of host and output in samples. |
| sample_rate | Sample rate in Hz. |
| data | Pointer to the binary data to hide. |
| data_len | Length of data in bytes. |
| method | MD_STEG_LSB, MD_STEG_FREQ_BAND, or MD_STEG_SPECTEXT. |
Definition at line 616 of file minidsp_steg.c.
| void MD_stft | ( | const double * | signal, |
| unsigned | signal_len, | ||
| unsigned | N, | ||
| unsigned | hop, | ||
| double * | mag_out ) |
Compute the Short-Time Fourier Transform (STFT) of a real-valued signal.
The STFT slides a Hanning-windowed FFT over the signal in steps of hop samples, producing a time-frequency magnitude matrix.
For each frame f starting at sample f * hop, the function:
The STFT formula for frame f and bin k is:
X_f(k) = SUM_{n=0}^{N-1} w[n] * x[f*hop + n] * e^{-j2pi*k*n/N}
mag_out[f * (N/2+1) + k] = |X_f(k)|
where w[n] is the Hanning window.
The output is not normalised by N – divide each value by N to get the "standard" DFT magnitude, consistent with MD_magnitude_spectrum().
The STFT reuses the same cached FFT plan as MD_magnitude_spectrum() and MD_power_spectral_density(). Only the Hanning window buffer is separate.
| signal | Input signal. |
| signal_len | Total number of samples in the signal. |
| N | FFT window size (must be >= 2). |
| hop | Hop size in samples (must be >= 1). |
| mag_out | Output array (row-major). Must be pre-allocated to at least MD_stft_num_frames(signal_len, N, hop) * (N/2+1) doubles. On return, mag_out[f*(N/2+1) + k] = |X_f(k)|. |
Compute the Short-Time Fourier Transform (STFT) of a real-valued signal.
Slides a Hanning-windowed r2c FFT over the signal in steps of hop samples. For each frame, the window is applied by multiplying directly into the shared _spec_in buffer (no separate memcpy pass), then FFTW executes the plan and magnitudes |X(k)| are written to the output row.
The shared spec* plan is reused so that interleaving calls to MD_stft(), MD_magnitude_spectrum(), and MD_power_spectral_density() with the same N incurs no extra plan-rebuild overhead.
| signal | Input signal. |
| signal_len | Number of samples (0 frames if < N, see header). |
| N | FFT window size (>= 2). |
| hop | Hop size (>= 1). |
| mag_out | Row-major output: mag_out[f*(N/2+1) + k] = |X_f(k)|. Must be pre-allocated by caller. |
Definition at line 479 of file minidsp_spectrum.c.
| unsigned MD_stft_num_frames | ( | unsigned | signal_len, |
| unsigned | N, | ||
| unsigned | hop ) |
Compute the number of STFT frames for the given signal length and parameters.
The formula is: num_frames = (signal_len - N) / hop + 1 when signal_len >= N num_frames = 0 when signal_len < N
Use this function to size the output buffer before calling MD_stft().
| signal_len | Total number of samples in the signal. |
| N | FFT window size (samples per frame). |
| hop | Hop size (samples between successive frame starts). |
Example:
Compute the number of STFT frames for the given signal length and parameters.
Returns (signal_len - N) / hop + 1 when signal_len >= N, else 0. Integer division truncates, so only complete frames are counted.
Definition at line 454 of file minidsp_spectrum.c.
| void MD_tremolo | ( | const double * | in, |
| double * | out, | ||
| unsigned | N, | ||
| double | rate_hz, | ||
| double | depth, | ||
| double | sample_rate ) |
Tremolo effect (amplitude modulation by a sinusoidal LFO).
The modulation gain is:
\[g[n] = (1 - depth) + depth \cdot \frac{1 + \sin(2\pi f_{LFO} n / f_s)}{2} \]
so \(g[n]\) ranges from \(1-depth\) to \(1\).
Output:
\[y[n] = g[n] \cdot x[n] \]
In-place safe: out may alias in.
| in | Input signal of length N. |
| out | Output signal of length N (caller-allocated). |
| N | Number of samples. |
| rate_hz | LFO rate in Hz (must be >= 0). |
| depth | Modulation depth in [0, 1]. |
| sample_rate | Sampling rate in Hz (must be > 0). |
Definition at line 477 of file minidsp_core.c.
| void MD_vad_calibrate | ( | MD_vad_state * | state, |
| const double * | signal, | ||
| unsigned | N, | ||
| double | sample_rate ) |
Feed a known-silence frame to seed the adaptive normalization.
Computes all five features and updates the EMA min/max estimates without running the state machine or producing a decision. Call this on several silence frames before processing live audio to improve initial normalization accuracy.
| state | VAD state (must be initialized). |
| signal | Frame samples of length N. |
| N | Frame length in samples (must be >= 2). |
| sample_rate | Sample rate in Hz (must be > 0). |
Definition at line 208 of file minidsp_vad.c.
| void MD_vad_default_params | ( | MD_vad_params * | params | ) |
Populate a VAD params struct with optimized defaults.
Default values (F2-optimized, recall-biased):
| Parameter | Value |
|---|---|
| weight (energy) | 0.723068 |
| weight (zcr) | 0.063948 |
| weight (entropy) | 0.005964 |
| weight (flatness) | 0.048865 |
| weight (band ratio) | 0.158156 |
| threshold | 0.245332 |
| onset_frames | 1 |
| hangover_frames | 22 |
| adaptation_rate | 0.012755 |
| band_low_hz | 126.4 |
| band_high_hz | 2899.3 |
| params | Output params struct. Must not be NULL. |
Definition at line 166 of file minidsp_vad.c.
| void MD_vad_init | ( | MD_vad_state * | state, |
| const MD_vad_params * | params ) |
Initialize VAD state from params.
If params is NULL, default params are used (equivalent to calling MD_vad_default_params() first). After initialization the detector is in the SILENCE state with all counters at zero.
| state | Output state struct. Must not be NULL. |
| params | Parameters to copy, or NULL for defaults. |
Definition at line 187 of file minidsp_vad.c.
| int MD_vad_process_frame | ( | MD_vad_state * | state, |
| const double * | signal, | ||
| unsigned | N, | ||
| double | sample_rate, | ||
| double * | score_out, | ||
| double * | features_out ) |
Process one audio frame and return a binary speech decision.
Processing pipeline:
\[ S = \sum_{i=0}^{4} w_i \cdot \hat{f}_i \]
| state | VAD state (must be initialized). |
| signal | Frame samples of length N. |
| N | Frame length in samples (must be >= 2). |
| sample_rate | Sample rate in Hz (must be > 0). |
| score_out | If non-NULL, receives the combined score. |
| features_out | If non-NULL, receives MD_VAD_NUM_FEATURES normalized feature values in [0.0, 1.0]. |
Definition at line 224 of file minidsp_vad.c.
| 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.
| output | Output buffer of length N (caller-allocated). |
| N | Number of samples to generate. Must be > 0. |
| amplitude | Standard deviation of the noise (e.g. 1.0). |
| seed | Seed for the random number generator. Using the same seed produces the same output sequence, which is useful for reproducible tests. |
Definition at line 27 of file minidsp_generators.c.
| double MD_zero_crossing_rate | ( | const double * | a, |
| unsigned | N ) |
Compute the zero-crossing rate of a signal.
The zero-crossing rate counts how often the signal changes sign, normalised by the number of adjacent pairs:
\[\mathrm{ZCR} = \frac{1}{N-1}\sum_{n=1}^{N-1} \mathbf{1}\!\bigl[\mathrm{sgn}(x[n]) \ne \mathrm{sgn}(x[n-1])\bigr] \]
Returns a value in [0.0, 1.0]. High ZCR indicates noise or high-frequency content; low ZCR indicates tonal or low-frequency content. Zero is treated as non-negative (standard convention).
| a | Input signal of length N. |
| N | Number of samples. Must be > 1. |
Compute the zero-crossing rate of a signal.
Returns a value in [0.0, 1.0].
Zero is treated as non-negative (standard convention).
Definition at line 301 of file minidsp_core.c.