Getting started
Parseval is a native macOS audio measurement application, built on JUCE with a headless DSP core (libparseval). It runs fully offline: no measurement feature needs a network connection, and license validation happens locally on your machine.
This is a prototype in active development. The DSP core is validated against known-truth test signals, but the app is not finished software — expect rough edges, and check the in-app notes on which measurements are fully implemented before relying on any single feature.
Requirements
- macOS on an Apple-silicon or Intel Mac.
- Any Core Audio input device (a built-in mic works for trying it out; a multichannel interface for real work).
- No internet connection required.
Install and first launch. Open Parseval.app. On launch you land on the TF (transfer function) view — magnitude over phase with a live coherence trace. If you have no interface connected, you can still explore using demo-room mode or the internal loopback (see below). On first run, Parseval asks once for your experience mode (Guided / Standard / Pro); this changes only how much advice you see, never the measurement data or the available features.
Audio setup
Choose a Core Audio device. Parseval opens a single Core Audio input device and maps its channels to a reference plus up to eight measurement engines. Use the mics: button to assign any input channel to any engine; the reference can be any input or the internal loopback.
The target rig. Parseval is designed around the Audient EVO Expanded System: an EVO 16 plus one or two EVO SP8 units over ADAT, giving up to 24 analog channels at 48 kHz on a single clock. Because the OS sees one USB device and the SP8 expanders are clocked by the EVO 16, the whole rig is one clock domain by construction. Dante via Virtual Soundcard is the supported second path — mics and the reference feed both arrive over the network on one PTP clock, so there is no long reference cable run.
Warning — never aggregate two interfaces. A transfer function measured across two clock domains is not a degraded measurement; it is a wrong one. Two free-running crystals drift by tens of ppm, so the reference-to-measurement delay changes continuously and HF coherence collapses. If Parseval detects an OS-level aggregate device (or an input/output sample-rate mismatch), it raises a prominent banner and refuses to treat it as a trustworthy single-clock measurement. Use one clocked rig, not two stacked USB boxes.
Per-channel calibration. Once you have multiple mics, calibration is per channel and only valid at a fixed preamp gain. The correct EVO workflow is: set your gains, save an EVO Mixer preset, calibrate, and then do not touch Smartgain again — one Smartgain press silently re-sets gain across all channels and invalidates every calibration. Parseval cannot read the EVO’s gain, so it infers a change: a sustained broadband level step flips the channel’s chip to CAL?.
Running a measurement
- Assign channels. Use
mics:to pick your reference and your measurement mics (1–8focus an engine). - Start excitation. Press
Gfor the signal generator — pink noise for transfer-function work, 1 kHz sine for level checks. It ramps in with a soft mute to avoid clicks. For a single-mic check with no cabling, pressLfor internal loopback (generator routed to the reference internally). - Read the transfer function. The TF view shows magnitude and phase with coherence-weighted rendering: low-coherence regions fade out instead of drawing a confident line.
Ptoggles magnitude/phase; adjust theblankthreshold to set where untrustworthy data disappears. - Find delays. Press
N(“find all delays”) to locate every engine’s propagation delay at once via GCC-PHAT, with sub-sample interpolation and temperature-corrected distances. Ambiguous peaks are reported asAMBIGUOUSrather than guessed. - Smooth. Apply complex fractional-octave smoothing (1/1 … 1/48) from the per-engine
smoothmenu. Smoothing is applied to the complex transfer function after delay compensation, so phase stays faithful.
MTW vs fixed window. Toggle between multi-time-window mode (a parallel FFT bank giving constant fractional-octave resolution, ≥24 points/octave, each engine aligned by its own delay) and a fixed-window mode.
Spatial averaging. Two modes, never conflated: coherent (complex, preserves phase) and incoherent (power, discards phase, drawn with a min/max spread envelope). Parseval refuses to coherently average unaligned positions — it explains why, then offers to auto-align to a common t=0. It also flags any average across engines with divergent smoothing/averaging settings as incomparable.
Trying it without hardware
- Demo-room mode (
D) streams a synthetic 8-mic scene through the real pipeline in real time, so the full multi-engine UI runs with no interface connected. - Loopback (
L) with the internal generator gives you a genuine single-mic transfer function using only your Mac and one input.
Sessions and export
- Sample rates: 44.1 / 48 / 88.2 / 96 kHz. 48 kHz is recommended — 96 kHz buys nothing above 20 kHz and costs channels over ADAT.
- File input: multichannel WAV/FLAC, treated identically to live input.
- Sessions: a single versioned session file (SAVE/LOAD). Newer-version files are refused with a message rather than half-loaded; unknown fields survive round-trips; floats are stored bit-exact. Autosave writes every 60 s and restores on relaunch with a banner.
- Export: CSV/text export; SPL logging writes append-on-write CSV that survives a crash.
- Mic correction: import per-mic FRD/.cal/.txt curves, applied in the complex domain when the file carries phase.
Troubleshooting
A channel shows UNCAL or CAL?. Calibration is per channel at a fixed gain. UNCAL means never calibrated — seat a 94/114 dB calibrator (or aim the 1 kHz sine) and press the engine’s C/K. CAL? means Parseval inferred a preamp gain change (e.g. Smartgain was touched); recalibrate to clear it and reset the baseline.
A cross-clock / aggregate-device warning appears. You have aggregated two interfaces or the input/output rates differ. Don’t aggregate two USB boxes — use one clocked rig (EVO Expanded over ADAT, or Dante VSC).
No transfer function appears. The engine needs a reference signal. Enable the generator (G) and, for a single mic, internal loopback (L), or assign a real reference channel.
A trace is faded or blanked. That is intentional. Coherence there is too low to trust; it is a message, not a rendering glitch. A dead mic reports low coherence, not a plausible-looking response.
A coherent average is refused. The positions aren’t delay-aligned. Run find-all delays (N) first, or accept Parseval’s offer to auto-align to a common t=0.
An uncalibrated channel shows dBFS in the SPL view. By design — Parseval never fabricates a dB SPL from an uncalibrated channel.
Verify the build itself. Run Parseval --smoke (headless self-check, exit 0 = pass) or Parseval --soak 480 (endurance run) from the app’s Contents/MacOS/Parseval binary.
Getting help
Email [email protected]. Because this is a prototype, please include: your macOS version, your interface/rig (e.g. EVO 16 + SP8 over ADAT, or Dante VSC), the session file if you can share it, and the exact steps that reproduce the problem.
A note on accuracy: Parseval’s published figures characterize the algorithms against synthetic, analytically-known truth. They are not an IEC instrument-class certification — real-world accuracy is additionally bounded by your microphones, preamps, converters, and technique.