音频算法speex中的aec分析以及解析
算法原理:
Speex的AEC是以NLMS(Normalized Least Mean Square)为基础,用MDF(multidelay block frequency domain)频域实现,最终推导出最优步长估计:残余回声与误差之比。最优步长等于残余回声方差与误差信号方差之比。 只有改与泄露系数相关部分的代码,才是对效果影响最大的地方,因为根据泄露系数,最终会估计出滤波器的最优步长。
使用实例:
测试代码:
#include "speex/speex_echo.h"
#include "speex/speex_preprocess.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> #define NN 128
#define TAIL 1024 int main(int argc, char **argv)
{
FILE *echo_fd, *ref_fd, *e_fd;
short echo_buf[NN], ref_buf[NN], e_buf[NN];
SpeexEchoState *st;
SpeexPreprocessState *den;
int sampleRate = ; if (argc != )
{
fprintf(stderr, "testecho mic_signal.sw speaker_signal.sw output.sw\n");
exit();
}
echo_fd = fopen(argv[], "rb");
ref_fd = fopen(argv[], "rb");
e_fd = fopen(argv[], "wb"); st = speex_echo_state_init(NN, TAIL);
den = speex_preprocess_state_init(NN, sampleRate);
speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
speex_preprocess_ctl(den, SPEEX_PREPROCESS_SET_ECHO_STATE, st); while (!feof(ref_fd) && !feof(echo_fd))
{
fread(ref_buf, sizeof(short), NN, ref_fd);
fread(echo_buf, sizeof(short), NN, echo_fd);
speex_echo_cancellation(st, ref_buf, echo_buf, e_buf);
speex_preprocess_run(den, e_buf);
fwrite(e_buf, sizeof(short), NN, e_fd);
}
speex_echo_state_destroy(st);
speex_preprocess_state_destroy(den);
fclose(e_fd);
fclose(echo_fd);
fclose(ref_fd);
return ;
}
命令: ./testecho speaker1.wav micin1.wav out1.wav
测试结果:
最新的speex的aec效果非常的好,超出了我的想象,回声消除效果不是一般的好,看来是speex更新了不少,因为自从2007年之后,speex很长一段时间都没有更新过代码。有兴趣的同学可以听一下消回声后的和之前的音频对比。
代码解析:
初始化中,第一个参数是每次处理的帧长度,这个一般是从10ms(80) 到30ms(240) 的处理长度,太长和太短都不是很好,filter_length 也是一个长度,它实际上就是speaker到rec之间的时间差。这个在不同设备上是不同的,跟产品的使用场景,结构,以及软件耗时有关系,一般的是可以测试出来的。
SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length)
系统默认的消回声采样是8k的,如下所示,假如你想改变采样频率,
/* This is the default sampling rate */
427 st->sampling_rate = 8000;
428 st->spec_average = DIV32_16(SHL32(EXTEND32(st->frame_size), 15), st->sampling_rate);
要使用下面的函数:speex_preprocess_state_init(NN,sampleRate)
接下来是要配置消回声的参数设置,一般是采样率设置。
speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
参数都可以以下这些:
46 /** Obtain frame size used by the AEC */
47 #define SPEEX_ECHO_GET_FRAME_SIZE 3
48
49 /** Set sampling rate */
50 #define SPEEX_ECHO_SET_SAMPLING_RATE 24
51 /** Get sampling rate */
52 #define SPEEX_ECHO_GET_SAMPLING_RATE 25
53
54 /* Can't set window sizes */
55 /** Get size of impulse response (int32) */
56 #define SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE 27
57
58 /* Can't set window content */
59 /** Get impulse response (int32[]) */
60 #define SPEEX_ECHO_GET_IMPULSE_RESPONSE 29
最重要的函数登场了:这个函数,非常的好用,估计只要看一下入参,你就知道怎么使用了。具体的使用就看上面的例子吧。
void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out)
假如在预处理中有些参数设置,需要调用预处理函数再把输出的结果处理一下,假如预处理没有了,那就不需要了。
speex_preprocess_run(den, e_buf);
其实,代码流程就这么简单,但是,想把系统效果调试的很好,还是要花不少功夫的。
注意事项:
1 AEC的线性算法处理不了Non-linear distortion(非线性失真)
2 在其它预处理前 先调用AEC
3 speex的aec并不是很适合音响系统里,音响中要慎用。耳机中效果还挺好。
4 实验用的音频数据就不放到这里了,有谁需要可以留言邮箱,我发个你。
音频算法speex中的aec分析以及解析的更多相关文章
- 音频软件开发中的debug方法和工具
本文系作者原创.如转载,请注明出处. 谢谢! 音频软件开发同其他软件开发一样,都需要去调试.音频软件调试同其他软件调试方法有相同的地方,也有不同的地方,同时调试时还需要借助一些专门的工具,有了这些方法 ...
- WebRTC 音频算法 附完整C代码
WebRTC提供一套音频处理引擎, 包含以下算法: AGC自动增益控制(Automatic Gain Control) ANS噪音抑制(Automatic Noise Suppression) AEC ...
- 音频压缩(Speex使用&Opus简介)--转
博客地址:http://blog.csdn.net/kevindgk GitHub地址:https://github.com/KevinDGK/MyAudioDemo 一简介 二局域网语音配置 三Sp ...
- OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...
- 第2章 rsync算法原理和工作流程分析
本文通过示例详细分析rsync算法原理和rsync的工作流程,是对rsync官方技术报告和官方推荐文章的解释. 以下是本文的姊妹篇: 1.rsync(一):基本命令和用法 2.rsync(二):ino ...
- Android 中图片压缩分析(上)
作者: shawnzhao,QQ音乐技术团队一员 一.前言 在 Android 中进行图片压缩是非常常见的开发场景,主要的压缩方法有两种:其一是质量压缩,其二是下采样压缩. 前者是在不改变图片尺寸的情 ...
- HanLP中人名识别分析
HanLP中人名识别分析 在看源码之前,先看几遍论文<基于角色标注的中国人名自动识别研究> 关于命名识别的一些问题,可参考下列一些issue: 名字识别的问题 #387 机构名识别错误 关 ...
- rsync算法原理和工作流程分析
本文通过示例详细分析rsync算法原理和rsync的工作流程,是对rsync官方技术报告和官方推荐文章的解释.本文不会介绍如何使用rsync命令(见rsync基本用法),而是详细解释它如何实现高效的增 ...
- HanLP中人名识别分析详解
HanLP中人名识别分析详解 在看源码之前,先看几遍论文<基于角色标注的中国人名自动识别研究> 关于命名识别的一些问题,可参考下列一些issue: l ·名字识别的问题 #387 l ·机 ...
随机推荐
- AngularJS 多级下拉框
<div ng-app="MultiDropDownApp" ng-controller="MultiDropDownControl as vm"> ...
- C# IDisposable接口的使用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 基于IdentityServer4的单点登录——Api
1.新建项目并添加引用 新建一个asp .net core 2.0的项目引用IdentityServer4.AccessTokenValidation 2.配置 将Api与IdentityServer ...
- JPlayer-MP3播放器(带播放列表)
第一篇随笔,写的不好的地方,各位不要见笑.其他的也不多说了,下面是我在工作中用的一个基于JQuery开源的插件,官方地址:http://www.jplayer.org/.先看下要实现的效果图: 首先引 ...
- WPF ScrollViewer(滚动条) 自定义样式表制作 (改良+美化)
原文:WPF ScrollViewer(滚动条) 自定义样式表制作 (改良+美化) 注释直接写在代码里了 不太理解意思的 可以先去看看我上一篇 WPF ScrollViewer(滚动条) 自定 ...
- WPF Calendar 日历控件 样式自定义
原文:WPF Calendar 日历控件 样式自定义 粗略的在代码上做了些注释 blend 生成出来的模版 有的时候 会生成 跟 vs ui界面不兼容的代码 会导致可视化设计界面 报错崩溃掉 但是确不 ...
- .NET VS 自定义新建代码文件模板
参考:http://www.cnblogs.com/fightingtong/p/3765914.html 在VS中新建文件时,可使用模板在文件中生成指定内容.只需要把IDE安装目录下的模板进行修改保 ...
- Win8Metro(C#)数字图像处理--2.31灰度拉伸算法
原文:Win8Metro(C#)数字图像处理--2.31灰度拉伸算法 [函数名称] 灰度拉伸函数GrayStretchProcess(WriteableBitmap src) [算法说明] ...
- 8086 CPU 寄存器简介(超详细,图文并茂)
http://www.cnblogs.com/BoyXiao/archive/2010/11/20/1882716.html
- .Net DateTime跨时区相关问题
项目:.Net CS结构,WCF通信,MySql存储. 场景:客户端(UTC+07:00)获取本地时间(DateTime对象)2017-01-17 15:20:12,通过WCF(http)传输至服务端 ...