Spatial Audio Enhance
OTR_AudioEnhance
- audio
- enhanced_audio
Raw TTS is flat, and flat is the wrong sound for a radio drama. OTR_AudioEnhance is the stage that makes it broadcast-ready - the same job a mastering engineer does, minus the engineer. In the OldTimeRadio pipeline it sits between the voice engines and OTR_EpisodeAssembler, and it's the reason a Kokoro or Bark line can sit next to music without sounding like a computer reading.
The headline number is target_sample_rate: 48000 Hz is the broadcast standard, and the canonical workflow runs the whole frozen master at 48k. Everything in this node points at that one goal - sounding like it came off a real transmitter.
How it works
It's a fixed DSP chain, and the order matters. Resample to the target rate → widen mono to stereo → add bass warmth → low-pass → Haas delay → tape emulation → mid-side stereo widening. Everything runs on CPU on purpose (the pack's determinism rules: a GPU op here would make the audio vary run to run and fight the video branch for VRAM).
Two controls are worth knowing before the rest:
lpf_cutoff_hz(default 16000) - this exists because Bark chirps on high frequencies. The low-pass kills those artifacts at the source. If your dialogue sounds like it's underwater, this is the dial.haas_delay_ms(default 0.4) - the Haas effect: a tiny delay on one channel that tricks your brain into hearing space. 0.2–0.8 ms is natural, 0 is off. It's the cheapest "room" you'll ever buy.
spatial_width (0.3 = natural, 1.0 = extreme) does mid-side widening, bass_warmth (0.1 subtle) gives that AM-radio bottom, and tape_emulation (off/subtle/medium/heavy) adds analog warmth. normalize_dbfs defaults to −1.0 dBFS, the broadcast ceiling.
Here's the trap: the source code skips peak normalization on purpose. It defers the final −1 dBFS pass to OTR_EpisodeAssembler, post-crossfade - normalizing here caused clipping during segment overlaps. So don't crank normalize_dbfs expecting it to do the whole job; the assembler finishes it.
What you actually set
The only required input is audio. The rest have sane defaults. If you're curious where the broadcast magic is, try spatial_width 0.5 and haas_delay_ms 0.6 on a narration clip and A/B it - that's the "oh, it's not broken, it's a room" moment. Output is a single enhanced_audio AUDIO that feeds the assembler.
Install and gotchas
Installs with the pack (ComfyUI Manager → ComfyUI-OldTimeRadio, or git clone + git checkout v2.0-alpha, restart). Audio DSP here uses numpy + soundfile, both in the pack's requirements.txt. The node also writes a schema-l3 gate record into the in-flight ledger (wall-clock timing, waveform hash) - best-effort, never aborts the render if metadata fails, so don't panic if you see a warning in the console. Watch the log for the "Bark chirps" line: if the LPF is doing nothing, you're probably feeding it a low-sample-rate mono input and it's resampling from 24k - check what your voice engine actually emitted.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | — | |
| target_sample_rateopt | INT | 4800024000–96000 | Target sample rate in Hz (48000 = broadcast standard) |
| spatial_widthopt | FLOAT | 0.000–1 | Mid-side stereo width ADDED to the signal: 0=none (default; the supplied image is kept), 0.3=natural, 1.0=extreme |
| haas_delay_msopt | FLOAT | 0.00–2 | Haas effect delay ms (0=off, default; 0.2-0.8 = natural widening) |
| bass_warmthopt | FLOAT | 0.000–0.5 | Low-freq warmth shelf (0=off, default; 0.1=subtle) |
| lpf_cutoff_hzopt | FLOAT | 00–24000 | Optional low-pass cutoff Hz for a voice engine that leaves high-frequency chirp artifacts (0=off, default; 16000 is a gentle cleanup) |
| tape_emulationopt | COMBO | off | Deterministic analog tape emulation. Each step up adds more period character (saturation, wow/flutter; no synthetic hiss) and costs more clarity -- 'heavy' audibly softens dialogue. 'off' is the clean master; this is an audible episode-facing choice, not a technical knob. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| enhanced_audio | AUDIO | — |