summaryrefslogtreecommitdiff
path: root/src/unix/sdl2/sound.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/unix/sdl2/sound.c')
-rw-r--r--src/unix/sdl2/sound.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/unix/sdl2/sound.c b/src/unix/sdl2/sound.c
new file mode 100644
index 0000000..a38cb29
--- /dev/null
+++ b/src/unix/sdl2/sound.c
@@ -0,0 +1,159 @@
+/*
+Copyright (C) 2007-2008 Andrey Nazarov
+
+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.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+//
+// snd_sdl.c
+//
+
+#include "shared/shared.h"
+#include "common/zone.h"
+#include "client/sound/dma.h"
+#include <SDL.h>
+
+static void Filler(void *userdata, Uint8 *stream, int len)
+{
+ int size = dma.samples << 1;
+ int pos = dma.samplepos << 1;
+ int wrapped = pos + len - size;
+
+ if (wrapped < 0) {
+ memcpy(stream, dma.buffer + pos, len);
+ dma.samplepos += len >> 1;
+ } else {
+ int remaining = size - pos;
+ memcpy(stream, dma.buffer + pos, remaining);
+ memcpy(stream + remaining, dma.buffer, wrapped);
+ dma.samplepos = wrapped >> 1;
+ }
+}
+
+static void Shutdown(void)
+{
+ Com_Printf("Shutting down SDL audio.\n");
+
+ SDL_CloseAudio();
+ if (SDL_WasInit(SDL_INIT_EVERYTHING) == SDL_INIT_AUDIO) {
+ SDL_Quit();
+ } else {
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ }
+
+ if (dma.buffer) {
+ Z_Free(dma.buffer);
+ dma.buffer = NULL;
+ }
+}
+
+static sndinitstat_t Init(void)
+{
+ SDL_AudioSpec desired, obtained;
+ int ret;
+
+ if (SDL_WasInit(SDL_INIT_EVERYTHING) == 0) {
+ ret = SDL_Init(SDL_INIT_AUDIO);
+ } else {
+ ret = SDL_InitSubSystem(SDL_INIT_AUDIO);
+ }
+ if (ret == -1) {
+ Com_EPrintf("Couldn't initialize SDL audio: %s\n", SDL_GetError());
+ return SIS_FAILURE;
+ }
+
+ memset(&desired, 0, sizeof(desired));
+ switch (s_khz->integer) {
+ case 48:
+ desired.freq = 48000;
+ break;
+ case 44:
+ desired.freq = 44100;
+ break;
+ case 22:
+ desired.freq = 22050;
+ break;
+ default:
+ desired.freq = 11025;
+ break;
+ }
+
+ desired.format = AUDIO_S16LSB;
+ desired.samples = 512;
+ desired.channels = 2;
+ desired.callback = Filler;
+ ret = SDL_OpenAudio(&desired, &obtained);
+ if (ret == -1) {
+ Com_EPrintf("Couldn't open SDL audio: %s\n", SDL_GetError());
+ return SIS_FAILURE;
+ }
+
+ if (obtained.format != AUDIO_S16LSB) {
+ Com_EPrintf("SDL audio format %d unsupported.\n", obtained.format);
+ goto fail;
+ }
+
+ if (obtained.channels != 1 && obtained.channels != 2) {
+ Com_EPrintf("SDL audio channels %d unsupported.\n", obtained.channels);
+ goto fail;
+ }
+
+ dma.speed = obtained.freq;
+ dma.channels = obtained.channels;
+ dma.samples = 0x8000 * obtained.channels;
+ dma.submission_chunk = 1;
+ dma.samplebits = 16;
+ dma.buffer = Z_Mallocz(dma.samples * 2);
+ dma.samplepos = 0;
+
+ Com_Printf("Using SDL audio driver: %s\n", SDL_GetCurrentAudioDriver());
+
+ SDL_PauseAudio(0);
+
+ return SIS_SUCCESS;
+
+fail:
+ Shutdown();
+ return SIS_FAILURE;
+}
+
+static void BeginPainting(void)
+{
+ SDL_LockAudio();
+}
+
+static void Submit(void)
+{
+ SDL_UnlockAudio();
+}
+
+static void Activate(qboolean active)
+{
+ if (active) {
+ SDL_PauseAudio(0);
+ } else {
+ SDL_PauseAudio(1);
+ }
+}
+
+void WAVE_FillAPI(snddmaAPI_t *api)
+{
+ api->Init = Init;
+ api->Shutdown = Shutdown;
+ api->BeginPainting = BeginPainting;
+ api->Submit = Submit;
+ api->Activate = Activate;
+}
+