From: black Date: Thu, 15 Jul 2004 13:01:48 +0000 (+0000) Subject: -Added SDL sound support (still needs a bit debugging, though). X-Git-Tag: xonotic-v0.1.0preview~5791 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=6068115093a24d125506e021ebc144d720553583 -Added SDL sound support (still needs a bit debugging, though). git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4271 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/snd_sdl.c b/snd_sdl.c new file mode 100644 index 00000000..45b359ac --- /dev/null +++ b/snd_sdl.c @@ -0,0 +1,205 @@ +/* +Copyright (C) 2004 Andreas Kirsch + +This program 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. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include "quakedef.h" +#include + +/* +Info: +One SDL sample consists of x channel samples +The mixer supposes that the driver has one channel entry/sample though it has x channels/sample +like the SDL +*/ + +#define AUDIO_SDL_SAMPLES 4096 +#define AUDIO_LOCALFACTOR 4 + +typedef struct AudioState_s +{ + int width; + int size; + int pos; + void *buffer; +} AudioState; + + +extern mempool_t *snd_mempool; +static AudioState as; + +static void Buffer_Callback(void *userdata, Uint8 *stream, int len); + +/* +================== +S_BlockSound +================== +*/ +void S_BlockSound( void ) +{ + snd_blocked++; + + if( snd_blocked == 1 ) + SDL_PauseAudio( true ); +} + + +/* +================== +S_UnblockSound +================== +*/ +void S_UnblockSound( void ) +{ + snd_blocked--; + if( snd_blocked == 0 ) + SDL_PauseAudio( false ); +} + + +/* +================== +SNDDMA_Init + +Try to find a sound device to mix for. +Returns false if nothing is found. +================== +*/ + +qboolean SNDDMA_Init(void) +{ + SDL_AudioSpec spec; + int i; + + // Init the SDL Audio subsystem + if( SDL_InitSubSystem( SDL_INIT_AUDIO ) ) { + Con_SafePrint( "Initializing the SDL Audio subsystem failed!\n" ); + return false; + } + + // Init the shm structure + memset( (void*) shm, 0, sizeof(*shm) ); + + shm->format.channels = 2; //stereo + shm->format.width = 2; + + i = COM_CheckParm( "-sndspeed" ); + if( i && i != ( com_argc - 1 ) ) + shm->format.speed = atoi( com_argv[ i+1 ] ); + else + shm->format.speed = 44100; + + shm->samplepos = 0; + shm->samples = AUDIO_SDL_SAMPLES * AUDIO_LOCALFACTOR; + shm->bufferlength = shm->samples * shm->format.width; + shm->buffer = Mem_Alloc( snd_mempool, shm->bufferlength ); + + // Init the as structure + as.buffer = shm->buffer; + as.width = shm->format.width; + as.pos = 0; + as.size = shm->bufferlength; + + // Init the SDL Audio subsystem + spec.callback = Buffer_Callback; + spec.channels = shm->format.channels; + spec.format = AUDIO_S16LSB; + spec.freq = shm->format.speed; + spec.userdata = NULL; + spec.samples = AUDIO_SDL_SAMPLES; + + if( SDL_OpenAudio( &spec, NULL ) ) { + Con_SafePrint( "Failed to open the audio device!\n" ); + Con_DPrintf( + "Audio Specification:\n" + "\tChannels : %i\n" + "\tFormat : %x\n" + "\tFrequency : %i\n" + "\tBuffersize: %i Bytes(%i Samples)\n", + spec.channels, spec.format, spec.freq, shm->bufferlength , spec.samples ); + Mem_Free( shm->buffer ); + return false; + } + + SDL_PauseAudio( false ); + + return true; +} + +/* +============== +SNDDMA_GetDMAPos + +return the current sample position (in mono samples read) +inside the recirculating dma buffer, so the mixing code will know +how many sample are required to fill it up. +=============== +*/ +int SNDDMA_GetDMAPos(void) +{ + shm->samplepos = (as.pos / as.width) % shm->samples; + return shm->samplepos; +} + +/* +============== +SNDDMA_Submit + +Send sound to device if buffer isn't really the dma buffer +=============== +*/ +void SNDDMA_Submit(void) +{ + +} + +/* +============== +SNDDMA_Shutdown + +Reset the sound device for exiting +=============== +*/ +void SNDDMA_Shutdown(void) +{ + SDL_CloseAudio(); + Mem_Free( as.buffer ); +} + +void *S_LockBuffer(void) +{ + SDL_LockAudio(); + return shm->buffer; +} + +void S_UnlockBuffer(void) +{ + SDL_UnlockAudio(); +} + +static void Buffer_Callback(void *userdata, Uint8 *stream, int len) +{ + if( len > as.size ) + len = as.size; + if( len > as.size - as.pos ) { + memcpy( stream, (Uint8*) as.buffer + as.pos, as.size - as.pos ); + len -= as.size - as.pos; + as.pos = 0; + } + memcpy( stream, (Uint8*) as.buffer + as.pos, len ); + as.pos = (as.pos + len) % as.size; +} +