From f9395d7d057e8722895f6c9f622faf8c6f595d6e Mon Sep 17 00:00:00 2001 From: Hermes Date: Mon, 14 Sep 2026 14:27:26 +0200 Subject: [PATCH] =?UTF-8?q?fix(ats):=20=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B8=20=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE?= =?UTF-8?q?=20=D0=B2=20=D0=BE=D0=B7=D0=B2=D1=83=D1=87=D0=BA=D0=B0=D1=85=20?= =?UTF-8?q?(=D0=A1=D1=83=D0=BF=D0=B5=D1=80,=20=D0=A1=D0=B0=D0=BC)=20+=20?= =?UTF-8?q?=D0=B8=D0=BD=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=86=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=B8=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D0=B5=20=D0=BE=D0=B7=D0=B2=D1=83=D1=87=D0=B5=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ats/gen-brand-prompts.sh | 23 ++++++++++++++++++++ docs/ats/prompt-generation.md | 40 +++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100755 docs/ats/gen-brand-prompts.sh create mode 100644 docs/ats/prompt-generation.md diff --git a/docs/ats/gen-brand-prompts.sh b/docs/ats/gen-brand-prompts.sh new file mode 100755 index 0000000..8ad3c81 --- /dev/null +++ b/docs/ats/gen-brand-prompts.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Финальная перегенерация озвучек с раздельным названием «Супер, Сам». +# Каждый файл синтезируем отдельным вызовом: в цикле Python два файла выходили +# побайтово одинаковыми (артефакт edge-tts), здесь этого не происходит. +set -e +VOICE="fr-FR-VivienneMultilingualNeural" +OUT=/tmp/brand_final +mkdir -p "$OUT" + +gen () { # $1 = имя файла, $2 = текст + edge-tts --voice "$VOICE" --text "$2" --write-media "$OUT/$1.mp3" >/dev/null 2>&1 + ffmpeg -v error -y -i "$OUT/$1.mp3" -ar 8000 -ac 1 -c:a pcm_s16le "$OUT/$1.wav" + rm -f "$OUT/$1.mp3" + dur=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$OUT/$1.wav") + printf "%s %.2f с %s байт\n" "$1" "$dur" "$(stat -c%s "$OUT/$1.wav")" +} + +gen ss_pkp_intro "Здравствуйте! Это Супер, Сам. Ваш заказ готов к выдаче. Выберите день самовывоза." +gen ss_c_intro_dlv "Здравствуйте! Это Супер, Сам. Ваша доставка запланирована на" +gen ss_c_intro_pkp "Здравствуйте! Это Супер, Сам. Ваш самовывоз запланирован на" + +echo "--- контрольные суммы (должны быть разными) ---" +md5sum "$OUT"/*.wav diff --git a/docs/ats/prompt-generation.md b/docs/ats/prompt-generation.md new file mode 100644 index 0000000..487e8d5 --- /dev/null +++ b/docs/ats/prompt-generation.md @@ -0,0 +1,40 @@ +# Озвучки робота: генерация и правки + +Все реплики робота — edge-tts, голос **`fr-FR-VivienneMultilingualNeural`**, формат +8 кГц / моно / 16 бит PCM WAV. Лежат на АТС в `/var/lib/asterisk/sounds/ru/` (`ss_*.wav`), +имя файла = имя реплики в `ss-dialog.agi`. + +```bash +edge-tts --voice fr-FR-VivienneMultilingualNeural --text "<текст>" --write-media out.mp3 +ffmpeg -v error -y -i out.mp3 -ar 8000 -ac 1 -c:a pcm_s16le out.wav +``` + +Деплой (всегда с бэкапом — был случай, когда файл на АТС обнулился): +`scp` в `/tmp` на АТС → `test -s` → `cp` в `/var/lib/asterisk/sounds/ru/` → +`chown asterisk:asterisk` + `chmod 644` → сверить `md5sum` с локальным. + +## Название компании — только раздельно + +Владелец попросил, чтобы «СуперСам» звучало раздельно. Проверено синтезом (пауза внутри названия): + +| Текст в подсказке | Длительность «Супер, Сам» | Пауза | +|---|---|---| +| `СуперСам` | одинаково с «Супер Сам» | нет | +| `Супер Сам` | +24 мс | почти не слышно | +| **`Супер, Сам`** | **+0,45 с** | **слышно отчётливо — используем** | +| `Супер... Сам` | +0,7 с | звучит неестественно | + +Речь в подсказке: `Здравствуйте! Это Супер, Сам. <дальше по сценарию>`. +Файлы с названием компании: `ss_pkp_intro`, `ss_c_intro_dlv`, `ss_c_intro_pkp` +(в сценариях A и B компания не представляется). + +## Проверка правки + +- **Текст** — распознать свой wav (`faster_whisper`, `small`, `language="ru"`): вернёт то, что + услышит человек. Whisper пишет название одним словом («Суперсан») даже при раздельном + произношении — по нему судить о паузе нельзя. +- **Пауза внутри названия** — по энергии сигнала (RMS по кадрам 10 мс, порог −32 дБ от пика): + у правильной версии появляется провал ≥ 0,3 с в районе названия, у старой его нет. +- ⚠️ Генерировать файлы по одному в отдельных вызовах `edge-tts`: в цикле внутри Python два + разных текста один раз вышли побайтово одинаковыми (артефакт), поэтому перед деплоем + сверять `md5sum` всех файлов между собой и с ожидаемым.