サウンドをDirectSoundで再生


// 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);