Save Audio WAV PCM16|PCM24|FLOAT32 ⬇️
24-bit WAV that works on ROCm, plus a switch that proves it
- audio
- audio
- file_path
ComfyUI's stock audio save takes you through TorchCodec or torchaudio for the actual encoding, and on a ROCm box that's where things get interesting - the encoders aren't always there, and 24-bit and float32 are the first casualties. Poking at a Radeon and getting 16-bit mono-ish output with no error is a known genre of afternoon.
Save Audio WAV PCM16|PCM24|FLOAT32 ⬇️ sidesteps the whole stack. The writers are pure struct/numpy - no torchaudio, no TorchCodec, no external binary - which is precisely what makes 24-bit and 32-bit float output work on a card where the torch encoders don't. The code is ported from ComfyUI-SoundHub (MIT, Yuan-Man) and the original project is left untouched; both packs' save nodes coexist fine.
Inputs
- audio - the thing you're saving.
- file_path - default
NovaAudio. Subfolders supported. - format -
wavonly in this build, and the tooltip says why: it's written directly, without TorchCodec. - wav_encoding -
PCM_16,PCM_24(default) orFLOAT_32. 24-bit for delivery, float32 for archival intermediates you'll keep processing. - filename_mode - this one is a real decision.
exact (overwrite)treatsfile_pathas the final path and overwrites it;appends number e.g. 00001gives you_00001.wavstyle increments. For a master you're versioning, appending is the safer default; for a fixed delivery name that a downstream tool expects, exact is correct. - reload_after_save - the interesting one. See below.
- sample_rate (optional) - an INT override for the rate carried in the AUDIO payload.
0means "use the payload's own rate", which is what almost every graph wants. This used to be SoundHub's privateSAMPLE_RATElink type, which would have made this node depend on that pack being installed.
Outputs: audio and file_path (the absolute path written).
The switch worth using
reload_after_save off - the audio output is your input, passed straight through, and you move on. reload_after_save on - the file is read back off disk and that is what leaves the output. Which means the audio you hand downstream is the real quantised 24-bit or 16-bit samples, not what you hoped they'd be.
That's the difference between trusting a dropdown and verifying a render. Wire the output into a player or a validator, and you're measuring the file rather than the intent. For a mastering chain where you signed off on a master and then wrote to disk, this is the honest way to check the write didn't change anything.
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 → 📦 Delivery & Metadata. No models, no downloads, no extra pip packages for this node - it's struct and numpy against an already-correct AUDIO payload.
Notes from the field
Where's MP3? Deliberately not here, and not on the player's download arrow either. The pack's position is that lossy is a transcode you do at the end - the WAV is one ffmpeg command away when you need it. If you need MP3 inside ComfyUI, add a node for it rather than asking this pack to be one.
Sample rate overrides are easy to regret. Setting sample_rate higher than your source doesn't add bandwidth - it just relabels and upsamples. Resample before the save if you actually want 48k from a 44.1k render.
ROCm users: the pack is explicit that its loader and encoder paths are CPU-side on purpose - a CPU float32 payload, moving to the GPU only inside the nodes that need it. That's both the ComfyUI-correct convention and the reason it doesn't trip the HIP allocator. Which is also why an NVIDIA-only troubleshooting checklist full of --no-half flags and xformers advice isn't relevant here.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | The audio to save. | |
| file_path | STRING | NovaAudio | The prefix for the file to save. Subfolders are supported. |
| format | COMBO | wav | WAV only in this build — written directly, without TorchCodec. |
| filename_mode | COMBO | exact (overwrite) | exact (overwrite): file_path is the path and file name that will be overridden Appends number: appends new number e.g. _00001.wav |
| reload_after_save | BOOLEAN | false | Off: the audio output passes the input through untouched. On: the file is read back off disk and that is what leaves the audio output — the real quantised samples, for verifying a 24-bit or 16-bit render rather than trusting it. |
| wav_encoding | COMBO | PCM_24 | PCM_16 = 16-bit PCM, PCM_24 = 24-bit delivery/master WAV, FLOAT_32 = 32-bit IEEE float archival WAV. |
| sample_rateopt | INT | 00–768000 | Override the rate carried in the AUDIO payload. 0 = use the payload's own rate. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | With reload_after_save on, the file read back off disk — the actual quantised samples. With it off, the input audio passed straight through. |
| file_path | STRING | Absolute path of the file that was written. |