2009-05-05 57 views
7

我想用Speex編解碼器庫進行聲學回聲消除(AEC)。根據該文件的Speex,我需要執行兩個電話:聲學回聲消除(AEC)與Speex語音和DirectSound的

每一個音頻幀播放時間,並

speex_echo_capture(echo_state, input_frame, output_frame); 

爲捕捉每一幀。

由於我使用的DirectSound,我在想,我可以使用主DirectSound的緩衝區爲echo_frame在調用speex_echo_playback,例如,

DWORD offset = 0; 
    DWORD length = 0; 
    LPVOID block1, block2; 
    DWORD length1, length2; 
    DWORD flags = DSBLOCK_ENTIREBUFFER; 

    HRESULT hr = primary_buffer->Lock(
     offset 
     , length 
     , &block1 
     , &length1 
     , &block2 
     , &length2 
     , flags 
    ); 

    // Would like to convert the buffer into a form that 
    // speex_echo_capture() can use. 
    // Why does length1 == length2 == 0 always? 

    hr = primary_buffer->Unlock(block1, length1, block2, length2); 

文檔不說這些是隻寫指針,但是有沒有辦法自己使用緩衝區數據?

這基本上是我怎麼了創建緩衝區:

CComPtr<IDirectSoundBuffer> primary_buffer; 
    DSBUFFERDESC primarydesc = { sizeof(DSBUFFERDESC), 
     DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRL3D | DSBCAPS_LOCHARDWARE, 
     0, 0, NULL, DS3DALG_HRTF_LIGHT }; 
    HRESULT hr = directsound_->CreateSoundBuffer(
     &primarydesc, &primary_buffer, NULL); 

另一種選擇,現在看來,使用DirectSound的緩衝區本身是使用speex_decode的輸出(),做自己的軟件混合。

用於獲取的Speex和DirectSound的共同努力,任何指針或建議嗎?謝謝你的幫助。

+0

你爲什麼要使用的DirectSound的底層API?你可以寫一個更容易的效果DMO。 – 2009-05-05 19:39:58

回答

3

我這樣做過一次。但我的方法如下:

我從來沒有直接使用過主緩衝區。相反,我只用一個輔助緩衝區工作。我有兩個線程 - 回放線程和捕捉線程。另外,我使用了另一個speex函數 - speex_echo_cancellation

因此,在我的播放線程我在一個全球性的緩衝,並調用當期的拍攝框架和以前存儲的播放幀率speex_echo_cancellation功能捕獲線程保存當前播放幀。

DMO並不適用於我,因爲我必須支持Windows XP也。

您還可以通過量 - speex mailing lists archive或更好,甚至subscribe here,以獲得更多有趣的信息。

祝你好運,

安東尼