Attempt to fix speaker layout for 5.1 and 7.1 sound, on Windows and Mac OS X; the...
authormolivier <molivier@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 6 Jun 2006 06:21:47 +0000 (06:21 +0000)
committermolivier <molivier@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 6 Jun 2006 06:21:47 +0000 (06:21 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6421 d7cf8633-e32d-0410-b094-e92efae38249

snd_alsa.c
snd_main.c
snd_main.h
snd_mix.c
snd_oss.c
snd_sdl.c

index 2e6b8f3..c9065bd 100644 (file)
@@ -201,6 +201,7 @@ 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;
        
        return true;
 
index 38ff9d1..06dc218 100644 (file)
@@ -53,6 +53,9 @@ 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.
+// (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[] =
 {
@@ -152,8 +155,10 @@ 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;
 
 // 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)"};
@@ -343,6 +348,60 @@ 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)
+{
+       unsigned int i;
+       listener_t swaplistener;
+       listener_t *listeners;
+
+       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",
+                                  snd_renderbuffer->format.channels);
+               i = SND_SPEAKERLAYOUTS - 1;
+       }
+
+       snd_speakerlayout = snd_speakerlayouts[i];
+       listeners = snd_speakerlayout.listeners;
+
+       // Swap the left and right channels if snd_swapstereo is set
+       if (snd_swapstereo.integer)
+       {
+               switch (snd_speakerlayout.channels)
+               {
+                       case 8:
+                               SWAP_LISTENERS(listeners[6], listeners[7], swaplistener);
+                               // no break
+                       case 4:
+                       case 6:
+                               SWAP_LISTENERS(listeners[2], listeners[3], swaplistener);
+                               // no break
+                       case 2:
+                               SWAP_LISTENERS(listeners[0], listeners[1], swaplistener);
+                               break;
+
+                       default:
+                       case 1:
+                               // Nothing to do
+                               break;
+               }
+       }
+
+       // Convert our layout (= ALSA) to Win32/CoreAudio layout if necessary
+       if (!alsaspeakerlayout &&
+               (snd_speakerlayout.channels == 6 || snd_speakerlayout.channels == 8))
+       {
+               SWAP_LISTENERS(listeners[2], listeners[4], swaplistener);
+               SWAP_LISTENERS(listeners[3], listeners[5], swaplistener);
+       }
+}
+
+
 void S_Startup (void)
 {
        qboolean fixed_speed, fixed_width, fixed_channels;
@@ -350,7 +409,6 @@ void S_Startup (void)
        static snd_format_t prev_render_format = {0, 0, 0};
        const char* env;
        int i;
-       unsigned int layout_id;
 
        if (!snd_initialized.integer)
                return;
@@ -477,6 +535,7 @@ 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);
 
@@ -516,6 +575,10 @@ 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;
@@ -541,18 +604,8 @@ void S_Startup (void)
        snd_renderbuffer->startframe = soundtime;
        snd_renderbuffer->endframe = soundtime;
 
-       // select speaker layout
-       for (layout_id = 0; layout_id < SND_SPEAKERLAYOUTS; layout_id++)
-               if (snd_speakerlayouts[layout_id].channels == snd_renderbuffer->format.channels)
-                       break;
-       if (layout_id >= SND_SPEAKERLAYOUTS)
-       {
-               Con_Printf("S_Startup: invalid number of channels (%hu). Can't find the corresponding speaker layout.\n"
-                                  "Defaulting to mono output\n",
-                                  snd_renderbuffer->format.channels);
-               layout_id = SND_SPEAKERLAYOUTS - 1;
-       }
-       snd_speakerlayout = snd_speakerlayouts[layout_id];
+       S_SetSpeakerLayout();
+       current_swapstereo = snd_swapstereo.integer;
 }
 
 void S_Shutdown(void)
@@ -1331,6 +1384,13 @@ void S_Update(const matrix4x4_t *listenermatrix)
        if (snd_renderbuffer == NULL || snd_blocked > 0 || nosound.integer)
                return;
 
+       // If snd_swapstereo has changed, recompute the speaker layout
+       if (current_swapstereo != snd_swapstereo.integer)
+       {
+               current_swapstereo = snd_swapstereo.integer;
+               S_SetSpeakerLayout();
+       }
+
        Matrix4x4_Invert_Simple(&basematrix, listenermatrix);
        Matrix4x4_OriginFromMatrix(listenermatrix, listener_origin);
 
index 47b622d..82c3472 100644 (file)
@@ -135,6 +135,8 @@ extern mempool_t *snd_mempool;
 // Used for isolating performance in the renderer.
 extern qboolean simsound;
 
+extern qboolean alsaspeakerlayout;
+
 
 // ====================================================================
 //         Architecture-independent functions
index 0e4dada..af6ba2b 100644 (file)
--- a/snd_mix.c
+++ b/snd_mix.c
@@ -91,102 +91,46 @@ static unsigned int S_TransferPaintBuffer(snd_ringbuffer_t* rb, unsigned int sta
                        short *snd_out = (short*)rb_ptr;
                        if (rb->format.channels == 8)  // 7.1 surround
                        {
-                               if (snd_swapstereo.value)
-                               {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[4], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[5], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[6], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[7], 32767);
-                                       }
-                               }
-                               else
+                               for (i = 0;i < nbframes;i++, painted_ptr++)
                                {
-                                       for (i = 0;i < nbframes;i++, painted_ptr++)
-                                       {
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[4], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[5], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[6], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[7], 32767);
-                                       }
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[4], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[5], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[6], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[7], 32767);
                                }
                        }
                        else if (rb->format.channels == 6)  // 5.1 surround
                        {
-                               if (snd_swapstereo.value)
-                               {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[4], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[5], 32767);
-                                       }
-                               }
-                               else
+                               for (i = 0; i < nbframes; i++, painted_ptr++)
                                {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[4], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[5], 32767);
-                                       }
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[4], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[5], 32767);
                                }
                        }
                        else if (rb->format.channels == 4)  // 4.0 surround
                        {
-                               if (snd_swapstereo.value)
-                               {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
-                                       }
-                               }
-                               else
+                               for (i = 0; i < nbframes; i++, painted_ptr++)
                                {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
-                                       }
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[2], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[3], 32767);
                                }
                        }
                        else if (rb->format.channels == 2)  // 2.0 stereo
                        {
-                               if (snd_swapstereo.value)
-                               {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
-                                       }
-                               }
-                               else
+                               for (i = 0; i < nbframes; i++, painted_ptr++)
                                {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
-                                               *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
-                                       }
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[0], 32767);
+                                       *snd_out++ = bound(-32768, painted_ptr->sample[1], 32767);
                                }
                        }
                        else if (rb->format.channels == 1)  // 1.0 mono
@@ -203,102 +147,46 @@ static unsigned int S_TransferPaintBuffer(snd_ringbuffer_t* rb, unsigned int sta
                        unsigned char *snd_out = (unsigned char*)rb_ptr;
                        if (rb->format.channels == 8)  // 7.1 surround
                        {
-                               if (snd_swapstereo.value)
-                               {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[4] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[5] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[6] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[7] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                       }
-                               }
-                               else
+                               for (i = 0; i < nbframes; i++, painted_ptr++)
                                {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[4] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[5] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[6] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[7] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                       }
+                                       val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[4] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[5] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[6] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[7] >> 8) + 128; *snd_out++ = bound(0, val, 255);
                                }
                        }
                        else if (rb->format.channels == 6)  // 5.1 surround
                        {
-                               if (snd_swapstereo.value)
-                               {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[4] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[5] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                       }
-                               }
-                               else
+                               for (i = 0; i < nbframes; i++, painted_ptr++)
                                {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[4] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[5] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                       }
+                                       val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[4] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[5] >> 8) + 128; *snd_out++ = bound(0, val, 255);
                                }
                        }
                        else if (rb->format.channels == 4)  // 4.0 surround
                        {
-                               if (snd_swapstereo.value)
-                               {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                       }
-                               }
-                               else
+                               for (i = 0; i < nbframes; i++, painted_ptr++)
                                {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                       }
+                                       val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[2] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[3] >> 8) + 128; *snd_out++ = bound(0, val, 255);
                                }
                        }
                        else if (rb->format.channels == 2)  // 2.0 stereo
                        {
-                               if (snd_swapstereo.value)
-                               {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                       }
-                               }
-                               else
+                               for (i = 0; i < nbframes; i++, painted_ptr++)
                                {
-                                       for (i = 0; i < nbframes; i++, painted_ptr++)
-                                       {
-                                               val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                               val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
-                                       }
+                                       val = (painted_ptr->sample[0] >> 8) + 128; *snd_out++ = bound(0, val, 255);
+                                       val = (painted_ptr->sample[1] >> 8) + 128; *snd_out++ = bound(0, val, 255);
                                }
                        }
                        else if (rb->format.channels == 1)  // 1.0 mono
index 8980069..ca17c05 100644 (file)
--- a/snd_oss.c
+++ b/snd_oss.c
@@ -161,6 +161,12 @@ qboolean SndSys_Init (const snd_format_t* requested, snd_format_t* suggested)
                return false;
        }
        
+#ifdef __linux__
+       alsaspeakerlayout = true;
+#else
+       alsaspeakerlayout = false;
+#endif
+
        old_osstime = 0;
        osssoundtime = 0;
        snd_renderbuffer = Snd_CreateRingBuffer(requested, 0, NULL);
@@ -228,9 +234,9 @@ void SndSys_Submit (void)
 
                snd_renderbuffer->startframe += written / factor;
 
-               if ((unsigned int)written < nbframes * factor)
+               if ((unsigned int)written < limit * factor)
                {
-                       Con_Printf("SndSys_Submit: audio can't keep up! (%d < %u)\n", written, nbframes * factor);
+                       Con_Printf("SndSys_Submit: audio can't keep up! (%u < %u)\n", written, limit * factor);
                        return;
                }
                
@@ -244,7 +250,14 @@ void SndSys_Submit (void)
                Con_Printf("SndSys_Submit: audio write returned %d!\n", written);
                return;
        }
+
+       if (written % factor != 0)
+               Sys_Error("SndSys_Submit: nb of bytes written (%d) isn't aligned to a frame sample!\n", written);
+
        snd_renderbuffer->startframe += written / factor;
+
+       if ((unsigned int)written < nbframes * factor)
+               Con_Printf("SndSys_Submit: audio can't keep up! (%u < %u)\n", written, nbframes * factor);
 }
 
 
index 6dccba7..90b5312 100644 (file)
--- a/snd_sdl.c
+++ b/snd_sdl.c
@@ -142,6 +142,12 @@ 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
+
        sdlaudiotime = 0;
        SDL_PauseAudio( false );