Important: |
---|
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. |
Most applications will use the DirectSound mixer; it should be sufficient for almost all mixing needs and it automatically takes advantage of any available hardware acceleration. However, if an application requires some other functionality that DirectSound does not provide, it can obtain write access to the primary sound buffer and mix streams directly into it.
To implement a custom mixer, the application must first set the DSSCL_WRITEPRIMARY cooperative level and then create a primary sound buffer. (See Access to the Primary Buffer.) It can then lock the buffer, write data to it, unlock it, and play it just like any other buffer. (See Playing Sounds.) Note however that the DSBPLAY_LOOPING flag must be specified or the IDirectSoundBuffer::Playcall will fail.
The following example illustrates how an application might implement a custom mixer. The AppMixIntoPrimaryBuffersample function would have to be called at regular intervals, frequently enough to prevent the sound device from repeating blocks of data. The CustomMixerfunction is an application-defined function that mixes several streams together, as specified in the application-defined AppStreamInfostructure, and writes the result to the specified pointer.
BOOL AppMixIntoPrimaryBuffer( LPAPPSTREAMINFO lpAppStreamInfo, LPDIRECTSOUNDBUFFER lpDsbPrimary, DWORD dwDataBytes, DWORD dwOldPos, LPDWORD lpdwNewPos) { LPVOID lpvPtr1; DWORD dwBytes1; LPVOID lpvPtr2; DWORD dwBytes2; HRESULT hr; // Obtain write pointer. hr = lpDsbPrimary->lpVtbl->Lock(lpDsbPrimary, dwOldPos, dwDataBytes, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); // If DSERR_BUFFERLOST is returned, restore and retry lock. if (DSERR_BUFFERLOST == hr) { lpDsbPrimary->lpVtbl->Restore(lpDsbPrimary); hr = lpDsbPrimary->lpVtbl->Lock(lpDsbPrimary, dwOldPos, dwDataBytes, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); } if SUCCEEDED(hr) { // Mix data into the returned pointers. CustomMixer(lpAppStreamInfo, lpvPtr1, dwBytes1); *lpdwNewPos = dwOldPos + dwBytes1; if (NULL != lpvPtr2) { CustomMixer(lpAppStreamInfo, lpvPtr2, dwBytes2); *lpdwNewPos = dwBytes2; // Because it wrapped around. } // Release the data back to DirectSound. hr = lpDsbPrimary->lpVtbl->Unlock(lpDsbPrimary, lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); if SUCCEEDED(hr) { return TRUE; } } // Lock or Unlock failed. return FALSE; }
Last updated on Tuesday, May 18, 2004