Qu

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.

CodeInputOutputDescription
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's
freq Veca length-nfft/2+1 Vec, Hz
time 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.