zoukankan      html  css  js  c++  java
  • speex 回声消除的用法

    speex 回声消除的用法

    分类: speex AEC 回声消除 1336人阅读 评论(0) 收藏 举报

    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

  • 相关阅读:
    Linux常用命令学习
    LA 6437 Power Plant (prim最小生成树)
    Atitit.提升稳定性-----分析内存泄漏PermGen OOM跟解决之道...java
    hdu 1248 寒冰王座
    数据结构——算法之(031)(将字符串中全部小写字母排在大写字母的前面)
    X-射线:探索原子世界的利器
    关于sql中的with(nolock)
    Netty In Action中文版
    抓包报文分析
    POJ 1562 Oil Deposits
  • 原文地址:https://www.cnblogs.com/kinyer/p/3326570.html
Copyright © 2011-2022 走看看