首先要声明三个接口,用于声音的播放
LPDIRECTSOUND8 g_pDirectSound=NULL; //directSound接口
LPDIRECTSOUNDBUFFER g_pPrimaryBuffer =NULL;//主缓冲区接口
LPDIRECTSOUNDBUFFER8 g_pSecondaryBuffer = NULL;//辅助缓冲区接口
建立一个结构体,标识wav文件的相关信息。
struct WAVEHEADER
{
char riff_sig[4]; // 'RIFF'
long waveform_chunk_size; // 8
char wave_sig[4]; // 'WAVE'
char format_sig[4]; // 'fmt ' (notice space after)
long format_chunk_size; // 16;
short format_tag; //WAVE_FORMAT_PCM
short channels; // #of channels
long sample_rate; // samplingrate
long bytes_per_sec; // bytesper second
short block_align; // sampleblock alignment
short bits_per_sample; // bits persecond
char data_sig[4]; // 'data'
long data_size; // sizeof waveform data
};
附录:wav文件的格式http://wenku.baidu.com/view/801b1537f111f18583d05aa7.html
然后在初始化函数中,
//创建directsound接口
if(FAILED(DirectSoundCreate8(NULL,&g_pDirectSound,NULL)))
::MessageBox(NULL,"Create DirectSound failed","DirectSoundCreate",0);
//设置 directsound协作级别
if(FAILED(g_pDirectSound->SetCooperativeLevel(hWnd,DSSCL_NORMAL)))
::MessageBox(NULL,"Set cooperative level failed!","SetCooperativeLevel",0);
//读取WAV音频信息
WAVEHEADER wave_header;
::ZeroMemory(&wave_header, sizeof(WAVEHEADER));
FILE* fp = fopen("example.wav", "rb");
fread((void*)&wave_header, 1, sizeof(WAVEHEADER), fp);
//根据wav文件,赋值结构体
WAVEFORMATEX wave_format;
ZeroMemory(&wave_format, sizeof(WAVEFORMATEX));
wave_format.wFormatTag=WAVE_FORMAT_PCM;
wave_format.nChannels=wave_header.channels; //2声道
wave_format.nSamplesPerSec=wave_header.sample_rate; //44100Hz回放频率
wave_format.wBitsPerSample=wave_header.bits_per_sample; //16位采样
wave_format.nBlockAlign=wave_format.wBitsPerSample/8*wave_format.nChannels;
wave_format.nAvgBytesPerSec=wave_format.nSamplesPerSec*wave_format.nBlockAlign;
DSBUFFERDESC ds_buf_desc;
ZeroMemory(&ds_buf_desc, sizeof(DSBUFFERDESC));
ds_buf_desc.dwSize= sizeof(DSBUFFERDESC);
ds_buf_desc.dwFlags=DSBCAPS_CTRLVOLUME;
ds_buf_desc.dwBufferBytes=wave_header.data_size; //缓冲区
ds_buf_desc.lpwfxFormat=&wave_format;
//创建主音频缓存和辅助音频缓存
g_pDirectSound->CreateSoundBuffer(&ds_buf_desc,&g_pPrimaryBuffer, NULL);
g_pPrimaryBuffer->QueryInterface(IID_IDirectSoundBuffer8, (void**)&g_pSecondaryBuffer);
// 加载WAV音频数据到辅助缓冲区
char *ptr1, *ptr2;
DWORD size1, size2;
fseek(fp, sizeof(WAVEHEADER), SEEK_SET);
g_pSecondaryBuffer->Lock(0,wave_header.data_size, (void**)&ptr1,&size1, (void**)&ptr2, &size2, 0);
if(ptr1) fread(ptr1, 1, size1, fp);
if(ptr2) fread(ptr2, 1, size2, fp);
g_pSecondaryBuffer->Unlock(ptr1, size1, ptr2, size2);
fclose(fp);
// 初始化时,音频数据放到了辅助缓冲区,辅助缓冲区与主缓冲区关联,主缓冲区与directsound接口关联
接着在渲染函数中播放声音
static longlPan = 0, lVolume = DSBVOLUME_MAX;
if(::GetAsyncKeyState(VK_LEFT) & 0x8000f)
lPan -= 500,g_pSecondaryBuffer->SetPan(lPan); // 声道控制
if(::GetAsyncKeyState(VK_RIGHT) & 0x8000f)
lPan += 500,g_pSecondaryBuffer->SetPan(lPan);
if(::GetAsyncKeyState(VK_UP) & 0x8000f)
lVolume += 500,g_pSecondaryBuffer->SetVolume(lVolume); // 音量控制
if(::GetAsyncKeyState(VK_DOWN) & 0x8000f)
lVolume -= 500,g_pSecondaryBuffer->SetVolume(lVolume);
if(::GetAsyncKeyState(VK_SPACE) & 0x8000f)
g_pSecondaryBuffer->Play(0,0, DSBPLAY_LOOPING); // 循环播放
if(::GetAsyncKeyState('S') & 0x8000f)
g_pSecondaryBuffer->Stop(); // 停止播放
最后释放掉directSound接口
If(g_pDirectSound!=NULL)
{
g_pDirectSound->Release();
g_pDirectSound=NULL;
}