From 2fb28c32491ce770550ebd59e0e9f222b4378b9a Mon Sep 17 00:00:00 2001 From: molivier Date: Sat, 10 Jun 2006 18:22:20 +0000 Subject: [PATCH] Added snd_channellayout to configure the speaker layout dynamically (0: auto, 1: standard, 2: ALSA) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6458 d7cf8633-e32d-0410-b094-e92efae38249 --- snd_alsa.c | 3 ++- snd_main.c | 73 ++++++++++++++++++++++++++++++++++++------------------ snd_main.h | 8 ++++-- snd_oss.c | 10 +++----- snd_sdl.c | 8 ++---- 5 files changed, 63 insertions(+), 39 deletions(-) diff --git a/snd_alsa.c b/snd_alsa.c index e4a9ffe0..23d66bd9 100644 --- a/snd_alsa.c +++ b/snd_alsa.c @@ -201,7 +201,8 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) snd_renderbuffer = Snd_CreateRingBuffer(requested, 0, NULL); expected_delay = 0; alsasoundtime = 0; - alsaspeakerlayout = true; + if (snd_channellayout.integer == SND_CHANNELLAYOUT_AUTO) + Cvar_SetValueQuick (&snd_channellayout, SND_CHANNELLAYOUT_ALSA); return true; diff --git a/snd_main.c b/snd_main.c index 13c3f725..53b89724 100644 --- a/snd_main.c +++ b/snd_main.c @@ -54,7 +54,7 @@ speakerlayout_t; static speakerlayout_t snd_speakerlayout; // Our speaker layouts are based on ALSA. They differ from those -// Win32 APIs and Mac OS X use when there's more than 4 channels. +// Win32 and Mac OS X APIs use when there's more than 4 channels. // (rear left + rear right, and front center + LFE are swapped). #define SND_SPEAKERLAYOUTS (sizeof(snd_speakerlayouts) / sizeof(snd_speakerlayouts[0])) static const speakerlayout_t snd_speakerlayouts[] = @@ -155,10 +155,11 @@ static sfx_t *known_sfx = NULL; static qboolean sound_spatialized = false; qboolean simsound = false; -qboolean alsaspeakerlayout = false; int snd_blocked = 0; -static int current_swapstereo = 0; +static int current_swapstereo = false; +static int current_channellayout = SND_CHANNELLAYOUT_AUTO; +static int current_channellayout_used = SND_CHANNELLAYOUT_AUTO; // Cvars declared in sound.h (part of the sound API) cvar_t bgmvolume = {CVAR_SAVE, "bgmvolume", "1", "volume of background music (such as CD music or replacement files such as sound/cdtracks/track002.ogg)"}; @@ -170,6 +171,7 @@ cvar_t snd_staticvolume = {CVAR_SAVE, "snd_staticvolume", "1", "volume of ambien cvar_t _snd_mixahead = {CVAR_SAVE, "_snd_mixahead", "0.1", "how much sound to mix ahead of time"}; cvar_t snd_streaming = { CVAR_SAVE, "snd_streaming", "1", "enables keeping compressed ogg sound files compressed, decompressing them only as needed, otherwise they will be decompressed completely at load (may use a lot of memory)"}; cvar_t snd_swapstereo = {CVAR_SAVE, "snd_swapstereo", "0", "swaps left/right speakers for old ISA soundblaster cards"}; +cvar_t snd_channellayout = {0, "snd_channellayout", "0", "channel layout. Can be 0 (auto - snd_restart needed), 1 (standard layout), or 2 (ALSA layout)"}; // Local cvars static cvar_t nosound = {0, "nosound", "0", "disables sound"}; @@ -350,18 +352,19 @@ static qboolean S_ChooseCheaperFormat (snd_format_t* format, qboolean fixed_spee #define SWAP_LISTENERS(l1, l2, tmpl) { tmpl = (l1); (l1) = (l2); (l2) = tmpl; } -void S_SetSpeakerLayout (void) +static void S_SetChannelLayout (void) { unsigned int i; listener_t swaplistener; listener_t *listeners; + int layout; for (i = 0; i < SND_SPEAKERLAYOUTS; i++) if (snd_speakerlayouts[i].channels == snd_renderbuffer->format.channels) break; if (i >= SND_SPEAKERLAYOUTS) { - Con_Printf("S_SetSpeakerLayout: Can't find the speaker layout for %hu channels. Defaulting to mono output\n", + Con_Printf("S_SetChannelLayout: can't find the speaker layout for %hu channels. Defaulting to mono output\n", snd_renderbuffer->format.channels); i = SND_SPEAKERLAYOUTS - 1; } @@ -392,13 +395,41 @@ void S_SetSpeakerLayout (void) } } - // Convert our layout (= ALSA) to Win32/CoreAudio layout if necessary - if (!alsaspeakerlayout && - (snd_speakerlayout.channels == 6 || snd_speakerlayout.channels == 8)) + // Sanity check + if (snd_channellayout.integer < SND_CHANNELLAYOUT_AUTO || + snd_channellayout.integer > SND_CHANNELLAYOUT_ALSA) + Cvar_SetValueQuick (&snd_channellayout, SND_CHANNELLAYOUT_STANDARD); + + if (snd_channellayout.integer == SND_CHANNELLAYOUT_AUTO) { - SWAP_LISTENERS(listeners[2], listeners[4], swaplistener); - SWAP_LISTENERS(listeners[3], listeners[5], swaplistener); + // If we're in the sound engine initialization + if (current_channellayout_used == SND_CHANNELLAYOUT_AUTO) + { + layout = SND_CHANNELLAYOUT_STANDARD; + Cvar_SetValueQuick (&snd_channellayout, layout); + } + else + layout = current_channellayout_used; } + else + layout = snd_channellayout.integer; + + // Convert our layout (= ALSA) to the standard layout if necessary + if (snd_speakerlayout.channels == 6 || snd_speakerlayout.channels == 8) + { + if (layout == SND_CHANNELLAYOUT_STANDARD) + { + SWAP_LISTENERS(listeners[2], listeners[4], swaplistener); + SWAP_LISTENERS(listeners[3], listeners[5], swaplistener); + } + + Con_Printf("S_SetChannelLayout: using %s speaker layout for 3D sound\n", + (layout == SND_CHANNELLAYOUT_ALSA) ? "ALSA" : "standard"); + } + + current_swapstereo = snd_swapstereo.integer; + current_channellayout = snd_channellayout.integer; + current_channellayout_used = layout; } @@ -535,7 +566,6 @@ void S_Startup (void) chosen_fmt.speed, chosen_fmt.width * 8, chosen_fmt.channels); - alsaspeakerlayout = false; memset(&suggest_fmt, 0, sizeof(suggest_fmt)); accepted = SndSys_Init(&chosen_fmt, &suggest_fmt); @@ -575,15 +605,14 @@ void S_Startup (void) Con_Printf("Sound format: %dHz, %d channels, %d bits per sample\n", chosen_fmt.speed, chosen_fmt.channels, chosen_fmt.width * 8); - if (chosen_fmt.channels > 4) - Con_Printf("Using %s speaker layout for 3D sound\n", - alsaspeakerlayout ? "ALSA" : "standard"); - // Update the cvars snd_speed.integer = chosen_fmt.speed; snd_width.integer = chosen_fmt.width; snd_channels.integer = chosen_fmt.channels; + current_channellayout_used = SND_CHANNELLAYOUT_AUTO; + S_SetChannelLayout(); + snd_starttime = realtime; // If the sound module has already run, add an extra time to make sure @@ -603,9 +632,6 @@ void S_Startup (void) extrasoundtime = 0; snd_renderbuffer->startframe = soundtime; snd_renderbuffer->endframe = soundtime; - - S_SetSpeakerLayout(); - current_swapstereo = snd_swapstereo.integer; } void S_Shutdown(void) @@ -678,6 +704,7 @@ void S_Init(void) Cvar_RegisterVariable(&snd_show); Cvar_RegisterVariable(&_snd_mixahead); Cvar_RegisterVariable(&snd_swapstereo); // for people with backwards sound wiring + Cvar_RegisterVariable(&snd_channellayout); Cvar_SetValueQuick(&snd_initialized, true); @@ -1388,12 +1415,10 @@ void S_Update(const matrix4x4_t *listenermatrix) if (snd_blocked > 0 && !cls.capturevideo_soundfile) return; - // If snd_swapstereo has changed, recompute the speaker layout - if (current_swapstereo != snd_swapstereo.integer) - { - current_swapstereo = snd_swapstereo.integer; - S_SetSpeakerLayout(); - } + // If snd_swapstereo or snd_channellayout has changed, recompute the channel layout + if (current_swapstereo != snd_swapstereo.integer || + current_channellayout != snd_channellayout.integer) + S_SetChannelLayout(); Matrix4x4_Invert_Simple(&basematrix, listenermatrix); Matrix4x4_OriginFromMatrix(listenermatrix, listener_origin); diff --git a/snd_main.h b/snd_main.h index 82c34727..9018f4eb 100644 --- a/snd_main.h +++ b/snd_main.h @@ -126,6 +126,12 @@ extern cvar_t _snd_mixahead; extern cvar_t snd_swapstereo; extern cvar_t snd_streaming; +#define SND_CHANNELLAYOUT_AUTO 0 +#define SND_CHANNELLAYOUT_STANDARD 1 +#define SND_CHANNELLAYOUT_ALSA 2 +extern cvar_t snd_channellayout; + + extern int snd_blocked; // counter. When > 0, we stop submitting sound to the audio device extern mempool_t *snd_mempool; @@ -135,8 +141,6 @@ extern mempool_t *snd_mempool; // Used for isolating performance in the renderer. extern qboolean simsound; -extern qboolean alsaspeakerlayout; - // ==================================================================== // Architecture-independent functions diff --git a/snd_oss.c b/snd_oss.c index 2693e51b..d1bc5d12 100644 --- a/snd_oss.c +++ b/snd_oss.c @@ -162,12 +162,10 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) SndSys_Shutdown(); return false; } - -#ifdef __linux__ - alsaspeakerlayout = true; -#else - alsaspeakerlayout = false; -#endif + + // TOCHECK: I'm not sure which channel layout OSS uses for 5.1 and 7.1 + if (snd_channellayout.integer == SND_CHANNELLAYOUT_AUTO) + Cvar_SetValueQuick (&snd_channellayout, SND_CHANNELLAYOUT_ALSA); old_osstime = 0; osssoundtime = 0; diff --git a/snd_sdl.c b/snd_sdl.c index acd2ba39..d30431c5 100644 --- a/snd_sdl.c +++ b/snd_sdl.c @@ -141,12 +141,8 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested) } snd_renderbuffer = Snd_CreateRingBuffer(requested, 0, NULL); - -#ifdef __linux__ - alsaspeakerlayout = true; -#else - alsaspeakerlayout = false; -#endif + if (snd_channellayout.integer == SND_CHANNELLAYOUT_AUTO) + Cvar_SetValueQuick (&snd_channellayout, SND_CHANNELLAYOUT_ALSA); sdlaudiotime = 0; SDL_PauseAudio( false ); -- 2.39.2