波形捕获:(6)“捕获缓冲区”通知
想要按期的将数据从“捕获缓冲区”复制出来,你的应用措施必 须知道什么时候这个读指针(读指针的位置就是可以安详读取数据的最高位置) 达到缓冲区中特定的位置。获取这个信息的一个步伐是通过 IDirectSoundCaptureBuffer8::GetCurrentPosition 要领轮询读指针的位置。 另一种更有效的步伐是利用通知(notification)。利用 IDirectSoundNotify8::SetNotificationPositions 要领,你可以在缓冲区中设 置若干个点,在这些点上会触发事件。你不能在缓冲区正在利用的时候配置它。
首先,你必需获得 IDirectSoundNotify8 接口。你可以通过利用缓冲区工具 的 QueryInterface 要领获得。
利用Win32 CreateEvent 要领为每一个通知的位置建设一个事件工具。将这 个事件的句柄安排在一个 DSBPOSITIONNOTIFY 布局体的 hEventNotify 成员中 。在这个布局体的 dwOffset 成员中,指定在缓冲区中你想要事件被触发的偏移 量。假如你想要配置多个通知位置那么就通报这个布局体(或布局体数组)的地 址给 SetNotificationPositions要领。
下面的例子在一秒钟的缓冲区中配置了三个通知位置。第一个事件将在读指 针靠近缓冲区中点的时候被触发,另一个事件将在读指针缓冲区终点的时候被触 发,第三个则会在捕获遏制的时候被触发。
Code
HRESULT SetCaptureNotifications(LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB)
{
#define cEvents 3
LPDIRECTSOUNDNOTIFY8 pDSNotify;
WAVEFORMATEX wfx;
HANDLE rghEvent[cEvents] = {0};
DSBPOSITIONNOTIFY rgdsbpn[cEvents];
HRESULT hr;
if (NULL == pDSCB) return E_INVALIDARG;
if (FAILED(hr = pDSCB->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&pDSNotify)))
{
return hr;
}
if (FAILED(hr = pDSCB->GetFormat(&wfx, sizeof(WAVEFORMATEX), NULL)))
{
return hr;
}
// Create events.
for (int i = 0; i < cEvents; ++i)
{
rghEvent[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
if (NULL == rghEvent[i])
{
hr = GetLastError();
return hr;
}
}
// Describe notifications.
rgdsbpn[0].dwOffset = (wfx.nAvgBytesPerSec/2) -1;
rgdsbpn[0].hEventNotify = rghEvent[0];
rgdsbpn[1].dwOffset = wfx.nAvgBytesPerSec - 1;
rgdsbpn[1].hEventNotify = rghEvent[1];
rgdsbpn[2].dwOffset = DSBPN_OFFSETSTOP;
rgdsbpn[2].hEventNotify = rghEvent[2];
// Create notifications.
hr = pDSNotify->SetNotificationPositions(cEvents, rgdsbpn);
pDSNotify->Release();
return hr;
}