android - 任何支持 48 kHz 的声学回声消除 (AEC) 库?

标签 android c++ signal-processing aec

我正在开发一个以 48 kHz 采样率运行的 VoIP 应用程序。由于它使用内部使用 48 kHz 的 Opus 作为其编解码器,并且大多数当前的 Android 硬件本身以 48 kHz 运行,因此 AEC 是我现在唯一缺少的拼图。我已经找到了 WebRTC 实现,但我似乎无法弄清楚如何让它工作。看起来它会随机破坏内存,迟早会导致整个系统崩溃。当它不崩溃时,声音有点粗,好像它在画面的一半更安静。这是我处理 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);
}

如果我注释掉实际的回声消除并只进行 float 转换和波段来回分割,它不会破坏内存,听起来也不奇怪并且会无限期地运行。 (我确实将远端/扬声器信号传递到 AEC,我只是不想通过将其包含在问题中来弄乱我的代码)

我还尝试过 Android 的内置 AEC。虽然它确实有效,但它会从 16 kHz 对捕获的信号进行上采样。

最佳答案

遗憾的是,没有支持 48khz 的免费 AEC 包。因此,要么转向 32khz,要么使用 48khz 的商业 AEC 包。

关于android - 任何支持 48 kHz 的声学回声消除 (AEC) 库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39959123/

相关文章:

java - 如果数字类似于 $12.5,则在末尾添加 0

java - 如何直接使用jni将字节数组从c复制到java byte[]属性

android - Android 每秒扫描 WiFi 网络的问题

c++ - nullptr 可以用作类型吗?

android - 为什么在 google+ 集成时显示错误为 "unknown issue with google play service"?

c++ - 类实例和指针背后的 Delphi 设计原则是什么?

c++ - std::streams 已经可以移动了吗?

java - 来自麦克风的平滑信号 - 心跳

c++ - WebRTC AGC(自动增益控制)

java - 从低通滤波转换