spectrogram
Builtin index · Signal processing
result = spectrogram(x, [nfft=256], [hop=nfft/2], [fs=1])
Input: x, nfft, hop, fs · Output: result
What it is
x: a length-N real vector or Signal. nfft/hop (optional numbers): STFT frame size and hop, as in stft. fs (optional number, Hz): scales row ticks to Hz and column ticks to seconds. If x is a Signal, its own Fs is used and fs need not be passed; passing one that disagrees with the signal's rate is an error rather than a silent relabelling (see *Which rate is used*, below). The default of 1 applies only to a plain vector, which carries no rate. Renders a heatmap of stft(x, nfft, hop)'s magnitude, restricted to the positive-frequency half (nfft/2+1 rows), in dB (floored at -120dB); frequency increases upward (row 0 = Nyquist). Draws and returns: the surface would otherwise be unreachable, with no way to read a level off it or hand it to Qu Studio's Interactive Mode.
Overloads
One call shape — this function is not overloaded.
| Code | Input | Output | Description |
result = spectrogram(x, [nfft=256], [hop=nfft/2], [fs=1]) | x vector or Signalx: a length-N real vector or Signal.nfft number, optional (default 256)nfft/hop (optional numbers): STFT frame size and hop, as in stft.hop number, optional (default nfft/2)nfft/hop (optional numbers): STFT frame size and hop, as in stft.fs number, optional (default 1)fs (optional number, Hz): scales row ticks to Hz and column ticks to seconds. | db Matan (nfft/2+1, frames) Mat of dB magnitudes, row 0 = DC — the honest axis order, the opposite of the drawn picture'sfreq Veca length-nfft/2+1 Vec, Hztime Veca length-frames Vec, seconds | Returns a Record with fields db (an (nfft/2+1, frames) Mat of dB magnitudes, row 0 = DC — the honest axis order, the opposite of the drawn picture's), freq (a length-nfft/2+1 Vec, Hz) and time (a length-frames Vec, seconds). |
Examples
From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.
import codec
x = codec.decode_flac("take.flac", channel = 0)
spectrogram(x)
not run by the build — this one needs something the repository cannot supply · from file-io
Fs = 1000
n = 0:1:1023
t = n / Fs
x = sin(2*pi*80*t) + sin(2*pi*300*t)
spectrogram(x, 128, 32, Fs)
title("Two stationary tones")
xlabel("time (s)")
ylabel("frequency (Hz)")
from numerics-dsp
Fs = 1000
n = 0:1:1023
t = n / Fs
x = sin(2*pi*80*t) + sin(2*pi*300*t)
spectrogram(x, 128, 32, Fs)
title("Two stationary tones")
xlabel("time (s)")
ylabel("frequency (Hz)")
from signal-processing
How it works
spectrogram(x, [nfft], [hop], [fs]) — heatmap-style render of stft(x, nfft, hop)'s magnitude, restricted to the positive-frequency half (a real input's spectrum mirrors around Nyquist, so the other half is redundant) and shown in dB (20*log10, floored at -120dB) since a handful of loud low-frequency bins would otherwise wash out everything else on a linear color scale. fs (default 1, i.e. normalized frequency) scales the row ticks to Hz and column ticks to seconds; frequency increases upward (row 0 = Nyquist), the usual spectrogram reading convention.
From the note above this builtin in the interpreter, where the reasoning was written down as it was built.