MiniMax Music Post-Process
From raw waveform to a loopable, loudness-matched track
- audio
- audio
- saved_path
Generated music never lands right. It starts too late, ends abruptly, is way quieter or louder than everything else you have, and doesn't loop. MiniMaxMusicPostProcess is the cleanup crew for the MiniMaxMusicGenerate node - it trims, loops, crossfades, normalizes, and writes a file, all in one output node. It's the "make it usable" step, and it's the kind of deterministic post-processing the KB's post-processing essay argues you should do with a $0 operation rather than a second generation.
The pipeline, in order: trim by trim_start_s (skip from the front) and trim_end_s (cut from the back) - the source computes them as start_sample = trim_start * sample_rate and end_sample = length − trim_end * sample_rate. Then loop: if loop_count > 1, it either repeats the trimmed waveform that many times or, if crossfade_s is set, blends each loop's tail into the next loop's head with linear fades - that's what makes the seam inaudible, and it's the difference between a looping track and a bump every N seconds. Then normalize: if normalize is on, it scales the waveform so its RMS hits a target derived from target_lufs (default −14, the streaming standard), clamped to ±1.0. Finally it writes the file via torchaudio.save to ComfyUI's output directory with an auto-incrementing filename_prefix.
One honest caveat about the "LUFS" label: the implementation scales to a target RMS (10^(lufs/20)), which is a loudness normalization in the RMS sense, not a K-weighted true-LUFS measurement. Fine for matching tracks to a similar level by ear; don't expect broadcast-grade metering from it.
Inputs that matter:
audio(required) - wire fromMiniMaxMusicGenerate'sAUDIOoutput.trim_start_s/trim_end_s(0–600) - trim the dead air off the front and back.loop_count(1–20) andcrossfade_s(0–10) - repeat with a seamless blend; setcrossfade_s> 0 or the loop seam will click.normalize(default on) andtarget_lufs(−30 to 0, default −14) - the level-matching controls.filename_prefixandexport_format(wav,mp3,flac) - where and how it's saved.
Outputs. audio (the processed AUDIO, so you can chain further nodes) and saved_path (a STRING with the full path - handy to feed a "show me where this went" node or wire into a workflow that tracks outputs).
Install. Same pack, same drill:
cd ComfyUI/custom_nodes
git clone https://github.com/TensorVizion/Minimax-H3-Video-Music-Nodes
or ComfyUI Manager, then restart. Deps are just torch, torchaudio, numpy, Pillow. Note: mp3 and flac encoding goes through torchaudio, so make sure your install has the right backend if mp3 export errors - wav always works.
Where it bites. The loop seam: if you crank loop_count without any crossfade_s, you will hear the join, because a straight repeat can't hide phase mismatch. Set a small crossfade and it disappears. Second, normalization is RMS-based as noted, so two tracks both at −14 will be close but not identical in perceived loudness - good enough for a quick comp, not for a master. Third, trim_end_s is measured from the end, so don't try to set it to the same value as the length and zero out the track - the source clamps to at least one sample. And the usual pack context holds: it's a fresh single-commit pack from a one-person author, but this node is the boring, deterministic, low-risk part of it - exactly what you want to trust when the generation side is still finding its feet.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | — | |
| trim_start_s | FLOAT | 0.00–600 | — |
| trim_end_s | FLOAT | 0.00–600 | — |
| loop_count | INT | 11–20 | — |
| crossfade_s | FLOAT | 0.00–10 | — |
| normalize | BOOLEAN | true | — |
| target_lufs | FLOAT | -14.0-30–0 | — |
| filename_prefix | STRING | MiniMaxMusic | — |
| export_format | COMBO | 3 options: wav, mp3, flac |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |
| saved_path | STRING | — |