[Player-dev] CN-Client: Support multi-channel playback on Linux using ALSA
Daniel Yek dyek at real.comThis is now in HEAD. Thanks, Bob. Revised description follows: Modified by: dyek at real.com Date: 10/26/2006 Project: Helix Player Reviewed by: bobclark at real.com Synopsis: We hear 2 channels only when playing 5.1 channel content. This change enables multi-channel playback on ALSA. Overview: (1) Many member functions implementation in Helix Client Core's ALSA audio device code, audlinux_alsa.cpp, share the same member variable, m_wLastError. When an error occurred in a member function, the ending _CloseAudio() call can wipe out the existing error condition. The code looked like this: m_wLastError = RA_AOE_BADFORMAT; _CloseAudio(); // This function always set: "m_wLastError = RA_AOE_NOERR;" return m_wLastError; So, we always returned RA_AOE_NOERR in _CheckFormat(), even when the system can't play the format. (2) The implementation was catered for 2-channel playback only. Playing back 5.1 channels content caused ALSA's "default" PCM device to invoke its ("plug" and) "route" plugin and shrink the channels to 2 channels, discarding surround sound content. The right ALSA PCM device to use to play 5.1 content is the "plug:surround51" PCM, which only takes 6-channel input. If the system isn't set up to play 5.1 content, snd_pcm_open() this PCM would fail and Helix client would then fallback to 2-channel and use the "default" PCM. Note that on some misconfigured system, "surround51" was defined even though the system isn't 5.1 capable. This is system configuration problem. On such system, ALSA would invoke the "plug" plugin, which uses "route" plugin to discard surround sound content and playback in 2-channel mode. On these systems, we really want to have Helix client "preserve" all channels by downmixing it to 2 channels. This is now handled by the "DisableMultiChannelPlayback" preference. If a system's surround sound playback isn't working, use: ~/.hxplayrc: DisableMultiChannelPlayback=1 That would force all channels to be merged into 2 channels (stereo). There is a checkbox provided in the players' Preference Dialog box too. (3) ALSA now always configures the sound card to 48000Hz. So, Helix's ALSA audio device _CheckFormat() code now forces Helix client to use 48000Hz. However, a user could change the "AlsaVaryingSampleRate" preference entry in the following file like this: ~/.hxplayerrc: AlsaVaryingSampleRate=1 With this, the previous player behavior is preserved to use whatever sample rate ALSA plug layer is accepting. ALSA's plug layer would then resample to 48000Hz before sending it to the device. (4) Implemented Surround Sound playback channels mapping from Helix/Windows internal channels mapping to ALSA's mapping. Files Modified: Player Part: player/app/gtk/prefsdialog.cpp - Added 5.1 ALSA Device preference entry. player/app/gtk/res/preferences.glade - Added 5.1 ALSA Device Text Entry. player/app/gtk/preferences_interface.c - Generated code. Core Part: audio/device/platform/unix/audlinux_alsa.cpp - Support surround sound playback. audio/device/platform/unix/audlinux_oss.cpp - _OpenAudio() prototype changed. audio/device/platform/unix/audUnix.cpp - _OpenAudio() prototype changed. audio/device/pub/platform/unix/audlinux_alsa.h audio/device/pub/platform/unix/audlinux_oss.h - _OpenAudio() prototype changed. audio/device/pub/platform/unix/audUnix.h - _OpenAudio() prototype changed. audio/device/pub/platform/unix/audhpux.h audio/device/pub/platform/unix/audirix.h audio/device/pub/platform/unix/audlinux_esound.h audio/device/pub/platform/unix/audSolaris.h audio/device/pub/platform/unix/audusound.h audio/device/platform/unix/audhpux.cpp audio/device/platform/unix/audirix.cpp audio/device/platform/unix/audlinux_esound.cpp audio/device/platform/unix/audSolaris.cpp audio/device/platform/unix/audusound.cpp Platforms and Profiles Affected: Linux Platforms and Profiles Build Verified: Profile: helix_client_all_define Platform: Fedora Core 5 Platforms and Profiles Functionality verified: Profile: helix_client_all_define Platform: Fedora Core 5 Branch: HEAD Copyright assignment: I am a RealNetworks employee. -- Daniel Yek