Artifact Frequency Analyzer
Find the exact Hz that's making your AI audio sound fake
- audio
- candidate_freqs
- spectrum_plot
AI-generated music usually fails in ways you can name: mush, mush, and then a high, thin whistle you can't quite place. That whistle and that faint metallic "AI sheen" aren't broadband noise - they're narrow spectral peaks, often left behind by the neural-vocoder upsampling that turns latent audio back into sound. And unlike a muddy mix, a narrow peak can be removed surgically. The only problem is finding it. Artifact Frequency Analyzer is a diagnostic node whose entire job is to scan an AUDIO input and hand you back the list of suspicious frequencies - which you then feed straight into its sibling, ArtifactCleaner, to notch out.
It exists because "trust your ears" is terrible UX. You can hear that something is wrong up high, but you can't hear that it's specifically 14801 Hz. This node turns a vague complaint into a paste-able number.
How it finds the needles
The mechanism is a straightforward spectral outlier hunt with one genuinely clever filter on top. It takes your audio (mono-summed from the first item of the batch), runs an STFT, and averages the magnitude over time into a dB spectrum. Then it builds a baseline - a median-filtered version of that spectrum smoothed to about 150 Hz of width - and subtracts. What's left is the residual: how far each frequency sticks up above its own neighborhood. scipy.signal.find_peaks flags anything poking above that baseline by at least prominence_db (default 6 dB), sorted strongest first and capped at the 24 best candidates.
Then the clever bit. Music is full of narrow peaks - that's what notes and harmonics are. If the analyzer reported everything, you'd get a list of the song's actual content and it'd be useless. So reject_musical_notes (on by default) drops any candidate that lands within note_tolerance_hz (default 15 Hz) of a standard 12-TET pitch, A4 tuned to 440 Hz. Vocal notes, instrument fundamentals, and their harmonics cluster tightly on real pitches; true generator artifacts generally don't. That's the difference between "here are the 200 loudest frequencies" and "here are the frequencies that don't belong to any note."
Outputs and what wires where
Two outputs, and you'll use both.
candidate_freqs- aSTRINGof comma-separated integers. This is the money wire: connect it to ArtifactCleaner'sfrequenciesinput and the two nodes form a find-then-fix pipeline. Type the number by hand if you must; wiring it is better.spectrum_plot- anIMAGErendered by matplotlib showing the spectrum, the dashed baseline, red markers on kept candidates, and gray dotted lines on the ones rejected as musical notes. Look at it before you cut anything. Pair it with the pack's Audio Player in Spectrogram mode for a visual before/after.
Inputs you'll actually touch
Defaults are sane, but know what they mean. min_freq/max_freq (2000–18000 by default) set the scan window - the defaults skip sub-bass rumble and the air above 18 kHz where nothing worth cutting lives. prominence_db is your sensitivity dial: raise it if you're drowning in junk candidates, lower it if it's missing something you can hear. Leave reject_musical_notes ON - turn it off and you'll get the song's own notes back. fft_size (2048–16384, default 4096) trades frequency resolution against time resolution: bigger FFTs see finer frequency detail, which suits stationary tones like a constant whistle.
Installing it
Same pack, same install as the cleaner it feeds:
cd ComfyUI/custom_nodes
git clone https://github.com/axces2000/comfyui-axces2000
pip install -r comfyui-axces2000/requirements.txt
Restart, or search "axces2000" in ComfyUI Manager. No model files - this is analysis, not inference. Two environment notes, both real: the pack's declared requirements only list torchaudio and soundfile, but the analyzer hard-imports scipy, so a scipy-less ComfyUI won't load any axces2000 node until you pip install scipy. And matplotlib is imported gracefully - if it's missing you get a blank placeholder image instead of the plot, but candidate_freqs still works, so the core job survives.
If you get nothing back
No candidates usually means one of three things: prominence_db is too strict for what's actually there, the artifact sits outside your min_freq–max_freq window, or the audio genuinely has no narrowband anomaly (some mush is just mush). And a candid caveat: this is a niche tool in a corner of ComfyUI most people never visit - there's essentially no community folklore around it yet, so expect to do a little trial-and-error on the prominence dial the first time. That's fine. It's one node in a pipeline where the alternative is guessing at frequencies by ear.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | — | |
| prominence_db | FLOAT | 6.01–30 | How far a peak must rise above the smoothed baseline to count as a candidate. |
| min_freq | FLOAT | 200020–24000 | — |
| max_freq | FLOAT | 1800020–24000 | — |
| fft_size | COMBO | 4096 | 4 options: 2048, 4096, 8192, 16384 |
| reject_musical_notes | BOOLEAN | true | Drop candidates that land within note_tolerance_hz of a standard 12-TET pitch — filters out vocal/instrument notes and harmonics, which is most of what shows up in a dense mix otherwise. |
| note_tolerance_hz | FLOAT | 151–50 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| candidate_freqs | STRING | — |
| spectrum_plot | IMAGE | — |