Skip to content

D. 数字音频基础

语音对话的本质是声波数字化后在网络中传输。本附录讲解数字音频的核心概念,帮助你理解 JoyInside 为什么要求 PCM 16k/16bit/单声道,为什么推荐 Opus,以及单包 300ms、帧长 60ms 这些参数背后的原理。

目录

D.1 信号转换基础(模拟 → 数字)

数字音频是将模拟声波转换为数字信号并进行处理、存储与传输的技术。核心分三步:采样 → 量化 → 编码

采样(Sampling)

以固定时间间隔采集模拟信号的瞬时幅度。采样率决定可重现的最高频率(奈奎斯特定理:采样率 ≥ 2 × 最高频率)。

  • 人耳听觉范围约 20Hz-20kHz,故 CD 采样率 44.1kHz(>40kHz)即可覆盖全频段;
  • 语音频段主要集中在 300Hz-3.4kHz,故通信语音常用 8kHz(电话)或 16kHz(VoIP);
  • JoyInside 默认 16kHz,覆盖语音频段且带宽适中。

量化(Quantization)

将采样值映射到离散电平。位深决定精度与动态范围

  • 16bit 对应 2^16 = 65536 个电平,信噪比约 96dB(CD 质量);
  • 8bit 仅 256 个电平,音质明显劣化;
  • JoyInside 使用 16bit,平衡音质与带宽。

编码(Encoding)

将量化值转换为二进制码流,形成原始 PCM 数字音频数据。

模拟声波 → 采样(16kHz) → 量化(16bit) → 编码 → PCM 二进制流

D.2 编码与压缩

音频压缩分无损(去冗余保全部信息,如 FLAC/ALAC,高保真存储)与有损(基于心理声学模型舍弃不敏感成分,如 MP3/Opus,流媒体与实时通信)。JoyInside 上行/下行用 PCM(不压缩)、Opus(有损)、MP3(有损下行)。

码率控制

模式全称特点JoyInside 支持
CBR恒定码率每帧固定字节数,传输稳定✅(Opus enableOpusCbr=true)
VBR可变码率按内容复杂度调整码率,音质更优✅(默认)
ABR平均码率按目标平均码率编码

JoyInside 支持 CBR 与 VBR,默认 VBR。详见 4.4 音频格式

D.3 三大音频格式对比

PCM(脉冲编码调制)---- 数字音频的基石

未经压缩的原始数字音频格式,所有数字音频处理都始于 PCM 数据流。

核心原理:采样 + 量化 + 编码三位一体。

优点:

  • 保真度高,无压缩损失;
  • 处理灵活,可直接进行滤波、均衡等操作;
  • 无编码延迟,仅传输/存储延迟。

局限:

  • 文件体积大(CD 音质约 1411kbps);
  • 存储与传输成本高。

在 JoyInside 中的应用:

  • 上行默认格式:16k/16bit/单声道,单包 ≤300ms;
  • 下行 TTS 支持格式,帧长 60-120ms;
  • 详见 4.4

MP3 ---- 有损压缩的里程碑

首个成功实现高压缩比且保持"可接受"音质的有损音频编码标准,基于心理声学模型。压缩比高、兼容性极广,但有损不可逆、延迟较高(>100ms)、不支持流式切分。

在 JoyInside 中的应用:

  • 仅支持下行 TTS;
  • 不支持流式切分(整段下发);
  • 不支持上行;
  • 内存不足时不要用 mp3 格式,缓存整段音频会导致丢包;
  • 详见 4.410.3.4

Opus ---- 现代低延迟、高效率的编码标准

IETF 制定的开源、免版税音频编码格式,结合 SILK(语音)与 CELT(音乐)两种编码模式自适应选择。极低延迟(单帧可低至 2.5ms)+ 高压缩比,适合实时通信。

在 JoyInside 中的应用:

  • 上行推荐格式:体积约 PCM 的 1/8,单包 ≤480 字节,帧长 ≤120ms(建议 60ms);
  • 下行 TTS 支持格式,帧长 10/20/40/60ms;
  • 支持 CBR(enableOpusCbr=true,默认 VBR);
  • 下发的 Opus 裸流是单声道;
  • 压缩比建议 8:1(≈32kbps),最高 24:1(超过报错),详见 Opus 压缩比与目标比特率;
  • 详见 4.4

Opus 压缩比与目标比特率

Opus 将 PCM 压缩成二进制码流,压缩比决定目标比特率。以 JoyInside 默认 PCM 配置(16k/16bit/单声道,原始 256kbps)为例:

目标比特率 = PCM 原始比特率 ÷ 压缩比 = 256kbps ÷ 压缩比
压缩比目标比特率说明
8:132 kbps建议
16:116 kbps可用
24:1≈10.7 kbps最高(不推荐),超过报错

字节闭环:8:1 压缩比下,32kbps × 120ms ÷ 8 = 480 字节——正好等于 JoyInside 默认 opus 音频包字节上限,三个数字(8:1 / 120ms / 480B)互相印证。

Opus 包结构与拼包原理

本节讲 Opus 包的内部结构与拼包机制,解释 4.4 能力清单与 5.3.4 落地选型背后的原理。设备端工程师按需阅读,接入调试时理解 frameSize 参数用。

三层概念:数据包 / opus 音频包 / opus 帧

JoyInside 上行 opus 涉及三个层级(与 4.4 一致):

层级定义
数据包一次 WebSocket 音频上传的 byte[](传输层产物)
opus 音频包opus 标准的包,以 TOC 字节开头(opus Packet)
opus 帧opus 音频包内的帧(opus Frame)
  • 单包模式:数据包 = 1 个 opus 音频包(1:1)
  • 拼包模式:数据包 = 多个 opus 音频包裸拼接成 1 个 byte[]

帧与包的关系

Opus 编码器把音频按**帧(Frame)**编码。一个 opus 音频包可含 1 帧或多帧;同一个包内的帧参数必须一致:编码模式、音频带宽、帧大小、声道数。

Opus 支持的帧长:2.5 / 5 / 10 / 20 / 40 / 60 ms(由 TOC 的 config 决定)。单帧最大 60ms。JoyInside 建议上行用 60ms/帧。

TOC 字节与四种包

每个 opus 音频包以一个 TOC(Table of Contents)字节开头,结构如下:

 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
| config  |s| c |
+-+-+-+-+-+-+-+-+
  • config(高 5 位):32 种编码配置,由编码模式(SILK/Hybrid/CELT)、音频带宽(NB/MB/WB/SWB/FB)、帧长度组合而成,决定本包的帧长。详见 opus 标准的 32 配置表
  • s:0 = 单声道,1 = 立体声
  • c(低 2 位):决定包内帧数与封装方式,即下表四种包
c 值名称帧数是否需帧长度/帧数指示说明
00 号包1 帧否(结构固定)TOC 后直接跟 1 帧数据,最简单
11 号包2 帧(等长)否(各占一半,包字节必为奇数)两帧大小相同
22 号包2 帧(不等长)是(需编码第 1 帧长度)两帧大小不同
33 号包任意帧 M是(TOC 后有帧数字节 v|p|M唯一支持任意帧数,且支持 CBR/VBR

四种包的本质区别:是否需要额外的帧长度/帧数指示字节。0/1 号包结构固定(1 帧、或 2 等长帧),解码器靠包大小自然确定边界,无需指示;2/3 号包帧大小或帧数不固定,必须显式编码指示字节。JoyInside 上行单包模式可用 0 号或 3 号包;1/2 号包很少用。

一个 opus 音频包如何支持 CBR

3 号包的帧数字节最高位 v 决定码率模式:

v 值模式说明
0CBR恒定码率,每帧字节数相同,传输稳定
1VBR可变码率,按内容复杂度调整,音质更优

JoyInside 默认 VBR,可通过 enableOpusCbr=true 切 CBR(弱网下推荐,传输更稳定)。详见 B.2 码率控制

拼包机制:多个 opus 音频包裸拼接

Opus 包与包之间没有边界(裸拼接无法区分),需额外机制告诉解码器每个包的大小(标准做法是用 Ogg 等容器格式)。JoyInside 的拼包不走容器,而是:

  • 拼包 = 把多个 opus 音频包裸拼接成 1 个 byte[] 作为数据包上传
  • 服务端按 frameSize 等长切分还原每个 opus 音频包

正因服务端按定长切分,拼包必然是 CBR(每个 opus 音频包字节数必须相同,否则切不开)。这也是拼包只能用 3 号包 + CBR 的根本原因。

时长与字节上限

  • opus 音频包时长:≤120ms(opus 标准硬上限,按最小帧 2.5ms 算最多 48 帧)
  • 数据包总时长:建议 ≤300ms(软建议,与 PCM 单包对齐,保证 ASR 流式处理时延)
  • opus 单帧字节上限:1275 字节(对应 20ms 帧约 510kbps,MDCT 算法最高有效码率)
  • JoyInside opus 音频包字节:默认上限 480 字节,超过需显式设 frameSize

frameSize 语义

audio.input.frameSize = 一个 opus 音频包的字节数,仅拼包时传:

  • 单包模式:数据包 = 1 个 opus 音频包,边界由包大小自然确定,无需 frameSize
  • 拼包模式:数据包 = 多个 opus 音频包,服务端按 frameSize 等长切分,必须传
  • 设错(< 实际 opus 音频包字节)→ 服务端切错 → 解码失败

这就是 5.3.4 易踩坑点里「frameSize 是单个 opus 音频包字节数」的原因。


三大格式对比总表

特性PCMMP3Opus
本质原始未压缩数据有损压缩(心理声学模型)有损压缩(自适应混合编码)
码率范围固定(16k/16bit/单声道 ≈ 256kbps)通常 128-320kbps6-510kbps(自适应)
音质上限最高(无损失)接近 CD(高码率下)接近 CD(中高码率下)
延迟无编码延迟较高(>100ms)极低(2.5-65ms)
JoyInside 上行✅ 默认❌ 不支持✅ 推荐
JoyInside 下行✅(不流式)
流式切分
主要用途端侧采集、原始处理音乐分发、大众播放实时通信、低带宽流媒体

D.4 关键参数关系

码率公式

音频码率(kbps) = 采样率(Hz) × 位深(bit) × 声道数 / 1000

示例(JoyInside PCM 默认配置):

码率 = 16000 × 16 × 1 / 1000 = 256 kbps

即每秒 PCM 数据约 32KB(256kbps ÷ 8)。

参数决定关系

参数决定因素典型值影响
采样率最高可记录频率16kHz(JoyInside)/ 44.1kHz(CD)/ 48kHz(影视)高频响应、时间精度
位深动态范围与噪声16 bit(JoyInside/CD)/ 24 bit(专业)信噪比、细节层次
声道数空间维度1(JoyInside 单声道)/ 2(立体声)沉浸感、混音复杂度
码率质量与文件大小256kbps(JoyInside PCM)/ 1411kbps(CD PCM)存储、传输带宽

为什么 JoyInside 选 16k/16bit/单声道

选择原因
16kHz 采样率覆盖语音频段(300Hz-3.4kHz),带宽适中;高于电话音质(8kHz),低于 CD(44.1kHz)以节省带宽
16bit 位深信噪比约 96dB,语音动态范围足够
单声道语音对话无需立体声,节省一半带宽

D.5 JoyInside 中的音频实践

上行音频(设备 → 云)

参数取值说明
codecpcm(默认)/ opus(推荐,体积 1/8)mp3 不支持上行
sampleRate16000 / 24000 / 32000默认 16k
PCM 单包≤300ms16k/16bit/单声道
Opus 单包opus 音频包 ≤480 字节(默认上限)、≤120ms(硬上限,帧长建议 60ms)数据包总时长建议 ≤300ms;单包不传 frameSize,拼包传(=单 opus 音频包字节)
发送间隔= 音频时长均匀发送,否则延时异常

详见 4.4 音频格式附录 B

下行 TTS(云 → 设备)

参数取值说明
codecpcm / opus / mp3mp3 不支持流式切分
frameSizeMspcm 60-120ms / opus 10/20/40/60ms下行 TTS 帧长
enableOpusCbrtrue / falseOpus CBR,默认 VBR
下发节奏首次 3 包 × 60ms,后续间隔 54ms10.3.4
二进制传输audio.binary=true上行 ws.send(bytes),下行 binary frame

详见 4.4附录 B

常见音频问题速查

现象根因章节
上传音频无回复ASR 未识别(EMPTY_CONTENT),检查音频有效性、格式匹配、发送间隔10.2.1
TTS 卡顿端侧攒包或单线程,改直接播放 + 多线程10.3.4
TTS 自言自语AEC 未生效,TTS 被回采触发 ASR10.2.4
binary not support未开 audio.binary=true 但传了 bytes10.7
音频格式不匹配端侧解码格式与 CLIENT_VOICE_CHAT_UPDATE 配置不一致4.4

下一步