让我从开始谈论这个话题开始,说我完全是WebRtc的新手,如果有什么我提起半讽刺的话,请允许我 一种可以原谅的方式。
我正在编写一个应用,该应用在Speex和Web RTC AEC3之间进行回声消除性能比较。 [WebRtc AEC3代码库(最新分支):https://webrtc.googlesource.com/src/+/branch-heads/72]
应用程序读取WAV文件并将样本馈送到AEC模块,并且WAV编写器保存回声消除的输出,
我有2个输入: 1)扬声器输入或渲染信号或远端信号 2)MicInput或捕获的信号或NearEnd信号
和一个输出: 1)MicOutput-是回声消除的结果。
现在对于Speex模块,我看到了一种表现良好的方式。请查看以下文件,它在消除来自 捕获的信号。
但是,当我使用WebRtc Aec3传递相同的文件时,我得到了一个稳定的信号。以下是AEC3的结果。
似乎它也在抵消原始的麦克风信号。
我正在使用以下参数(摘自Wav文件阅读器): 采样率:8000 频道1 位/样本:16 样品数:270399 一次将样品送入AEC:(10 * SampleRate)/ 1000 = 80
这是初始化:
m_streamConfig.set_sample_rate_hz(sampleRate);
m_streamConfig.set_num_channels(CHANNEL_COUNT);
// Create a temporary buffer to convert our RTOP input audio data into the webRTC required AudioBuffer.
m_tempBuffer[0] = static_cast<float*> (malloc(sizeof(float) * m_samplesPerBlock));
// Create AEC3.
m_echoCanceller3.reset(new EchoCanceller3(m_echoCanceller3Config, sampleRate, true)); //use high pass filter is true
// Create noise suppression.
m_noiseSuppression.reset(new NoiseSuppressionImpl(&m_criticalSection));
m_noiseSuppression->Initialize(CHANNEL_COUNT, sampleRate);
这就是我调用API的方式:
auto renderAudioBuffer = CreateAudioBuffer(spkSamples);
auto capturedAudioBuffer = CreateAudioBuffer(micSamples);
// Analyze capture buffer
m_echoCanceller3->AnalyzeCapture(capturedAudioBuffer.get());
// Analyze render buffer
m_echoCanceller3->AnalyzeRender(renderAudioBuffer.get());
// Cancel echo
m_echoCanceller3->ProcessCapture(
capturedAudioBuffer.get(), false);
// Assuming the analog level is not changed.
//If we want to detect change, need to use gain controller and remember the previously rendered audio's analog level
// Copy the Captured audio out
capturedAudioBuffer->CopyTo(m_streamConfig, m_tempBuffer);
arrayCopy_32f(m_tempBuffer[0], micOut, m_samplesPerBlock);
关于参数(延迟,echoModel,混响,noisefloor等),我正在使用所有默认值。
谁能告诉我我做错了什么?或者如何通过调整适当的参数使其更好呢?
更新日期:(02/22/2019) 找出为什么回声输出静音。似乎Webrtc AEC3无法处理8k和16k采样率,尽管在源代码中有指示它们支持4种不同的采样率:8k,16k,32k和48k。 输入32k和48k样本后,得到了回声消除输出。但是,我看不到任何回声消除。它只是将准确的样本吐出,作为送入NearEnd / Mic / Captured输入的样本。是的,可能我缺少关键参数设置。仍在寻求帮助。
答案 0 :(得分:2)
最重要的是称为“延迟”的东西,您可以在audio_processing.h中找到它的定义。
设置|延迟|接收远端的ProcessReverseStream()之间的毫秒数 frame和ProcessStream()接收包含 相应的回声。在客户端,这可以表示为 延迟=(t_render-t_analyze)+(t_process-t_capture) 在哪里,
- t_analyze is the time a frame is passed to ProcessReverseStream() and
t_render is the time the first sample of the same frame is rendered by
the audio hardware.
- t_capture is the time the first sample of a frame is captured by the
audio hardware and t_process is the time the same frame is passed to
ProcessStream().
2。 EchoCanceller3延迟
SetAudioBufferDelay(int Dealy);
答案 1 :(得分:1)
在将输入信号传递到 AEC3 之前,您必须将输入信号拆分为频段:
renderAudioBuffer->SplitIntoFrequencyBands();
m_echoCanceller3->AnalyzeRender(renderAudioBuffer.get());
renderAudioBuffer->MergeFrequencyBands();
capturedAudioBuffer->SplitIntoFrequencyBands();
m_echoCanceller3->ProcessCapture(capturedAudioBuffer.get(), false);
capturedAudioBuffer->MergeFrequencyBands();