# HG changeset patch # User Sam Lantinga # Date 1151053268 0 # Node ID a7ad7081b9774e0e1bfec3e6c6d6b9eb05d90687 # Parent 442248d4e738a60ba57fc4bad41825aa7e0b405a Merged Ryan's 5.1 audio fix from SDL 1.2 diff -r 442248d4e738 -r a7ad7081b977 src/audio/alsa/SDL_alsa_audio.c --- a/src/audio/alsa/SDL_alsa_audio.c Fri Jun 23 08:48:24 2006 +0000 +++ b/src/audio/alsa/SDL_alsa_audio.c Fri Jun 23 09:01:08 2006 +0000 @@ -351,6 +351,69 @@ } } + +/* + * http://bugzilla.libsdl.org/show_bug.cgi?id=110 + * "For Linux ALSA, this is FL-FR-RL-RR-C-LFE + * and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-RL-RR" + */ +#define SWIZ6(T) \ + T *ptr = (T *) mixbuf; \ + const Uint32 count = (this->spec.samples / 6); \ + Uint32 i; \ + for (i = 0; i < count; i++, ptr += 6) { \ + T tmp; \ + tmp = ptr[2]; ptr[2] = ptr[4]; ptr[4] = tmp; \ + tmp = ptr[3]; ptr[3] = ptr[5]; ptr[5] = tmp; \ + } + +static __inline__ void +swizzle_alsa_channels_6_64bit(_THIS) +{ + SWIZ6(Uint64); +} +static __inline__ void +swizzle_alsa_channels_6_32bit(_THIS) +{ + SWIZ6(Uint32); +} +static __inline__ void +swizzle_alsa_channels_6_16bit(_THIS) +{ + SWIZ6(Uint16); +} +static __inline__ void +swizzle_alsa_channels_6_8bit(_THIS) +{ + SWIZ6(Uint8); +} + +#undef SWIZ6 + + +/* + * Called right before feeding this->mixbuf to the hardware. Swizzle channels + * from Windows/Mac order to the format alsalib will want. + */ +static __inline__ void +swizzle_alsa_channels(_THIS) +{ + if (this->spec.channels == 6) { + const Uint16 fmtsize = (this->spec.format & 0xFF); /* bits/channel. */ + if (fmtsize == 16) + swizzle_alsa_channels_6_16bit(this); + else if (fmtsize == 8) + swizzle_alsa_channels_6_8bit(this); + else if (fmtsize == 32) + swizzle_alsa_channels_6_32bit(this); + else if (fmtsize == 64) + swizzle_alsa_channels_6_64bit(this); + } + + /* !!! FIXME: update this for 7.1 if needed, later. */ +} + + static void ALSA_PlayAudio(_THIS) { @@ -358,8 +421,11 @@ int sample_len; signed short *sample_buf; + swizzle_alsa_channels(this); + sample_len = this->spec.samples; sample_buf = (signed short *) mixbuf; + while (sample_len > 0) { status = SDL_NAME(snd_pcm_writei) (pcm_handle, sample_buf, sample_len); @@ -372,8 +438,7 @@ do { SDL_Delay(1); status = SDL_NAME(snd_pcm_resume) (pcm_handle); - } - while (status == -EAGAIN); + } while (status == -EAGAIN); } if (status < 0) { status = SDL_NAME(snd_pcm_prepare) (pcm_handle);