EVS语音编解码器详解:从SDP协商到VoLTE/VoNR测试实践

发布时间:2026/10/8 5:56:27
EVS语音编解码器详解:从SDP协商到VoLTE/VoNR测试实践
简介面向移动语音通信与编解码器开发者的EVS技术详解文档围绕3GPP R12版本定义的音频编解码器展开系统说明EVS从编码流程、信号分类到关键特性的原理并给出实际应用前的准备工作适合从事VoLTE/VoWiFi、VoIP终端优化的工程师学习参考。文档重点梳理TS26.441至TS26.445规范指出TS26.442定点实现代码、TS26.444测试序列的使用要点同时展示ACELP语音编码与MDCT音乐编码的切换机制以及全频段、宽码率、抗丢包等特性可直接用于理解EVS协议体系和评估开发工作量。资源包为单个docx文档大小约367KB内容覆盖原理、规范索引、工程落地注意事项结构完整、便于通读。目前已有364人学习下载适合作为接入EVS前的入门与实战备查材料。1. 音频编解码器EVS从“能听清”到“连呼吸都清楚”的那一跳音频编解码器 EVSEnhanced Voice Services是 3GPP 在 R12 阶段定稿的新一代语音编码技术也是目前 VoLTE 和 5G VoNR 里能把通话从“电话音质”抬高到接近现场录音的唯一主力。我第一次在 VoNR 测试里抓到一个用 EVS 的呼叫对方在楼道里走路的脚步声都是清晰的那一刻才明白 AMR-WB 的 7kHz 上限到底限制了什么。这篇笔记面向准备引入 EVS 的终端、IMS 平台和通信测试工程师把协议层面怎么协商、测试怎么搭、还有那些让集成翻车的细节一次理清。它不解决音频调音只解决“能不能让 EVS 上线、上线后怎么确认它工作”。2. 先用懂再上手EVS 的带宽、码率与 SDP 协商三件事很多团队拿到 EVS 的第一反应是找芯片平台把参数打开然后抓包看是不是 EVS。这个思路没错但漏了中间一步EVS 不是一个“打开就生效”的开关它的工作带宽、码率档位和 SIP/SDP 协商结果共同决定了最终音质。这三件事不先理顺后面看到的抓包结果大概率是玄学。2.1 四种工作带宽NB/WB/SWB/FB 分别对应什么样的听感EVS 最容易被忽略的设计是它同时支持四种工作带宽NB8kHz 采样、WB16kHz 采样、SWB32kHz 采样、FB48kHz 采样。注意这里的采样率是音频采样率不是无线空口采样率。传统 AMR-NB 只用 8kHz 采样实际还原出来的声音频带只有 3.4kHz打电话听感就是“蒙着一层纱布”AMR-WB 用 16kHz 采样带宽拉到 7kHz能分辨“s”和“f”这类高频摩擦音已经比普通通话清楚不少而 EVS 的 SWB 和 FB 可以把音频带宽推到 14kHz 甚至 20kHz 以上踩踏板的摩擦声、空调风声、衣料摩擦声都会被还原出来。工作带宽音频采样率可还原频带上限典型听感常见部署场景NB8kHz3.4kHz传统电话声2G/3G 回退、弱覆盖兜底WB16kHz7kHz高清通话接近面对面说话VoLTE/VoNR 默认主流SWB32kHz14kHz能听到气息细节像录音棚说话VoNR 高质量场景FB48kHz20kHz接近原始录音未来全频段语音/音乐场景工程上并不是“带宽越高越好”。终端麦克风能不能拾取高频、听筒/耳机能不能回放高频、蓝牙传输链路是不是瓶颈都决定 SWB 和 FB 是否真的有意义。常见做法是 VoLTE/VoNR 默认把 WB 和 SWB 打开FB 只在特定旗舰终端上启用。原因很简单FB 档位编码器复杂度高手机 DSP 功耗会明显上涨而且很多通话场景只有一个窄带麦克风采样率再高也是白搭。2.2 码率档位和 AMR-WB 的关系是加持不是替代EVS 最容易被误解的地方是“EVS 一定比 AMR-WB 更耗带宽”。实际上 EVS 标准里同时内置了 AMR-WB 兼容模式也就是说 EVS 编码器可以产出完全符合 AMR-WB 格式的码流反之 AMR-WB 解码器也能解出这部分 EVS 码流。这让运营商在 EVS 尚未全网铺开时能通过 SDP 协商在 EVS 和 AMR-WB 之间平滑切换不需要在网络里同时维护两套编码逻辑。EVS 的原生编码档位并不是只往高码率走它还增加了 5.9kbps、7.2kbps 这类比 AMR-WB 最低档还低的比特率。低码率档位的价值在于弱覆盖场景空口质量差的时候EVS 可以在码率更低的情况下维持比 AMR-NB 更好的清晰度这是它作为“应急音质兜底”的核心卖点。而 13.2kbps、16.4kbps、24.4kbps 这几个档位才是运营商量化音质时的常客。我见过不少优化工程师只盯着频谱看忽略了网络侧对码率档位的限制。如果核心网给 EVS 配置的最大码率只有 13.2kbps哪怕终端和网络都宣称支持 SWB实际也跑不出 24.4kbps 的超宽带效果。EVS 和 AMR-WB 的关系更像是“同一屋檐下的两套菜单”。网络侧通常把协商优先级写成 EVS AMR-WB AMR-NB两端都支持 EVS就进入 EVS 原生模式一端不支持就退回 AMR-WB都不支持再退回 AMR-NB。这个回退链的每一个节点都要测试到尤其是 EVS 到 AMR-WB 的切换切换瞬间不能让用户感觉到声音“从立体声变成收音机”。2.3 把 SDP 写对EVS 协商的最小字段与参数表EVS 是通过 SIP/SDP 协商上线的。SDP 里写错字段轻则协商不成功重则设备虽然回应 200 OK实际却仍走 AMR-WB。下面是一个最小可用的 EVS SDP 片段m 行同时声明了 EVS 和 AMR-WB 两个编解码器v0 oevs_test 2890844526 2890842807 IN IP4 192.0.2.1 sEVS SDP Test cIN IP4 192.0.2.1 t0 0 maudio 49170 RTP/AVP 96 97 artpmap:96 EVS/16000 afmtp:96 max-red0; dtx0; br1-8; bwwb-swb artpmap:97 AMR-WB/16000 afmtp:97 mode-set1,2,3,4,5,6,7,8; octet-align1rtpmap 里编码名必须是“EVS”时钟通常声明为 16000少数设备会写成 8000 或 32000。这里声明的采样率直接影响 RTP 时间戳的单位不直接决定音频实际带宽实际带宽由 fmtp 里的 bw 参数约束。fmtp 字段里 br1-8 表示可用码率档位覆盖 1 到 8 号索引bwwb-swb 表示支持宽带到超宽带。不同厂商对 bw 参数的写法略有差异有的写 bwnb-wb-swb有的写 bws,wb,swb这个值在协商时以接收方解析为准我一般会在协议栈日志里确认对方最终选定的取值而不是只看 INVITE 里写了什么。SDP 字段EVS 常见写法说明rtpmap 编码名EVS/16000编码名是 EVS不是 EVS-FBbrbr1-8可用码率档位索引范围bwbwwb-swb / bs,wb,swb可用的音频带宽能力dtxdtx0 / dtx1是否启用在静音时暂停发送的机制max-redmax-red0冗余的最大重传次数通常为 0如果把这段 SDP 直接用于测试有一个很隐蔽的坑fmtp 里 br 和 bw 的取值必须和终端固件的编码表对齐。曾经有设备只支持窄带和宽带却因为 INVITE 里写了 bwwb-swb 而返回 488 Not Acceptable原因不是设备不支持 EVS而是它不认可这个字段的值。遇到这种翻车第一个动作是把 fmtp 简化成最小集合比如只留 dtx0再加一项一项排查。3. 把 EVS 真正跑起来从 INVITE 到 PCM 还原的完整测试链路原理只会停留在 PPT 上真正要验证 EVS 上线得从构造信令请求开始一路走到还原出可听的 PCM。这里给出一条我自己反复使用的测试链路先用 SIPp 构造一个带 EVS 声明的 INVITE再用 tshark 抓包分析 RTP 连续性最后通过参考解码器或芯片 SDK 把码流还原成 PCM。三步走完EVS 是否工作、工作在什么带宽、有没有隐性丢包都会原形毕露。3.1 用 SIPp 伪造一个“我支持 EVS”的 INVITESIPp 是绕不开的信令工具。下面这个 scenario 文件会向被测设备发送一个带 EVS SDP 的 INVITE并打印收到的响应。如果被测设备回 200 OK说明它接受 EVS 协商如果回 488 或 415说明 SDP 里有它不认的字段。?xml version1.0 encodingUTF-8? scenario send retrans500 ![CDATA[ INVITE sip:[service][remote_ip] SIP/2.0 Via: SIP/2.0/UDP [local_ip]:[local_port] From: sipp sip:sipp[local_ip];tag[call_number] To: sut sip:[service][remote_ip] Contact: sip:sipp[local_ip]:[local_port] Call-ID: [call_id] CSeq: 1 INVITE Content-Type: application/sdp Max-Forwards: 10 Content-Length: [len] v0 osipp 0 0 IN IP4 [local_ip] sEVS test cIN IP4 [media_ip] t0 0 maudio [audio_port] RTP/AVP 96 97 artpmap:96 EVS/16000 afmtp:96 max-red0; dtx0; br1-8; bwwb-swb artpmap:97 AMR-WB/16000 afmtp:97 mode-set1,2,3,4,5,6,7,8; octet-align1 ]] /send recv response100 optionaltrue/ recv response200 optionaltrue/ /scenario把文件保存为 evs_invite.xml 后用下面命令发起呼叫sipp -sf evs_invite.xml 10.20.1.1 -s 8613800138000 -p 5060 -l 1 -m 1 -timeout 20s参数含义-sf 指定场景文件-s 是被叫号码-p 是本地 SIP 端口-l 是并发呼叫数-m 是最大呼叫数timeout 是每次呼叫的超时时间。20 秒超时通常足够完成一次 INVITE/200 OK 的握手。如果被测设备是真实终端记得先把终端注册到同一个 IMS 平台否则 INVITE 会被网络拒掉。这里只验证 SDP 层的“接受度”真正呼叫成功还需要继续回 ACK 并建立 RTP 连接SIPp 场景可以按需扩展。3.2 用 tshark 解析呼叫抓包连续性问题一眼定位SIP 协商通过后RTP 媒体流里才见真章。我一般会在呼叫同时抓双端 pcap然后用 tshark 把 RTP 摘要导成 CSV再用一个几十行的 Python 脚本看连续性和间隔。tshark -r evs_call.pcap -Y rtp ip.src192.0.2.10 -T fields -E headery -E separator, -e frame.number -e frame.time_epoch -e rtp.timestamp -e rtp.payload rtp_trace.csvimport csv rows [] with open(rtp_trace.csv) as f: reader csv.reader(f) header next(reader) for row in reader: if len(row) 4: continue rows.append((int(row[0]), float(row[1]), int(row[2]), row[3])) prev_ts None for frame_no, t, ts, payload_hex in rows: if prev_ts is not None: d_ts ts - prev_ts # 16kHz 采样、20ms 帧长时RTP 时间戳增量应为 320 if d_ts 480: print(fframe {frame_no}: ts jump {d_ts}, time gap {t - prev_t:.3f}s) if len(payload_hex) 4: print(fframe {frame_no}: short payload (possible SID/DTX)) prev_ts ts prev_t tEVS 在 16kHz 采样、20ms 帧长配置下RTP 时间戳每次固定增加 320。如果出现超过 480 的跳变说明中间丢了一到两个语音帧或者进入了半帧模式如果时间戳正常但 payload 非常短很可能是 DTX 生成的舒适噪声帧不是真正的语音帧。注意 DTX 不等于丢包不能因为包间隔变大就直接判定网络有质量问题。码流连续性验证是所有后续质量评估的前提这一步数据没处理好后面 POLQA 的分数没有参考价值。3.3 还原 PCM 的三种现实路径参考解码器、协议仪表、芯片SDK拿到 RTP payload 后想听到 EVS 到底把声音还原成什么样有三个现实路径。最常见的是芯片平台提供的 SDK 里有 EVS 解码工具直接把抓到的 payload 文件喂进去就能出 PCM这条路最快但受限于芯片厂商的工具链格式不同平台的输出格式不太一样。第二个路径是 3GPP 发布的 EVS 参考解码软件也就是 TS 26.441 系列标准里配套的 ANSI-C 参考代码。这套代码需要通过网络侧或芯片厂商的软件许可途径获得通常运行在 Linux 工作站上输入是剥离了 RTP 头、CMR 和 ToC 字节之后的裸 EVS 帧序列输出是 16bit PCM。注意抓包得到的 RTP payload 不能直接输入EVS 复用并扩展了 RFC 4867 那种带 CM R 和 ToC 的封装格式必须先按负载头长度裁剪这一点我见过太多人在这里栽跟头。第三个路径是用商用协议分析仪。这类仪表一般自带 EVS 解码插件能实时把空口或 IMS 侧的码流还原成 PCM 文件还能和上位机录音做对齐。它的优点是省去自己写解析器的麻烦缺点是贵而且大部分功能集中在实验室环境里不方便带出去跑外场。我的习惯是实验室用仪表外场用芯片 SDK参考解码器只用来做最终一致性校验。4. EVS 落地避坑5 个让工程师加班的真实场景以下每一条都是我在实际项目里亲眼见过或自己踩过的不是从标准里抄的。现象、原因、解决三步拆开写方便你照着排查。4.1 终端说支持 EVS抓包还是 AMR-WB现象终端参数配置页里明明勾了 EVS网络侧也已打开 EVS 开关但呼叫建立后抓 SDP媒体行里选的还是 AMR-WB。原因最多的情况是 INVITE 里同时上报了多个编解码器网络侧按自己的优先级列表选择了 AMR-WB而不是终端上报顺序。另一个常见原因是终端固件里 EVS 只支持“EVSAMR-WB 共存”的兼容模式没有把 EVS 放在 AMR-WB 之前。解决先看 IN VITE 请求里的原始 SDP 顺序再做网络侧编解码器优先级配置调整把 EVS 排到最前面。如果网络侧不支持只能看 IMS 网元的 codec negotiation 日志确认它做媒体协商时过滤了哪个字段。还有一种情况是终端“支持 EVS”但只在特定 APN 下才上报换一张只有默认 LTE APN 的卡就会静默降级这种情况需要核对终端的 IMS 配置文件。4.2 把 DTX 静音帧当成了丢包结论跟着错现象pcap 里语音 RTP 包每 20ms 一个很规律忽然连续 600ms 没有包接着又恢复。测试报告写着“EVS 呼叫存在严重丢包”。原因EVS 的 DTX不连续发送机制在检测到静音后会停止发送常规语音帧只偶尔发出一个很小的 SID 舒适噪声帧。在通话音量较小或者远端静音时抓包看起来就像断了流一样。解决不要只看包间隔要看 RTP 时间戳。DTX 期间时间戳依然按正常速率累加只是实际发送的包变少真正的丢包是“时间戳跳变包缺失”同时出现。把 3.2 里的脚本改成同时检查 d_ts 和 payload 长度就能区分。另外EVS 的 DTX 参数在 SDP 里是 dtx1测试对比时建议 dtx0 和 dtx1 各跑一轮不要混在一起看。4.3 第三方播放器放不出 EVS不是码流损坏现象抓包导出 payload 后用 VLC 或 Audacity 打开声音完全是炸裂的噪声。原因EVS 是 3GPP 受控标准绝大多数通用播放器没有内置 EVS 解码器只能按 PCM 或 AMR 去解 EVS 码流结果当然不对。这个和码流无关也不是抓包抓坏了。解决确认播放前已经把 EVS 帧剥离成裸帧并且解码器是支持 EVS 的。最简单的方法是先用芯片 SDK 的 demo 工具解码确认能出 PCM 后再做主观听测。用通用播放器做对照时可以同时解码一个 AMR-WB 呼叫作为参考排除工具链本身的问题。还有一点容易被忽略EVS 解码器对帧边界很敏感RTP payload 里的 CMR/ToC 字节没剔干净再好的解码器也会出沙沙声。4.4 SWB 档位让 VoNR 终端发热别小看编码器功耗现象VoNR 下开了 EVS SWB 档位手机通话 5 分钟后明显发烫电量掉得比平时快 30%后来甚至触发温控性能降频。原因SWB/FB 档位的 EVS 编码器复杂度远高于 AMR-WB尤其是 24.4kbps 和 48kHz 采样配置需要更频繁的 DSP 运算。如果终端散热设计一般长时间调用就是会发热。解决把 EVS 最大码率限制在 13.2kbps 或 16.4kbps带宽能力限制到 wb-swb。低档位在户外和弱覆盖场景下体验差异很小功耗却差很多。另外要检查终端是否支持 EVS 的低功耗模式各家芯片的 EVS 低功耗 profile 是真实存在但经常没被调用的。规划时长通话场景时建议把 SWB 保留给室内静态场景室外移动场景强制回退到 WB。4.5 从 5G 切 WiFi 呼叫掉话回退策略没有配好现象5G VoNR 通话中进入办公室终端切换到 VoWiFi 后通话直接挂断或切过去成了回声极大的劣质音。原因VoNR 和 VoWiFi 用的核心网策略、编码器配置可能不一致。VoNR 侧协商成功的是 EVS SWB而 VoWiFi 侧 IMS 接入点不支持 EVS同时又没有配置“降级到 AMR-WB”的回退策略媒体重协商失败后只能拆线。解决在 IMS 和 ePDG 侧把 VoWiFi 支持的编解码器列表配成包含 AMR-WB 在内的 EVS 兼容集并且开启媒体重协商能力。测试时模拟切网场景抓 SDP re-INVITE重点看协商后的 fmtp 是否变化。如果支持无缝切换应该看到一次 re-INVITE 后媒体流不断、时间戳不乱如果没有 re-INVITE说明切换走的还是整包转发质量损耗在所难免。5. 最后一步三种验证方法确定 EVS 用好了外加我的一个教训5.1 听感、POLQA 与日志三件套判断 EVS 是否“用好”了不能只看协商成功就完事。我的三件套是主观听感、POLQA 客观分、日志侧协商记录。主观听感用同一句测试语料分别在 WB 和 SWB 下播放关注背景音乐和语气词POLQAITU-T P.863是目前少数支持超宽带语音的客观评测算法测试语料要准备 8~10 秒的句子左右声道分开采集参考信号用本地录音或标准语料库待测信号用网络抓包解码后的 PCM。两者时间对齐误差不要超过 50ms否则分数会无意义地偏低。日志侧则要确认 SDP 协商出的 bw 和 br 确实是预设值不是网络“好心”替你降了档。三件套互相印证才算闭环。5.2 我的教训永远先录一份本地 PCM有一年给某个重点场景做 VoNR 验收晚上在测试车里抓了三个多小时空口数据回去解码之后 POLQA 打分正常但产品经理坚持“用户投诉音质差”。两边堵了两天最后才意识到问题在测试车里没有同步录音参考信号用的是标准语料而实际通话时车里的空调噪声和胎噪让主观听感崩了。客观分和主观体验都重要但如果一开始没有在本地录一份 PCM 作为基准“你说好、他说差”就成了永远扯不清的悬案。从那以后我的测试规范里多了一条铁律任何 EVS 测试开始前先在手机侧和测试电脑侧同时录制一份本地 PCM和网络侧解码出来的 PCM 做差分。差分对不上就不可能把“编解码器的问题”和“声学环境的问题”分开。这套方法虽然朴素但能挡住大量后续争议希望帮到你。本文还有配套的精品资源点击获取