Zero Crossing Rate — v1.0 User Guide
Frame‑by‑frame analysis of the rate at which the signal crosses zero. High ZCR indicates noisy/unvoiced content; low ZCR indicates voiced/tonal content. Uses Praat’s built‑in PointProcess (zeroes) (C‑level, no per‑sample script loop) for maximum efficiency. Outputs a ZCR time‑series curve, global statistics, voiced/unvoiced segmentation, and optionally exports the ZCR curve as a Sound object for further use.
What this does
Zero Crossing Rate (ZCR) measures the number of times the signal changes sign per second. It is a simple but powerful indicator of spectral content:
- Low ZCR (typically < 3000 Hz) – voiced, tonal sounds (vowels, musical notes).
- High ZCR (typically > 3000 Hz) – unvoiced, noisy sounds (fricatives, percussive noise, high‑frequency content).
To PointProcess (zeroes) to detect all zero crossings in one pass (C‑level, no Praat script loop). Then, for each analysis frame, it queries the PointProcess to count crossings within the window using Get high index and Get low index – two O(log n) operations per frame. This is orders of magnitude faster than a per‑sample loop.
Quick start
- In Praat, select exactly one Sound object (mono or stereo – stereo will be downmixed to mono for analysis).
- Run script… →
Zero_Crossing_Rate.praat. - Choose an Analysis Preset:
- Fine (10 ms window, 2.5 ms hop), Standard (20 ms, 5 ms), Speech (30 ms, 10 ms), Coarse (50 ms, 20 ms), Ultra‑Fine (5 ms, 1 ms)
- For custom mode (preset = Custom), set:
- Window_duration_ms – length of each analysis frame.
- Hop_duration_ms – step between frames.
- VU_threshold_Hz – threshold above which a frame is considered unvoiced.
- Optionally enable Export_ZCR_curve to save the ZCR time series as a Sound object for further analysis.
- Click OK. The script analyses zero crossings, computes statistics, and draws a multi‑panel visualisation.
The 5 presets (+ Custom)
表表格Analysis method
- Convert to mono (if stereo).
- Create PointProcess (zeroes) – finds every sample where the signal crosses zero.
- For each frame
[t, t+window]:- Find the first zero‑crossing index
hiat or aftert. - Find the last zero‑crossing index
loat or beforet+window. - Number of crossings =
lo – hi + 1(if both exist). - ZCR = crossings / frame_duration (Hz).
- Find the first zero‑crossing index
- Compute global statistics (mean, std, min, max, voiced/unvoiced percentage).
- Optionally export ZCR time series as a Sound object (sample rate = 1/hop).
Because the PointProcess stores all zero‑crossing times as a sorted array, the per‑frame lookup is O(log n) – extremely efficient. The script avoids any per‑sample Praat loops.
Parameters & defaults
Analysis preset
Select one of the presets (Fine, Standard, Speech, Coarse, Ultra‑Fine) to set window and hop automatically. For custom, use the manual fields below.
Analysis parameters
表表格Output
表表格ZCR_originalname with the ZCR time series (1 sample per frame). You can query it with Get value at time....Visualization (Praat picture)
When Draw_visualization = 1, the script draws a 5‑panel figure:
- Input waveform (grey).
- ZCR curve over time (blue for voiced, red for unvoiced). Horizontal lines show:
- Mean ZCR (dotted green).
- Voiced/unvoiced threshold (dotted red).
- ZCR histogram – distribution of ZCR values, colour‑coded by voiced/unvoiced.
- Statistics panel – mean, std, min, max, and a horizontal bar showing voiced/unvoiced percentage.
- Summary panel – source name, preset, window/hop, frame count, and key statistics.
FAQ / troubleshooting
ZCR depends on the frequency content. A pure 100 Hz sine wave has 200 zero crossings per second (each period crosses twice). So ZCR ≈ 2 × frequency. For noisy signals, ZCR can be > 20 kHz. If your material is band‑limited, you may see lower values. The threshold for voiced/unvoiced can be adjusted.
The exported ZCR Sound has a sample rate = 1/hop. For a 10 ms hop, the SR is 100 Hz – far below the audible range. This Sound is intended for further analysis (e.g., using Praat’s query functions), not for listening. The Play_result option is mainly for debugging.
Even with the optimised method, a 10‑minute file at 44.1 kHz produces about 60,000 zero crossings. The per‑frame query is O(log n) and very fast; typical analysis time is still under 1 s per minute of audio. If you experience slowness, increase the hop size (coarser analysis) or reduce the window size.
Praat’s To PointProcess (zeroes) is implemented in C and scans the entire signal once, creating a list of zero‑crossing times. Then each frame only needs to find the indices of the first and last zero within that window – two binary searches (O(log n) each). This is far more efficient than a Praat script loop over every sample in each frame.
The default 3000 Hz is typical for speech, but you can adjust it based on your material. For music, a higher threshold (e.g., 5000 Hz) may be more appropriate. The visualisation shows the threshold line, and the statistics panel updates the voiced/unvoiced percentages.