# PCM ASR 上行协议 v1(机端实现摘要) 与 `CloudVoiceClient`(`voice_drone/core/cloud_voice_client.py`)及 voicellmcloud 的 `pcm_asr_uplink` **session.start.transport_profile** 对齐。 ## 上行:仅文本 WebSocket 帧 **禁止**用 WebSocket **binary** 发送用户 PCM。对端(Starlette)`receive_text()` 与 `receive_bytes()` 分流;binary 上发会导致对端异常,客户端可能表现为空文本等异常。 用户音频只出现在 **`turn.audio.chunk` 的 JSON 字段 `pcm_base64`** 中(标准 Base64,内容为 little-endian **pcm_s16le** 原始字节)。 ## session.start - `transport_profile`: **`pcm_asr_uplink`** - 其余与会话通用字段相同(`client`、`auth_token`、`session_id` 等)。 ## 单轮上行(一个 `turn_id`) 1. **文本 JSON**:`turn.audio.start` - `type`: `"turn.audio.start"` - `proto_version`: `"1.0"` - `transport_profile`: `"pcm_asr_uplink"` - `turn_id`: UUID 字符串 - `sample_rate_hz`: 整数(机端一般为 **16000**,与采集一致) - `codec`: `"pcm_s16le"` - `channels`: **1** 2. **文本 JSON**(可多条):`turn.audio.chunk` - `type`: `"turn.audio.chunk"` - `proto_version`、`transport_profile`、`turn_id` 与 start 一致 - `pcm_base64`: 本段 PCM 原始字节的 Base64(不传 WebSocket binary) 每段原始字节长度由环境变量 **`ROCKET_CLOUD_AUDIO_CHUNK_BYTES`** 控制(默认 8192,对 **解码前** 的 PCM 字节数做钳制)。 3. **文本 JSON**:`turn.audio.end` - `type`: `"turn.audio.end"` - `proto_version`、`transport_profile`、`turn_id` 与 start 一致。 **并发**:同一 WebSocket 会话内,**勿**在收到上一轮的 `turn.complete` 之前再发新一轮 `turn.audio.start`。 ## 下行(与 turn.text 同形态) - 可选:`asr.partial` — 机端仅日志/UI,**不参与状态机**。 - `llm.text_delta`(可选) - `tts_audio_chunk`(JSON)后随 **binary PCM**(TTS 下行仍可为 binary,与上行约定无关) - `dialog_result` - `turn.complete` 机端对 **空文本帧** 会忽略并继续读(与云端「空文本忽略」一致)。 机端须 **收齐 `turn.complete` 且按序拼完该轮 TTS 二进制** 后再视为播报结束,再按产品规则分支(闲聊再滴声 / 飞控确认窗等)。 ## 参考 - 会话产品流:[`CLOUD_VOICE_SESSION_SCHEME_v1.md`](./CLOUD_VOICE_SESSION_SCHEME_v1.md) - 飞控确认:`CLOUD_VOICE_FLIGHT_CONFIRM_v1.md`