Platform SDK: DirectX

Play Buffer Notification

[C++]

When data is being streamed to a secondary buffer, you may want your application to be notified when the current play position reaches a certain point in the buffer, or when playback is stopped. With the IDirectSoundNotify::SetNotificationPositions method you can set any number of points in the buffer where events are to be signaled. You cannot do this while the buffer is playing.

First, you have to obtain a pointer to the IDirectSoundNotify interface. You can do this by using the buffer object's QueryInterface method, as in the following C++ example, where lpDsbSecondary is an IDirectSoundBuffer interface pointer.

LPDIRECTSOUNDNOTIFY lpDsNotify; 
 
HRESULT hr = lpDsbSecondary->QueryInterface(IID_IDirectSoundNotify, 
                                            (LPVOID *)&lpDsNotify); 
if SUCCEEDED(hr) 
{ 
    // Go ahead and use lpDsNotify->SetNotificationPositions. 
} 
 

The IDirectSoundNotify interface is associated with the buffer from which you obtained the pointer. The methods of the new interface will automatically apply to that buffer.

Now create an event object with the Win32 CreateEvent function. Put the handle to this event in the hEventNotify member of a DSBPOSITIONNOTIFY structure. In the dwOffset member of the structure, specify the offset within the buffer where you want the event to be signaled. Then you pass the address of the structure—or of an array of structures, if you want to set more than one notification position—to the IDirectSoundNotify::SetNotificationPositions method.

The following example sets a single notification position. The event is signaled when playback stops, either because it is not looping and the end of the buffer has been reached, or because the application calls the IDirectSoundBuffer::Stop method.

DSBPOSITIONNOTIFY PositionNotify;
 
PositionNotify.Offset = DSBPN_OFFSETSTOP;
PositionNotify.hEventNotify = hMyEvent;
// hMyEvent is the handle returned by CreateEvent()
 
lpDsNotify->SetNotificationPositions(1, &PositionNotify);
 

If you are using voice management, it's possible that a buffer could be terminated before a notification position is reached. See the Remarks for DSBPOSITIONNOTIFY.

[Visual Basic]

When data is being streamed to a secondary buffer, you may want your application to be notified when the current play position reaches a certain point in the buffer, or when playback is stopped. By using the DirectSoundBuffer.SetNotificationPositions method you can set any number of points within the buffer where events are to be signaled. You cannot do this while the buffer is playing.

To set a notification event on a buffer, you must implement a DirectXEvent object in the form that contains the code for the buffer. Then you create an event handle by calling the DirectX7.CreateEvent method. Put the event handle in the hEventNotify member of a DSBPOSITIONNOTIFY type. Pass the type to the DirectSoundBuffer.SetNotificationPositions method.

When the play position reaches a notification position in the buffer, the DirectXEvent.DXCallback is called.

If you are using voice management, it's possible that a buffer could be terminated before a notification position is reached. See the Remarks for DSBPOSITIONNOTIFY.

The following example code shows how to set up a single notification position. The following are the relevant lines in the Declarations section of the module.

Dim gDX As New DirectX7
Dim gDSB As DirectSoundBuffer
Dim dsbpn(0) As DSBPOSITIONNOTIFY
Dim endEvent As Long
Implements DirectXEvent

Note that dsbpn must be an array, even though it contains only a single notification position.

When the form is loaded, an event is created.

endEvent = gDX.CreateEvent(Me)

After the DirectSoundBuffer object has been created, the notification position is set and associated with the event, as follows:

With dsbpbn(0)
  .hEventNotify = endEvent
  .lOffset = DSBPN_OFFSETSTOP
End With
gDX.SetEvent endEvent
gDSB.SetNotificationPositions 1, dsbpn()

The offset of the notification, DSBPN_OFFSETSTOP or -1, is a special value indicating that the event will be set when the buffer stops playing, either because it is not looping and the end of the buffer has been reached, or because the application calls the DirectSoundBuffer.Stop method.. When this happens, the application-defined callback function is automatically called, with the event identifier endEvent being passed in as the parameter.

Private Sub DirectXEvent_DXCallback(ByVal eventid As Long)
  If eventid = endEvent Then
    lblStatusDesc.Caption = "Buffer stopped."
  End If
End Sub