Speex AEC仅删除回声的一部分



我尝试使用qt 5.2.0使用speex acoustic Echo取消,但仅删除了Echo的一部分,仍然保留。

这是我的测试(未针对内存管理优化)。它记录语音,删除Echo并在400毫秒之后使用非常小的Echo取消。


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

//************
// 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。不是您拥有多少个字节。

基本上,请在没有 echo取消的情况下使您的设置工作,并验证它只是添加了延迟。只有这样,您才能尝试获得回声取消工作。如果第一部分有效,则无需在此处发布。

相关内容

  • 没有找到相关文章

最新更新