diff options
author | Tim Angus <tim@ngus.net> | 2005-12-10 03:08:56 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2005-12-10 03:08:56 +0000 |
commit | 3b447421efc76ba76fbdae62f893fc6916af5433 (patch) | |
tree | 035963614a2e6333b6d38667b5142c2c0e7863c7 /ioq3-r437/src/unix/sdl_snd.c | |
parent | 08446c16acbbb9a9d12fccb21e27cfa29d076e77 (diff) |
* Well I fucked that up then...
Diffstat (limited to 'ioq3-r437/src/unix/sdl_snd.c')
-rw-r--r-- | ioq3-r437/src/unix/sdl_snd.c | 362 |
1 files changed, 0 insertions, 362 deletions
diff --git a/ioq3-r437/src/unix/sdl_snd.c b/ioq3-r437/src/unix/sdl_snd.c deleted file mode 100644 index 20d4bfd5..00000000 --- a/ioq3-r437/src/unix/sdl_snd.c +++ /dev/null @@ -1,362 +0,0 @@ -#if USE_SDL_SOUND - -/* - * SDL implementation for Quake 3: Arena's GPL source release. - * - * This is a replacement of the Linux/OpenSoundSystem code with - * an SDL backend, since it allows us to trivially point just about any - * existing 2D audio backend known to man on any platform at the code, - * plus it benefits from all of SDL's tapdancing to support buggy drivers, - * etc, and gets us free ALSA support, too. - * - * This is the best idea for a direct modernization of the Linux sound code - * in Quake 3. However, it would be nice to replace this with true 3D - * positional audio, compliments of OpenAL... - * - * Written by Ryan C. Gordon (icculus@icculus.org). Please refer to - * http://icculus.org/quake3/ for the latest version of this code. - * - * Patches and comments are welcome at the above address. - * - * I cut-and-pasted this from linux_snd.c, and moved it to SDL line-by-line. - * There is probably some cruft that could be removed here. - * - * You should define USE_SDL=1 and then add this to the makefile. - * USE_SDL will disable the Open Sound System target. - */ - -/* -Original copyright on Q3A sources: -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Quake III Arena source code; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ - -#include <stdlib.h> -#include <stdio.h> - -#include "SDL.h" - -#include "../qcommon/q_shared.h" -#include "../client/snd_local.h" - -qboolean snd_inited = qfalse; - -cvar_t *s_sdlBits; -cvar_t *s_sdlSpeed; -cvar_t *s_sdlChannels; -cvar_t *s_sdlDevSamps; -cvar_t *s_sdlMixSamps; - -static qboolean use_custom_memset = qfalse; - -/* -=============== -Snd_Memset - -https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=371 - -<TTimo> some shitty mess with DMA buffers -<TTimo> the mmap'ing permissions were write only -<TTimo> and glibc optimized for mmx would do memcpy with a prefetch and a read -<TTimo> causing segfaults -<TTimo> some other systems would not let you mmap the DMA with read permissions -<TTimo> so I think I ended up attempting opening with read/write, then try write only -<TTimo> and use my own copy instead of the glibc crap -=============== -*/ - -#ifdef Snd_Memset -#undef Snd_Memset -#endif -void Snd_Memset (void* dest, const int val, const size_t count) -{ - int *pDest; - int i, iterate; - - if (!use_custom_memset) - { - Com_Memset(dest,val,count); - return; - } - iterate = count / sizeof(int); - pDest = (int*)dest; - for(i=0; i<iterate; i++) - { - pDest[i] = val; - } -} - -/* The audio callback. All the magic happens here. */ -static int dmapos = 0; -static int dmasize = 0; - -/* -=============== -sdl_audio_callback -=============== -*/ -static void sdl_audio_callback(void *userdata, Uint8 *stream, int len) -{ - int pos = (dmapos * (dma.samplebits/8)); - if (pos >= dmasize) - dmapos = pos = 0; - - if (!snd_inited) /* shouldn't happen, but just in case... */ - { - memset(stream, '\0', len); - return; - } - else - { - int tobufend = dmasize - pos; /* bytes to buffer's end. */ - int len1 = len; - int len2 = 0; - - if (len1 > tobufend) - { - len1 = tobufend; - len2 = len - len1; - } - memcpy(stream, dma.buffer + pos, len1); - if (len2 <= 0) - dmapos += (len1 / (dma.samplebits/8)); - else /* wraparound? */ - { - memcpy(stream+len1, dma.buffer, len2); - dmapos = (len2 / (dma.samplebits/8)); - } - } - - if (dmapos >= dmasize) - dmapos = 0; -} - -static struct -{ - Uint16 enumFormat; - char *stringFormat; -} formatToStringTable[ ] = -{ - { AUDIO_U8, "AUDIO_U8" }, - { AUDIO_S8, "AUDIO_S8" }, - { AUDIO_U16LSB, "AUDIO_U16LSB" }, - { AUDIO_S16LSB, "AUDIO_S16LSB" }, - { AUDIO_U16MSB, "AUDIO_U16MSB" }, - { AUDIO_S16MSB, "AUDIO_S16MSB" } -}; - -static int formatToStringTableSize = - sizeof( formatToStringTable ) / sizeof( formatToStringTable[ 0 ] ); - -/* -=============== -print_audiospec -=============== -*/ -static void print_audiospec(const char *str, const SDL_AudioSpec *spec) -{ - int i; - char *fmt = NULL; - - Com_Printf("%s:\n", str); - - for( i = 0; i < formatToStringTableSize; i++ ) { - if( spec->format == formatToStringTable[ i ].enumFormat ) { - fmt = formatToStringTable[ i ].stringFormat; - } - } - - if( fmt ) { - Com_Printf( " Format: %s\n", fmt ); - } else { - Com_Printf( " Format: " S_COLOR_RED "UNKNOWN\n", fmt ); - } - - Com_Printf( " Freq: %d\n", (int) spec->freq ); - Com_Printf( " Samples: %d\n", (int) spec->samples ); - Com_Printf( " Channels: %d\n", (int) spec->channels ); -} - -/* -=============== -SNDDMA_Init -=============== -*/ -qboolean SNDDMA_Init(void) -{ - char drivername[128]; - SDL_AudioSpec desired; - SDL_AudioSpec obtained; - int tmp; - - if (snd_inited) - return qtrue; - - Com_Printf("Initializing SDL audio driver...\n"); - - if (!s_sdlBits) { - s_sdlBits = Cvar_Get("s_sdlBits", "16", CVAR_ARCHIVE); - s_sdlSpeed = Cvar_Get("s_sdlSpeed", "0", CVAR_ARCHIVE); - s_sdlChannels = Cvar_Get("s_sdlChannels", "2", CVAR_ARCHIVE); - s_sdlDevSamps = Cvar_Get("s_sdlDevSamps", "0", CVAR_ARCHIVE); - s_sdlMixSamps = Cvar_Get("s_sdlMixSamps", "0", CVAR_ARCHIVE); - } - - if (!SDL_WasInit(SDL_INIT_AUDIO)) - { - if (SDL_Init(SDL_INIT_AUDIO) == -1) - { - Com_Printf("SDL_Init(SDL_INIT_AUDIO) failed: %s\n", SDL_GetError()); - return qfalse; - } - } - - if (SDL_AudioDriverName(drivername, sizeof (drivername)) == NULL) - strcpy(drivername, "(UNKNOWN)"); - Com_Printf("SDL audio driver is \"%s\".\n", drivername); - - memset(&desired, '\0', sizeof (desired)); - memset(&obtained, '\0', sizeof (obtained)); - - tmp = ((int) s_sdlBits->value); - if ((tmp != 16) && (tmp != 8)) - tmp = 16; - - desired.freq = (int) s_sdlSpeed->value; - if(!desired.freq) desired.freq = 22050; - desired.format = ((tmp == 16) ? AUDIO_S16SYS : AUDIO_U8); - - // I dunno if this is the best idea, but I'll give it a try... - // should probably check a cvar for this... - if (s_sdlDevSamps->value) - desired.samples = s_sdlDevSamps->value; - else - { - // just pick a sane default. - if (desired.freq <= 11025) - desired.samples = 256; - else if (desired.freq <= 22050) - desired.samples = 512; - else if (desired.freq <= 44100) - desired.samples = 1024; - else - desired.samples = 2048; // (*shrug*) - } - - desired.channels = (int) s_sdlChannels->value; - desired.callback = sdl_audio_callback; - - if (SDL_OpenAudio(&desired, &obtained) == -1) - { - Com_Printf("SDL_OpenAudio() failed: %s\n", SDL_GetError()); - SDL_QuitSubSystem(SDL_INIT_AUDIO); - return qfalse; - } // if - - print_audiospec("SDL_AudioSpec", &obtained); - - // dma.samples needs to be big, or id's mixer will just refuse to - // work at all; we need to keep it significantly bigger than the - // amount of SDL callback samples, and just copy a little each time - // the callback runs. - // 32768 is what the OSS driver filled in here on my system. I don't - // know if it's a good value overall, but at least we know it's - // reasonable...this is why I let the user override. - tmp = s_sdlMixSamps->value; - if (!tmp) - tmp = (obtained.samples * obtained.channels) * 10; - - if (tmp & (tmp - 1)) // not a power of two? Seems to confuse something. - { - int val = 1; - while (val < tmp) - val <<= 1; - - tmp = val; - } - - dmapos = 0; - dma.samplebits = obtained.format & 0xFF; // first byte of format is bits. - dma.channels = obtained.channels; - dma.samples = tmp; - dma.submission_chunk = 1; - dma.speed = obtained.freq; - dmasize = (dma.samples * (dma.samplebits/8)); - dma.buffer = calloc(1, dmasize); - - Com_Printf("Starting SDL audio callback...\n"); - SDL_PauseAudio(0); // start callback. - - Com_Printf("SDL audio initialized.\n"); - snd_inited = qtrue; - return qtrue; -} - -/* -=============== -SNDDMA_GetDMAPos -=============== -*/ -int SNDDMA_GetDMAPos(void) -{ - return dmapos; -} - -/* -=============== -SNDDMA_Shutdown -=============== -*/ -void SNDDMA_Shutdown(void) -{ - Com_Printf("Closing SDL audio device...\n"); - SDL_PauseAudio(1); - SDL_CloseAudio(); - SDL_QuitSubSystem(SDL_INIT_AUDIO); - free(dma.buffer); - dma.buffer = NULL; - dmapos = dmasize = 0; - snd_inited = qfalse; - Com_Printf("SDL audio device shut down.\n"); -} - -/* -=============== -SNDDMA_Submit - -Send sound to device if buffer isn't really the dma buffer -=============== -*/ -void SNDDMA_Submit(void) -{ - SDL_UnlockAudio(); -} - -/* -=============== -SNDDMA_BeginPainting -=============== -*/ -void SNDDMA_BeginPainting (void) -{ - SDL_LockAudio(); -} - -#endif // USE_SDL_SOUND |