X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=snd_win.c;h=92ff70dd564972d4d5f83945322107c4d8fb260a;hb=c7ca06d4cfc3aa10eb1a21633f0443e4e81ecc53;hp=06aed2bbe03dcb4f358b4aa67d50853aa6302bb1;hpb=a19dce25671ecfa28e4eb3861f8636750bf3ba68;p=xonotic%2Fdarkplaces.git diff --git a/snd_win.c b/snd_win.c index 06aed2bb..92ff70dd 100644 --- a/snd_win.c +++ b/snd_win.c @@ -20,12 +20,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" #include "snd_main.h" +#ifdef SUPPORTDIRECTX #ifndef DIRECTSOUND_VERSION # define DIRECTSOUND_VERSION 0x0500 /* Version 5.0 */ #endif +#endif #include #include +#ifdef SUPPORTDIRECTX #include +#endif // ============================================================================== @@ -78,12 +82,15 @@ static const GUID MY_KSDATAFORMAT_SUBTYPE_PCM = // ============================================================================== extern HWND mainwindow; +static cvar_t snd_wav_partitionsize = {CVAR_SAVE, "snd_wav_partitionsize", "1024", "controls sound delay in samples, values too low will cause crackling, too high will cause delayed sounds"}; +static qboolean sndsys_registeredcvars = false; +#ifdef SUPPORTDIRECTX HRESULT (WINAPI *pDirectSoundCreate)(GUID FAR *lpGUID, LPDIRECTSOUND FAR *lplpDS, IUnknown FAR *pUnkOuter); +#endif -// Wave output: 64KB in 64 buffers of 1KB -// (64KB is > 1 sec at 16-bit 22050 Hz mono, and is 1/3 sec at 16-bit 44100 Hz stereo) -#define WAV_BUFFERS 64 +// Wave output: queue of this many sound buffers to play, reused cyclically +#define WAV_BUFFERS 16 #define WAV_MASK (WAV_BUFFERS - 1) static unsigned int wav_buffer_size; @@ -94,16 +101,19 @@ static unsigned int wav_buffer_size; typedef enum sndinitstat_e {SIS_SUCCESS, SIS_FAILURE, SIS_NOTAVAIL} sndinitstat; +#ifdef SUPPORTDIRECTX static qboolean dsound_init; -static qboolean wav_init; +static unsigned int dsound_time; static qboolean primary_format_set; +#endif + +static qboolean wav_init; static int snd_sent, snd_completed; static int prev_painted; static unsigned int paintpot; -static unsigned int dsound_time; /* @@ -125,13 +135,17 @@ DWORD gSndBufSize; DWORD dwStartTime; +#ifdef SUPPORTDIRECTX LPDIRECTSOUND pDS; LPDIRECTSOUNDBUFFER pDSBuf, pDSPBuf; HINSTANCE hInstDS; +#endif qboolean SNDDMA_InitWav (void); +#ifdef SUPPORTDIRECTX sndinitstat SNDDMA_InitDirect (void); +#endif /* @@ -193,6 +207,7 @@ static qboolean SndSys_BuildWaveFormat (const snd_format_t* requested, WAVEFORMA } +#ifdef SUPPORTDIRECTX /* ================== SndSys_InitDirectSound @@ -223,7 +238,7 @@ static sndinitstat SndSys_InitDirectSound (const snd_format_t* requested) return SIS_FAILURE; } - pDirectSoundCreate = (void *)GetProcAddress(hInstDS,"DirectSoundCreate"); + pDirectSoundCreate = (HRESULT (__stdcall *)(GUID *, LPDIRECTSOUND *,IUnknown *))GetProcAddress(hInstDS,"DirectSoundCreate"); if (!pDirectSoundCreate) { @@ -362,7 +377,7 @@ static sndinitstat SndSys_InitDirectSound (const snd_format_t* requested) // Make sure mixer is active IDirectSoundBuffer_Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); - Con_DPrintf(" %d channel(s)\n" + Con_Printf(" %d channel(s)\n" " %d bits/sample\n" " %d samples/sec\n", requested->channels, requested->width * 8, requested->speed); @@ -404,6 +419,7 @@ static sndinitstat SndSys_InitDirectSound (const snd_format_t* requested) return SIS_SUCCESS; } +#endif /* @@ -443,7 +459,7 @@ static qboolean SndSys_InitMmsystem (const snd_format_t* requested) } } - wav_buffer_size = (requested->speed / 2 / WAV_BUFFERS) * requested->channels * requested->width; + wav_buffer_size = bound(128, snd_wav_partitionsize.integer, 8192) * requested->channels * requested->width; /* * Allocate and lock memory for the waveform data. The memory @@ -458,7 +474,7 @@ static qboolean SndSys_InitMmsystem (const snd_format_t* requested) SndSys_Shutdown (); return false; } - lpData = GlobalLock(hData); + lpData = (HPSTR)GlobalLock(hData); if (!lpData) { Con_Print("Sound: Failed to lock.\n"); @@ -530,18 +546,29 @@ May return a suggested format if the requested format isn't available */ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) { +#ifdef SUPPORTDIRECTX qboolean wavonly; +#endif sndinitstat stat; + if (!sndsys_registeredcvars) + { + sndsys_registeredcvars = true; + Cvar_RegisterVariable(&snd_wav_partitionsize); + } + Con_Print ("SndSys_Init: using the Win32 module\n"); +#ifdef SUPPORTDIRECTX // COMMANDLINEOPTION: Windows Sound: -wavonly uses wave sound instead of DirectSound wavonly = (COM_CheckParm ("-wavonly") != 0); dsound_init = false; +#endif wav_init = false; stat = SIS_FAILURE; // assume DirectSound won't initialize +#ifdef SUPPORTDIRECTX // Init DirectSound if (!wavonly) { @@ -552,12 +579,15 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) else Con_Print("DirectSound failed to init\n"); } +#endif // if DirectSound didn't succeed in initializing, try to initialize // waveOut sound, unless DirectSound failed because the hardware is // already allocated (in which case the user has already chosen not // to have sound) +#ifdef SUPPORTDIRECTX if (!dsound_init && (stat != SIS_NOTAVAIL)) +#endif { if (SndSys_InitMmsystem (requested)) Con_Print("Wave sound (MMSYSTEM) initialized\n"); @@ -565,7 +595,11 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) Con_Print("Wave sound failed to init\n"); } +#ifdef SUPPORTDIRECTX return (dsound_init || wav_init); +#else + return wav_init; +#endif } @@ -578,6 +612,7 @@ Stop the sound card, delete "snd_renderbuffer" and free its other resources */ void SndSys_Shutdown (void) { +#ifdef SUPPORTDIRECTX if (pDSBuf) { IDirectSoundBuffer_Stop(pDSBuf); @@ -595,6 +630,7 @@ void SndSys_Shutdown (void) IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_NORMAL); IDirectSound_Release(pDS); } +#endif if (hWaveOut) { @@ -629,15 +665,17 @@ void SndSys_Shutdown (void) snd_renderbuffer = NULL; } +#ifdef SUPPORTDIRECTX pDS = NULL; pDSBuf = NULL; pDSPBuf = NULL; + dsound_init = false; +#endif hWaveOut = 0; hData = 0; hWaveHdr = 0; lpData = NULL; lpWaveHdr = NULL; - dsound_init = false; wav_init = false; } @@ -668,17 +706,24 @@ void SndSys_Submit (void) { h = lpWaveHdr + (snd_sent & WAV_MASK); - snd_sent++; /* * Now the data block can be sent to the output device. The * waveOutWrite function returns immediately and waveform * data is sent to the output device in the background. */ wResult = waveOutWrite(hWaveOut, h, sizeof(WAVEHDR)); - - if (wResult != MMSYSERR_NOERROR) + if (wResult == MMSYSERR_NOERROR) + snd_sent++; + else if (wResult == WAVERR_STILLPLAYING) + { + if(developer_insane.integer) + Con_DPrint("waveOutWrite failed (too much sound data)\n"); + //h->dwFlags |= WHDR_DONE; + //snd_sent++; + } + else { - Con_Print("Failed to write block to device\n"); + Con_Printf("waveOutWrite failed, error code %d\n", (int) wResult); SndSys_Shutdown (); return; } @@ -702,6 +747,7 @@ unsigned int SndSys_GetSoundTime (void) factor = snd_renderbuffer->format.width * snd_renderbuffer->format.channels; +#ifdef SUPPORTDIRECTX if (dsound_init) { DWORD dwTime; @@ -714,6 +760,7 @@ unsigned int SndSys_GetSoundTime (void) dsound_time += diff / factor; return dsound_time; } +#endif if (wav_init) { @@ -733,16 +780,32 @@ unsigned int SndSys_GetSoundTime (void) } return (snd_completed * wav_buffer_size) / factor; + + /* + * S_PaintAndSubmit: WARNING: newsoundtime (soundtime (275 < 134217707) + * apparently this sound time wraps quite early? + { + MMRESULT res; + MMTIME mmtime; + + mmtime.wType = TIME_SAMPLES; + res = waveOutGetPosition(hWaveOut, &mmtime, sizeof(mmtime)); + if(res == MMSYSERR_NOERROR) + return mmtime.u.sample; + } + */ } return 0; } +#ifdef SUPPORTDIRECTX static DWORD dsound_dwSize; static DWORD dsound_dwSize2; static DWORD *dsound_pbuf; static DWORD *dsound_pbuf2; +#endif /* ==================== @@ -753,6 +816,7 @@ Get the exclusive lock on "snd_renderbuffer" */ qboolean SndSys_LockRenderBuffer (void) { +#ifdef SUPPORTDIRECTX int reps; HRESULT hresult; DWORD dwStatus; @@ -797,6 +861,7 @@ qboolean SndSys_LockRenderBuffer (void) Sys_Error("SndSys_LockRenderBuffer: the ring address has changed!!!\n"); return true; } +#endif return wav_init; } @@ -811,6 +876,20 @@ Release the exclusive lock on "snd_renderbuffer" */ void SndSys_UnlockRenderBuffer (void) { +#ifdef SUPPORTDIRECTX if (pDSBuf) IDirectSoundBuffer_Unlock(pDSBuf, dsound_pbuf, dsound_dwSize, dsound_pbuf2, dsound_dwSize2); +#endif +} + +/* +==================== +SndSys_SendKeyEvents + +Send keyboard events originating from the sound system (e.g. MIDI) +==================== +*/ +void SndSys_SendKeyEvents(void) +{ + // not supported }