The tutorial requires the following definitions and global variables:
#define NUMEVENTS 2
LPDIRECTSOUND lpds;
DSBUFFERDESC dsbdesc;
LPDIRECTSOUNDBUFFER lpdsb;
LPDIRECTSOUNDBUFFER lpdsbPrimary;
LPDIRECTSOUNDNOTIFY lpdsNotify;
WAVEFORMATEX *pwfx;
HMMIO hmmio;
MMCKINFO mmckinfoData, mmckinfoParent;
DSBPOSITIONNOTIFY rgdsbpn[NUMEVENTS];
HANDLE rghEvent[NUMEVENTS];
The first step is to create the DirectSound object, establish a cooperative level, and set the primary buffer format. All this is done in the InitDSound function shown in the following code.
The function takes two parameters: the main window handle and a pointer to the GUID of the sound device. In most cases you will pass NULL as the second parameter, indicating the default device, but you may obtain a GUID by device enumeration.
BOOL InitDSound(HWND hwnd, GUID *pguid)
{
// Create DirectSound
if FAILED(DirectSoundCreate(pguid, &lpds, NULL))
return FALSE;
// Set co-op level
if FAILED(IDirectSound_SetCooperativeLevel(
lpds, hwnd, DSSCL_PRIORITY))
return FALSE;
You have set the priority cooperative level in order to be able to set the format of the primary buffer. If you don't change the default format, output will be in the 8-bit, 22 kHz format regardless of the format of the input. Setting the primary buffer to a higher format can do no harm, because even if the secondary buffers are in a lower format, the samples will be converted automatically by DirectSound. Note also that there's no danger of the call to IDirectSoundBuffer::SetFormat failing because the hardware doesn't support the higher format. DirectSound will simply set the closest available format.
To set the format of the primary buffer, you first describe it in the global DSBUFFERDESC structure, then pass this description to the IDirectSound::CreateSoundBuffer method.
// Obtain primary buffer
ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
if FAILED(lpds->CreateSoundBuffer(&dsbdesc, &lpdsbPrimary, NULL))
return FALSE;
Once you have a primary buffer object, you describe the desired wave format and pass the description to the IDirectSoundBuffer::SetFormat method:
// Set primary buffer format
WAVEFORMATEX wfx;
memset(&wfx, 0, sizeof(WAVEFORMATEX));
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = 44100;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
hr = lpdsbPrimary->SetFormat(&wfx);
return TRUE;
} // InitDSound()