CWT Scalogram — Complex Morlet Wavelet Analysis

Computes and draws a continuous wavelet transform (CWT) scalogram using a complex Morlet wavelet, with logarithmically spaced frequencies. Time–frequency resolution adapts to pitch content — high temporal precision where events move fast, high frequency precision where they are slow.

Author: Shai Cohen Affiliation: Department of Music, Bar-Ilan University, Israel Version: 1.1 (2026) License: MIT License Repo: https://github.com/ShaiCohen-ops/Praat-plugin_AudioTools
Contents:

What this does

This script computes a Continuous Wavelet Transform (CWT) scalogram for the currently selected Sound, using a complex Morlet wavelet. Unlike a fixed-window spectrogram, the wavelet's duration shrinks at high frequencies and stretches at low frequencies, giving better time resolution for fast‑moving pitch content and better frequency resolution for slow‑moving content — the usual motivation for reaching for a scalogram over a Fourier spectrogram in transient‑rich or pitch‑glide‑heavy material.

Why a wavelet scalogram? A spectrogram uses a fixed analysis window: high‑frequency events are smeared in time, low‑frequency events are smeared in frequency. The Morlet wavelet automatically adapts: at high frequencies the wavelet is short (good time resolution), at low frequencies it is long (good frequency resolution). This makes it ideal for analysing percussive transients, glissandi, speech formants, and musical ornaments.

Key Features:

Cost: Run time is dominated by the 2 × nFreq FFT convolutions over the full signal length. Raising voices per octave or the octave span costs linearly; raising the time step costs almost nothing after the v1.1 rewrite.

Method notes

Complex Morlet wavelet

ψ(t) = π⁻¹/⁴ · exp(i·ω₀·t) · exp(−t²/2)

At scale s: ψₛ(t) = ψ(t/s) / √s (L2 energy preserved). The real and imaginary parts are built as two ordinary (real‑valued) Sound objects, centred on t = 0.

Frequency–scale correspondence: s = (ω₀ + √(2 + ω₀²)) / (4π f) (Torrence & Compo 1998). This is exact at any ω₀, not a large‑ω₀ approximation.

Magnitude computation:
  • For each frequency f, build the real and imaginary kernels.
  • Convolve each with the signal using Praat's FFT‑based Convolve.
  • Take √(real² + imag²) at each time sample.
  • Because the real kernel is even and the imaginary kernel is odd, convolution and the textbook analytic‑wavelet cross‑correlation agree exactly in magnitude — no separate reversal or conjugation step is needed.
Kernel truncation: Each kernel is truncated to ±Wavelet_cutoff_std standard deviations of its Gaussian envelope (default 5 σ, residual amplitude below ~4×10⁻⁶ of the peak).
v1.1 improvements: (1) Frequency rows are preserved first in the colour heatmap, then time columns — the glide detail that the analysis resolved is not thrown away at draw time. (2) Adjacent cells that quantize to the same colour are merged into one rectangle along the time axis, reducing the number of drawing commands from ~nFreq×nTime to ~nFreq×run‑lengths. (3) The output grid is no longer sampled one command at a time — time_step_s now costs almost nothing. (4) Truncated time range is clearly reported. (5) Viewport re‑selection fixes annotation placement. (6) Cone of influence drawn as dashed curves.

5 Presets

PresetFreq range (Hz)Voices/octTime step (ms)ω₀Character
Speech (pitch‑oriented)60 – 4000244.05Optimised for speech formants and pitch contours
Music (wide‑band)40 – 8000242.06General‑purpose musical analysis
Percussion (transient‑focused)100 – 12000121.04High temporal resolution for percussive attacks
Low drone (sub‑bass detail)20 – 1000368.08High frequency resolution for deep bass and sustained tones
Customuser‑defineduser‑defineduser‑defineduser‑definedFull manual control
Tip: For speech, start with the Speech preset — it focuses on the formant range with good time resolution for pitch. For music, Music (wide‑band) covers a broad range. For drums or percussion, Percussion uses a smaller ω₀ (shorter wavelet) and higher time resolution. For deep bass or sustained tones, Low drone gives very high frequency resolution.

Visualisation

Main scalogram panel

Time on the horizontal axis, log₂(frequency) on the vertical axis. Colour or grayscale shows magnitude in dB re global peak.

Colour heatmap: uses a "hot" ramp (black → red → yellow → white). Cells are merged for efficiency. Grayscale: uses Praat's Paint image, loud = dark.

Cone of influence (COI)

Dashed red curves show the edge‑attenuation region due to zero‑padding. Values inside the COI are fully reliable; outside, the wavelet sees the silent zero‑padding and magnitudes decay. The COI widens at low frequencies (longer wavelets).

Mean‑spectrum profile

A side panel shows the time‑averaged magnitude spectrum (dB) across the analysed frequency range. This gives a quick overview of the spectral envelope.

Summary strip

Displays wavelet parameters, preset, dynamic range, and render grid size. Also shows whether the time axis was truncated due to the cell cap.

Render‑time caps: The script caps frequency bins at 400 and time steps at 20000 to avoid excessive memory use. If your requested resolution exceeds these, the script truncates the time axis and reports it clearly in the title and summary strip.

Applications

Speech formant analysis

Use case: Analyse a spoken sentence to see formant trajectories and pitch contours.

Settings: Speech preset, Colour heatmap, COI on. The scalogram shows formants as horizontal bands that shift with vowel changes, and pitch as a fine, fast‑varying trace.

Musical glissandi

Use case: Analyse a violin or synth glissando to see the continuous pitch movement.

Settings: Music (wide‑band) preset, Colour heatmap. The scalogram shows a smooth diagonal line, revealing the speed and continuity of the glide.

Percussion transients

Use case: Examine a drum loop to see the temporal structure of attacks.

Settings: Percussion preset, Grayscale (high resolution), COI on. The scalogram shows sharp vertical lines at each hit, with frequency content spreading over time.

Low drone / sub‑bass

Use case: Analyse a sustained bass note or synth drone to see subtle frequency fluctuations.

Settings: Low drone preset, Colour heatmap. The scalogram shows a stable horizontal band with very fine frequency detail — ideal for examining vibrato or instability.

Workflow: Speech → Formant tracking

Source: A spoken vowel sequence.
Settings: Speech preset, Colour heatmap, COI on.
Result: The scalogram shows formants F1, F2, F3 as horizontal bands that shift with each vowel, while the fundamental frequency appears as a fine, fast‑varying trace at the bottom.

Workflow: Drum loop → Transient visualisation

Source: A breakbeat drum loop.
Settings: Percussion preset, Grayscale, COI on.
Result: Each drum hit appears as a vertical burst of energy, with the kick drum low‑frequency energy and snare high‑frequency spread clearly visible.

Troubleshooting:
Scalogram is all black / no contrast: The signal may be silent, or the frequency range does not contain energy. Try widening the frequency range or checking the source level.
Colour heatmap is slow: Reduce the number of voices per octave or increase the time step. The script caps cells at 80,000 by default.
Cone of influence covers most of the panel: The signal is short relative to the lowest wavelet scale. Use a higher minimum frequency or a longer signal.
Frequency axis labels are sparse: The script only labels frequencies that fall within the analysed range. Increase the range or use custom ticks in the Picture window.
Matrix object is deleted after run: Enable Keep_analysis_objects to retain the magnitude and dB matrices for further inspection or export.

Output & Objects

Matrix: cwt_magnitude

Linear |CWT| values. x = time (s), y = log₂(frequency in Hz). Can be inspected, plotted, or exported as a text file.

Matrix: cwt_dB

dB values re global peak, clipped to the dynamic range. Used for the heatmap. Also retains the full 2D scalogram for further analysis.

Table: cwt_<soundname>

One row per frequency bin, with columns: bin, frequency_Hz, peak_dB, mean_dB, peak_time_s, coi_halfwidth_s, wavelet_scale_s. Can be saved as CSV for external plotting.

Info window

Reports analysis settings, band summary (per octave), global statistics (peak, centroid, COI area), and analysis cost (grid size, convolutions, elapsed time).

Keep_analysis_objects: By default, the script deletes the matrices after drawing to keep the Objects list clean. Enable this option to retain them for further work — they can be inspected, plotted, or exported.
Band summary: The script can report a band table (Bands_per_octave divisions) showing for each band: frequency range, number of bins, peak dB, mean dB, peak frequency, peak time, and COI half‑width. This is useful for spectral‑temporal feature extraction.