Files
SoundGame/docs/setup.md
T
SoundGame Dev f0f0a9b50e 初始提交:3 款纯音频游戏 + 共享引擎 + 完整文档与资产管线
- 共享引擎(app/src/main):GestureEngine 6 手势识别、AudioEngine 三层音频
  (ExoPlayer BGM 交叉淡入 / 对白 ducking / SoundPool 低延迟)、Game/GameEngine
  状态机接口、MainActivity 全屏封面 + TalkBack
- 《声命线》storyline:末世互动广播剧,3 幕 8 抉择点 4 结局
- 《声东击西》reflex:听声辨位反应,12 波战斗 + BGM 三档 BPM 变速
- 《暗室》escape:3x3 网格密室逃脱,钥匙→铁柜→保险丝→电箱→大门谜题链
- 文档:setup(从零搭建)/ architecture(架构)/ engine-api(引擎 API)/
  asset-pipeline(资产流水线)/ games/*(三款游戏设计文档)
- 资产管线:Qwen3-TTS 对白 + 程序合成音效/BGM + Mureka BGM 的 gen 脚本与台账,
  全部 ogg 资产入库可复现
- env.d 环境脚本:android/tts 入库;sfx/mureka 含密钥不入库,仅提交 .example.sh 模板
2026-08-29 13:00:34 +08:00

9.4 KiB
Raw Blame History

SoundGame — 从零环境搭建手册

本文档描述在一台全新的 WSL2(Ubuntu)机器上,如何以**纯用户态(无 sudo)**方式 复现本项目的全部开发环境:Android 构建链、Qwen3-TTS 对白生成、Stable Audio 3 音效生成、ffmpeg 音频处理。

前置条件:

  • WSL2 + Ubuntu,能访问外网(部分站点需走镜像,见文末速查表)
  • NVIDIA GPU(本项目用 RTX 3090 24GB)+ Windows 侧已装 NVIDIA 驱动 (WSL2 透传 CUDA,无需在 WSL 内装驱动,只需 nvidia-smi 能跑通)
  • 项目放在 /home/ubuntu/SoundGame,下文所有路径以此为准

为什么不用 apt

  • 本机没有 sudo 权限,apt install 直接不可用;
  • 即使可用,Ubuntu 仓库的 JDK / Android SDK / ffmpeg 版本也偏旧, 且会污染系统目录,不利于把整个环境收进项目目录随仓库一起搬走;
  • 所有工具因此都装在 /home/ubuntu/SoundGame/tools/ 或用户目录下, 通过 env.d/*.sh 注入 PATH 使用,不开 shell 不污染环境。

1. uv(Python 包/环境管理)

curl -LsSf https://astral.sh/uv/install.sh | sh   # 装到 ~/.local/bin
~/.local/bin/uv --version                          # 实测 0.12.7 (x86_64-unknown-linux-gnu)

uv 自带 python 管理和虚拟环境管理,后续两个 venv 都由它创建。 注意 uv 不在默认 PATH,env.d/sfx.sh 里有 export PATH="$HOME/.local/bin:$PATH"。

2. JDK 17(用户态)

# 来源:华为云镜像的 Oracle OpenJDK 17.0.2(Adoptium 官方源在本机过慢)
# https://repo.huaweicloud.com/openjdk/17.0.2/openjdk-17.0.2_linux-x64_bin.tar.gz
cd /home/ubuntu/SoundGame/tools
curl -LO https://repo.huaweicloud.com/openjdk/17.0.2/openjdk-17.0.2_linux-x64_bin.tar.gz
tar xzf openjdk-17.0.2_linux-x64_bin.tar.gz
mv jdk-17.0.2 jdk17
tools/jdk17/bin/java -version   # openjdk 17.0.2

3. Android SDK(cmdline-tools,无 Android Studio)

cd /home/ubuntu/SoundGame/tools
# 来源:Google 官方 dl.google.com(commandlinetools-linux-15859902_latest.zip)
curl -LO https://dl.google.com/android/repository/commandlinetools-linux-15859902_latest.zip
unzip commandlinetools-linux-15859902_latest.zip -d android-sdk-tmp
# 官方要求目录结构必须是 cmdline-tools/latest/,否则 sdkmanager 报路径错误
mkdir -p android-sdk/cmdline-tools
mv android-sdk-tmp/cmdline-tools android-sdk/cmdline-tools/latest
rm -rf android-sdk-tmp commandlinetools-linux-15859902_latest.zip

source /home/ubuntu/SoundGame/env.d/android.sh   # 注入 JAVA_HOME/ANDROID_HOME/PATH
yes | sdkmanager --licenses
sdkmanager "platform-tools" "platforms;android-36" "build-tools;36.0.0"

安装结果(与 env.d/android.md 一致):platform-tools 37.0.1、android-36、 build-tools 36.0.0。

4. ffmpeg / ffprobe(静态构建)

# 来源:BtbN/FFmpeg-Builds 的 linux-x86_64 静态版(crosstool-NG 构建,零依赖)
# https://github.com/BtbN/FFmpeg-Builds/releases (ffmpeg-master-latest-linux64-gpl.tar.xz)
mkdir -p /home/ubuntu/SoundGame/tools/bin
# 解压后把 ffmpeg / ffprobe 两个二进制放进 tools/bin/ 即可
/home/ubuntu/SoundGame/tools/bin/ffmpeg -version
# 实测版本 N-126303-g9f35e220ff-20260827,含 libvorbis/libmp3lame/libopus

必须用含 libvorbis 的构建(资产出片格式是 ogg vorbis),GPL 版静态包自带。

5. Gradle

不需要单独安装:项目用 Gradle Wrapper,首次 ./gradlew 自动下载。 本机 dl.google.com / services.gradle.org 均较慢,wrapper 已指向腾讯镜像:

# gradle/wrapper/gradle-wrapper.properties
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.13-bin.zip

首次构建:

source /home/ubuntu/SoundGame/env.d/android.sh
cd /home/ubuntu/SoundGame
./gradlew assembleDebug   # 首次下载依赖较慢属正常,daemon 有缓存

6. Qwen3-TTS 对白环境(.venv-tts)

cd /home/ubuntu/SoundGame
~/.local/bin/uv venv .venv-tts --python 3.12        # 实测 Python 3.12.14
# PyPI 走阿里云镜像,torch 需 cu128 轮子
~/.local/bin/uv pip install --python .venv-tts/bin/python \
  --index-url https://mirrors.aliyun.com/pypi/simple/ \
  qwen-tts soundfile transformers
~/.local/bin/uv pip install --python .venv-tts/bin/python \
  torch torchaudio --index-url https://download.pytorch.org/whl/cu128

实测版本:torch 2.11.0+cu128、torchaudio 2.11.0+cu128、qwen-tts 0.1.1、 transformers 4.57.3。

模型下载(共 3 个仓库,缓存在 models/hf,由 HF_HOME 指定):

source /home/ubuntu/SoundGame/env.d/tts.sh   # HF_HOME + HF_ENDPOINT=https://hf-mirror.com
.venv-tts/bin/python -c "
from huggingface_hub import snapshot_download
for repo in ['Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice',
             'Qwen/Qwen3-TTS-12Hz-1.7B-VoiceDesign',
             'Qwen/Qwen3-TTS-Tokenizer-12Hz']:
    snapshot_download(repo); print('ok', repo)
"

镜像注意事项:本机连不通 huggingface.co,公开模型必须走 HF_ENDPOINT=https://hf-mirror.com(tts.sh 已设好)。Qwen 三个仓库均为公开 仓库,经镜像下载无障碍;gated 模型则不能走镜像,见下节。

冒烟测试:

source env.d/tts.sh
.venv-tts/bin/python tools/tts_smoke_test.py
# 输出 tools/samples/tts_test.wav(约 2s,24kHz)

详细用法(CustomVoice / VoiceDesign / 预置音色表)见 env.d/tts.md。

7. Stable Audio 3 音效环境(gated 模型)

cd /home/ubuntu/SoundGame/tools
git clone <stable-audio-3 仓库> stable-audio-3    # 项目内已有副本
cd stable-audio-3
cp /home/ubuntu/SoundGame/env.d/sfx.example.sh /home/ubuntu/SoundGame/env.d/sfx.sh
# 编辑 sfx.sh 填入真实 HF_TOKEN(见下)
source /home/ubuntu/SoundGame/env.d/sfx.sh
uv sync --extra ui        # Python 3.10 venv,PyPI 走阿里云镜像(sfx.sh 已设)

实测:Python 3.10.6,torch 2.7.1+cu126,CUDA 验证通过。

gated 模型 token 获取流程

stabilityai/stable-audio-3-small-sfx 是 gated(auto 批准) 仓库:

  1. 注册/登录 HuggingFace 账号;
  2. 打开 https://huggingface.co/stabilityai/stable-audio-3-small-sfx 接受 Stable Audio Community License(auto 模式立即通过,无需人工审核);
  3. 在 https://huggingface.co/settings/tokens 创建 read 权限 token;
  4. 填入 env.d/sfx.sh 的 HF_TOKEN(该文件已被 .gitignore 忽略,不会入库)。

坑:hf-mirror 对 gated 模型的 308 重定向

gated 模型不能走 hf-mirror:镜像会把带 token 的请求 308 重定向回 huggingface.co,本机直连官方又不可达时会直接失败。因此 env.d/sfx.sh 里 故意不设 HF_ENDPOINT(直连官方端点,当前实测 huggingface.co 对该域名 可达)。如果以后直连失效且只下公开模型,可临时取消脚本里的镜像注释。

Qwen3-TTS(公开)走镜像、Stable Audio 3(gated)走直连——这就是 tts.sh 与 sfx.sh 的 HF_ENDPOINT 配置相反的原因。两个环境不要同时 source。

8. Mureka BGM API(可选,需付费 key)

cp env.d/mureka.example.sh env.d/mureka.sh   # 填入 https://platform.mureka.ai 的 key
source env.d/mureka.sh
python3 tools/mureka_gen.py --prompt "..." --out tools/mureka_out/xxx

env.d/mureka.sh 含真实 API key,已被 .gitignore 忽略。计费与调用记录见 tools/mureka_log.md,完整流程见 docs/asset-pipeline.md。

网络镜像速查表

用途 镜像 配置位置
HuggingFace 公开模型 https://hf-mirror.com HF_ENDPOINT(tts.sh / gen 脚本内)
HuggingFace gated 模型 不可用,直连官方 sfx.sh 故意不设 HF_ENDPOINT
PyPI https://mirrors.aliyun.com/pypi/simple/ UV_DEFAULT_INDEX / uv pip --index-url
Gradle 发行包 https://mirrors.cloud.tencent.com/gradle/ gradle/wrapper/gradle-wrapper.properties
JDK https://repo.huaweicloud.com/openjdk/ 手动下载

常见故障排查

sdkmanager 提示路径/找不到 cmdline-tools 必须位于 android-sdk/cmdline-tools/latest/,多一层少一层都会报错。

Gradle 下载卡住 确认 wrapper 用的是腾讯镜像(见上);依赖仓库(google/mavenCentral)本机直连可用, 如不行可在 settings.gradle.kts 临时加阿里云 maven 镜像。

qwen-tts 打印 sox 警告 系统无 sox 二进制(无 sudo 装不了),警告可忽略,不影响生成; 只有用到 sox 音频处理链路时才需要它。

HF 下载 403 / 401 模型是 gated 的(Stable Audio 3):先接受许可再带 token;且 gated 模型经 hf-mirror 会被 308 回官网,见第 7 节。

HF 下载卡住不动 确认 HF_ENDPOINT=https://hf-mirror.com 已生效(source env.d/tts.sh), 并关掉 hf_transfer(HF_HUB_ENABLE_HF_TRANSFER=0,tts.sh 已设)。

TTS / SFX 同时抢 GPU 所有 GPU 任务必须用 flock /home/ubuntu/SoundGame/.gpu.lock 串行 (各 gen_voice.py 头部注释都有标准命令)。Stable Audio 3 small 峰值显存约 2.4GB,Qwen3-TTS 1.7B bf16 也远低于 24GB,理论上可共存,但仍建议串行省心。

WSL2 里 adb devices 看不到手机 WSL2 不能直接访问 USB。用无线调试(adb pair + adb connect)或让 adb server 跑在 Windows 侧,详见 env.d/android.md。

真机上第一个音效没声音 SoundPool 加载是异步的,首个音效会被吞。三个游戏都已在 onStart 里用 音量 0 预播预热(搜索源码里的 prewarm),新增音效记得加进预热清单。