audio-fork-server
Go 全双工音频网关(Go 1.23,纯静态编译 CGO_ENABLED=0)。在同一条 WebSocket 长连接上桥接 FreeSWITCH mod_audio_fork 与本地 sherpa-asr-server / sherpa-tts-server:上行把麦克风 PCM16 转发给 ASR 识别,下行把 TTS 合成的 PCM16 灌回 FreeSWITCH 播放,上下行真正并发,并内建 「开嗓打断」(barge-in)。
- 用途:为平台提供真正的全双工语音链路,取代「先识别、后单向播报」的半双工时序。
- 边界:本服务不做识别与合成,只做双向桥接、会话管理与打断判定;识别文本来自
sherpa-asr-server,合成音频来自sherpa-tts-server。它讲的下游契约与mod_audio_fork一致(WS/audio、子协议audio.drachtio.org、PCM16 音频与控制信令),接入方把apps/callflow-esl的[duplex]网关地址指向本服务即可。 - 打断策略:
[bargeIn].trigger三态对齐平台 barge-in 规范——partial(增量文本达minTextLength时打断,默认,抗噪)、speech-start(VAD 开嗓信号瞬时打断)、final(整句 定稿才打断)。
专题导航
目录结构
text
speech-gateway/audio-fork-server/
├── cmd/audio_fork_server/ # main:解析参数/配置、装配会话管理器与服务、优雅停机
├── internal/
│ ├── config/ # config.toml 解析、默认值与 AUDIO_FORK_* 环境变量覆盖
│ ├── server/ # HTTP /health + WS /audio 服务端、子协议协商、名额控制
│ ├── session/ # 会话管理器与单连接全双工生命周期
│ ├── asr/ # 上行:连接 sherpa-asr-server 流式识别、断线重连
│ ├── tts/ # 下行:请求 sherpa-tts-server PCM16 流式合成
│ └── protocol/ # mod_audio_fork 帧结构与控制信令
├── config.toml # 默认配置
├── build.ps1 / build.sh # Windows / Linux 构建入口(跨平台静态编译 + 装配 dist/)
├── .air.toml # air 热重载配置(本地开发)
├── test_e2e.ts # 端到端联调脚本
└── dist/ # 自包含交付目录(dist/win_x64、dist/linux_x64),不提交构建
需要 Go 1.23+。build.ps1(Windows)与 build.sh(Linux/macOS)等价,均一次性交叉编译 Windows x64 与 Linux x64 两个纯静态二进制(CGO_ENABLED=0、-ldflags "-s -w"),并把 config.toml 一并拷入交付目录:
powershell
pwsh ./build.ps1 # 或根目录 bun run build:native audio-forkbash
bash ./build.sh # 或根目录 bun run build:native audio-fork产物为自包含交付目录 dist/win_x64/(audio_fork_server.exe + config.toml)与 dist/linux_x64/(audio_fork_server + config.toml)。dist/ 与 tmp/ 不提交。
运行
本服务属于根 bun run dev 默认启动组。开发期用 air 热重载(改动 .go / .toml 自动重编重启):
powershell
bun run dev:audio-fork:air # = bun run --cwd speech-gateway/audio-fork-server airair 依据 .air.toml 执行 go build ./cmd/audio_fork_server 并以 -c config.toml 拉起进程, 需本机 PATH 中已安装 air。也可直接运行交付目录中的二进制:
powershell
cd dist\win_x64
.\audio_fork_server.exe -c config.toml配置路径解析顺序:-c / --config 参数 → AUDIO_FORK_CONFIG_PATH → 进程 CWD 下 ./config.toml / ../config.toml → 可执行文件同目录 config.toml。
最小配置
config.toml 关键字段(完整字段见文件内注释):
[server]:port(默认10091)、path(/audio)、subprotocol(audio.drachtio.org)、healthPath(/health)。[asr].wsUrl:本地 sherpa-asr-server 流式识别地址(默认ws://127.0.0.1:10096/audio)。[tts].baseUrl:本地 sherpa-tts-server 地址(默认http://127.0.0.1:9080),format必须为pcm、sampleRate须与 ASR/FreeSWITCH 统一为16000。[bargeIn]:enabled/trigger/minTextLength。
部署时常用环境变量覆盖:AUDIO_FORK_PORT、AUDIO_FORK_ASR_WS_URL、AUDIO_FORK_TTS_BASE_URL、 AUDIO_FORK_TTS_SPEED、AUDIO_FORK_TTS_SPEAKER_ID、AUDIO_FORK_LOG_LEVEL。跨机部署时 asr.wsUrl / tts.baseUrl 必须从本服务所在主机可达,server.host 需绑定 FreeSWITCH 可达网卡。
健康检查
powershell
Invoke-WebRequest http://127.0.0.1:10091/health返回 JSON:status、activeSessions / maxSessions,以及当前生效的 asr.wsUrl、 tts(baseUrl / sampleRate / format / speed / speakerId)与 bargeIn (enabled / trigger)。健康通过只代表本服务已监听、配置合法,不代表上游 ASR / TTS 可达。
最小验证
- 先起
sherpa-asr-server(10096)与sherpa-tts-server(9080),再起本服务。 GET /health返回status: ok且asr.wsUrl/tts.baseUrl指向已就绪的上游。- 用
test_e2e.ts端到端联调脚本,或把apps/callflow-esl的[duplex]网关指向ws://<本机>:10091/audio走一通真实通话,确认上行识别与下行灌音并发、开嗓可打断。
注意事项
- 端口、路径、健康检查等事实以全仓服务目录为唯一来源。
- 任务中启动的服务必须在结束前停止,避免端口 / 资源残留。