啃论文俱乐部——移植speexdsp到OpenHarmony标准系统⑤ 原创 精华
- 大家好!我来自南京,在OpenHarmony成长计划啃论文俱乐部,与
华为、软通动力、润和软件、拓维信息、深开鸿
等公司一起,学习和研究操作系统技术
从今年1月11日加入OpenHarmony俱乐部已经有接近8个月时间了。笔者一直在思考啃论文给我带来了些什么,通过啃论文能为OpenHarmony做些什么。笔者利用大二升大三暑假两个月时间移植了Speexdsp这个三方库到OpenHarmony标准系统,而关于前面的问题我似乎找到了答案,现将啃论文和三方库移植分享经验如下:
由于想要分享的内容较多,为避免读者姥爷们失去看下去的耐心,分享将以连载的方式进行。感谢润和软件提供的硬件支持。
下期预告:OAT开源扫描和三方库上仓基本要求
往期回顾:
啃论文俱乐部——移植speexdsp到OpenHarmony标准系统①
啃论文俱乐部——移植speexdsp到OpenHarmony标准系统②
啃论文俱乐部——移植speexdsp到OpenHarmony标准系统③
啃论文俱乐部——移植speexdsp到OpenHarmony标准系统④
本期为移植speexdsp到OpenHarmony标准系统
的第⑤期,主要内容如下:
目录
speexdsp移植后已提交至openhamrony sig仓库:https://gitee.com/openharmony-sig/contest/tree/master/2022_OpenHarmony_thirdparty/speexdsp
七、Speexdsp功能分析
- 将speexdsp加入openharmony编译体系后,能成功编译出来动态链接库和测试用的可执行文件,并不代表移植三方库成功。还要在开发板上运行测试其功能是否正常。
speexdsp核心库分析
1.库实现方式
- 编程语言:C
- 原生平台:linux
2.依赖分析
- 除C标准库外,无其他第三方库依赖
3.license以及版权
- 根据speex官网https://speex.org/的信息,speexdsp使用的开源协议为
revised BSD license
(revised BSD license
又称为3-clause BSD License
或者BSD 3-Clause License
,一般使用BSD 3-Clause)
- OpenHamorny第三方开源软件许可证类型必须是
OSI
明确定义的。OSI
明确定义的开源许可证有:https://opensource.org/licenses/alphabeticalBSD 3-Clause License
是OSI
明确定义的开源许可。
如下类型许可证可以引入到OpenHarmony项目中:
如下类型许可证不建议引入到OpenHarmony项目中:
speexdsp的license以及版权内容如下:
4.最新一次版本
- 2022年6月16日,版本号1.2.1
5.代码规模
linux系统提供了wc命令来统计文件的行数,统计当前目录下的所有文件行数,终端输入如下命令:
文件名 | 代码行数 |
---|---|
arch.h | 232 |
bfin.h | 15 |
buffer.c | 176 |
fftwrap.c | 448 |
fftwrap.h | 58 |
filterbank.c | 227 |
filterbank.h | 66 |
fixed_arm4.h | 135 |
fixed_arm5e.h | 160 |
fixed_bfin.h | 141 |
fixed_debug.h | 497 |
fixed_generic.h | 106 |
jitter.c | 839 |
kiss_fft.c | 523 |
_kiss_fft_guts.h | 160 |
kiss_fft.h | 108 |
kiss_fftr.c | 297 |
kiss_fftr.h | 51 |
math_approx.h | 332 |
mdf.c | 1279 |
misc_bfin.h | 56 |
os_support.h | 169 |
preprocess.c | 1215 |
pseudofloat.h | 379 |
resample.c | 1239 |
resample_neon.h | 339 |
resample_sse.h | 128 |
scal.c | 293 |
smallft.c | 1261 |
smallft.h | 46 |
vorbis_psy.h | 97 |
speex_buffer.h | 68 |
speexdsp_config_types.h | 12 |
speexdsp_types.h | 126 |
speex_echo.h | 170 |
speex_jitter.h | 197 |
speex_preprocess.h | 219 |
speex_resampler.h | 343 |
总行数 | 12207 |
功能分析
可以参考speexdsp提供的文档分析功能
预处理器
预处理器被设计为在运行编码器之前在音频上使用。预处理器提供三个主要功能:
- 噪声抑制
- 自动增益控制(AGC)
- 语音活动检测(V AD)
自适应抖动缓冲区
- 当通过UDP或RTP传输语音(或任何相关内容)时,包可能会丢失,以不同的延迟到达,甚至乱序。
- 抖动缓冲区的目的是重新排序数据包,并缓冲足够长的时间,以便它们可以被发送以进行解码。
声学回声消除器
回声消除是为了提高远端质量。
- 在任何免提通信系统中,远端语音通过本地扬声器播放。音频在房间内传播,并被麦克风捕获。如果从麦克风捕获的音频被直接发送到远端,那么用户就会听到远端语音的回声。声学回声消除器设计用于在声学回声发送到远端之前消除它。
重采样器
这个重采样器可以用于在任意两个速率之间进行转换(比率必须是有理数),并且可以控制质量/复杂性的权衡。
- 重采样器在某些情况下将音频从一个采样率转换到另一个采样率。
- 它可以用于混合具有不同采样率的流、用于支持声卡不支持的采样率、用于转码等。
八、Speexdsp功能测试
测试逻辑
-
在speexdsp原生库的libspeexdsp目录下有原生的测试源文件testresample.c、testresample2.c、testecho.c、testdenoise.c、testjitter.c。
-
进行功能测试需要对比pc端和开发板的运行效果,因此需要在pc端编译出测试用的可执行文件(开发板上的已经编译出来了)。
重采样功能
- 查看源码可知,运行测试重采样率的可执行文件时,输入一份音频文件的同时需要指定处理后输出的音频文件。
- 测试重采样功能的源文件为testresample.c和testresample2.c。
testresample.c源码分析如下:
可以得知:
- 输入音频的采样率要求为96000Hz、声道为单声道。
- 输出音频的采样率为44100。
回声消除功能
-
运行测试回声消除的可执行文件时,需要输入两段音频文件,分别为一份麦克风的音频、一份speaker的音频。另外需要指定一份处理后输出的音频文件。采样率都为8000Hz
-
测试回声消除功能的源文件为testecho.c。
testecho.c源码分析如下:
预处理功能
-
运行测试预处理功能的可执行文件时,输入一份音频文件的同时需要指定处理后输出的音频文件。(采样率为8000Hz)
-
测试源文件testdenoise.c测试的是预处理功能中的噪声抑制。
testdenoise.c源码分析如下:
抖动缓冲功能
当通过UDP或RTP传输语音(或任何相关内容)时,包可能会丢失,以不同的延迟到达,甚至乱序。
1.抖动缓冲区的目的是重新排序数据包,并缓冲足够长的时间,以便它们可以被发送以进行解码。
2.测试源文件testjitter.c,这个去抖动测试需要接收来自udp/rtp的网络语音数据,原生测试程序没有做到真正意义上的测试,从程序上看是告诉用户如何使用接口。
testjitter.c源码分析:
测试步骤
编译pc端上的测试用的可执行程序
编译pc端的可执行程序:
其中:
- gcc后面是测试用的源文件
- -L 后指定so库所在的文件夹
- -l+so库的名字(除去lib和后缀)
- -o 后面是可执行文件的名字,
- -l 后面是测试用的源文件要用到的头文件的路径
将编译生成的库以及测试用的可执行文件推送到开发板上
- hdc工具的使用 请参考用hdc工具在OpenHarmony3.2 上安装应用中的相关内容
- 获取了ohos源码,也可以执行
./build.sh --product-name ohos-sdk
编译sdk。- 如果有这样的编译报错,说明依赖的库没在linux上安装完整。
- 安转完整才能成功编译。
- 如果有这样的编译报错,说明依赖的库没在linux上安装完整。
1.通过与ohos版本匹配的hdc_std工具,将编译生成的库以及测试用的可执行文件推送到开发板上
2.将压缩包push到开发板
3.解压压缩包并将库文件拷贝到对应的目录
本次移植是基于openharmony标准系统3.2Beta1版本,是arm64位系统
执行测试程序、分析测试结果
分析测试结果需要使用到的音频处理软件是ocenaudio
,下载地址:https://www.ocenaudio.com/en/
①执行testresample可执行文件
通过分析testresample.c源码可知:执行测试程序时输入一份采样率为96000Hz并且为单声道的音频时,经过重采样输出的音频采样率为44100Hz。
在pc端运行:
输入的音频为input.pcm,把它拷贝到testresample同目录下,并且新建空白文档命名为output.pcm。
打开终端执行如下命令:
使用重定向<
符号指定输入文件、>
符号指定输出文件
输出的output.pcm采样率变为44100Hz,音频的波形图
和声谱图
如下:
在rk3568上运行:
这里测试testresample时,将一份与pc端同样的input.pcm和output.pcm拷贝至开发板speexdsp目录。
在开发板speexdsp目录执行语句如下
将开发板输出的output.pcm拷贝至pc端
测试结果:经过重采样,pc端和rk3568开发板输出的output.pcm音频采样率都为44100Hz,两者运行测试程序testresample结果一致。
②执行testresample2可执行文件
通过分析testresample2.c源码可知,执行测试程序时需要指定一份空白的单声道音频文件output.pcm。
测试testresample2时,需要把空白的单声道音频文件output.pcm拷贝至开发板speexdsp目录。
pc端运行:
执行语句如下:
输出结果如下:
终端打印信息
输出音频output.pcm波形图和声谱图如下:
rk3568开发板上运行:
执行语句如下:
测试结果:输出一份不为空的output.pcm音频文件,并且在终端输出文本如下:
以最后一行"128000 1024 1024 2731 -> 1024 2730“”为例,其中128000为采样率(Hz);1024为一个编码单元采样点数(帧);1024为输入音频理论帧长;2731为输出音频理论帧长。"->"符号后的1024为经过重采样处理输入音频实际帧长,2730为输出音频实际帧长。
- pc端和rk3568开发板运行testresample2可执行程序效果一致。
③执行testecho可执行文件
测试testecho时,需要输入两份音频文件,同时需要指定一份输出的音频文件。
输入的两份音频一份为speaker.wav(麦克风收录的说话人语音信号+在房间多径反射的语音),另一份为micin.wav(麦克风收录的房间多径反射的语音)。
- speaker.wav正常房间环境下收录说话人说话声音即可,mic2.pcm在正常环境收录时说话人不说话即可。
- 同时需要指定一份testecho_output.wav输出文件。
执行语句如下:
测试结果:对比输入的speaker.wav和输出testecho_output.wav的波形图和声谱图,回声已经被消除。pc端和rk3568开发板运行testecho可执行程序效果一致。
④执行testdenoise可执行文件
通过分析testdenoise.c源码,执行测试程序时需要指定一份输入的不为空的8000Hz的input.pcm音频,并且需要指定一份空的输出的output.pcm音频。
rk3568上运行:
执行语句如下:
测试结果:对比输入的input.pcm和输出的outpu.pcm的波形图和声谱图,噪声已经被消除。pc端和rk3568开发板运行testdenoise可执行程序效果一致。
⑤执行testjitter可执行文件
通过分析testjitter.c源码,测试需要接收来自udp/rtp的网络语音数据,原生测试程序没有做到真正意义上的测试,从程序上看是告诉用户如何使用接口。
执行语句如下
测试结果:终端打印出语句
pc端和rk3568开发板运行testjitter可执行程序效果一致。
https://ost.51cto.com/posts/17007第7期已更新