// this example does everything: it sets up directsound
// creates a secondary buffer, loads it with a synthesizer
// sine wave and plays it
void *audio_ptr_1 = NULL, // used to lock memory
*audio_ptr_2 = NULL;
DWORD dsbstatus; // status of sound buffer
DWORD audio_length_1 = 0, // length of locked memory
audio_length_2 = 0,
snd_buffer_length = 64000; // working buffer
// allocate memory for buffer
UCHAR *snd_buffer_ptr = (UCHAR *)malloc(snd_buffer_length);
// we need some data for the buffer, you could load a .VOC or .WAV
// but as an example, lets synthesize the data
// fill buffer with a synthesized 100hz sine wave
for (int index=0; index < (int)snd_buffer_length; index++)
snd_buffer_ptr[index] = 127*sin(6.28*((float)(index%110))/(float)110);
// note the math, 127 is the scale or amplitude
// 6.28 is to convert to radians
// (index % 110) read below
// we are playing at 11025 hz or 11025 cycles/sec therefore, in 1 sec
// we want 100 cycles of our synthesized sound, thus 11025/100 is approx.
// 110, thus we want the waveform to repeat each 110 clicks of index, so
// normalize to 110
// create a directsound object
if (DirectSoundCreate(NULL, &lpds, NULL)!=DS_OK )
return(0);
// set cooperation level
if (lpds->SetCooperativeLevel(main_window_handle,DSSCL_NORMAL)!=DS_OK)
return(0);
// set up the format data structure
memset(&pcmwf, 0, sizeof(WAVEFORMATEX));
pcmwf.wFormatTag = WAVE_FORMAT_PCM;
pcmwf.nChannels = 1;
pcmwf.nSamplesPerSec = 11025;
pcmwf.nBlockAlign = 1;
pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
pcmwf.wBitsPerSample = 8;
pcmwf.cbSize = 0;
// create the secondary buffer (no need for a primary)
memset(&dsbd,0,sizeof(DSBUFFERDESC));
dsbd.dwSize = sizeof(DSBUFFERDESC);
dsbd.dwFlags = DSBCAPS_CTRLDEFAULT | DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE;
dsbd.dwBufferBytes = snd_buffer_length+1;
dsbd.lpwfxFormat = &pcmwf;
if (lpds->CreateSoundBuffer(&dsbd,&lpdsbsecondary,NULL)!=DS_OK)
return(0);
// copy data into sound buffer
if (lpdsbsecondary->Lock(0,
snd_buffer_length,
&audio_ptr_1,
&audio_length_1,
&audio_ptr_2,
&audio_length_2,
DSBLOCK_FROMWRITECURSOR)!=DS_OK)
return(0);
// copy first section of circular buffer
CopyMemory(audio_ptr_1, snd_buffer_ptr, audio_length_1);
// copy last section of circular buffer
CopyMemory(audio_ptr_2, (snd_buffer_ptr+audio_length_1),audio_length_2);
// unlock the buffer
if (lpdsbsecondary->Unlock(audio_ptr_1,
audio_length_1,
audio_ptr_2,
audio_length_2)!=DS_OK)
return(0);
// play the sound in looping mode
if (lpdsbsecondary->Play(0,0,DSBPLAY_LOOPING )!=DS_OK)
return(0);
// release the memory since DirectSound has made a copy of it
free(snd_buffer_ptr);