Iroha-TTS / spatial /README.md
cyacya8023's picture
Claude Opus 5.5
Add binaural 360 post-processing (spatial/) and its agent guide section
9394dd2 verified
|
Raw History Blame Contribute Delete
4.05 kB

Binaural 360° post-processing

Places finished speech around the listener's head for headphones: circling, sweeping from ear to ear, or held at one spot. 中文

This is a separate post-processing step, not a feature of the Iroha-TTS model. It works on any speech recording and needs no GPU or model weights.

Quick start

python3.12 -m venv .venv-spatial
.venv-spatial/bin/pip install -r spatial/requirements.txt

# Start at the left ear and circle the head twice, at 0.5 m
.venv-spatial/bin/python spatial/binaural.py --in a.wav b.wav c.wav --gap 0.6 --start -90 --turns 2 --near 0.8 --out orbit.wav

# Sweep from the left ear through the front to the right ear
.venv-spatial/bin/python spatial/binaural.py --in a.wav b.wav --start -90 --turns 0.5 --near 0.6 --out sweep.wav

# Hold at the right ear, 0.25 m
.venv-spatial/bin/python spatial/binaural.py --in a.wav --start 90 --turns 0 --near 1 --out right.wav

Parameters

Parameter Default Meaning
--in Required Clips in playing order. Any sample rate; stereo is mixed to mono.
--gap 0.6 Silence before each clip after the first, in seconds.
--gaps Unset One silence per clip after the first. Overrides --gap.
--lead 0.5 Silence before the first clip, in seconds.
--keep-level Off Keep the clips' relative levels (pieces cut from one take). Otherwise each clip is set to -20 dBFS RMS first.
--start -90 Azimuth where the first clip starts: 0° front, 90° right, 180° behind, 270° (or -90°) left.
--turns 1 Turns from the first clip's start to the last clip's end. Positive is clockwise seen from above, negative the other way, 0 holds still.
--near 0.8 Closeness from 0 to 1. Picks the measured distance: ≥ .9 is 0.25 m, ≥ .7 is 0.5 m, ≥ .55 is 0.75 m, otherwise 1 m. Each 0.25 also adds 1 dB.
--ceil 0.99 Peak limit.
--hrir spatial/hrir Folder with the four SOFA files.
--out Required Output WAV. A log with the same name and .json is written next to it.

The output is a 48 kHz, stereo, 24-bit WAV with voiced parts near -20 dBFS RMS (limiting can lower this by about 1 dB). The path moves at constant speed and keeps moving during pauses, so each clip starts wherever the path has reached.

The log lists each clip's start, duration, azimuths, and ild_db, the level of the right ear minus the left. Use it to check the side: positive means the right ear is louder.

How it works

Each position is rendered by convolving the voice with the left- and right-ear impulse responses measured for that direction on a KU100 dummy head. The level difference, time difference, and spectral coloring between the ears come from the measurements. On a moving clip the response changes every 20 ms with a triangular crossfade.

Limitations

  • Headphones only. Over loudspeakers, or after a mono downmix, the effect is lost. Do not apply further panning or stereo processing to the output.
  • Front and back are easily confused. The KU100 is a generic head, not fitted to each listener, and some listeners hear the voice inside the head. Left, right, and close-to-ear positions are the clearest.
  • Horizontal circle only. There is no elevation control, and only the four measured distances are available.
  • No perceptual study was run on these settings. Listen before choosing a distance.

License and credit

binaural.py is under the MIT License (LICENSE-MIT). The SOFA files are by TH Köln under CC BY-SA 3.0 (hrir/LICENSE). If the voice comes from Iroha-TTS, that audio remains subject to the Fish Audio Research License, and the speaker's consent is still required.

When you publish rendered audio, credit the measurements. We do not take a position on whether rendered audio counts as an adaptation of the data, so crediting is the cautious choice:

Binaural rendering uses KU100 near-field HRIRs by TH Köln (CC BY-SA 3.0).