diff --git a/source/snd_sdl.c b/source/snd_sdl.c index 75f09c8..5ea007a 100644 --- a/source/snd_sdl.c +++ b/source/snd_sdl.c @@ -43,6 +43,7 @@ #include "console.h" #include "qargs.h" #include "sound.h" +#include "sys.h" static dma_t the_shm; static int snd_inited; @@ -53,11 +54,27 @@ extern int desired_bits; static void paint_audio (void *unused, Uint8 * stream, int len) { + int streamsamples; + int sampleposbytes; + int samplesbytes; + if (shm) { - shm->buffer = stream; - shm->samplepos += len / (shm->samplebits / 8); - // Check for samplepos overflow? - S_PaintChannels (shm->samplepos); + streamsamples = len / (shm->samplebits / 8); + sampleposbytes = shm->samplepos * (shm->samplebits / 8); + samplesbytes = shm->samples * (shm->samplebits / 8); + + shm->samplepos += streamsamples; + while (shm->samplepos >= shm->samples) + shm->samplepos -= shm->samples; + S_PaintChannels (soundtime + streamsamples); + + if (shm->samplepos + streamsamples <= shm->samples) + memcpy (stream, shm->buffer + sampleposbytes, len); + else { + memcpy (stream, shm->buffer + sampleposbytes, samplesbytes - sampleposbytes); + memcpy (stream + samplesbytes - sampleposbytes, shm->buffer, len - (samplesbytes - sampleposbytes)); + } + soundtime += streamsamples; } } @@ -85,7 +102,7 @@ SNDDMA_Init (void) return 0; } desired.channels = 2; - desired.samples = 512; + desired.samples = 1024; desired.callback = paint_audio; /* Open the audio device */ @@ -119,6 +136,7 @@ SNDDMA_Init (void) memcpy (&obtained, &desired, sizeof (desired)); break; } + SDL_LockAudio(); SDL_PauseAudio (0); /* Fill the audio DMA information block */ @@ -127,10 +145,14 @@ SNDDMA_Init (void) shm->samplebits = (obtained.format & 0xFF); shm->speed = obtained.freq; shm->channels = obtained.channels; - shm->samples = obtained.samples * shm->channels; + shm->samples = obtained.samples * 16; shm->samplepos = 0; shm->submission_chunk = 1; - shm->buffer = NULL; + shm->buffer = calloc(shm->samples * (shm->samplebits / 8), 1); + if (!shm->buffer) + { + Sys_Error ("Failed to allocate buffer for sound!\n"); + } snd_inited = 1; return 1; @@ -146,8 +168,11 @@ void SNDDMA_Shutdown (void) { if (snd_inited) { + SDL_PauseAudio (1); + SDL_UnlockAudio (); SDL_CloseAudio (); snd_inited = 0; + shm = NULL; } } @@ -161,4 +186,6 @@ SNDDMA_Shutdown (void) void SNDDMA_Submit (void) { + SDL_UnlockAudio(); + SDL_LockAudio(); }