|
miniDSP
A small C library for audio DSP
|
Five fundamental time-domain operations that complement the existing signal measurements (energy, power, entropy) and FFT-based spectrum analysis. Together they give you a toolkit for analysing and manipulating signals before or instead of going to the frequency domain.
RMS is the standard measure of signal "loudness" — the square root of the mean squared amplitude:
\[\mathrm{RMS} = \sqrt{\frac{1}{N}\sum_{n=0}^{N-1} x[n]^2} \]
Reading the formula in C:
A unit-amplitude sine wave has RMS = \(1/\sqrt{2} \approx 0.707\). A DC signal of value \(c\) has RMS = \(|c|\).
API:
Quick example — measure the RMS of three signals:
Verification tip: MD_rms(a, N) should always equal sqrt(MD_power(a, N)) to within floating-point precision.
The zero-crossing rate (ZCR) 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] \]
Reading the formula in C:
A pure sine at frequency \(f\) with sample rate \(f_s\) has ZCR \(\approx 2f/f_s\). White noise has a higher ZCR than a low-frequency tone — this makes ZCR a simple proxy for distinguishing noise from tonal content.
API:
Quick example — compare ZCR of sine, noise, and their mix:
Verification tip: for a sine wave with an integer number of cycles in the buffer, the ZCR should be very close to \(2f/f_s\).
The autocorrelation measures the similarity between a signal and a delayed copy of itself. The normalised form divides by \(R[0]\) (the signal energy) so the output is bounded:
\[R[\tau] = \frac{\displaystyle\sum_{n=0}^{N-1-\tau} x[n]\,x[n+\tau]} {\displaystyle\sum_{n=0}^{N-1} x[n]^2} \]
Reading the formula in C:
\(R[0] = 1.0\) always, and \(|R[\tau]| \le 1.0\). For a periodic signal, the autocorrelation peaks at the fundamental period (the inverse of the fundamental frequency) — this is the basis of time-domain pitch detection.
API:
Quick example — autocorrelation of a noisy sine:
Verification tip: for a 200 Hz sine at 8000 Hz sample rate, the autocorrelation should peak at lag 40 (= 8000 / 200).
Peak detection finds local maxima in a signal. A sample \(a[i]\) is a peak if it is strictly greater than both immediate neighbours and above a given threshold. The min_distance parameter suppresses nearby secondary peaks.
Reading the algorithm:
Endpoints (i=0 and i=N-1) are never peaks because they lack two neighbours. A flat signal (all values equal) produces zero peaks.
API:
Quick example — find peaks in the autocorrelation to estimate pitch:
Verification tip: pass a hand-crafted signal like {0, 1, 3, 1, 0, 2, 5, 2, 0} with threshold 0 and min_distance 1. You should get peaks at indices 2 and 6 (values 3 and 5).
Mixing computes the element-wise weighted sum of two signals:
\[\mathrm{out}[n] = w_a \cdot a[n] + w_b \cdot b[n] \]
Reading the formula in C:
Equal weights of 0.5 produce the average. A weight of 1.0/0.0 passes one signal through unchanged. The output buffer may alias either input (in-place safe).
API:
Quick example — mix 80% sine with 20% noise:
Verification tip: for uncorrelated signals (e.g. a sine and white noise), the energy of the mix is approximately the sum of energies: \(E(\mathrm{mix}) \approx w_a^2 E(a) + w_b^2 E(b)\).