From df51d08616811313170dc27e26bfd24bbb6c6547 Mon Sep 17 00:00:00 2001 From: TimeServ Date: Wed, 10 May 2006 05:18:08 +0000 Subject: [PATCH] add snd_samplebits to change sample bit size (defaults to 16, can use 8), add snd_buffersize to control driver buffer size (usable with ALSA and directsound, defaults to 0 which lets the driver decide) git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2268 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/snd_alsa.c | 18 +++++--- engine/client/snd_directx.c | 21 +++++---- engine/client/snd_dma.c | 27 +++++++++++- engine/client/snd_linux.c | 87 +++++++++++++++++-------------------- engine/client/snd_win.c | 22 +++++----- 5 files changed, 103 insertions(+), 72 deletions(-) diff --git a/engine/client/snd_alsa.c b/engine/client/snd_alsa.c index ee2e3c8e5..fc7ee3d1a 100755 --- a/engine/client/snd_alsa.c +++ b/engine/client/snd_alsa.c @@ -255,7 +255,6 @@ static int ALSA_InitCard (soundcardinfo_t *sc, int cardnum) } // get sample bit size - sc->sn.samplebits = 16; // TODO: this should be changable by a cvar bps = sc->sn.samplebits; { snd_pcm_format_t spft; @@ -282,11 +281,7 @@ static int ALSA_InitCard (soundcardinfo_t *sc, int cardnum) } // get speaker channels - stereo = (int)snd_speakers.value; - if (stereo > 6) // limit channels to 6 (engine limit) - stereo = 6; - if (!stereo) - stereo = 2; + stereo = sc->sn.numchannels; err = psnd_pcm_hw_params_set_channels (pcm, hw, stereo); while (err < 0) { @@ -371,6 +366,17 @@ static int ALSA_InitCard (soundcardinfo_t *sc, int cardnum) sc->sn.samplepos = 0; sc->sn.samplebits = bps; + buffer_size = sc->sn.samples / stereo; + if (buffer_size) + { + err = psnd_pcm_hw_params_set_buffer_size_near(pcm, hw, &buffer_size); + if (err < 0) + { + Con_Printf ("ALSA: unable to set buffer size. %s\n", psnd_strerror (err)); + goto error; + } + } + err = psnd_pcm_hw_params_get_buffer_size (hw, &buffer_size); if (0 > err) { Con_Printf ("ALSA: unable to get buffer size. %s\n", diff --git a/engine/client/snd_directx.c b/engine/client/snd_directx.c index 8821f558e..c0d0ab754 100644 --- a/engine/client/snd_directx.c +++ b/engine/client/snd_directx.c @@ -506,7 +506,7 @@ Direct-Sound support */ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum) { - extern cvar_t snd_khz, snd_eax, snd_speakers, snd_inactive; + extern cvar_t snd_eax, snd_inactive; DSBUFFERDESC dsbuf; DSBCAPS dsbcaps; DWORD dwSize, dwWrite; @@ -521,13 +521,9 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum) if (COM_CheckParm("-wavonly")) return SND_NOMORE; - - sc->sn.numchannels = 2; - sc->sn.samplebits = 16; - memset (&format, 0, sizeof(format)); - if (snd_speakers.value >= 5) //5.1 surround + if (sc->sn.numchannels >= 6) //5.1 surround { format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; format.Format.cbSize = 22; @@ -536,7 +532,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum) format.dwChannelMask = KSAUDIO_SPEAKER_5POINT1; sc->sn.numchannels = 6; } - else if (snd_speakers.value >= 3) //4 speaker quad + else if (sc->sn.numchannels >= 4) //4 speaker quad { format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; format.Format.cbSize = 22; @@ -545,7 +541,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum) format.dwChannelMask = KSAUDIO_SPEAKER_QUAD; sc->sn.numchannels = 4; } - else if (snd_speakers.value >= 1.5) //stereo + else if (sc->sn.numchannels >= 2) //stereo { format.Format.wFormatTag = WAVE_FORMAT_PCM; format.Format.cbSize = 0; @@ -713,7 +709,14 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum) dsbuf.dwFlags |= DSBCAPS_GLOBALFOCUS; sc->inactive_sound = true; } - dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; + dsbuf.dwBufferBytes = sc->sn.samples / format.Format.nChannels; + if (!dsbuf.dwBufferBytes) + { + dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; + // the fast rates will need a much bigger buffer + if (format.Format.nSamplesPerSec > 48000) + dsbuf.dwBufferBytes *= 4; + } dsbuf.lpwfxFormat = (WAVEFORMATEX *)&format; memset(&dsbcaps, 0, sizeof(dsbcaps)); diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 14278b503..7b3758997 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -78,6 +78,8 @@ cvar_t _snd_mixahead = SCVARF("_snd_mixahead", "0.2", CVAR_ARCHIVE); cvar_t snd_leftisright = SCVARF("snd_leftisright", "0", CVAR_ARCHIVE); cvar_t snd_eax = SCVAR("snd_eax", "0"); cvar_t snd_speakers = SCVAR("snd_numspeakers", "2"); +cvar_t snd_buffersize = SCVAR("snd_buffersize", "0"); +cvar_t snd_samplebits = SCVARF("snd_samplebits", "16", CVAR_ARCHIVE); cvar_t snd_playersoundvolume = SCVAR("snd_localvolume", "1"); //sugested by crunch cvar_t snd_capture = SCVAR("snd_capture", "0"); @@ -181,7 +183,8 @@ static int SNDDMA_Init(soundcardinfo_t *sc, int *cardnum, int *drivernum) int st = 0; memset(sc, 0, sizeof(*sc)); - //set by a slider + + // set requested rate if (!snd_khz.value) sc->sn.speed = 22050; /* else if (snd_khz.value >= 195) @@ -201,6 +204,26 @@ static int SNDDMA_Init(soundcardinfo_t *sc, int *cardnum, int *drivernum) else sc->sn.speed = 8000; + // set requested speaker count + if (snd_speakers.value > 6) + sc->sn.numchannels = 6; + else if (snd_speakers.value > 1) + sc->sn.numchannels = (int)snd_speakers.value; + else + sc->sn.numchannels = 1; + + // set requested sample bits + if (snd_samplebits.value >= 16) + sc->sn.samplebits = 16; + else + sc->sn.samplebits = 8; + + // set requested buffer size + if (snd_buffersize.value > 0) + sc->sn.samples = (int)snd_buffersize.value * sc->sn.numchannels; + else + sc->sn.samples = 0; + sd = &drivers[*drivernum]; if (!sd->ptr) return 2; //no more cards. @@ -561,6 +584,8 @@ void S_Init (void) Cvar_Register(&snd_leftisright, "Sound controls"); Cvar_Register(&snd_eax, "Sound controls"); Cvar_Register(&snd_speakers, "Sound controls"); + Cvar_Register(&snd_buffersize, "Sound controls"); + Cvar_Register(&snd_samplebits, "Sound controls"); Cvar_Register(&snd_capture, "Sound controls"); diff --git a/engine/client/snd_linux.c b/engine/client/snd_linux.c index 4a15f27aa..72c021394 100644 --- a/engine/client/snd_linux.c +++ b/engine/client/snd_linux.c @@ -85,7 +85,7 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) if (sc->audio_fd < 0) { perror(snddev); - Con_Printf("Could not open %s\n", snddev); + Con_Printf(S_ERROR "OSS: Could not open %s\n", snddev); OSS_Shutdown(sc); return 0; } @@ -95,7 +95,7 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) if (rc < 0) { perror(snddev); - Con_Printf("Could not reset %s\n", snddev); + Con_Printf(S_ERROR "OSS: Could not reset %s\n", snddev); OSS_Shutdown(sc); return 0; } @@ -103,14 +103,14 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) if (ioctl(sc->audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1) { perror(snddev); - Con_Printf("Sound driver too old\n"); + Con_Printf(S_ERROR "OSS: Sound driver too old\n"); OSS_Shutdown(sc); return 0; } if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP)) { - Con_Printf("Sorry but your soundcard can't do this\n"); + Con_Printf(S_ERROR "OSS: Sorry but your soundcard can't do this\n"); OSS_Shutdown(sc); return 0; } @@ -118,7 +118,7 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) if (ioctl(sc->audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1) { perror("GETOSPACE"); - Con_Printf("Um, can't do GETOSPACE?\n"); + Con_Printf(S_ERROR "OSS: Um, can't do GETOSPACE?\n"); OSS_Shutdown(sc); return 0; } @@ -127,57 +127,52 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) // set sample bits & speed - s = getenv("QUAKE_SOUND_SAMPLEBITS"); - if (s) sc->sn.samplebits = atoi(s); - else if ((i = COM_CheckParm("-sndbits")) != 0) - sc->sn.samplebits = atoi(com_argv[i+1]); - if (sc->sn.samplebits != 16 && sc->sn.samplebits != 8) + ioctl(sc->audio_fd, SNDCTL_DSP_GETFMTS, &fmt); + if (!(fmt & AFMT_S16_LE) && sc->sn.samplebits > 8) + sc->sn.samplebits = 8; + else if (!(fmt & AFMT_U8)) { - ioctl(sc->audio_fd, SNDCTL_DSP_GETFMTS, &fmt); - if (fmt & AFMT_S16_LE) - sc->sn.samplebits = 16; - else if (fmt & AFMT_U8) - sc->sn.samplebits = 8; + Con_Printf(S_ERROR "OSS: No needed sample formats supported\n"); + OSS_Shutdown(sc); + return 0; } - s = getenv("QUAKE_SOUND_SPEED"); - if (s) - sc->sn.speed = atoi(s); - else if ((i = COM_CheckParm("-sndspeed")) != 0) - sc->sn.speed = atoi(com_argv[i+1]); - else - { - if (!sc->sn.speed || ioctl(sc->audio_fd, SNDCTL_DSP_SPEED, &sc->sn.speed)) //use the default - menu set value. - { //humph, default didn't work. Go for random preset ones that should work. - for (i=0 ; iaudio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break; - sc->sn.speed = tryrates[i]; + //use the default - menu set value. + if (ioctl(sc->audio_fd, SNDCTL_DSP_SPEED, &sc->sn.speed)) + { //humph, default didn't work. Go for random preset ones that should work. + for (i=0 ; iaudio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break; + if (i == (sizeof(tryrates)/4)) + { + perror(snddev); + Con_Printf(S_ERROR "OSS: Failed to obtain a suitable rate\n"); + OSS_Shutdown(sc); + return 0; } + sc->sn.speed = tryrates[i]; } - s = getenv("QUAKE_SOUND_CHANNELS"); - if (s) sc->sn.numchannels = atoi(s); - else if ((i = COM_CheckParm("-sndmono")) != 0) - sc->sn.numchannels = 1; - else if ((i = COM_CheckParm("-sndstereo")) != 0) - sc->sn.numchannels = 2; - else sc->sn.numchannels = 2; - - sc->sn.samples = info.fragstotal * info.fragsize / (sc->sn.samplebits/8); + if (sc->sn.samples > (info.fragstotal * info.fragsize * 4)) + { + Con_Printf(S_NOTICE "OSS: Enabling bigfoot's mmap hack! Hope you know what you're doing!\n"); + sc->sn.samples = info.fragstotal * info.fragsize * 4; + } + sc->sn.samples = info.fragstotal * info.fragsize; sc->sn.submission_chunk = 1; // memory map the dma buffer - sc->sn.buffer = (unsigned char *) mmap(NULL, info.fragstotal - * info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, sc->audio_fd, 0); + sc->sn.buffer = (unsigned char *) mmap(NULL, sc->sn.samples, PROT_WRITE, MAP_FILE|MAP_SHARED, sc->audio_fd, 0); if (!sc->sn.buffer) { perror(snddev); - Con_Printf("Could not mmap %s\n", snddev); + Con_Printf(S_ERROR "OSS: Could not mmap %s\n", snddev); OSS_Shutdown(sc); return 0; } + sc->sn.samples /= (sc->sn.samplebits/8); + tmp = 0; if (sc->sn.numchannels == 2) tmp = 1; @@ -185,7 +180,7 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) if (rc < 0) { perror(snddev); - Con_Printf("Could not set %s to stereo=%d", snddev, sc->sn.numchannels); + Con_Printf(S_ERROR "OSS: Could not set %s to stereo=%d\n", snddev, sc->sn.numchannels); OSS_Shutdown(sc); return 0; } @@ -198,7 +193,7 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) if (rc < 0) { perror(snddev); - Con_Printf("Could not set %s speed to %d", snddev, sc->sn.speed); + Con_Printf(S_ERROR "OSS: Could not set %s speed to %d\n", snddev, sc->sn.speed); OSS_Shutdown(sc); return 0; } @@ -210,7 +205,7 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) if (rc < 0) { perror(snddev); - Con_Printf("Could not support 16-bit data. Try 8-bit.\n"); + Con_Printf(S_ERROR "OSS: Could not support 16-bit data. Try 8-bit.\n"); OSS_Shutdown(sc); return 0; } @@ -222,7 +217,7 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) if (rc < 0) { perror(snddev); - Con_Printf("Could not support 8-bit data.\n"); + Con_Printf(S_ERROR "OSS: Could not support 8-bit data.\n"); OSS_Shutdown(sc); return 0; } @@ -230,7 +225,7 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) else { perror(snddev); - Con_Printf("%d-bit sound not supported.", sc->sn.samplebits); + Con_Printf(S_ERROR "OSS: %d-bit sound not supported.\n", sc->sn.samplebits); OSS_Shutdown(sc); return 0; } @@ -242,7 +237,7 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) if (rc < 0) { perror(snddev); - Con_Printf("Could not toggle.\n"); + Con_Printf(S_ERROR "OSS: Could not toggle.\n"); OSS_Shutdown(sc); return 0; } @@ -251,7 +246,7 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum) if (rc < 0) { perror(snddev); - Con_Printf("Could not toggle.\n"); + Con_Printf(S_ERROR "OSS: Could not toggle.\n"); OSS_Shutdown(sc); return 0; } diff --git a/engine/client/snd_win.c b/engine/client/snd_win.c index ce62c5287..3ddea1a90 100644 --- a/engine/client/snd_win.c +++ b/engine/client/snd_win.c @@ -232,7 +232,6 @@ Crappy windows multimedia base */ int WAV_InitCard (soundcardinfo_t *sc, int cardnum) { - extern cvar_t snd_khz; WAVEFORMATEX format; int i; HRESULT hr; @@ -246,8 +245,8 @@ int WAV_InitCard (soundcardinfo_t *sc, int cardnum) sc->snd_sent = 0; sc->snd_completed = 0; - sc->sn.numchannels = 2; - sc->sn.samplebits = 16; + if (sc->sn.speed > 48000) // limit waveout to 48000 until that buffer issue gets solved + sc->sn.speed = 48000; memset (&format, 0, sizeof(format)); format.wFormatTag = WAVE_FORMAT_PCM; @@ -267,7 +266,10 @@ int WAV_InitCard (soundcardinfo_t *sc, int cardnum) { if (hr != MMSYSERR_ALLOCATED) { - Con_SafePrintf ("waveOutOpen failed\n"); + if (hr == WAVERR_BADFORMAT) + Con_SafePrintf (S_ERROR "waveOutOpen failed, format not supported\n"); + else + Con_SafePrintf (S_ERROR "waveOutOpen failed, return code %i\n", hr); WAV_Shutdown (sc); return false; } @@ -278,7 +280,7 @@ int WAV_InitCard (soundcardinfo_t *sc, int cardnum) // "Sound not available", // MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY) // { - Con_SafePrintf ("waveOutOpen failure;\n" + Con_SafePrintf (S_ERROR "waveOutOpen failure;\n" " hardware already in use\nclose the app, then try using snd_restart\n"); WAV_Shutdown (sc); return false; @@ -295,14 +297,14 @@ int WAV_InitCard (soundcardinfo_t *sc, int cardnum) wh->hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, wh->gSndBufSize); if (!wh->hData) { - Con_SafePrintf ("Sound: Out of memory.\n"); + Con_SafePrintf (S_ERROR "Sound: Out of memory.\n"); WAV_Shutdown (sc); return false; } wh->lpData = GlobalLock(wh->hData); if (!wh->lpData) { - Con_SafePrintf ("Sound: Failed to lock.\n"); + Con_SafePrintf (S_ERROR "Sound: Failed to lock.\n"); WAV_Shutdown (sc); return false; } @@ -318,7 +320,7 @@ int WAV_InitCard (soundcardinfo_t *sc, int cardnum) if (wh->hWaveHdr == NULL) { - Con_SafePrintf ("Sound: Failed to Alloc header.\n"); + Con_SafePrintf (S_ERROR "Sound: Failed to Alloc header.\n"); WAV_Shutdown (sc); return false; } @@ -327,7 +329,7 @@ int WAV_InitCard (soundcardinfo_t *sc, int cardnum) if (wh->lpWaveHdr == NULL) { - Con_SafePrintf ("Sound: Failed to lock header.\n"); + Con_SafePrintf (S_ERROR "Sound: Failed to lock header.\n"); WAV_Shutdown (sc); return false; } @@ -343,7 +345,7 @@ int WAV_InitCard (soundcardinfo_t *sc, int cardnum) if (waveOutPrepareHeader(wh->hWaveOut, wh->lpWaveHdr+i, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) { - Con_SafePrintf ("Sound: failed to prepare wave headers\n"); + Con_SafePrintf (S_ERROR "Sound: failed to prepare wave headers\n"); WAV_Shutdown (sc); return false; }