DirectSound缓冲区
DirectSound缓冲区对象控制波形数据从源到目的地的传播。源可能是一个合成器,另一个合成器,一个WAV文件,或一个资源。对于大多数合成器,目的地是一个称作主缓冲区的混合装置。从主缓冲区开始,数据传输到硬件,由硬件将采样转换为声波。
缓冲区基础
你的应用程序必须创建至少一个辅助缓冲区来存储合播放单独的声音。
一个辅助缓冲区能够在整个应用程序生命周期内存在,或者在不再需要时销毁。它可以时一个静态缓冲区,包含单个短声音,或者是一个流缓冲区,在缓冲区播放的同时更新数据。为限制对内存的要求,长声音应该通过流缓冲区播放,它容纳几秒长的声音数据。
创建的辅助缓冲区并不都是相似的。缓冲区的特性包括:
格式:缓冲区的格式必须与它播放的波形数据格式匹配。
控制:不同的缓冲区可以有不同的控制,如音量,频率,以二维或三维方式移动等。当创建一个缓冲区时,你应该仅指定你所需要的控制。如不要在非3D环境下创建一个3D声音缓冲区。
位置:一个缓冲区能够位于由硬件管理的内存中,也可以位于由软件管理的内存中。硬件缓冲区更有效但是数量受限。
创建辅助缓冲区
调用IDirectSound8::CreateSoundBuffer方法创建一个缓冲区。这个方法返回一个IDirectSoundBuffer接口的指针,通过它应用程序能够获得一个IDirectSoundBuffer8接口。
下面的例子创建了一个辅助声音缓冲区,并返回IDirectSoundBuffer8接口。
{
WAVEFORMATEX wfx;
DSBUFFERDESC dsbdesc;
LPDIRECTSOUNDBUFFER pDsb = NULL;
HRESULT hr;
// Set up WAV format structure.
memset(&wfx, 0, sizeof(WAVEFORMATEX));
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = 22050;
wfx.nBlockAlign = 4;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
wfx.wBitsPerSample = 16;
// Set up DSBUFFERDESC structure.
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags =
DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
dsbdesc.dwBufferBytes = 3 * wfx.nAvgBytesPerSec;
dsbdesc.lpwfxFormat = &wfx;
// Create buffer.
hr = lpDirectSound->CreateSoundBuffer(&dsbdesc, &pDsb, NULL);
if (SUCCEEDED(hr))
{
hr = pDsb->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*) ppDsb8);
pDsb->Release();
}
return hr;
}
例子函数创建了一个流缓冲区,大小足以容纳三秒的流数据。非流缓冲区应该创建足够大小来容纳整个声音数据。
如果一个缓冲区的位置没有指定,DirectSound尽可能将它放在硬件控制内存中。因为硬件缓冲区由声卡处理器进行混合,它们对应用程序性能的影响很少。
如 果你希望指定一个缓冲区的位置,而不是让DirectSound决定它属于哪里,设置SDBUFFERDESC结构中的 DSBCAPS_LOCHARDWARE或DSBCAPS_LOCSOFTWARE标识。如果DSBCAPS_LOCHARDWARE标识被设置,但是没 有足够的硬件资源,那么缓冲区创建请求将失败。
为利用DirecSound的声音管理特性,在创建缓冲区的时候要设置DSBCAPS_LOCDEFFER标识。这个标识将缓冲区资源的分配延迟到缓冲区播放的时候。
你能够通过IDirectSoundBuffer8::GetCaps方法,检查DSBCAPS结构的dwFlags成员来探知已存在缓冲区的位置。
缓冲区对象属于创建它的设备对象。当释放设备对象时,所有由该对象创建的缓冲区也将被释放,所以不应该再被引用。
复制缓冲区
你能够使用IDirectSound8::DuplicateSoundBuffer方法创建两个以上包含相同数据的辅助缓冲区。你不能够复制主缓冲区。