qboolean SNDDMAHD_DSEnumSoundDevices(qboolean blistonly) { HMODULE hdsounddll = NULL; pDirectSoundEnumerate DSEnumerate; if ((hdsounddll = LoadLibrary("dsound.dll")) != NULL && (DSEnumerate = (pDirectSoundEnumerate)GetProcAddress(hdsounddll, "DirectSoundEnumerateA")) != NULL && s_dev->string != NULL && s_dev->string[0] != '\0') { if (blistonly) { Com_Printf( "^4List of DirectSound devices:\n"); if (FAILED(DSEnumerate(SNDDMAHD_DSEnumCallbackList, NULL))) { Com_Printf("^1Error Enumerating DirectSound Devices\n"); return qfalse; } } else { Com_Printf( "^4Looking for DirectSound Device '%s'\n", s_dev->string); if (FAILED(DSEnumerate(SNDDMAHD_DSEnumCallback, NULL))) { Com_Printf("^1Error Enumerating DirectSound Devices\n"); return qfalse; } if (g_dsguid == NULL) Com_Printf("^1Device '%s' not found. ^2Using default driver.\n", s_dev->string); } } if (hdsounddll != NULL) FreeLibrary(hdsounddll); hdsounddll = NULL; return qtrue; }
int SNDDMA_InitDS () { HRESULT hresult; DSBUFFERDESC dsbuf; DSBCAPS dsbcaps; WAVEFORMATEX format; int use8; HMODULE hdsounddll; pDirectSoundEnumerate DSEnumerate; if ((hdsounddll = LoadLibrary("dsound.dll")) != NULL && (DSEnumerate = (pDirectSoundEnumerate)GetProcAddress(hdsounddll, "DirectSoundEnumerateA")) != NULL && s_dev->string != NULL && s_dev->string[0] != '\0') { Com_Printf( "^4Looking for DirectSound Device '%s'\n", s_dev->string); if (FAILED(DSEnumerate(SNDDMAHD_DSEnumCallback, NULL))) Com_Printf("^1Error Enumerating DirectSound Devices\n"); if (g_dsguid == NULL) Com_Printf("^1Device '%s' not found. ^2Using default driver.\n", s_dev->string); } Com_Printf( "Initializing DirectSound\n"); use8 = 1; // Create IDirectSound using the primary sound device if( FAILED( hresult = CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void **)&pDS))) { use8 = 0; if( FAILED( hresult = CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void **)&pDS))) { Com_Printf ("failed\n"); SNDDMA_Shutdown (); return qfalse; } } hresult = pDS->lpVtbl->Initialize( pDS, g_dsguid); Com_DPrintf( "ok\n" ); Com_DPrintf("...setting DSSCL_PRIORITY coop level: " ); if ( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, g_wv.hWnd, DSSCL_PRIORITY ) ) { Com_Printf ("failed\n"); SNDDMA_Shutdown (); return qfalse; } Com_DPrintf("ok\n" ); // create the secondary buffer we'll actually work with dma.channels = 2; dma.samplebits = 16; if (s_khz->integer >= 44) dma.speed = 44100; else if (s_khz->integer >= 32) dma.speed = 32000; else if (s_khz->integer >= 24) dma.speed = 24000; else if (s_khz->integer >= 22) dma.speed = 22050; else dma.speed = 11025; memset (&format, 0, sizeof(format)); format.wFormatTag = WAVE_FORMAT_PCM; format.nChannels = dma.channels; format.wBitsPerSample = dma.samplebits; format.nSamplesPerSec = dma.speed; format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; format.cbSize = 0; format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; memset (&dsbuf, 0, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); // Micah: take advantage of 2D hardware.if available. dsbuf.dwFlags = DSBCAPS_LOCHARDWARE; if (use8) { dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2; } dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; dsbuf.lpwfxFormat = &format; memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); Com_DPrintf( "...creating secondary buffer: " ); if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) { Com_Printf( "locked hardware. ok\n" ); } else { // Couldn't get hardware, fallback to software. dsbuf.dwFlags = DSBCAPS_LOCSOFTWARE; if (use8) { dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2; } if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) { Com_Printf( "failed\n" ); SNDDMA_Shutdown (); return qfalse; } Com_DPrintf( "forced to software. ok\n" ); } // Make sure mixer is active if ( DS_OK != pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING) ) { Com_Printf ("*** Looped sound play failed ***\n"); SNDDMA_Shutdown (); return qfalse; } // get the returned buffer size if ( DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps) ) { Com_Printf ("*** GetCaps failed ***\n"); SNDDMA_Shutdown (); return qfalse; } gSndBufSize = dsbcaps.dwBufferBytes; dma.channels = format.nChannels; dma.samplebits = format.wBitsPerSample; dma.speed = format.nSamplesPerSec; dma.samples = gSndBufSize/(dma.samplebits/8); dma.submission_chunk = 1; dma.buffer = NULL; // must be locked first sample16 = (dma.samplebits/8) - 1; SNDDMA_BeginPainting (); if (dma.buffer) memset(dma.buffer, 0, dma.samples * dma.samplebits/8); SNDDMA_Submit (); return 1; }