关于DirectSoundFullDuplexCreate8的两个问题

时间:2012-12-24 07:10:29

标签: windows audio audio-streaming directsound

我正在使用DirectSoundFullDuplexCreate8进行录制,在某些情况下,在Win 7下播放。我有几个问题。

一个很简单 - FullDuplex可以与所有音频硬件配合使用吗?在某些情况下,我们将使用不同的设备进行录制和播放。到目前为止似乎工作,但如果有机器不支持Win版本的全双工,我们可以自己动手。

另一个可能是一个愚蠢的问题,但我没有看到如何设置事件通知进行录制。这是我到目前为止所获得的代码,但我没有看到如何开始录制或如何设置,以便我可以将正在录制的数据复制到其他缓冲区,包括播放缓冲区:

hr = DirectSoundFullDuplexCreate8((LPCGUID)recordDeviceDS, (LPCGUID)playbackDeviceDS&capBufferDescription, &playBufferDescription, hWnd, DSSCL_PRIORITY, &pDSFullDuplex,     &pDSCaptureBuffer8, &pDSPlayBuffer8, NULL );
if (hr != DS_OK)
    return false;

// Set up the notify events
hr = pDSCaptureBuffer8->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&pDSNotify);
if (hr != DS_OK)
    return false;
for (int i = 0; i < 3; ++i)
{
    eventHandles[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (eventHandles[i] == NULL)
        return false;
}
notifyEvents[0].dwOffset = 500;
notifyEvents[0].hEventNotify = eventHandles[0];

notifyEvents[1].dwOffset = 1000;
notifyEvents[1].hEventNotify = eventHandles[1];

notifyEvents[2].dwOffset = DSBPN_OFFSETSTOP;
notifyEvents[2].hEventNotify = eventHandles[2];

hr = pDSNotify->SetNotificationPositions(NUM_CAP_EVENTS, notifyEvents);
if (hr != DS_OK)
    return false;
pDSNotify->Release();

接下来会发生什么?我假设我使用:

pDSCaptureBuffer8->Start(true);

开始捕获,但我没有看到任何关于如何设置DS事件处理函数的引用,该函数在累积了适量的数据时被激活。

1 个答案:

答案 0 :(得分:1)

欢迎使用StackOverflow。为了将来参考,最好一次提出一个精确的问题。

  

一个很简单 - FullDuplex可以与所有音频硬件配合使用吗?

如果记忆有效,我不这么认为。特别是如果硬件是USB或捕获和记录设备不在同一声卡上。如果它在不同的物理设备(或usb)上工作,你可能不会从AEC获得任何好处。

我相信你想要使用DirectSoundFullDuplexCreate而不是仅手动创建捕获和回放对象分离的唯一原因是AEC(声学回声消除支持)。而如果内存服务,Windows中用于DirectSound的内置AEC不是很好,并且不能很好地进行回声消除。 (YMMV)

根据MSDN

  

访问Windows XP Acoustic Echo的现有应用程序   将不再通过DirectSound API取消(AEC)功能   在Windows Vista上运行时获取AEC。

以上内容适用于Windows 7.因此,请将DirectSoundFullDuplexCreate视为死API。只需手动创建一个捕获和回放缓冲区。

如果您需要AEC,可以查看使用AEC系统过滤器。 Windows SDK中有一个旧的示例应用程序,向您展示如何使用它。 http://msdn.microsoft.com/en-us/library/ff536174.aspx

  

但我没有看到如何设置录制事件通知。这是我到目前为止所获得的代码,但我没有看到如何开始录制或如何设置,以便我可以将正在录制的数据复制到其他缓冲区,包括播放缓冲区:

此外,在DirectSound对象上设置事件句柄可能不可靠。您最好定期轮询捕获和回放缓冲区位置(IDirectSoundCaptureBuffer8 :: GetCurrentPosition)。你必须处理早期醒来和事件处理后期醒来的所有情况。所以Sleep()和WaitForSingleObject一样好。

要开始录制,请调用IDirectSoundCaptureBuffer8 :: Start()

还有其他问题吗?