java speex回声消除_speex 回声消除的用法

java speex回声消除_speex 回声消除的用法speex的回声消息就是speex_echo_cancellation函数的正确用法回声消息的原理:对参考声音(解码的对端原始语音包)做延迟(会有多个延迟,如麦克风直接采集到音箱的声音,经墙壁反射后再次采集),衰减,从声卡里采集到的语音,做一个语音合成。回声产生的条件:通话中,有一方使用音箱(或者双方都用音箱)。在实际中如何使用speex_echo_cancellation这个函数呢?错误的使用,…

大家好,欢迎来到IT知识分享网。

speex的回声消息

就是speex_echo_cancellation函数的正确用法

回声消息的原理:

对参考声音(解码的对端原始语音包)做延迟(会有多个延迟,如麦克风直接采集到音箱的声音,经墙壁反射后再次采集),衰减,

从声卡里采集到的语音,做一个语音合成。

回声产生的条件:

通话中,有一方使用音箱(或者双方都用音箱)。

在实际中如何使用speex_echo_cancellation这个函数呢?错误的使用,将导致speex无法快速地收敛回声滤波器的参数。

使用音箱的那一方,这里我们称之为”发送方”,调用speex_echo_cancellation,

这样做就绕开了网络延迟,引起对算法收敛的干挠。

这是第一点要注意的

(也可以在”接收方”调用speex_echo_cancellation,但网络出现抖动时,就会使算法无法快速收敛,就无法消除回声了)

这样,我们的代码中,大概会是这样的逻辑:

解码网络语音包(记为 play)

写入声卡

采集麦克风的声音(记为rec)

调用speex_echo_cancellation 参play与rec传给这个函数

回想一下,应用层的程序可能会是这样(当然您的程序也可能不是这样,但情形类似):

一个接收线程,收包,放音

一个发送线程,录音,发包

我们自然会在录音线程里调用speex_echo_cancellation

但这有一个问题,录音线程与放音线程因为系统的调度问题,也会造成抖动,导致speex的回声消除算法无法收敛。

以下的一个程序模形,读者们可以参考

1 接收线程A,解码网络语音包,接语音包推入一个消息队列A

2 放音录音线程B,从队列A中取出语音包,放音,录音,录音得到的语音包,通过speex_echo_cancellation处理后,存入队列B

3 发送线程C,从队列B中取语音包,编码,发送

简单地说,就是用一个线程放音,录音,然后echo cancel,这样就不存在线程调度引起的延迟抖动

采用这种方式,就避免了因为线程调度引起的抖动,避免了不确定的延迟对speex算法收敛过程的干挠。

最后一个干挠因素:os提供的录音放音接口也是异步的。。。

这个干挠因素基本在应用层是无法排除的了。。。可能就是几毫秒的误差,但足以干挠回声消除算法了。

多路语音(会议)

选一个超级节点做合成语音,或者终端对语音进行合成,之后,处理就变成与单对单语音通话类似的情形了

直接上speex_echo_cancellation

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/23901.html

(0)
上一篇 2023-09-02 21:00
下一篇 2023-09-03 14:45

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信