20 #include "client/sound/dma.h"
26 #define SECONDARY_BUFFER_SIZE 0x10000
35 static LPDIRECTSOUND
pDS;
45 case DSERR_BUFFERLOST:
46 return "DSERR_BUFFERLOST";
47 case DSERR_INVALIDCALL:
48 return "DSERR_INVALIDCALL";
49 case DSERR_INVALIDPARAM:
50 return "DSERR_INVALIDPARAM";
51 case DSERR_PRIOLEVELNEEDED:
52 return "DSERR_PRIOLEVELNEEDED";
55 return "<unknown error>";
63 Com_DPrintf(
"Destroying DS buffers\n");
65 Com_DPrintf(
"...setting NORMAL coop level\n");
66 IDirectSound_SetCooperativeLevel(
pDS,
win.wnd, DSSCL_NORMAL);
70 Com_DPrintf(
"...stopping and releasing sound buffer\n");
71 IDirectSoundBuffer_Stop(
pDSBuf);
72 IDirectSoundBuffer_Release(
pDSBuf);
77 Com_DPrintf(
"...releasing primary buffer\n");
78 IDirectSoundBuffer_Release(
pDSPBuf);
95 Com_Printf(
"Shutting down DirectSound\n");
100 Com_DPrintf(
"...releasing DS object\n");
101 IDirectSound_Release(
pDS);
105 Com_DPrintf(
"...freeing DSOUND.DLL\n");
125 memset(&format, 0,
sizeof(format));
126 format.wFormatTag = WAVE_FORMAT_PCM;
127 format.nChannels =
dma.channels;
128 format.wBitsPerSample =
dma.samplebits;
129 format.nSamplesPerSec =
dma.speed;
130 format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
131 format.cbSize =
sizeof(format);
132 format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
134 Com_DPrintf(
"Creating DS buffer\n");
136 Com_DPrintf(
"...setting PRIORITY coop level: ");
137 if (DS_OK != IDirectSound_SetCooperativeLevel(
pDS,
win.wnd, DSSCL_PRIORITY)) {
138 Com_DPrintf(
"failed\n");
144 memset(&dsbuf, 0,
sizeof(dsbuf));
145 dsbuf.dwSize =
sizeof(DSBUFFERDESC);
146 dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCHARDWARE;
148 dsbuf.lpwfxFormat = &format;
150 memset(&dsbcaps, 0,
sizeof(dsbcaps));
151 dsbcaps.dwSize =
sizeof(dsbcaps);
153 Com_DPrintf(
"...creating secondary buffer: ");
154 if (DS_OK != IDirectSound_CreateSoundBuffer(
pDS, &dsbuf, &
pDSBuf, NULL)) {
155 dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE;
156 if (DS_OK != IDirectSound_CreateSoundBuffer(
pDS, &dsbuf, &
pDSBuf, NULL)) {
157 Com_DPrintf(
"failed\n");
161 Com_DPrintf(
"ok\n...forced to software\n");
163 Com_DPrintf(
"ok\n...locked hardware\n");
166 dma.channels = format.nChannels;
167 dma.samplebits = format.wBitsPerSample;
168 dma.speed = format.nSamplesPerSec;
170 if (DS_OK != IDirectSoundBuffer_GetCaps(
pDSBuf, &dsbcaps)) {
171 Com_DPrintf(
"*** GetCaps failed ***\n");
176 if (DS_OK != IDirectSoundBuffer_Play(
pDSBuf, 0, 0, DSBPLAY_LOOPING)) {
177 Com_DPrintf(
"*** Play failed ***\n");
181 Com_DPrintf(
" %d channel(s)\n"
184 dma.channels,
dma.samplebits,
dma.speed);
188 IDirectSoundBuffer_Stop(
pDSBuf);
190 IDirectSoundBuffer_Play(
pDSBuf, 0, 0, DSBPLAY_LOOPING);
194 dma.submission_chunk = 1;
216 memset(&
dma, 0,
sizeof(
dma));
220 switch (
s_khz->integer) {
235 Com_DPrintf(
"Initializing DirectSound\n");
238 Com_DPrintf(
"...loading dsound.dll: ");
239 hInstDS = LoadLibrary(
"dsound.dll");
241 Com_DPrintf(
"failed\n");
248 GetProcAddress(
hInstDS,
"DirectSoundCreate");
249 if (!pDirectSoundCreate) {
250 Com_DPrintf(
"...couldn't get DS proc addr\n");
254 Com_DPrintf(
"...creating DS object: ");
255 while ((hresult = pDirectSoundCreate(NULL, &
pDS, NULL)) != DS_OK) {
256 if (hresult != DSERR_ALLOCATED) {
257 Com_DPrintf(
"failed\n");
262 "The sound hardware is in use by another app.\n\n"
263 "Select Retry to try to start sound again or Cancel to run " PRODUCT
" with no sound.",
264 "Sound not available",
265 MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY) {
266 Com_DPrintf(
"failed, hardware already in use\n");
272 dscaps.dwSize =
sizeof(dscaps);
274 if (DS_OK != IDirectSound_GetCaps(
pDS, &dscaps)) {
275 Com_DPrintf(
"...couldn't get DS caps\n");
280 if (dscaps.dwFlags & DSCAPS_EMULDRIVER) {
281 Com_DPrintf(
"...no DSound driver found\n");
291 Com_Printf(
"DirectSound initialized\n");
313 DWORD dwStatus, dwWrite;
320 mmtime.wType = TIME_SAMPLES;
321 IDirectSoundBuffer_GetCurrentPosition(
pDSBuf, &mmtime.u.sample, &dwWrite);
323 dma.samplepos = s & (
dma.samples - 1);
326 if (IDirectSoundBuffer_GetStatus(
pDSBuf, &dwStatus) != DS_OK) {
327 Com_EPrintf(
"DS_BeginPainting: Couldn't get sound buffer status\n");
332 if (dwStatus & DSBSTATUS_BUFFERLOST)
333 IDirectSoundBuffer_Restore(
pDSBuf);
335 if (!(dwStatus & DSBSTATUS_PLAYING))
336 IDirectSoundBuffer_Play(
pDSBuf, 0, 0, DSBPLAY_LOOPING);
344 (
void **)&pbuf2, &dwSize2, 0)) != DS_OK) {
345 if (hresult != DSERR_BUFFERLOST) {
346 Com_EPrintf(
"DS_BeginPainting: Lock failed with error '%s'\n",
DSoundError(hresult));
351 IDirectSoundBuffer_Restore(
pDSBuf);
356 dma.buffer = (
byte *)pbuf;
392 Com_EPrintf(
"DS_Activate: DS_CreateBuffers failed\n");