Direct Sound 8

8/26/2018

A quick guide to programming Direct Sound 8

Microsoft DirectX is a set of low-level application programming interfaces (APIs) for creating games and other high-performance multimedia applications. The latest version of DirectX as of 1/6/2001 is DirectX 8.1.  One component of DirectX 8.1 is DirectX Audio that merges former DirectMusic and DirectSound into one set of more unified API. Most applications using sound only need the current DirectMusic that can handle waveforms that used to be only handled by DirectSound.

However DirectSound is still needed to handle waveform data in sound buffers directly.  This article addresses the concepts of programming DirectSound and lays out a practical guideline for coding.

Programmer need to clearly understand the concept (not the details) of COM to use DirectX that is set of COM objects. Usually programmers are only interested in some functions (that are called methods in COM) that will get the work done, but the functions (methods) belong to interfaces that belong to COM objects as shown in the following figure:

 

Figure 1. COM Structure

Therefore to use a method two things have to be done first: 1. creating the object; 2. getting the interface.  In most cases one function of DirectX creates an object and returns a pointer to an interface at the same time.  The interface pointer can be used to get other interfaces of the same object through the method QueryInterface().  

The following is the procedures to use DirectSound to play waveform and capture waveform.  Two separate procedures listed for using DirectSound and DirectSoundCapture objects respectively to make the concepts clearer although the function of DirectSoundFullDuplexCreate8() can be used to create create both of the objects.

To use COM the functions of CoInitializeEx() and ::CoUninitialize( ) need to be run at the beginning and end of the use of COM objects respectively.  Two header files from DirectX SDK should be included:

#include <dmusici.h>
#include <Dxerr8.h>

The following libraries should be added to the link list: Dsound.lib, dxguid.lib and  Dxerr8.lib 

A. Play waveform (for notification, please refer to the notification part of B):

  1.  Use DirectSoundCreate8() to create and initialize an object and get the pointer (pDS8) to IDirectSound8.
  2. Use the method SetCooperativeLevel() of IDirectSound8 (pDS8->SetCooperativeLevel()) to set the cooperative level.
  3. Use the method CreateSoundBuffer() of IDirectSound8 (pDS8->CreateSoundBuffer()) to create and initialize an object and get the  pointer (pDsb) to IDirectSoundBuffer.
  4. Use the method QueryInterface of IDirectSoundBuffer (pDsb->QueryInterface()) to get a pointer(pDSCB8) to the interface IDirectSoundBuffer8.
  5. Use the method Lock() of IDirectSound8 (pDSCB8->Lock()) to lock the buffer and get a pointer to it (lpvWrite).
  6. Use the pointer (lpvWrite) to write waveform to the buffer.
  7. Use the method Unlock() of IDirectSoundBuffer (pDSCB8->Unlock()) to unlock the buffer.
  8. Use the method SetCurrentPosition() of IDirectSoundBuffer (pDSCB8->SetCurrentPosition()) to set the current play position.
  9. Use the method SetCurrentPosition() of IDirectSound8 (pDSCB8->SetCurrentPosition()) to set the current play position.
  10. Use the method Play() of IDirectSoundBuffer (pDSCB8->Play()) to play the waveform.
  11. After finishing playing, use the method Stop() of IDirectSoundBuffer (pDSCB8->Stop()) to stop the playing. 
  12. Use the method Release() of IDirectSoundBuffer,  IDirectSoundBuffer and IDirectSound8 to realease the objects (pDSCB8->Release(), pDsb->Release(), pDS8->Release()).

B. Capture waveform (including notification):

  1. Use DirectSoundCaptureCreate8() to create and initialize an object and get the pointer (pDSC8) to IDirectSoundCapture8.
  2. Use the method CreateCaptureBuffer() of IDirectSoundCapture8(pDSC8->CreateSoundBuffer()) to create and initialize an object and get the  pointer (pDSCB) to IDirectSoundCaptureBuffer.
  3. Use the method QueryInterface of  IDirectSoundCaptureBuffer(pDSCB->QueryInterface()) to get a pointer(pDSCB8) to the interface IDirectSoundCaptureBuffer8.
  4. Use the method QueryInterface of  IDirectSoundCaptureBuffer8(pDSCB8->QueryInterface()) to get a pointer(lpDsNotify) to the interface IDirectSoundNotify8.
  5. Use the SetNotificationPositions() of IDirectSoundNotify8(lpDsNotify->SetNotificationPositions()) to set the notification buffer positions.
  6. Use the method Start() of IDirectSoundCaptureBuffer8(pDSCB8->Start()) to start the waveform capturing.
  7. After finishing capturing, use the method Stop() of IDirectSoundCaptureBuffer8(dDsb8->Stop()) to stop the the capturing. 
  8. Use the method Release() of IDirectSoundCaptureBuffer8,  IDirectSoundCaptureBuffer and IDirectSoundCapture8 to release the objects (pDSCB8->Release(), pDSCB->Release(), pDSC8->Release()).

 

(originaly written in January, 2002)