summaryrefslogtreecommitdiff
path: root/ioq3-r437/src/unix/sdl_snd.c
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2005-12-10 03:08:56 +0000
committerTim Angus <tim@ngus.net>2005-12-10 03:08:56 +0000
commit3b447421efc76ba76fbdae62f893fc6916af5433 (patch)
tree035963614a2e6333b6d38667b5142c2c0e7863c7 /ioq3-r437/src/unix/sdl_snd.c
parent08446c16acbbb9a9d12fccb21e27cfa29d076e77 (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.c362
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