青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴(yán)以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

Speex 一個(gè)開源的聲學(xué)回聲消除器(Acoustic Echo Cancellation)

轉(zhuǎn)載自:http://blog.csdn.net/chinabinlang/article/details/8086014

在一般的VOIP軟件或視頻會(huì)議系統(tǒng)中,假設(shè)我們只有A和B兩個(gè)人在通話,首先,A的聲音傳給B,B然后用喇叭放出來,而這時(shí)B的MIC呢則會(huì)采集到喇叭放出來的聲音,然后傳回給A,如果這個(gè)傳輸?shù)倪^程中時(shí)延足夠大,A就會(huì)聽到一個(gè)和自己剛才說過的話一樣的聲音,這就是回聲,聲學(xué)回聲消除器的作用就是在B端對(duì)B采集到的聲音進(jìn)行處理,把采集到聲音包含的A的聲音去掉再傳給A,這樣,A就不會(huì)聽到自己說過的話了。
聲學(xué)回聲消除的原理我就不說了,這在網(wǎng)上有很多文檔,網(wǎng)上缺少的是實(shí)現(xiàn),所以,我在這把一個(gè)開源的聲學(xué)回聲消除器介紹一下,希望對(duì)有些有人用,如果有人知道怎么把這消除器用的基于實(shí)時(shí)流的VOIP軟件中,希望能一起分享一下。
這個(gè)聲學(xué)回聲消除器是一個(gè)著名的音頻編解碼器speex中的一部分,1.1.9版本后的回聲消除器才起作用,以前版本的都不行,我用的也是這個(gè)版本,測(cè)試表明,用同一個(gè)模擬文件,它有效果比INTEL IPP庫4.1版中的聲學(xué)回聲消除器的還要好。
先說編譯。首先,從www.speex.org上下載speex1.1.9的源代碼,解壓,打開speex/win32/libspeex中的libspeex.dsw,這個(gè)工作區(qū)里有兩個(gè)工程,一個(gè)是libspeex,另一個(gè)是libspeex_dynamic。然后,將libspeex中的mdf.c文件添加到工程libspeex中,編譯即可。
以下是我根據(jù)文檔封裝的一個(gè)類,里面有一個(gè)測(cè)試程序:
 //file name: speexEC.h
#ifndef SPEEX_EC_H
#define SPEEX_EC_H
#include 
<stdio.h>
#include 
<stdlib.h>
#include 
"speex/speex_echo.h"
#include 
"speex/speex_preprocess.h" 
class CSpeexEC
{
public:
CSpeexEC();
~CSpeexEC();
void Init(int frame_size=160int filter_length=1280int sampling_rate=8000); 
void DoAEC(short *mic, short *refshort *out);

protected:
void Reset();

private:
bool      m_bHasInit;
SpeexEchoState
*   m_pState;
    SpeexPreprocessState
* m_pPreprocessorState;
int      m_nFrameSize;
int      m_nFilterLen;
int      m_nSampleRate;
float*      m_pfNoise;
}
;

#endif

//fine name:speexEC.cpp
#include "SpeexEC.h"

CSpeexEC::CSpeexEC()
{
m_bHasInit   
= false;
m_pState   
= NULL;
m_pPreprocessorState  
= NULL;
m_nFrameSize   
= 160;
m_nFilterLen   
= 160*8;
m_nSampleRate   
= 8000;
m_pfNoise   
= NULL;
}


CSpeexEC::
~CSpeexEC()
{
Reset();
}


void CSpeexEC::Init(int frame_size, int filter_length, int sampling_rate)
{
Reset(); 

if (frame_size<=0 || filter_length<=0 || sampling_rate<=0)
{
  m_nFrameSize  
=160;
  m_nFilterLen  
= 160*8;
  m_nSampleRate 
= 8000;
}

else
{
  m_nFrameSize  
=frame_size;
  m_nFilterLen  
= filter_length;
  m_nSampleRate 
= sampling_rate;
}


m_pState 
= speex_echo_state_init(m_nFrameSize, m_nFilterLen);
m_pPreprocessorState 
= speex_preprocess_state_init(m_nFrameSize, m_nSampleRate);
m_pfNoise 
= new float[m_nFrameSize+1];
m_bHasInit 
= true;
}


void CSpeexEC::Reset()
{
if (m_pState != NULL)
{
  speex_echo_state_destroy(m_pState);
  m_pState 
= NULL;
}

if (m_pPreprocessorState != NULL)
{
  speex_preprocess_state_destroy(m_pPreprocessorState);
  m_pPreprocessorState 
= NULL;
}

if (m_pfNoise != NULL)
{
  delete []m_pfNoise;
  m_pfNoise 
= NULL;
}

m_bHasInit 
= false;
}


void CSpeexEC:DoAEC(short* mic, short* refshort* out)
{
if (!m_bHasInit)
  
return;

speex_echo_cancel(m_pState, mic, 
refout, m_pfNoise);
    speex_preprocess(m_pPreprocessorState, (__int16 
*)out, m_pfNoise);
    
}

可以看出,這個(gè)回聲消除器類很簡(jiǎn)單,只要初始化一下就可以調(diào)用了。但是,要注意的是,傳給回聲消除器的兩個(gè)聲音信號(hào),必須同步得非常的好,就是說,在B端,接收到A說的話以后,要把這些話音數(shù)據(jù)傳給回聲消除器做參考,然后再傳給聲卡,聲卡再放出來,這有一段延時(shí),這時(shí),B再采集,然后傳給回聲消除器,與那個(gè)參考數(shù)據(jù)比較,從采集到的數(shù)據(jù)中把頻域和參考數(shù)據(jù)相同的部分消除掉。如果傳給消除器的兩個(gè)信號(hào)同步得不好,即兩個(gè)信號(hào)找不到頻域相同的部分,就沒有辦法進(jìn)行消除了。
測(cè)試程序:
#define NN 160
void main()
{
FILE
* ref_fd, *mic_fd, *out_fd;
short ref[NN], mic[NN], out[NN];
ref_fd 
= fopen ("ref.pcm""rb"); //打開參考文件,即要消除的聲音
mic_fd = fopen ("mic.pcm",  "rb");//打開mic采集到的聲音文件,包含回聲在里面
out_fd = fopen ("echo.pcm""wb");//消除了回聲以后的文件

CSpeexEC ec;
ec.Init();

while (fread(mic, 1, NN*2, mic_fd))
   
{
      fread(
ref1, NN*2, ref_fd);  
      ec.DoAEC(mic, 
refout);
      fwrite(
out1, NN*2, out_fd);
   }

  
   fclose(ref_fd);
   fclose(mic_fd);
   fclose(out_fd);
}
  以上的程序是用文件來模擬回聲和MIC,但在實(shí)時(shí)流中是大不一樣的,在一般的VOIP軟件中,接收對(duì)方的聲音并傳到聲卡中播放是在一個(gè)線程中進(jìn)行的,而采集本地的聲音并傳送到對(duì)方又是在另一個(gè)線程中進(jìn)行的,而聲學(xué)回聲消除器在對(duì)采集到的聲音進(jìn)行回聲消除的同時(shí),還需要播放線程中的數(shù)據(jù)作為參考,而要同步這兩個(gè)線程中的數(shù)據(jù)是非常困難的,因?yàn)樯陨杂行┎煌剑晫W(xué)回聲消除器中的自適應(yīng)濾波器就會(huì)發(fā)散,不但消除不了回聲,還會(huì)破壞原始采集到的聲音,使被破壞的聲音難以分辨。我做過好多嘗試,始終無法用軟件來實(shí)現(xiàn)對(duì)這兩個(gè)線程中的數(shù)據(jù)進(jìn)行同步,導(dǎo)致實(shí)現(xiàn)失敗,希望有經(jīng)驗(yàn)的網(wǎng)友們一起分享一下這方面的經(jīng)驗(yàn)。

示例代碼:

Sample code

This section shows sample code for encoding and decoding speech using the Speex API. The commands can be used to encode and decode a file by calling:  
% sampleenc in_file.sw | sampledec out_file.sw 
where both files are raw (no header) files encoded at 16 bits per sample (in the machine natural endianness).

 

sampleenc.c

sampleenc takes a raw 16 bits/sample file, encodes it and outputs a Speex stream to stdout. Note that the packing used is NOT compatible with that of speexenc/speexdec.

#include <speex/speex.h>
#include 
<stdio.h>
/*The frame size in hardcoded for this sample code but it doesn't have to be*/
#define FRAME_SIZE 160
int main(int argc, char **argv)
{
char *inFile;
FILE 
*fin;
short in[FRAME_SIZE];
float input[FRAME_SIZE];
char cbits[200];
int nbBytes;
/*Holds the state of the encoder*/
void *state;
/*Holds bits so they can be read and written to by the Speex routines*/
SpeexBits bits;
int i, tmp;
/*Create a new encoder state in narrowband mode*/
state 
= speex_encoder_init(&speex_nb_mode);
/*Set the quality to 8 (15 kbps)*/
tmp
=8;
speex_encoder_ctl(state, SPEEX_SET_QUALITY, 
&tmp);
inFile 
= argv[1];
fin 
= fopen(inFile, "r");
/*Initialization of the structure that holds the bits*/
speex_bits_init(
&bits);
while (1)
{
/*Read a 16 bits/sample audio frame*/
fread(
insizeof(short), FRAME_SIZE, fin);
if (feof(fin))
break;
/*Copy the 16 bits values to float so Speex can work on them*/
for (i=0;i<FRAME_SIZE;i++)
input[i]
=in[i];
/*Flush all the bits in the struct so we can encode a new frame*/
speex_bits_reset(
&bits);
/*Encode the frame*/
speex_encode(state, input, 
&bits);
/*Copy the bits to an array of char that can be written*/
nbBytes 
= speex_bits_write(&bits, cbits, 200);
/*Write the size of the frame first. This is what sampledec expects but
it's likely to be different in your own application
*/

fwrite(
&nbBytes, sizeof(int), 1, stdout);
/*Write the compressed data*/
fwrite(cbits, 
1, nbBytes, stdout);
}

/*Destroy the encoder state*/
speex_encoder_destroy(state);
/*Destroy the bit-packing struct*/
speex_bits_destroy(
&bits);
fclose(fin);
return 0;
}

 

sampledec.c

sampledec reads a Speex stream from stdin, decodes it and outputs it to a raw 16 bits/sample file. Note that the packing used is NOT compatible with that of speexenc/speexdec.

#include <speex/speex.h>
#include 
<stdio.h>
/*The frame size in hardcoded for this sample code but it doesn't have to be*/
#define FRAME_SIZE 160
int main(int argc, char **argv)
{
char *outFile;
FILE 
*fout;
/*Holds the audio that will be written to file (16 bits per sample)*/
short out[FRAME_SIZE];
/*Speex handle samples as float, so we need an array of floats*/
float output[FRAME_SIZE];
char cbits[200];
int nbBytes;
/*Holds the state of the decoder*/
void *state;
/*Holds bits so they can be read and written to by the Speex routines*/
SpeexBits bits;
int i, tmp;
/*Create a new decoder state in narrowband mode*/
state 
= speex_decoder_init(&speex_nb_mode);
/*Set the perceptual enhancement on*/
tmp
=1;
speex_decoder_ctl(state, SPEEX_SET_ENH, 
&tmp);
outFile 
= argv[1];
fout 
= fopen(outFile, "w");
/*Initialization of the structure that holds the bits*/
speex_bits_init(
&bits);
while (1)
{
/*Read the size encoded by sampleenc, this part will likely be
different in your application
*/

fread(
&nbBytes, sizeof(int), 1, stdin);
fprintf (stderr, 
"nbBytes: %d/n", nbBytes);
if (feof(stdin))
break;
/*Read the "packet" encoded by sampleenc*/
fread(cbits, 
1, nbBytes, stdin);
/*Copy the data into the bit-stream struct*/
speex_bits_read_from(
&bits, cbits, nbBytes);
/*Decode the data*/
speex_decode(state, 
&bits, output);
/*Copy from float to short (16 bits) for output*/
for (i=0;i<FRAME_SIZE;i++)
out[i]=output[i];
/*Write the decoded audio to file*/
fwrite(
outsizeof(short), FRAME_SIZE, fout);
}

/*Destroy the decoder state*/
speex_decoder_destroy(state);
/*Destroy the bit-stream truct*/
speex_bits_destroy(
&bits);
fclose(fout);
return 0;
}

 

posted on 2013-01-11 00:24 楊粼波 閱讀(2159) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日韩国产亚洲一区| 亚洲欧美日韩另类| 午夜在线一区| 午夜在线不卡| 久久久精品欧美丰满| 欧美一区二区三区四区夜夜大片| 欧美一区二区三区在线观看视频| 久久激情五月丁香伊人| 久久一日本道色综合久久| 农村妇女精品| 一本久久综合亚洲鲁鲁五月天| 亚洲欧美成人网| 久久影院午夜片一区| 欧美日韩国产小视频在线观看| 国产精品嫩草影院一区二区 | 欧美日韩一区二区三区| 欧美视频精品在线观看| 国产综合色产| 亚洲免费不卡| 久久久www成人免费精品| 欧美不卡在线视频| 在线视频亚洲欧美| 久久久久久亚洲精品中文字幕 | 久久国产精品久久久久久| 麻豆精品国产91久久久久久| 亚洲欧洲一区二区三区| 中文日韩在线视频| 美女黄网久久| 国产一区二区三区高清| 亚洲一级在线观看| 免费在线日韩av| 亚洲欧美区自拍先锋| 欧美国产一区二区三区激情无套| 国产欧美视频一区二区| 美女久久网站| 中日韩美女免费视频网站在线观看| 午夜精品一区二区三区在线视| 另类酷文…触手系列精品集v1小说| 欧美视频一区二区| 亚洲精品免费看| 免费成人毛片| 久久激情视频免费观看| 国产精品久久久久99| 一本色道久久综合精品竹菊 | 欧美日韩高清在线观看| 狠狠88综合久久久久综合网| 亚洲免费在线| 日韩午夜精品| 欧美日韩免费观看一区 | 久久国产欧美| 亚洲一区二区视频在线| 欧美日韩黄色一区二区| 亚洲精品一区二区三区在线观看| 欧美a级片一区| 久久人人爽人人爽| 黄色成人免费观看| 蜜臀久久99精品久久久久久9| 午夜宅男久久久| 国产一区二区三区在线观看视频| 久久高清国产| 欧美一级理论片| 狠狠噜噜久久| 欧美大片一区二区| 欧美14一18处毛片| 亚洲精品日韩在线| 亚洲激情网站免费观看| 欧美金8天国| 国产精品99久久久久久久久久久久| 亚洲啪啪91| 欧美新色视频| 欧美在线啊v一区| 久久久久**毛片大全| 亚洲国产精品久久久久| 亚洲电影观看| 欧美日韩国产一中文字不卡 | 红桃视频国产一区| 欧美激情第3页| 欧美精品二区| 午夜久久福利| 久久婷婷蜜乳一本欲蜜臀| 91久久精品久久国产性色也91| 亚洲国产婷婷香蕉久久久久久99 | 欧美中文字幕在线视频| 在线观看国产成人av片| 91久久精品美女高潮| 欧美特黄一级大片| 久久久xxx| 国产伦精品一区二区三区视频孕妇 | 欧美丰满高潮xxxx喷水动漫| 欧美成人免费小视频| 亚洲综合社区| 老司机精品久久| 亚洲中字黄色| 免费观看在线综合| 午夜精品一区二区三区四区 | 午夜在线精品偷拍| 亚洲日本激情| 午夜视频久久久久久| 91久久黄色| 亚欧成人精品| 一本色道久久综合狠狠躁篇怎么玩| 亚洲欧美国产精品桃花 | 久久精品欧美| 欧美日本国产一区| 久久这里有精品视频| 欧美精品一级| 麻豆国产精品va在线观看不卡| 欧美日韩在线观看一区二区三区 | 亚洲国产精品欧美一二99| 亚洲视频香蕉人妖| 亚洲精品久久久久久久久| 欧美一区二区高清在线观看| 夜夜爽av福利精品导航| 猫咪成人在线观看| 久久久久久亚洲精品中文字幕| 欧美视频在线观看一区| 亚洲国产清纯| 亚洲全黄一级网站| 久久夜色精品国产欧美乱| 午夜久久美女| 国产精品久久久久久久app| 91久久精品网| 亚洲国产激情| 老司机精品视频一区二区三区| 久久不射电影网| 国产精品视频专区| 亚洲国产小视频| 亚洲精品一区二区三区婷婷月| 久久久久久穴| 久久三级福利| 黄色av一区| 久久久蜜桃精品| 欧美不卡视频| 亚洲日韩成人| 欧美激情一区二区三区成人| 亚洲国产精品福利| 亚洲日韩欧美一区二区在线| 欧美激情一区二区三区| 亚洲欧洲日韩综合二区| 一区二区三区高清| 亚洲美女视频在线观看| 亚洲欧洲另类| 亚洲精品一区二区三区婷婷月| 欧美18av| 日韩视频一区二区三区在线播放免费观看 | 久久久国产精品亚洲一区| 国产精品欧美日韩久久| 亚洲男人的天堂在线观看| 久久成人av少妇免费| 狠狠久久亚洲欧美| 老司机免费视频一区二区| 亚洲黄页视频免费观看| 亚洲小说区图片区| 国产精品美女久久久免费| 午夜精品久久久久久久久| 久久视频国产精品免费视频在线| 一区二区在线视频| 欧美第一黄网免费网站| 99视频在线观看一区三区| 性色一区二区三区| 极品尤物av久久免费看| 欧美国产国产综合| 亚洲一区激情| 免费久久99精品国产自| 一区二区三区视频在线| 国产亚洲亚洲| 欧美日本一道本| 欧美在线视频一区二区| 亚洲国产欧美日韩| 欧美一区高清| 日韩亚洲在线| 精品99一区二区| 欧美手机在线视频| 久久日韩精品| 亚洲淫性视频| 亚洲人在线视频| 久久久久久一区| 亚洲午夜电影| 亚洲精品视频免费在线观看| 国产视频一区在线| 欧美日韩国产成人在线| 久久精品天堂| 亚洲无线一线二线三线区别av| 欧美国产视频日韩| 久久精品一区二区三区中文字幕| 99精品欧美一区二区蜜桃免费| 国产日韩欧美a| 国产精品videossex久久发布| 免费不卡中文字幕视频| 欧美专区日韩专区| 亚洲欧美国产毛片在线| 99热这里只有精品8| 亚洲丰满在线| 欧美h视频在线| 久久婷婷国产综合国色天香| 欧美亚洲免费高清在线观看| 99这里只有久久精品视频| 亚洲国产91| 一区二区三区在线免费播放| 国产伦精品一区二区三区四区免费|