【发布时间】:2009-05-05 19:31:52
【问题描述】:
我正在尝试使用 Speex 编解码器库执行回声消除 (AEC)。根据 Speex 文档,我需要执行两个调用:
speex_echo_playback(echo_state, echo_frame);
每次播放音频帧,并且
speex_echo_capture(echo_state, input_frame, output_frame);
捕捉到的每一帧。
由于我使用的是 DirectSound,我想我可以在调用 speex_echo_playback 时使用主 DirectSound 缓冲区作为 echo_frame,例如,
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 协同工作的任何指示或建议?感谢您的帮助。
【问题讨论】:
-
为什么要使用 DirectSound 的低级 API?你可以写一个效果 DMO 更容易。
-
感谢您的推荐。您有 DirectX 媒体对象 (DMO) 的基本用法示例吗?我在大量代码基础设施之上工作,所以我不确定使用 DMO 有多容易。
-
> 为什么要使用 DirectSound 的低级 API? - 因为它允许编写可移植的代码。
标签: c++ audio echo directsound speex