# VIP Drop Ball · 欢乐街机音效首版

依据《音效需求单.pdf》（2026-09-24），按用户选择的“欢乐街机：活泼、弹跳感强、奖励音更夸张”制作。

这是可试听、可供开发接入验证的首版。音乐与音效为本次程序合成制作，未使用外部采样。16 句英文 VO 已使用豆包 Seed TTS 2.0 的 Allison 美式女声重新合成，按欢迎、落球、中奖和 Plinko 场景设计明亮活泼的主持人表演，保留原台词。没有游戏画面或动画时间轴，因此当前时长需在接入后对齐。

## 先听什么

- 打开 `index.html`，可直接按分类试听全部 41 个文件，无需联网。
- `preview/04_all_voiceovers.mp3`：全部 16 句新生成人声连听，按清单顺序排列；`preview/voice_timeline.json` 提供对应时间点。
- `preview/01_full_walkthrough.mp3`：约 63 秒的完整风格串烧，覆盖待机、下注、落球、四档中奖、Plinko 与大奖。
- `preview/02_win_tiers.mp3`：Regular → Big → Mega → Super Mega，留空分隔便于比较。
- `preview/03_plinko_jackpot.mp3`：Plinko 钉柱、三级入口落定和大奖叠加示例。

串烧为了展示声音，会连续演示所有中奖档和入口档，不代表一局的真实游戏逻辑。

## 文件与规格

| 文件夹 | 数量 | 内容 |
|---|---:|---|
| `audio/music` | 3 | 待机、基础游戏、Plinko 配乐 |
| `audio/sfx` | 22 | 交互、碰撞、奖励、悬念、大奖 |
| `audio/vo_placeholder` | 16 | 豆包 AI 英文人声，包含六种牌面；目录名为兼容现有接入保留 |

正式素材格式统一为 WAV / PCM / 48 kHz / 24 bit / 双声道。VO 是居中双单声道。试听 MP3 仅用于审听，不用于精确无缝循环。

`manifest.json` 与 `asset_list.csv` 提供稳定 ID、路径、时长、循环标记、BPM、触发条件及台词。CSV 使用 UTF-8 BOM，可用 Excel 打开。`qa_report.json` 是自动化音频检测结果。

`voice_review.json` 保存本次 16 句的本地 Whisper 转写核对结果与音频校验和；忽略标点、大小写和数字拼写后，全部匹配合成输入。当前工具无法直接听取音频，因此这项检查不代表自然度、情绪表现或精确发音已完成人工审听。更换语音后需重新做内容核对；日常交付重建不会自动更新这份一次性审查记录。

音乐统一采用 C 大调音色体系，便于叠加同一组奖励声音。三首音乐都为 16 小节，分别是 108 / 132 / 148 BPM；Plinko 悬念床为 4 秒、120 BPM 的独立循环。

## 接入顺序与混音

以下增益与冷却时间是首版制作建议，不是需求单新增的硬性规则。`integration_rules.json` 将确定规则与待确认项目分开记录。

1. 同时只播放一首背景音乐，曲目切换时交叉淡化约 350 ms。循环直接使用整段 WAV，从第 0 帧回到第 0 帧，不裁掉循环头尾，也不在每一圈加淡入淡出。声音加载完再触发。Web 游戏需由用户首次交互解锁音频。
2. 初始可设 music 总线 −8 dB、sfx −3 dB、vo −3 dB、master −3 dB。语音播放时，背景音乐额外降低约 6 dB，语音结束后约 250 ms 恢复。播放器里的单条试听播放原文件，未应用这些运行时总线增益。
3. 落球释放、台面弹跳按物理事件触发。`ball_land` 是单次接触，不是多次弹跳组合。Plinko 所有钉柱均使用 `plinko_peg`，不根据结果改变音色；最多 6 路并发，可按碰撞速度调音量。
4. `chip_win` 按实际中奖区块数量重复；建议顺序间隔至少 120 ms。最后一个筹码中奖声音播放完，再选择一档中奖横幅声音，每局仅一次。高亮音随高亮动画触发，可以轻声叠加。
5. Plinko 入口未确定时循环 `plinko_suspense_loop`，结果确定时约 80 ms 淡出；悬念床不暗示结果。三级入口使用 `plinko_land_low/mid/high`；非大奖播放 `plinko_win`。两侧大奖入口都用 High。
6. 大奖出现时，`plinko_land_high` 与 `jackpot_celebration` 同帧叠加，High 可额外降低 3 dB，背景音乐暂停或大幅降低。`jackpot_banner` 随横幅／弹窗出现，庆祝中额外降低 6 dB。同一玩家端的两个视觉组件若同时出现，应去重为一次声音。
7. 对大奖混音和密集碰撞设置峰值限制器，例如 −1 dBTP。包内 `qa_report.json` 检查了建议增益下的 High + 大奖 + 横幅叠加；真实游戏更复杂的叠加仍需接入后验证。

## VO 规则

- 进入主画面：`vo_welcome` 每次载入一次，100%。
- 每局释放落球：三个 `vo_release_*` 随机必选一句，100%。等概率为本版建议，PDF 只要求随机择一。
- 本局有派彩：先进行一次 40% 的播放判定；60% 不播放中奖语音，不影响音效。若播放，再按条件选库，不能对每个中奖区块分别抽一次 40%。
- 仅下注一个区块且中奖：选择对应 `vo_card_king/queen/jack/ace/10/9`。
- 下注多个区块且至少两个中奖：`vo_win_more`。
- 其它中奖情况：三个 `vo_win_*` 通用语料中随机一句（不包含 `vo_win_more`）。
- 触发 Plinko：两个 `vo_plinko_*` 随机择一的总播放概率尚未确定，不要直接当作 100% 写死。
- 语音总线保持单句播放，避免多段主持人同时说话；Plinko 与中奖语音同轮的优先级需要产品确认。

## 还需要对齐的内容

1. 需求单提到的 High / Mid / Low 入口分级表未附在这份 PDF 中。只确定两个大奖边缘入口都为 High，不能推测其它入口。
2. Regular / Big / Mega / Super Mega 的实际派彩倍数阈值、完整第 4.4 节未提供。
3. Plinko 触发语音概率，以及它与同轮中奖语音的播放优先级。
4. 各动画的实际时长，以及本次明亮活泼女声的主观听感验收。当前音效均有自然尾音，建议保留尾音并对齐起音，不直接粗暴拉伸。

## 修改与重建

- `source/build_audio.py`：音乐、音效、素材清单与串烧的生成脚本。默认复用已有 VO；`--vo-only --reuse-vo` 仅刷新语音元数据与串烧，保持音乐／音效文件原样。只有显式传入 `--regenerate-samantha` 才会重新生成 macOS 占位语音。固定随机种子便于复现音乐／音效。
- `source/build_voice.py`：豆包 Seed TTS 2.0 人声生成工具，固定使用 Allison 美式女声，按场景传入独立表演指令。先生成候选，再安装完整的 16 句；不会在请求中途覆盖交付素材。
- `source/build_delivery.py`：生成试听页、压缩试听和检测报告，依赖 NumPy、SciPy、pyloudnorm、imageio-ffmpeg。运行于其它系统时可保留已有 WAV，只重建试听页面。
- 调整后先试听真实场景中的音量、碰撞密度、循环感和 VO 表演，再定正式版本。

### 下载入口开关

试听页默认隐藏卡片的「下载 WAV」和页脚的 CSV、manifest 下载链接，保留试听、搜索、分类、接入说明与检测报告。开关由生成命令控制，网页上不提供切换按钮。

```sh
# 隐藏下载入口（默认）
.venv/bin/python source/build_delivery.py

# 恢复下载入口
.venv/bin/python source/build_delivery.py --allow-downloads
```

每次生成时重新选择模式；不带参数运行会恢复隐藏。生成命令会同时刷新试听页、MP3 预览和技术检测报告。更新线上页面时，需要重新发布生成的 `index.html`。

隐藏模式使用 `controlslist="nodownload"` 请求浏览器隐藏播放器自带的下载菜单；[浏览器支持情况](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/controlsList)有所不同。这只是界面开关，不是访问控制：页面仍直接播放原始 WAV，音频可通过文件地址、网络请求或录音获得，不能保证阻止他人保存。

### 豆包人声重建

```sh
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python source/build_voice.py --env-file /path/to/.env.local --output-dir .cache/vo-final
.venv/bin/python source/build_voice.py --install-from .cache/vo-final
.venv/bin/python source/build_audio.py --vo-only --reuse-vo
.venv/bin/python source/build_delivery.py
.venv/bin/python -m unittest discover -s source/tests -v
```

配置文件只读取 `VOLCENGINE_APP_ID`、`VOLCENGINE_ACCESS_TOKEN`，进程环境变量优先。使用火山官方单向流 HTTP 接口与 `seed-tts-2.0` 资源；凭证不复制到本项目，不进入页面、日志或生成记录。

用 `--ids vo_welcome vo_release_here` 生成指定句子，`--variant b` 增强惊喜与节奏感；不同候选放到不同输出目录。相同参数和音频校验和命中时复用候选；`--force` 才强制重录。选定后将全部 WAV 与对应的 `voice_generation.json` 记录汇总到一个候选目录，安装工具会检查 16 句是否完整、台词和校验和是否匹配、格式及峰值是否合格。

安装后的 `voice_generation.json` 记录音色、原文、发音文本、逐句表演指令、请求参数、时间及音频校验和，不含凭证。云端合成不保证再次生成完全相同的波形，因此以已交付 WAV 为准；`--reuse-vo` 无需联网，并保留其原始字节和来源记录。输出为 48 kHz / 24-bit 居中双声道，响度目标 −18 LUFS，真峰值上限 −3 dBTP 优先于响度目标。

为保证发音，合成输入将 VIP 展开为 V I P、数字牌面展开为 Ten / Nine；Ace's 展开为等义的 Ace is，避免缩写尾音被吞掉。页面与素材清单中的原始英文台词不变。

生成工具将超时、限流和暂时性服务错误最多尝试三次；鉴权、音色权限、无音频及校验错误会停止。发生错误时先修复原因，再复用已完成的候选继续生成。
