次の方法で共有


キャプチャー バッファーの通知

定期的にキャプチャー バッファーからデータをコピーするには、読み取りカーソルがバッファー内の指定のポイントに到達したことをアプリケーションで認識する必要があります。読み取りカーソルとは、安全に読み取ることのできるデータの末尾を示すポイントです。この情報を取得する方法の 1 つは、IDirectSoundCaptureBuffer8::GetCurrentPosition を使用して、読み取りカーソルの位置をポーリングすることです。さらに効果的な方法として、通知を使用する方法があります。IDirectSoundNotify8::SetNotificationPositions メソッドを使用すると、イベント通知を行うポイントをバッファー内に必要なだけ設定できます。バッファーの実行中はこの設定はできません。

最初に、IDirectSoundNotify8 インターフェイスを取得する必要があります。これには、バッファー オブジェクトの QueryInterface メソッドを使用します。

それぞれの通知位置に、Win32 の CreateEvent 関数を使用してイベント オブジェクトを作成します。イベントへのハンドルを、DSBPOSITIONNOTIFY 構造体の hEventNotify メンバーに配置します。この構造体の dwOffset メンバーで、イベント通知を行う位置のバッファー内におけるオフセットを指定します。次に、この構造体のアドレスを SetNotificationPositions に渡します。通知位置を複数設定する場合は、構造体の配列のアドレスを渡します。

次の例では、1 秒分のバッファーに 3 つの通知位置を設定しています。1 つ目のイベントは、読み取り位置がバッファーの中間ポイントに近づいたときに通知されます。2 つ目は、読み取り位置がバッファーの最後に近づいたときに、3 つ目は、キャプチャーが停止したときにそれぞれ通知されます。

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;
}