Skip to content
← All articles

Phantom v1.5.2: Improved Measurements and Other Things

FadeLabs Team
FadeLabs Team -

This release sharpens your ruler. Phantom has four refined measurements, enhanced with precision.

Stereo width gets its own scale

Phantom grades your mix against a target across loudness, dynamics, tonal balance and stereo. Stereo width now has deviation thresholds of its own: 0.05, 0.15 and 0.25.

If that sounds like a small number change, it is the difference between the reading moving or not.

Width is a side/mid ratio. For anything you would recognize as a mix, it sits between 0.0 and about 1.2. That’s a narrow scale where a tenth is a meaningful step. It was graded against the thresholds the decibel measurements share, where 1.0 counts as on target. Across that whole 0 to 1.2 range no gap is ever large enough to clear 1.0, so the grade came back the same either way. This has been fixed.

As a result, a mono mix now reads significantly_below against pop and ambient, and on_target against lo-fi, which targets narrow.

The 0.25 top threshold is set by the tightest constraint rather than by taste. “Moderate” width, 0.3 to 0.7, is the most common target in the bundled profiles (four of nine) and it permits only a 0.3 below range deviation. Anything at or above 0.3 would put the most common genre target back where it started. The 0.05 and 0.15 steps keep roughly the 1:3:6 shape of the decibel thresholds they replace.

Every genre target is now covered

Width targets are named rather than numeric. “Narrow”, “moderate”, “wide,” with each name mapping to a range. Ambient asks for very_wide, which now maps to 1.2 through 2.0, continuing rather than falling back to a catch-all.

Reference comparison got the same treatment, plus correlation

compare_to_profile measures against a genre target. compare_to_reference measures against another mix. Both now rate stereo on ratio scales.

Width reuses the same thresholds. It is the same quantity either way. Correlation gets its own set from analysis: Phantom treats a 0.05 departure from fully mono as the line where stereo bass content exists, which makes 0.05 the established just detectable step, with 0.15 and 0.25 continuing that pattern. Correlation gaps between two mixes span a max of 2.0, so it needed a scale for that range instead of one for decibels.

If you have compared stereo against a profile or a reference before, run it again. The numbers will have changed, and now they respond to your mix better.

Delay measurement is accurate on short clips

compare_phase estimates the offset between two files. It searches a 50 ms window, which at 44.1 kHz is 2205 samples. That window is now bound to half the input length, the widest span a correlation can represent without overlapping itself.

That makes short material measurable. Previously, once an input dropped under about 100 ms, the search region ran past the end of the correlation and the reported delay came back displaced by the full width of the window: a true offset of zero read −50.00 ms, and a true offset of 100 samples read −47.73 ms. The reading tracked reality but sat 2205 samples away from it.

This comes up more than the numbers suggest, because compare_phase truncates both signals to the shorter one. Comparing a drum hit against a full take put both below the threshold.

New Capability: Mono and anti-phase are now distinguishable

The mid/side ratio is undefined at both extremes: a mono file has no side energy, and a fully inverted file has no mids. Mono is usually fine, but fully inverted means the mix cancels the moment it is played in mono.

Stereo analysis now returns mid_side_state alongside the ratio, reading pure_mid or pure_side when the ratio itself cannot be expressed as a number. The existing field is unchanged, so nothing you already read moves.

"mid_side_ratio_db": null,
"mid_side_state": "pure_side"

That second line is the difference between “no reading available” and “this mix disappears in mono.”

Masking limit accuracy improved

PHANTOM_MASKING_TOP_N controls how many masking pairs multi_stem_masking returns, and it now rejects zero and negative values instead of accepting them.

Pairs come back sorted worst first, so a negative limit removed the most severe pairs and kept the rest. Every other limit on that path already validated its input; this one now does too.

A few smaller improvements

phantom fix --interactive --json produces clean, parseable JSON on stdout. The interactive prompt now goes to standard error, where the rest of the interactive output already went, so you can redirect the document straight to a file.

read_live_metrics returns the ordinary “no live metrics” message when a plugin closes mid-read, rather than surfacing a raw filesystem error.

The decode size check reports through Phantom’s own error type.

The installer is improved. It reports success as actual success. It drops deprecation warnings, and it no longer returns a failure code when it finds nothing to drop. Before that fix, a clean install could print “MCP setup had issues” and look broken when it had really worked.

Several tests were also rewritten to depend on the behavior they name, covering the band normalization call sites, the problem sort order and the analysis window truncation.

Windows support and where it stands

Phantom’s Python engine runs on macOS and Linux. Its analysis engine is essentia, which has never published a Windows wheel for any version, so uv tool install phantom-audio cannot resolve on that OS. Replacing it with a Windows-capable backend is tracked as issue #52 on the repository.

However, it comes with some caveats. Rebuilding essentia for Windows is beyond the scope of Phantom, so we are looking into options to replace it or create something different that works. This will take some time as the team is very small and this project is free and open sourced, requiring volunteered time. Just know that it is on the roadmap and something we intend to do.

Worth knowing in the meantime: Phantom Studio, the real-time plugin coming soon, runs on Windows, macOS and Linux. Studio does not depend on essentia and is built on a different architecture entirely: a JUCE audio plugin that runs as VST3, AU or standalone. Stay tuned for that.

Updating Phantom improved

uv tool install "phantom-audio[all]" --python 3.13 --force

The --force matters. uv tool install will not replace an existing installation without it, so leaving it off can leave you stuck on the version you already had.

← All articles