/* ================== SNDDMA_InitDirect Direct-Sound support ================== */ si_state_t SNDDMA_InitDirect( void *hInst ) { DSCAPS dscaps; HRESULT hresult; if( !dsound_dll.link ) { if( !Sys_LoadLibrary( &dsound_dll )) return SIS_FAILURE; } MsgDev( D_NOTE, "SNDDMA_InitDirect: creating DS object " ); if(( hresult = iDirectSoundCreate( NULL, &pDS, NULL )) != DS_OK ) { if( hresult != DSERR_ALLOCATED ) { MsgDev( D_NOTE, "- failed\n" ); return SIS_FAILURE; } MsgDev( D_NOTE, "- failed, hardware already in use\n" ); return SIS_NOTAVAIL; } MsgDev( D_NOTE, "- ok\n" ); dscaps.dwSize = sizeof( dscaps ); if( pDS->lpVtbl->GetCaps( pDS, &dscaps ) != DS_OK ) MsgDev( D_ERROR, "SNDDMA_InitDirect: GetCaps failed\n"); if( dscaps.dwFlags & DSCAPS_EMULDRIVER ) { MsgDev( D_ERROR, "SNDDMA_InitDirect: no DSound driver found\n" ); SNDDMA_FreeSound(); return SIS_FAILURE; } if( !DS_CreateBuffers( hInst )) return SIS_FAILURE; return SIS_SUCCESS; }
/* SNDDMA_InitDirect Direct-Sound support */ sndinitstat SNDDMA_InitDirect (void) { DSBUFFERDESC dsbuf; DSBCAPS dsbcaps; DWORD dwSize, dwWrite; DSCAPS dscaps; WAVEFORMATEX format, pformat; HRESULT hresult; int reps; memset ((void *) &sn, 0, sizeof (sn)); shm = &sn; shm->channels = 2; shm->samplebits = 16; shm->speed = 11025; memset (&format, 0, sizeof (format)); format.wFormatTag = WAVE_FORMAT_PCM; format.nChannels = shm->channels; format.wBitsPerSample = shm->samplebits; format.nSamplesPerSec = shm->speed; format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; format.cbSize = 0; format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; if (!hInstDS) { hInstDS = LoadLibrary ("dsound.dll"); if (hInstDS == NULL) { Con_Printf ("Couldn't load dsound.dll\n"); return SIS_FAILURE; } pDirectSoundCreate = (void *) GetProcAddress (hInstDS, "DirectSoundCreate"); if (!pDirectSoundCreate) { Con_Printf ("Couldn't get DS proc addr\n"); return SIS_FAILURE; } } while ((hresult = iDirectSoundCreate (NULL, &pDS, NULL)) != DS_OK) { if (hresult != DSERR_ALLOCATED) { Con_Printf ("DirectSound create failed\n"); return SIS_FAILURE; } Con_Printf ("DirectSoundCreate failure\n" " hardware already in use\n"); return SIS_NOTAVAIL; } dscaps.dwSize = sizeof (dscaps); if (DS_OK != IDirectSound_GetCaps (pDS, &dscaps)) { Con_Printf ("Couldn't get DS caps\n"); } if (dscaps.dwFlags & DSCAPS_EMULDRIVER) { Con_Printf ("No DirectSound driver installed\n"); FreeSound (); return SIS_FAILURE; } if (DS_OK != IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE)) { Con_Printf ("Set coop level failed\n"); FreeSound (); return SIS_FAILURE; } // get access to the primary buffer, if possible, so we can set the // sound hardware format memset (&dsbuf, 0, sizeof (dsbuf)); dsbuf.dwSize = sizeof (DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbuf.dwBufferBytes = 0; dsbuf.lpwfxFormat = NULL; memset (&dsbcaps, 0, sizeof (dsbcaps)); dsbcaps.dwSize = sizeof (dsbcaps); primary_format_set = false; if (!COM_CheckParm ("-snoforceformat")) { if (DS_OK == IDirectSound_CreateSoundBuffer (pDS, &dsbuf, &pDSPBuf, NULL)) { pformat = format; if (DS_OK != IDirectSoundBuffer_SetFormat (pDSPBuf, &pformat)) { } else primary_format_set = true; } } if (!primary_format_set || !COM_CheckParm ("-primarysound")) { // create the secondary buffer we'll actually work with memset (&dsbuf, 0, sizeof (dsbuf)); dsbuf.dwSize = sizeof (DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE; dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; dsbuf.lpwfxFormat = &format; memset (&dsbcaps, 0, sizeof (dsbcaps)); dsbcaps.dwSize = sizeof (dsbcaps); if (DS_OK != IDirectSound_CreateSoundBuffer (pDS, &dsbuf, &pDSBuf, NULL)) { Con_Printf ("DS:CreateSoundBuffer Failed"); FreeSound (); return SIS_FAILURE; } shm->channels = format.nChannels; shm->samplebits = format.wBitsPerSample; shm->speed = format.nSamplesPerSec; if (DS_OK != IDirectSound_GetCaps (pDSBuf, &dsbcaps)) { Con_Printf ("DS:GetCaps failed\n"); FreeSound (); return SIS_FAILURE; } } else { if (DS_OK != IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_WRITEPRIMARY)) { Con_Printf ("Set coop level failed\n"); FreeSound (); return SIS_FAILURE; } if (DS_OK != IDirectSound_GetCaps (pDSPBuf, &dsbcaps)) { Con_Printf ("DS:GetCaps failed\n"); return SIS_FAILURE; } pDSBuf = pDSPBuf; } // Make sure mixer is active IDirectSoundBuffer_Play (pDSBuf, 0, 0, DSBPLAY_LOOPING); gSndBufSize = dsbcaps.dwBufferBytes; // initialize the buffer reps = 0; while ((hresult = IDirectSoundBuffer_Lock (pDSBuf, 0, gSndBufSize, (LPVOID *) & lpData, &dwSize, NULL,NULL, 0)) != DS_OK) { if (hresult != DSERR_BUFFERLOST) { Con_Printf ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n"); FreeSound (); return SIS_FAILURE; } if (++reps > 10000) { Con_Printf ("SNDDMA_InitDirect: DS: couldn't restore buffer\n"); FreeSound (); return SIS_FAILURE; } } memset (lpData, 0, dwSize); // lpData[4] = lpData[5] = 0x7f; // force a pop for debugging IDirectSoundBuffer_Unlock (pDSBuf, lpData, dwSize, NULL, 0); /* we don't want anyone to access the buffer directly w/o locking it first. */ lpData = NULL; IDirectSoundBuffer_Stop (pDSBuf); IDirectSoundBuffer_GetCurrentPosition (pDSBuf, &mmstarttime.u.sample, &dwWrite); IDirectSoundBuffer_Play (pDSBuf, 0, 0, DSBPLAY_LOOPING); shm->soundalive = true; shm->splitbuffer = false; shm->samples = gSndBufSize / (shm->samplebits / 8); shm->samplepos = 0; shm->submission_chunk = 1; shm->buffer = (unsigned char *) lpData; sample16 = (shm->samplebits / 8) - 1; dsound_init = true; return SIS_SUCCESS; }
/* ================== SNDDMA_InitDirect Direct-Sound support ================== */ sndinitstat SNDDMA_InitDirect (void) { DSCAPS dscaps; HRESULT hresult; dma.channels = 2; dma.samplebits = 16; if (s_khz->value == 44) dma.speed = 44100; if (s_khz->value == 22) dma.speed = 22050; else dma.speed = 11025; Com_Printf( "Initializing DirectSound\n"); if ( !hInstDS ) { Com_DPrintf( "...loading dsound.dll: " ); hInstDS = LoadLibrary("dsound.dll"); if (hInstDS == NULL) { Com_Printf ("failed\n"); return SIS_FAILURE; } Com_DPrintf ("ok\n"); pDirectSoundCreate = (void *)GetProcAddress(hInstDS,"DirectSoundCreate"); if (!pDirectSoundCreate) { Com_Printf ("*** couldn't get DS proc addr ***\n"); return SIS_FAILURE; } } Com_DPrintf( "...creating DS object: " ); while ( ( hresult = iDirectSoundCreate( NULL, &pDS, NULL ) ) != DS_OK ) { if (hresult != DSERR_ALLOCATED) { Com_Printf( "failed\n" ); return SIS_FAILURE; } if (MessageBox (NULL, "The sound hardware is in use by another app.\n\n" "Select Retry to try to start sound again or Cancel to run Quake with no sound.", "Sound not available", MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY) { Com_Printf ("failed, hardware already in use\n" ); return SIS_NOTAVAIL; } } Com_DPrintf( "ok\n" ); dscaps.dwSize = sizeof(dscaps); if ( DS_OK != pDS->lpVtbl->GetCaps( pDS, &dscaps ) ) { Com_Printf ("*** couldn't get DS caps ***\n"); } if ( dscaps.dwFlags & DSCAPS_EMULDRIVER ) { Com_DPrintf ("...no DSound driver found\n" ); FreeSound(); return SIS_FAILURE; } if ( !DS_CreateBuffers() ) return SIS_FAILURE; dsound_init = true; Com_DPrintf("...completed successfully\n" ); return SIS_SUCCESS; }
static int SNDDMA_InitDS () { HRESULT hresult; qboolean pauseTried; DSBUFFERDESC dsbuf; DSBCAPS dsbcaps; WAVEFORMATEX format; Com_Printf( "Initializing DirectSound\n"); if ( !hInstDS ) { Com_DPrintf( "...loading dsound.dll: " ); hInstDS = LoadLibrary("dsound.dll"); if ( hInstDS == NULL ) { Com_Printf ("failed\n"); return 0; } Com_DPrintf ("ok\n"); pDirectSoundCreate = (long (__stdcall *)(struct _GUID *,struct IDirectSound ** ,struct IUnknown *)) GetProcAddress(hInstDS,"DirectSoundCreate"); if ( !pDirectSoundCreate ) { Com_Printf ("*** couldn't get DS proc addr ***\n"); return 0; } } Com_DPrintf( "...creating DS object: " ); pauseTried = qfalse; while ( ( hresult = iDirectSoundCreate( NULL, &pDS, NULL ) ) != DS_OK ) { if ( hresult != DSERR_ALLOCATED ) { Com_Printf( "failed\n" ); return 0; } if ( pauseTried ) { Com_Printf ("failed, hardware already in use\n" ); return 0; } // first try just waiting five seconds and trying again // this will handle the case of a sysyem beep playing when the // game starts Com_DPrintf ("retrying...\n"); Sleep( 3000 ); pauseTried = qtrue; } Com_DPrintf( "ok\n" ); Com_DPrintf("...setting DSSCL_PRIORITY coop level: " ); if ( DS_OK != pDS->SetCooperativeLevel( 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 == 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); #define idDSBCAPS_GETCURRENTPOSITION2 0x00010000 dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCHARDWARE | idDSBCAPS_GETCURRENTPOSITION2; dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; dsbuf.lpwfxFormat = &format; Com_DPrintf( "...creating secondary buffer: " ); if (DS_OK != pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL)) { dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY; hresult = pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL); if (hresult != DS_OK) { Com_Printf( "failed to create secondary buffer - %s\n", DSoundError( hresult ) ); SNDDMA_Shutdown (); return qfalse; } } Com_Printf( "locked hardware. ok\n" ); // Make sure mixer is active if ( DS_OK != pDSBuf->Play(0, 0, DSBPLAY_LOOPING) ) { Com_Printf ("*** Looped sound play failed ***\n"); SNDDMA_Shutdown (); return qfalse; } memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); // get the returned buffer size if ( DS_OK != pDSBuf->GetCaps (&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; }
/* ================== SNDDMA_InitDirect Direct-Sound support ================== */ static sndinitstat SNDDMA_InitDirect (void) { DSBUFFERDESC dsbuf; DSBCAPS dsbcaps; DWORD dwSize, dwWrite; DSCAPS dscaps; WAVEFORMATEX format, pformat; HRESULT hresult; int reps; memset (&dma, 0, sizeof(dma)); dma.channels = 2; dma.samplebits = 16; if (s_khz.value == 44) dma.speed = 44100; else if (s_khz.value == 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; if (!hInstDS) { hInstDS = LoadLibrary("dsound.dll"); if (hInstDS == NULL) { Com_Printf ("Couldn't load dsound.dll\n"); return SIS_FAILURE; } pDirectSoundCreate = (HRESULT (WINAPI *)(GUID FAR *, LPDIRECTSOUND FAR *, IUnknown FAR *))GetProcAddress(hInstDS,"DirectSoundCreate"); if (!pDirectSoundCreate) { Com_Printf ("Couldn't get DS proc addr\n"); return SIS_FAILURE; } } if ((hresult = iDirectSoundCreate(NULL, &pDS, NULL)) != DS_OK) { if (hresult == DSERR_ALLOCATED) { Com_Printf ("DirectSoundCreate failed, hardware already in use\n"); return SIS_NOTAVAIL; } Com_Printf ("DirectSound create failed\n"); return SIS_FAILURE; } dscaps.dwSize = sizeof(dscaps); if (DS_OK != pDS->lpVtbl->GetCaps (pDS, &dscaps)) { Com_Printf ("Couldn't get DS caps\n"); } if (dscaps.dwFlags & DSCAPS_EMULDRIVER) { Com_Printf ("No DirectSound driver installed\n"); FreeSound (); return SIS_FAILURE; } if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE)) { Com_Printf ("Set coop level failed\n"); FreeSound (); return SIS_FAILURE; } // get access to the primary buffer, if possible, so we can set the // sound hardware format memset (&dsbuf, 0, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbuf.dwBufferBytes = 0; dsbuf.lpwfxFormat = NULL; memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); primary_format_set = false; if (!COM_CheckParm ("-snoforceformat")) { if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSPBuf, NULL)) { pformat = format; if (DS_OK != pDSPBuf->lpVtbl->SetFormat (pDSPBuf, &pformat)) { // if (snd_firsttime) // Com_Printf ("Set primary sound buffer format: no\n"); } else // { // if (snd_firsttime) // Com_Printf ("Set primary sound buffer format: yes\n"); primary_format_set = true; // } } } if (!primary_format_set || !COM_CheckParm ("-primarysound")) { // create the secondary buffer we'll actually work with memset (&dsbuf, 0, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE; dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; dsbuf.lpwfxFormat = &format; memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) { Com_Printf ("DS:CreateSoundBuffer Failed"); FreeSound (); return SIS_FAILURE; } dma.channels = format.nChannels; dma.samplebits = format.wBitsPerSample; dma.speed = format.nSamplesPerSec; if (DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps)) { Com_Printf ("DS:GetCaps failed\n"); FreeSound (); return SIS_FAILURE; } // if (snd_firsttime) // Com_Printf ("Using secondary sound buffer\n"); } else { if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_WRITEPRIMARY)) { Com_Printf ("Set coop level failed\n"); FreeSound (); return SIS_FAILURE; } if (DS_OK != pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps)) { Com_Printf ("DS:GetCaps failed\n"); return SIS_FAILURE; } pDSBuf = pDSPBuf; // Com_Printf ("Using primary sound buffer\n"); } // Make sure mixer is active pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); /* if (snd_firsttime) Com_Printf (" %d channel(s)\n" " %d bits/sample\n" " %d bytes/sec\n", dma.channels, dma.samplebits, dma.speed);*/ gSndBufSize = dsbcaps.dwBufferBytes; // initialize the buffer reps = 0; #ifdef MINGW32 #define Lock(a,b,c,d,e,f,g,h) Lock(a,b,c,(void *)d,e,(void *)f,g,h) #endif while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &lpData, &dwSize, NULL, NULL, 0)) != DS_OK) { if (hresult != DSERR_BUFFERLOST) { Com_Printf ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n"); FreeSound (); return SIS_FAILURE; } if (++reps > 10000) { Com_Printf ("SNDDMA_InitDirect: DS: couldn't restore buffer\n"); FreeSound (); return SIS_FAILURE; } } memset(lpData, 0, dwSize); // lpData[4] = lpData[5] = 0x7f; // force a pop for debugging pDSBuf->lpVtbl->Unlock(pDSBuf, lpData, dwSize, NULL, 0); /* we don't want anyone to access the buffer directly w/o locking it first. */ lpData = NULL; pDSBuf->lpVtbl->Stop(pDSBuf); pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmstarttime.u.sample, &dwWrite); pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); dma.samples = gSndBufSize/(dma.samplebits/8); dma.samplepos = 0; dma.submission_chunk = 1; dma.buffer = (unsigned char *) lpData; sample16 = (dma.samplebits/8) - 1; dsound_init = true; return SIS_SUCCESS; }