📊

Phase Frequency Analyzer

Live magnitude · phase · group delay from your microphone, computed via FFT. Toggle between wrapped (±180°) and unwrapped phase display, smooth across frames, and capture a snapshot to compare a before/after measurement — drop in an EQ or filter between captures and see exactly how it shifts the phase and group delay.

Status: Idle Sample rate: FFT: Snapshot: No snapshot captured
Magnitude (dB) — live (green) · snapshot (yellow dashed)
Phase — live (cyan) · snapshot (yellow dashed)
Group delay (ms) — live (magenta) · snapshot (yellow dashed)

Reading Phase & Group Delay

Phase response tells you the time offset that every frequency in your signal sees as it passes through a system. Group delay is the audible consequence — it's how long a wave-packet around each frequency is delayed in seconds (or milliseconds). Together they describe everything about a system's behaviour that isn't its magnitude response.

Wrapped vs unwrapped

FFT-derived phase is wrapped to ±180° (or ±π radians) because atan2 only produces values in that range. As you scan up the spectrum, the true phase often passes through ±180° boundaries and "wraps" to the other side — producing the saw-tooth look on the wrapped plot. The Unwrap phase toggle detects those jumps and adds ±360° to subsequent points so the underlying continuous phase trajectory becomes visible. Unwrapped phase is what you need to compute group delay.

Group delay = −d(phase) / d(ω)

Group delay is the negative slope of unwrapped phase vs angular frequency. A flat (constant) phase slope gives flat group delay — meaning all frequencies are delayed by the same amount, which preserves a transient's shape. A varying group delay smears transients differently across the spectrum: a sharp drum hit's high-frequency components arrive at a different time than its low-frequency components.

The before/after workflow

Start the mic with a clean signal — pink noise played through your monitors, a sine sweep, or even just music. Click Capture snapshot (A). The current magnitude, phase, and group delay are stored as a yellow dashed overlay on all three plots. Now insert an EQ or filter in your signal chain and watch how the live curves move relative to the snapshot. A minimum-phase EQ will shift phase smoothly without introducing extra delay; a linear-phase EQ will produce constant group delay but possibly with pre-ringing; an analogue-modelled EQ will show its characteristic phase shift around each band.

Why is the phase plot so noisy?

Phase is only well-defined where there's energy. At frequencies with very low magnitude, the bin's complex value is essentially zero plus noise, and its angle is random. The Smoothing control averages the complex spectrum across frames (smoothing in the complex domain avoids the wraparound artefacts you'd get from averaging phase directly). 75 % smoothing is a good default; for transient material drop it to 30 % so you don't blur fast changes.

Why isn't my phase changing when I move my hand?

Phase only changes meaningfully when the spectrum's energy moves between frequencies, or when something is delaying or shifting the signal. A steady tone has a constant phase per bin. Voice and music have rapidly-varying phase that's mostly noise-like — phase analysis is most useful on responses to controlled stimuli (pink noise sweeps, impulses), not on arbitrary content.

Frequently Asked Questions

My group-delay plot bounces around wildly. Is that broken?
Group delay = −dφ/dω, so any noise in the phase estimate gets amplified by the derivative. At frequencies with little energy, phase is essentially random and the derivative is enormous. Raise the smoothing to 80–90 %, and remember that meaningful group delay requires an excitation signal with energy at the frequencies you care about (pink noise is ideal). For a music signal, group-delay numbers are only stable when energy is briefly concentrated in a bin.
Why does my microphone need echo cancellation off?
Browser-supplied echo cancellation, noise suppression and AGC all process the signal in ways that introduce frequency-dependent phase shift and time-varying gain. For phase analysis you want the rawest possible microphone signal — the tool asks for echoCancellation: false, noiseSuppression: false, autoGainControl: false in its getUserMedia constraints to disable them.
What FFT size should I pick?
Bigger FFT = finer frequency resolution (Δf = sampleRate / fftSize) but longer time window and slower update rate. 4096 is a good general default at 48 kHz: Δf ≈ 11.7 Hz, time window ≈ 85 ms. Use 8192–16384 for low-frequency precision (e.g., measuring a sub crossover); use 1024–2048 for fast-changing material where you want quick updates.
What's the difference between minimum-phase and linear-phase EQ?
A minimum-phase EQ (most analogue and standard digital EQs) introduces phase shift that's tied to its magnitude curve — boost a peak and you get characteristic phase distortion around it. Linear-phase EQ uses an FIR filter to give constant group delay (all frequencies delayed equally), at the cost of pre-ringing and large latency. The Capture-A snapshot is the easiest way to see the difference — load each EQ type in turn and compare its phase response.
Is my microphone audio uploaded?
No. The tool uses the browser's Web Audio API to read your mic locally; the signal goes straight from the microphone into the AnalyserNode for FFT, never to any server. The browser will ask once for permission to use the microphone — you can revoke that any time from the site permissions menu.
Can I export the snapshot data?
Not in this tool — for that you'd want a measurement app like Room EQ Wizard (REW) or ARTA, which write CSV / WAV files. This tool's strength is rapid visual A/B comparison: you can see whether a filter change is doing what you expect within a few seconds, without saving anything.
Why is the unwrapped phase off-scale on a flat-magnitude region?
Unwrapping a noisy phase trajectory can accumulate spurious 360° jumps in regions where there's no signal. The auto-scaling tries to fit the unwrapped values but they can run to ±10 000° in degenerate cases. If that happens, switch to wrapped view, raise smoothing, and play a signal with broadband energy — the unwrapping will then track a meaningful trajectory.