资讯动态

PESQ语音质量评估工具:源码编译、参数配置与批处理避坑指南

发布时间:2026/10/22 8:36:20 来源:尧图企业网站定制
简介PESQ感知语音质量评估是ITU-T P.862标准推荐的客观语音质量评价工具常用于通信系统、音频编码及语音增强的效果检验。这份源码包面向音频算法工程师与语音处理研究人员提供可直接编译的C/C源码、头文件及Windows批处理脚本并附带编译教程帮助解决PESQ在本地环境构建与命令行调用中的常见问题。压缩包共88个文件约5.53MB其中包含5个C源码、3个头文件、2个bat编译脚本以及66个用于测试的wav参考/待测音频另有P.862标准PDF和P862E说明文档便于对照原理理解输出分数。资源还配有使用说明txt与源码编译教程读者可按步骤生成pesq可执行程序利用wav样本验证不同模式如窄带/宽带下的评分流程。已有655人学习下载适合需要快速上手PESQ的开发者参考。1. 语音质量评估绕不开的 PESQ从 ITU-T P.862 标准到可执行文件做语音质量评估的工程师手里要是没有 PESQ 这个工具很多活根本没法干。它是 ITU-T P.862 标准定义的客观语音质量评估方法核心思想是用心理声学模型模拟人耳听觉对参考语音和处理后的语音打分输出 -0.5 到 4.5 之间的 MOS 分。无论是评估 VoIP 通话质量、对比音频编解码器性能还是验证降噪算法的效果PESQ 几乎是事实标准。但问题是官方发布的往往不是现成的可执行文件而是一堆 C 源码和编译脚本拿到手要先自己编译才能用。这份资源的核心价值就在这把 P.862 源码包和配套的编译教程放在一起省去到处找旧版本代码和折腾编译环境的麻烦。2. 源码包内幕P.862 文件结构、版本陷阱与 .DS_Store 干扰项2.1 压缩包里到底有什么逐文件拆解解开 T-REC-P.862-200102.zip 之后里面不是只有一堆 .c 和 .h 文件还有一些容易让人困惑的东西。我过了一遍文件清单按实际用途分类如下文件/目录类型作用T-REC-P.862-200102目录标准文本目录内含 PDF 版规范P862E.doc文档ITU-T P.862 的附录 E 说明文档P.862.pdf标准原文完整的 P.862 建议书含算法数学描述源码编译教程.txt教程针对该源码的编译步骤说明含命令.DS_Store系统文件macOS Finder 生成的元数据文件无用途需要注意 .DS_Store 的存在意味着这个压缩包在 macOS 环境打包过里面的源码大概率是 Unix/Linux 风格换行符这直接影响后续在 Windows 上的编译。另外P862E.doc 是后期修订的附录文件它和 P.862.pdf 的区别在于附录 E 补充了窄带模式下某些边界情况的处理建议但这些修订并未全部体现在源码里读文档时要留意版本差异。2.2 版本识别200102 是源代码的定版时间戳目录名里的 200102 对应 2001 年 2 月这是该版代码的提交时间。P.862 标准后续有修订版本比如 P.862.1、P.862.2但基础算法以这版源码为准。判断源码版本有个更直接的方法看代码里#define VERSION或char version[]这类字符串常量。我见过有人在网上下载了名字相近的包里面混入 P.862.2 的补丁代码结果编译出的工具行为不一致。如果拿到代码后准备二次开发先确认版本字符串再动手改这是最基本的习惯。3. 编译流程全解WindowsMinGW、LinuxGCC与 macOS 环境配置3.1 Linux 下用 GCC 直接编最简单也最容易出问题PESQ 源码主体是纯 C在 Linux 上编译理论上最简单。先把代码解压进入源码目录执行cd pesq-archive/T-REC-P.862-200102/P862_Software ls -la make如果目录下存在 Makefile直接make就能生成可执行文件pesq。但是这段流程里最大的问题在于源码里某些文件是只读权限从 zip 解压或者从光盘拷出来时常见的权限位保留make可能会报Permission denied。我一般会先做一个预处理chmod -R uw . make clean make其中chmod -R uw .是对当前目录下所有文件添加写权限避免只读文件导致的目标文件无法生成make clean是为了清掉上一次可能的失败产物让编译重新来过。如果make报错说找不到头文件如dsp.h大概率是因为 Makefile 里写的源文件路径与解压后的实际目录结构不一致需要修改 Makefile 里的SRC_DIR或INCLUDE_DIR变量。3.2 Windows 上用 MinGW 编要改的不是代码是 Makefile在 Windows 上最顺的路径是用 MinGW-w64 模拟 Linux 环境编译前先确认 gcc 在 PATH 中gcc --version如果没有输出说明环境变量没配置好需要手动把 MinGW 安装目录下的bin路径追加到 PATH 中。接下来进入源码目录先看一眼 Makefile 的关键行CC gcc CFLAGS -O2 -Wall -I. OBJS pesq.o dsp.o ...Windows 下最容易挂的两处一是-I.表示当前目录下的头文件路径如果你把源码放在带空格的路径里例如C:\Users\My Documents\pesq编译时会出现找不到头文件的问题二是 Makefile 里的换行符如果是 Unix 的 LF而你用了记事本编辑过变成了 CRLFMinGW 的 make 会直接报错missing separator。我习惯把源码复制到一个无空格的纯英文路径下编译例如C:\pesq\src。路径里带中文或者空格在 make 阶段十有八九会翻车。接下来执行mingw32-make.exe如果你的 MinGW 安装里没有mingw32-make.exe而是只有make.exe则替换命令名即可。编译成功后目录下会多出pesq.exe此时可以执行./pesq.exe -h看到用法输出说明编译成功。3.3 macOS 上编译.DS_Store 带来的隐藏问题上面提到压缩包里有.DS_Store文件这在 macOS 上解压会产生额外的元数据文件。用tar或命令行解压时_MACOSX目录里也常有._pesq_main.c这类 AppleDouble 文件。如果解压时没有设置COPYFILE_DISABLE1这些隐藏文件会伴随源码一起落地但不会干扰编译——因为 Makefile 用的是通配符加上明确的 .c 文件名不会把这些隐藏文件编进去。真正要留意的是终端里执行make时如果代码目录不在/usr/local/include能搜到的范围需要在 CFLAGS 里加上-I./或者直接用绝对路径指定头文件目录make CFLAGS-O2 -I\$(pwd)这里$(pwd)在 shell 里会被替换成当前目录的绝对路径确保 dsp.h、pesq.h 等头文件能被编译器找到。macOS 自带的 clang 对 C99 的支持很好老版本 P.862 源码里没有用到 C11 特性所以 clang 编译几乎无障碍。4. 命令行参数与输出解析mode、文件格式、采样率边界与常见报错4.1 核心参数-w 与默认窄带的区别PESQ 命令行签名是pesq [options] ref_file deg_file。第二个参数mode控制是否启用宽带模式。窄带模式默认电话带宽 300 Hz 到 3400 Hz采样率要求为 8 kHz宽带模式下采样率要求为 16 kHz。实际使用中需要区分的有三点-w参数对应宽带必须放在文件路径前面如果不加-w即窄带模式内部会对输入信号做带通滤波处理宽窄带不能随意混用不然输出的 MOS 分数与预期场景不符典型调用示例pesq -w ref_wideband.wav deg_wideband.wav输出的结果以P.862 Prediction (Raw MOS, MOS-LQO):形式呈现其中Raw MOS是算法内部未做任何映射的原始分MOS-LQO是经过映射后的主观分后者更贴近实际用户体验调查结果。4.2 输入文件的隐藏要求格式与电平PESQ 代码对输入文件有强约束需要波形文件.wav最好为 PCM 16 bit 单体mono采样率必须匹配模式。代码内部对齐到内部计算采样率后再执行感知模型的分帧处理。如果给的是立体声文件常见做法是在读文件阶段就报错Error: input file has 2 channels, expected 1解决办法是用 SoX 或 ffmpeg 转成单声道ffmpeg -i stereo.wav -ac 1 mono.wav另一个隐含的坑是电平问题。PESQ 内部的响度对齐算法假设输入信号电平在正常语音范围如果文件是数字静音或者接近满幅削波输出的 MOS 会异常低。我给客户做验收测试时遇到过极端情况原文件是 16 bit 正弦波处理文件是静音PESQ 的分数是 1.0 左右此时不是算法坏了而是输入本来就没有可比性。这种情况可以在用 PESQ 之前先检查波形文件的 RMS 电平一般用 ffmpeg 的volumedetect滤镜ffmpeg -i ref.wav -af volumedetect -f null -看mean_volume是否在 -25 dB 到 -15 dB 之间偏离太远就需要先做增益归一化否则 PESQ 的分值会失真。4.3 输出分数区间解读-0.5 到 4.5 的物理含义PESQ 的原始输出理论上限是 4.5下限是 -0.5。实际经验值如下分数区间主观感受常见典型场景4.0 - 4.5几乎无感知损伤G.722 宽带编码、无损传输3.5 - 4.0轻微可感知但不烦人中等码率 Opus、AMR-WB 高码率3.0 - 3.5可感知损伤但可接受普通移动通信场景2.0 - 3.0损伤明显聆听疲劳低码率编码或严重丢包 2.0质量差几乎不可用严重网络损伤或非语音文件理解这个区间比记数字更重要PESQ 的分数不是线性的从 3.5 提到 4.0 所需的质量改进幅度远小于从 2.5 提到 3.0。做编解码器对比时如果两版差距在 0.2 以内大概率是算法差异不明显不建议直接按分数差异做决策。4.4 无法逃避的常见报错与对应解法报错一Error: Unsupported sample rate.原因输入文件采样率不是 8 kHz 或者 16 kHz。解决用 ffmpeg 重采样后再跑。ffmpeg -i input.wav -ar 8000 -ac 1 ref_8k.wav报错二Error: Could not open file.原因文件路径错误PESQ 对路径中的特殊字符支持极差例如中文路径在某些版本里会出现问题。解决把 wav 文件和 pesq 可执行文件放同一目录用相对路径调用。报错三Bad MagicNumber in header.原因输入文件不是标准 RIFF/WAVE 头格式可能是 RAW PCM 文件或者 WAV 头被破坏。解决用 sox 重新封装sox -t raw -r 8000 -e signed -b 16 raw.pcm wrapper.wav5. 避坑全记录跨平台编译与批处理中的 5 个真实踩坑点5.1 现象make 报missing separator或syntax error原因Makefile 的换行符是 Windows CRLFLinux 下 make 无法解析。这是在 Windows 上用记事本编辑过 Makefile 后最常见的翻车现场。解决执行sed -i s/\r$// Makefile把回车符去掉再用make重新编译。5.2 现象编译通过但执行时报段错误Segmentation fault原因命令行参数中文件数量不对或者 mode 参数位置放错。PESQ 源码里的main()对 argc 有明确检查但如果参数是宽窄带模式字符串且未匹配任何分支代码可能走到未定义分支。解决严格按pesq ref.wav deg.wav顺序调用mode 参数放在两个文件之前不要写成pesq ref.wav deg.wav -w。5.3 现象批处理脚本里连续跑几十个文件突然某个文件报assertion failed原因输入文件时长差异过大。PESQ 要求两段文件长度一致如果 deg 文件比 ref 文件短了超过一个内部帧的长度代码内部的assert会直接中止进程。解决在批处理脚本中先比较两个 wav 的时长时长不一致时先做末尾补零trim再调用 pesq。我一般是预处理成统一时长sox ref.wav ref_pad.wav pad 0 1这个命令在末尾补一秒静音如果 deg 文件更短也能跑通但要在后续计算中扣除静音段的偏移。5.4 现象Windows 上双击生成的 pesq.exe 闪退原因命令行参数为空时程序退出但终端窗口关闭。这不是程序 bug而是 PESQ 需要在命令行终端中运行。解决在 cmd 或 PowerShell 中运行或者写一个批处理文件封装参数echo off pesq.exe -w ref.wav deg.wav pause加一行pause就能看到输出结果。5.5 现象Linux 编出的 pesq 拿到另一台机器上跑提示cannot execute binary file原因架构不匹配。比如在一台 x86_64 机器上编译拷到 ARM 板子上运行二进制指令集不同。解决在目标平台上重新编译或者用file命令确认二进制格式file pesq输出会显示ELF 64-bit LSB executable, x86-64这类信息和目标板子的uname -m输出对照一下即可找出问题。6. 输出到批量评估工作流用脚本封装 PESQ 并实现 MOS 分数自动归档当手头有几十对语音文件待评估时逐条手敲命令显然不现实。这里给出一个可扩展的批处理框架把 PESQ 包成自动化流程。把待测文件放在refs/与degs/两个目录文件名一一对应下面这个 bash 脚本负责循环评估并输出 CSV 格式结果#!/bin/bash # 批处理 PESQ 评估脚本 # 用法: ./run_pesq.sh ref_dir deg_dir output.csv REF_DIR$1 DEG_DIR$2 OUT_CSV$3 echo filename,raw_mos,mos_lqo $OUT_CSV for ref_wav in $REF_DIR/*.wav do fname$(basename $ref_wav) deg_wav$DEG_DIR/$fname if [ ! -f $deg_wav ]; then echo 跳过缺失文件: $deg_wav continue fi # 先统一采样率和声道 tmp_ref/tmp/${fname%.wav}_ref.wav tmp_deg/tmp/${fname%.wav}_deg.wav ffmpeg -y -i $ref_wav -ar 16000 -ac 1 $tmp_ref /dev/null 21 ffmpeg -y -i $deg_wav -ar 16000 -ac 1 $tmp_deg /dev/null 21 # 跑 PESQ提取输出行中的数值 output$(./pesq -w $tmp_ref $tmp_deg 2/dev/null | grep Prediction) raw_mos$(echo $output | awk -F[(,] {print $2}) mos_lqo$(echo $output | awk -F[(,] {print $3}) echo $fname,$raw_mos,$mos_lqo $OUT_CSV done echo 评估完成结果写入 $OUT_CSV脚本逻辑说明外层循环遍历参考文件用basename提取文件名与待测目录中的文件对应。两个ffmpeg命令负责把任意采样率、任意声道的 wav 强制转成 16 kHz 单声道避免 PESQ 因格式问题中途退出。awk -F[(,]按括号和逗号切分输出行例如输出P.862 Prediction (Raw MOS, MOS-LQO): 3.456 3.721此时$2是 3.456$3是 3.721分别对应原始 MOS 和映射后的 MOS-LQO。最后一行写回 CSV。注意脚本里grep Prediction是区分 PESQ 输出与错误输出错误输出走 stderr已被重定向丢弃。这套脚本跑完后整个目录的评估数据直接落成表格再导入 Excel 或者 Python 分析。需要扩展功能时可以在 CSV 里加一列用于记录每组文件的编码参数方便后续按条件筛选。我自己用 PESQ 这几年最大的教训是永远不要盲目信任第一次跑出的分数。每次批量评估前先挑一对已知质量差异的文件做 smoke test确认无参考与待测文件的路径映射没有错位。从那以后我每次整理语音质量测试数据都强制走一遍「格式统一 → 时长对齐 → 批处理脚本 → 抽检输出」的流程至今没再出过大面积数据错乱的事故。希望这份源码和编译教程也能让你的 PESQ 之旅少走弯路。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑