/
/
/
# What does this implement/fix? The spoken AI Radio sections played noticeably quieter than the music around them. Clips are sound effects, and the streams controller never applies volume normalization to those, so the music was pulled to the normalization target while the host's voice aired at whatever level the TTS engine happened to produce — several dB below it. Speech also can't simply be turned up: it has roughly 16 dB between its average level and its peaks, so a plain gain that reaches the wanted level clips hard. The clip is now evened out and peak-limited instead, so it can sit above the music without ever clipping. While in there: a Dutch host reading English song titles sounded awkward, because the AI was never told what to do with names that stay in another language than the script. ## Changes - Measure the level a text-to-speech engine speaks at, once per voice, and reuse it for every clip that voice renders (clips from one voice land within a dB of each other). - Level each clip against the queue's normalization target plus a new **Spoken Clip Loudness Boost** setting (advanced, default 3 dB), with a limiter holding the peaks so a louder target can never clip. - Leave the clip untouched when the queue does not normalize or when the level could not be measured; otherwise the clip is placed on the target, which also brings an unusually loud voice back down. - Tell the AI to respell foreign names phonetically for the language it is writing in, so a Dutch voice reading an English title stays recognisable. - Fix `parse_loudnorm`, which never matched the report modern ffmpeg prints and so always came back empty. ## Types of changes - [ ] Bugfix (non-breaking change which fixes an issue) — `bugfix` - [ ] New feature (non-breaking change which adds functionality) — `new-feature` - [x] Enhancement to an existing feature — `enhancement` - [ ] New music/player/metadata/plugin provider — `new-provider` - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) — `breaking-change` - [ ] Refactor (no behaviour change) — `refactor` - [ ] Documentation only — `documentation` - [ ] Maintenance / chore — `maintenance` - [ ] CI / workflow change — `ci` - [ ] Dependencies bump — `dependencies` ## Checklist - [x] The code change is tested and works locally. - [x] `pre-commit run --all-files` passes. - [x] `pytest` passes, and tests have been added/updated under `tests/` where applicable. - [ ] For changes to shared models, the companion PR in `music-assistant/models` is linked. - [ ] For changes affecting the UI, the companion PR in `music-assistant/frontend` is linked. - [x] I have read and complied with the project's [AI Policy](https://github.com/music-assistant/.github/blob/main/AI_POLICY.md) for any AI-assisted contributions. - [ ] I have [raised a PR against the documentation repository](https://github.com/music-assistant/music-assistant.io/blob/main/CONTRIBUTING.md) targeting the main or beta branch as appropriate.