0

我正在使用 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 事件处理函数的参考。

4

1 回答 1

1

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

一个非常简单——FullDuplex 可以与所有音频硬件一起使用吗?

如果没记错的话,我不这么认为。特别是如果硬件是 USB 或者如果捕获和录制设备不在同一个声卡上。如果它确实适用于不同的物理设备(或 USB),您可能不会从中获得任何好处,例如 AEC。

我相信您想要使用 DirectSoundFullDuplexCreate 而不是仅仅手动创建单独的捕获和播放对象的唯一原因是 AEC(声学回声消除支持)。如果没有记错的话,Windows 中用于 DirectSound 的内置 AEC 不是很好,也不能很好地消除回声。(YMMV)

根据MSDN

通过 DirectSound API 访问 Windows XP Acoustic Echo Cancellation (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()

还有其他问题吗?

于 2012-12-24T08:09:27.457 回答