Nova Final Master Validator
Did the file you saved still reproduce the master you approved?
- candidate_audio
- candidate_audio
- sample_rate
- validation_report
- validation_json
- verdict
- archive_audio_path
- archive_report_path
Here's the gap nobody talks about in mastering workflows. You master in memory, you listen, you approve it, you write a file - and then you ship the file. But writing to disk is a separate operation from mastering, and it's the one that quantises, clamps and names things. A 24-bit render that came out 16-bit, a level that got limited on the way out, a resample you didn't ask for: all of it happens after the moment you signed off.
Nova Final Master Validator answers exactly one question: does the file reproduce the master I approved? It's the last node in the pack's mastering chain for a reason.
How it decides
It compares the candidate against the reference in two ways at once.
Measurement. It computes the same metric set the mastering report carries - integrated LUFS, true peak, sample peak, RMS, crest, L/R correlation and per-band energy percentages - and compares each against the reference with a tolerance: 0.10 LU for loudness, 0.10 dB for peaks and RMS, 0.15 dB for crest, 0.01 for correlation, 0.50 percentage points for band shares. Each metric lands as MATCH, WITHIN_TOLERANCE, DRIFT or FAIL, and those are weighted into a confidence score.
Format. Sample rate, channel count and sample count are checked exactly. If all three match, the PCM is bit-comparable.
Those combine into a verdict output: BIT_EXACT, REPRODUCTION_MATCH, ACCEPTABLE_DERIVATIVE, VALIDATION_FAIL or DRIFT_DETECTED. tolerance_multiplier (default 1.0, range 0.5–5) scales all the measurement tolerances at once, which is how you tell it how strict to be about a derivative format - a 16-bit delivery is allowed to be a derivative, not a clone.
Inputs
- candidate_audio - the audio you just wrote (or loaded).
- reference_report_json - the
report_jsonfrom Nova Audio Master. Optional and multiline: leave it empty and the node goes looking for the matching archived report itself. - archive_name - normally wired from Nova Master Identity. On a mastering pass it names the saved reference; on a validation pass it selects which archived report to load.
- identity_selector and lookup_mode - this pair is the thoughtful part. File names in an archive folder are working names and can't be trusted, so
identity_selectormatches on something recorded inside each report: release title, ISRC, catalogue number, identity ID, report ID, or the master PCM SHA-256.lookup_modepicks the strategy -auto(identity, else archive name, else content scan),identity,content scan, or the oldarchive namelookup. Content scan ignores every name and simply measures the candidate to find the archive it matches. - reference_format -
PCM_16,PCM_24orFLOAT_32. It's the format recorded in the validation report; archives written by older versions were named with it, and are still found whatever this is set to, so it no longer has to match to locate a report. - report_path / audio_path - folders relative to ComfyUI's output for reference JSON and archived audio. Both default to the
NovaAudioMasters/…layout. - save_reference_json - writes the reference on a mastering pass.
Outputs: candidate_audio, sample_rate, validation_report (text), validation_json, verdict, archive_audio_path, archive_report_path.
One honest note about BIT_EXACT
Bit-exact is a strong claim, and the node is careful about it. If the reference report was produced with mastering bypassed - Nova Audio Master in Off mode - then the report describes the unprocessed input, so a match proves your candidate is unaltered, not that it's the master. The validator detects that case and says so in the report rather than letting a 100/100 verdict imply more than it can support. Read the text, not just the word.
Install
ComfyUI Manager → Nova Audio Player → install → restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/NovaFemme/ComfyUI-NovaAudioPlayer.git
Under ▶️ Nova Audio → 📊 Analysis & Validation. No models, no extra pip packages. Download scipy if you want the loudness comparison to be properly K-weighted rather than approximate - without it the LUFS figure is unweighted and ungated, and a tolerance of 0.10 LU against a figure that's already approximate is a comparison you'd rather not be making.
Try it before you need it
The pack ships Nova Audio Master Comparison Validation, a five-node workflow that does exactly this on a file you already have: load, compare, validate, listen. Run it once on a known-good pair so you've seen what the verdicts look like before a real release depends on them.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| candidate_audio | AUDIO | — | |
| reference_report_json | STRING | Optional. Leave empty to auto-load the matching report JSON from Path using the selected WAV filename. | |
| tolerance_multiplieropt | FLOAT | 1.00.5–5 | — |
| reference_formatopt | COMBO | PCM_16 | Delivery format recorded in the validation report. Archives written by v0.3.0 and earlier were named with this format, and are still found whatever it is set to, so it no longer has to match to locate a report. |
| save_reference_jsonopt | BOOLEAN | false | — |
| archive_nameopt | STRING | Archive name, normally wired from Nova Master Identity. On a mastering pass it names the saved reference JSON. On a validation pass it selects which archived report to load; leave it empty and the candidate's own filename is used instead. | |
| report_pathopt | STRING | NovaAudioMasters/Reports | Folder relative to ComfyUI/output. Save location for reference JSON, leave blank to save directly in output. |
| audio_pathopt | STRING | NovaAudioMasters/Audio | Folder relative to ComfyUI/output. Save location for mastered Audio, leave blank to save directly in output. |
| identity_selectoropt | STRING | Which archived master to validate against, by identity rather than by file name: release title, ISRC, catalog number, identity ID, report ID or master PCM SHA-256. Names in the archive folder are working names and cannot be trusted; this is matched against the identity recorded inside each report. | |
| lookup_modeopt | COMBO | auto | How the reference archive is found when reference_report_json is empty. auto: identity_selector if set, else archive_name, else content scan. identity: identity_selector only. content scan: ignore every name, measure the candidate and find the archive it matches. archive name: the old file-name lookup. |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| candidate_audio | AUDIO | — |
| sample_rate | SAMPLE_RATE | — |
| validation_report | STRING | — |
| validation_json | STRING | — |
| verdict | STRING | — |
| archive_audio_path | STRING | — |
| archive_report_path | STRING | — |