Basic Signal Operations

Five fundamental time-domain analysis techniques that work alongside energy(), power(), and entropy().

RMS (Root Mean Square)

The standard measure of signal “loudness”:

\[\text{RMS} = \sqrt{\frac{1}{N}\sum_{n=0}^{N-1} x[n]^2}\]

A unit sine wave yields ≈ 0.707; a DC signal of value c has RMS = |c|.

import pyminidsp as md

signal = md.sine_wave(44100, amplitude=1.0, freq=440.0, sample_rate=44100.0)
print(md.rms(signal))  # ≈ 0.707

Zero-crossing rate

Counts how often the signal changes sign, normalised by the number of adjacent pairs. High ZCR → noise or high-frequency content. Low ZCR → tonal or low-frequency content.

signal = md.sine_wave(16000, freq=1000.0, sample_rate=16000.0)
zcr = md.zero_crossing_rate(signal)
# zcr ≈ 2 * 1000 / 16000 = 0.125

Autocorrelation

Measures the similarity between a signal and a delayed copy of itself. Periodic signals produce a strong peak at the fundamental period — the basis of autocorrelation-based pitch detection.

signal = md.sine_wave(1024, freq=100.0, sample_rate=1000.0)
acf = md.autocorrelation(signal, max_lag=50)
# acf[0] = 1.0
# acf[10] ≈ 1.0  (lag 10 = one period of 100 Hz at 1 kHz sample rate)

Peak detection

Finds local maxima above a threshold with a minimum distance constraint to suppress secondary peaks.

import numpy as np

signal = np.array([0, 1, 3, 1, 0, 2, 5, 2, 0], dtype=float)
peaks = md.peak_detect(signal, threshold=0.0, min_distance=1)
print(peaks)  # [2, 6]  (values 3 and 5)

Signal mixing

Element-wise weighted sum of two signals:

\[\text{out}[n] = w_a \cdot a[n] + w_b \cdot b[n]\]
sine = md.sine_wave(1024, amplitude=1.0, freq=440.0, sample_rate=44100.0)
noise = md.white_noise(1024, amplitude=0.1, seed=42)
mixed = md.mix(sine, noise, w_a=0.8, w_b=0.2)