Skip to content

Analysis Settings

Phantom’s analyzers are tunable. Every analysis threshold and frame size is a knob on a single settings object called AnalysisSettings (src/phantom/_settings.py), and every knob has an environment variable override with a documented default. The knobs fall into four groups: phase and dynamics thresholds, the problem-detection threshold block, masking severity splits, and the FFT/frame sizes.

This page explains how tuning works, what the typed result models are, and the one caveat that matters before you change frame sizes.

How tuning works

  • Defaults reproduce the original constants. With no env var set, results are identical to the built-in constants Phantom always used. Nothing changes until you tune.

  • Every knob is env-overridable. Each field on AnalysisSettings maps to a PHANTOM_* variable. Setting one overrides the default for every analysis that reads it. The complete list is in the Environment Variables Reference.

  • Settings resolve per call. Analyzers read the effective settings when they run, not at import. A change to an env var takes effect on the next analysis without a restart.

  • The cache keys on your settings. The analysis cache folds a fingerprint of the current settings into its cache key. A tuned run is never served a result computed under different settings, and reverting to defaults doesn’t break earlier cached results.

The knob groups

GroupKnobsWhat changes
Phase and dynamicspolarity_threshold, phat_window_s, crest_factor_low_dbPolarity flagging, GCC-PHAT window, over-compression detection
Problem detection14 thresholds (clipping, DC offset, ISP, noise floor, SNR, band excess, resonances, lossy shelf)Where each detector starts flagging and at what severity
Masking severityseverity_high, severity_moderate, severity_low, masking_floor_dbWhere masking overlap scores become high/moderate/low labels
FFT / frame sizes6 frame and hop sizes across the spectral, octave-band, flatness, and power-spectrum passesThe analysis geometry itself

Typed result models

Every tool returns a typed result model, not free text: each analyzer is a function that returns a Pydantic model with a fixed field schema, and the tools serialize it to structured JSON. Your assistant receives the same fields with the same names on every call.

The six analysis dimensions each return their own model:

DimensionResult modelCarries
SpectralSpectralResultCentroid, rolloff, contrast, flatness, dissonance, octave band energy
LoudnessLoudnessResultIntegrated LUFS, true peak dBTP, loudness range, short-term and momentary LUFS
DynamicsDynamicsResultRMS, peak, crest factor, dynamic range, dynamic complexity
StereoStereoResultCorrelation, width, mid/side ratio, L/R balance, panorama distribution
PhasePhaseResultOverall and per-band correlation, polarity
ProblemsProblemsResultClipping, DC offset, ISP, noise, hum, sibilance, mud, harshness, resonances

Composite tools combine these models into larger typed payloads:

  • full_diagnostic / batch_diagnostic return a StemDiagnosticResult per file: file metadata (name, duration, sample rate, channels) plus one typed field per dimension. The model rejects unknown fields, so output shape is stable by construction.
  • batch_diagnostic wraps stems in a BatchDiagnosticResult with a stems map and stem_count; failed stems appear as error objects, not dropped entries.
  • multi_stem_masking returns typed MaskingPair entries with severity scores per pair.
  • read_live_metrics returns a LiveMetricsResult with instance metadata and the raw meter snapshot.
  • load_profile returns a ReferenceProfile with loudness, frequency, stereo, and spatial targets.

Because the models are typed, tuning a threshold changes values inside the same schema — never the output shape. An assistant that learned the schema once keeps working when you adjust a knob.

The FFT comparability caveat

Changing frame sizes changes the analysis geometry, so results are not numerically comparable with the built-in genre profiles or reference-target comparisons, both of which are calibrated to the default frame sizes. A different octave-band or spectral frame size produces different band energies and descriptors.

Two rules when you tune the frame-size knobs:

  1. Reset the knobs to defaults before comparing, or
  2. Re-run the comparison itself under the same tuned geometry.

$ tune and re-run comparisons under the same geometry

both analyses must share the same frame sizes to be comparable

PHANTOM_SPECTRAL_FRAME_SIZE=4096 phantom compare master.wav —reference ref.wav PHANTOM_SPECTRAL_FRAME_SIZE=4096 phantom compare master.wav —profile pop

Pro tip

The threshold knobs (problem detection, masking severity, crest factor) don’t change analysis geometry, so tuned thresholds stay comparable with profiles and references. Only the six frame-size knobs trigger the caveat.