今天把试了下DirectSound,说实话,用起来还没有PlaySound()方便。但功能却要强得多。要使用这个组件,首先要用DirectSoundCreate8创建一个LPDIRECTSOUND8对象;
LPDIRECTSOUND8 m_sound;
HRESULT hr;
hr = DirectSoundCreate8(NULL, &m_sound, NULL);
if (FAILED(hr))
{
return FALSE;
}
然后跟之前所说的DirectInput一样要设置协议。
hr = m_sound->SetCooperativeLevel(m_hwnd, DSSCL_NORMAL);
if (FAILED(hr))
{
return FALSE;
}
有了协议之后就只需要创建一个缓冲区来缓冲我们的wav文件,不过很多书上说什么主缓冲区和次缓冲区。龙儿我也不管那么多了。我就创一个缓冲区。
不过在之前要知道怎么读取wav文件。龙儿提供一个完整的读取wav文件的函数
BYTE* Dsound::LoadWaveFile(LPSTR filename, DWORD* length)
{
HMMIO file = mmioOpenA(filename, NULL, MMIO_READ);
if (file == NULL)
{
return NULL;
}
char ch[4];
mmioSeek(file, 8L, SEEK_SET);
mmioRead(file, ch, 4L);
if (ch[0] != 'W' || ch[1] != 'A' || ch[2] != 'V' || ch[3] != 'E')
{
mmioClose(file, 0);
return NULL;
}
mmioSeek(file, 20L, SEEK_SET);
mmioRead(file, HPSTR(&m_fmt), sizeof(WAVEFORMATEX));
DWORD len;
mmioSeek(file, 40L, SEEK_SET);
mmioRead(file, (char*)&len, sizeof(DWORD));
(*length) = len;
BYTE* data;
data = new BYTE[len];
mmioSeek(file, 44L, SEEK_SET);
mmioRead(file, (char*)data, LONG(len));
mmioClose(file, 0);
return data;
}
其中m_fmt是一个WAVEFORMATEX结构体,将会在接下来的创建缓冲区的时候用到。
创建缓冲区说白了就是真充两个结构体。一个DSBUFFERDESC,还有一个WAVEFORMATEX已经在文件中读取到了。简单吧。。。
DSBUFFERDESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.dwSize = sizeof(desc);
desc.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_STATIC;
desc.dwBufferBytes = length;
desc.lpwfxFormat = &m_fmt;
hr = m_sound->CreateSoundBuffer(&desc, &lpbuffer, NULL);
if (FAILED(hr))
{
return FALSE;
}
缓冲区创建后,就只剩锁定你所创建的缓冲区然后把你从wav文件中读取出来的数据写入缓冲区就行了。
LPVOID lpvPtr;
DWORD dwByte;
lpbuffer->Lock(0, 0, &lpvPtr, &dwByte, NULL, NULL, DSBLOCK_ENTIREBUFFER);
memcpy(lpvPtr, m_data, dwByte);
lpbuffer->Unlock(lpvPtr, dwByte, NULL, 0);
终于万事俱备,只欠东风了。就差一个play了。
lpbuffer->SetCurrentPosition(0);
lpbuffer->Play(0, 0, DSBPLAY_LOOPING);
然后就听一下音乐享受一下自己的成果吧。
龙儿顺便提供一个这几讲的源码吧。