简体   繁体   English

任何声学回声消除(AEC)库能够达到48 kHz?

[英]Any acoustic echo cancellation (AEC) library capable of 48 kHz?

I'm developing a VoIP application that runs at the sampling rate of 48 kHz. 我正在开发一个以48 kHz的采样率运行的VoIP应用程序。 Since it uses Opus, which uses 48 kHz internally, as its codec, and most current Android hardware natively runs at 48 kHz, AEC is the only piece of the puzzle I'm missing now. 由于它使用内部使用48 kHz的Opus作为其编解码器,而且目前大多数Android硬件本机运行频率为48 kHz,因此AEC是我现在所缺少的唯一一个难题。 I've already found the WebRTC implementation but I can't seem to figure out how to make it work. 我已经找到了WebRTC实现,但我似乎无法弄清楚如何使其工作。 It looks like it corrupts the memory randomly and crashes the whole thing sooner or later. 看起来它会随机破坏内存并且迟早会崩溃整个事情。 When it doesn't crash, the sound is kinda chunky as if it's quieter for the half of the frame. 当它没有崩溃时,声音有点粗糙,好像它对于帧的一半更安静。 Here's my code that processes a 20 ms frame: 这是我处理20毫秒帧的代码:

webrtc::SplittingFilter* splittingFilter;
webrtc::IFChannelBuffer* bufferIn;
webrtc::IFChannelBuffer* bufferOut;
webrtc::IFChannelBuffer* bufferOut2;
// ...
splittingFilter=new webrtc::SplittingFilter(1, 3, 960);
bufferIn=new webrtc::IFChannelBuffer(960, 1, 1);
bufferOut=new webrtc::IFChannelBuffer(960, 1, 3);
bufferOut2=new webrtc::IFChannelBuffer(960, 1, 3);
// ...
int16_t* samples=(int16_t*)data;
float* fsamples[3];
float* foutput[3];
int i;
float* fbuf=bufferIn->fbuf()->bands(0)[0];
// convert the data from 16-bit PCM into float
for(i=0;i<960;i++){
    fbuf[i]=samples[i]/(float)32767;
}
// split it into three "bands" that the AEC needs and for some reason can't do itself
splittingFilter->Analysis(bufferIn, bufferOut);
// split the frame into 6 consecutive 160-sample blocks and perform AEC on them
for(i=0;i<6;i++){
    fsamples[0]=&bufferOut->fbuf()->bands(0)[0][160*i];
    fsamples[1]=&bufferOut->fbuf()->bands(0)[1][160*i];
    fsamples[2]=&bufferOut->fbuf()->bands(0)[2][160*i];
    foutput[0]=&bufferOut2->fbuf()->bands(0)[0][160*i];
    foutput[1]=&bufferOut2->fbuf()->bands(0)[1][160*i];
    foutput[2]=&bufferOut2->fbuf()->bands(0)[2][160*i];
    int32_t res=WebRtcAec_Process(aecState, (const float* const*) fsamples, 3, foutput, 160, 20, 0);
}
// put the "bands" back together
splittingFilter->Synthesis(bufferOut2, bufferIn);
// convert the processed data back into 16-bit PCM
for(i=0;i<960;i++){
    samples[i]=(int16_t) (CLAMP(fbuf[i], -1, 1)*32767);
}

If I comment out the actual echo cancellation and just do the float conversion and band splitting back and forth, it doesn't corrupt the memory, doesn't sound weird and runs indefinitely. 如果我注释掉实际的回声消除并且只是来回执行浮点转换和波段分割,它不会破坏内存,听起来不奇怪并无限期地运行。 (I do pass the farend/speaker signal into AEC, I just didn't want to make the mess of my code by including it in the question) (我确实将farend /扬声器信号传递给AEC,我只是不想通过将其包含在问题中来使我的代码混乱)

I've also tried Android's built-in AEC. 我也试过Android的内置AEC。 While it does work, it upsamples the captured signal from 16 kHz. 虽然它确实有效,但它会对16 kHz的捕获信号进行上采样。

Unfortunately, there is no free AEC package that support 48khz. 不幸的是,没有免费的AEC包支持48khz。 So, either move to 32khz or use a commercial AEC package at 48khz. 因此,要么转移到32khz,要么使用48khz的商用AEC包。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM