gpt4 book ai didi

c++ - Speex AEC 仅去除一部分回声

转载 作者:太空宇宙 更新时间:2023-11-04 13:56:31 25 4
gpt4 key购买 nike

我尝试在 Qt 5.2.0 中使用 Speex Acoustic Echo Cancellation,但只有一部分回声被移除,它仍然存在。
这是我的测试(未针对内存管理进行优化)。它录制语音,去除回声并在 400 毫秒后播放,回声消除非常小。

知道我的代码哪里错了吗?

//************
// declared in MainWindows.h
QAudioInput* m_audioInput;
QAudioOutput* m_audioOutput;
QIODevice* m_ioIn;
QIODevice* m_ioOut;
QList<QByteArray> m_listBA;
//************

void MainWindow::InitSpeex()
{
int loc_samplingRate=16000;
int loc_frameSize=320;
m_echo_state = speex_echo_state_init(loc_frameSize, 10*loc_frameSize);
speex_echo_ctl(m_echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &loc_samplingRate);
m_preprocess = speex_preprocess_state_init(loc_frameSize, loc_samplingRate);
}

void MainWindow::DestroySpeex()
{
speex_echo_state_destroy(m_echo_state);
speex_preprocess_state_destroy(m_preprocess);
m_echo_state = NULL;
m_preprocess = NULL;
}

void MainWindow::Start()
{
QAudioFormat format;
// Set up the desired format, for example:
format.setSampleRate(SAMPLING_RATE);
format.setChannelCount(1);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);

QAudioDeviceInfo loc_infoInput = QAudioDeviceInfo::defaultInputDevice();
if (!loc_infoInput.isFormatSupported(format)) {
qWarning() << "Default format not supported, trying to use the nearest.";
format = loc_infoInput.nearestFormat(format);
}

m_audioInput = new QAudioInput(format, this);


QAudioDeviceInfo loc_infoOutput(QAudioDeviceInfo::defaultOutputDevice());
if (!loc_infoOutput.isFormatSupported(format)) {
qWarning() << "Raw audio format not supported by backend, cannot play audio.";
return;
}

m_audioOutput = new QAudioOutput(format, this);

m_ioIn = m_audioInput->start();
m_ioOut = m_audioOutput->start();

connect(m_ioIn, SIGNAL(readyRead()), this, SLOT(on_data_input()));
}

void MainWindow::on_data_input()
{
// push data on the list
m_listBA.push_back( m_ioIn->readAll() );


// il list is about 400ms of sample
if( m_listBA.size() > 20)
{
// send oldest sample to speex and play it
speex_echo_playback(m_echo_state, (spx_int16_t*)m_listBA[1].constData());
m_ioOut->write( m_listBA.takeFirst() );

// get most recent sample, remove echo and repush it on the list to be played later
speex_echo_capture(m_echo_state, (spx_int16_t*)m_listBA[m_listBA.size()-1].data(), m_AECBufferOut);
loc_vad = speex_preprocess_run(m_preprocess, m_AECBufferOut);
m_listBA.takeLast();
m_listBA.push_back( QByteArray((const char*)m_AECBufferOut, sizeof( m_AECBufferOut)) );
}
}

最佳答案

我想知道你想用 m_listBA 做什么。显然它是一个 FIFO,但您没有使用 [0]。

此外,为什么要将原始输入添加到列表中只是为了在几行之后将其删除?

最后,m_AECBufferOut 可能是一个指针。在那种情况下,sizeof(m_AECBufferOut) 可能是 4 或 8。这不是您有多少字节的输出。

基本上,让您的设置在没有回声消除的情况下工作,并验证它是否只是增加了延迟。只有这样你才应该尝试让回声消除工作。如果第一部分有效,则无需在此处发布。

关于c++ - Speex AEC 仅去除一部分回声,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21254279/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com