Есть ли библиотека подавления акустического эха (AEC) с частотой 48 кГц?

#android #c #signal-processing #aec

#Android #c #обработка сигналов #aec

Вопрос:

Я разрабатываю приложение VoIP, которое работает с частотой дискретизации 48 кГц. Поскольку в качестве своего кодека он использует Opus, который использует 48 кГц внутри, а большинство современных аппаратных средств Android изначально работают на частоте 48 кГц, 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]=amp;bufferOut->fbuf()->bands(0)[0][160*i];
    fsamples[1]=amp;bufferOut->fbuf()->bands(0)[1][160*i];
    fsamples[2]=amp;bufferOut->fbuf()->bands(0)[2][160*i];
    foutput[0]=amp;bufferOut2->fbuf()->bands(0)[0][160*i];
    foutput[1]=amp;bufferOut2->fbuf()->bands(0)[1][160*i];
    foutput[2]=amp;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);
}
  

Если я закомментирую фактическое подавление эха и просто выполню преобразование с плавающей запятой и разделение полосы вперед и назад, это не повредит память, не звучит странно и работает бесконечно. (Я передаю сигнал дальнего / громкоговорителя в AEC, я просто не хотел портить свой код, включив его в вопрос)

Я также пробовал встроенный AEC в Android. Хотя она работает, она повышает дискретизацию захваченного сигнала с 16 кГц.

Комментарии:

1. Для тех, кто голосует за закрытие: дело не в том, что я не знаю, что любая другая реализация VoIP использует более низкие частоты дискретизации, которые «обеспечивают достаточную пропускную способность для передачи голоса». Я просто думаю, что пришло время отказаться от этого, поскольку у нас более мощное оборудование и более эффективные кодеки.

Ответ №1:

К сожалению, нет бесплатного пакета AEC, поддерживающего частоту 48 кГц. Итак, либо перейдите на частоту 32 кГц, либо используйте коммерческий пакет AEC с частотой 48 кГц.