首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Speex和DirectSound实现声学回声消除

使用Speex和DirectSound实现声学回声消除
EN

Stack Overflow用户
提问于 2009-05-05 19:31:53
回答 1查看 6.3K关注 0票数 8

我正在尝试使用Speex编解码库执行声学回声消除(AEC)。根据Speex文档,我需要执行两个调用:

代码语言:javascript
运行
复制
 speex_echo_playback(echo_state, echo_frame); 

每次播放音频帧时,

代码语言:javascript
运行
复制
 speex_echo_capture(echo_state, input_frame, output_frame);

对于捕获的每一帧。

因为我使用的是DirectSound,所以我想我可以使用主DirectSound缓冲区作为speex_echo_playback调用中的echo_frame,例如,

代码语言:javascript
运行
复制
  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 );

文档确实说这些是只写指针,但是我自己有没有办法使用buffer数据呢?

这基本上就是我创建buffer的方式:

代码语言:javascript
运行
复制
  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协同工作,有什么建议或建议吗?谢谢你的帮助。

EN

回答 1

Stack Overflow用户

发布于 2011-07-28 11:27:10

我已经做过一次了。但我的方法如下:

我从来没有直接使用过主缓冲区。相反,我只使用了一个辅助缓冲区。我有两个线程-回放线程和捕获线程。此外,我还使用了另一个speex函数- speex_echo_cancellation

因此,在我的回放线程中,我将当前回放帧保存在全局缓冲区中,并在捕获线程中使用当前捕获帧和先前存储的回放帧调用speex_echo_cancellation函数。

DMO不适用于我,因为我还必须支持Windows XP。

你也可以通过g- speex mailing lists archive或者更好的subscribe here来获取更多有趣的信息。

祝好运,

安东尼

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/826554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档