[vlc-devel] [PATCH] Added new config parameter "alsa-preferred-layout" to allow preselection of speaker layout when playing media files.

Marcus Schmid doc at lanaticasylum.de
Sat Oct 11 17:22:03 CEST 2008


When opening a media file, vlc sets "Stereo" as default audio device,
even if the audio stream played contains multiple channels and the
hardware supports that number of channels. This is especially annoying
when you watch movies that are split over multiple files but contain a
5.1 audiostream, because you have to manually set "5.1" as audio device
after a new file of the set starts playing, which interrupts your
entertainment.

With the supplied patch, the ALSA audio output module gains support for
a new configuration parameter, called "alsa-preferred-layout". This
integer value holds the value for the variable "audio-device" which the
user wants to use if available; it defaults to AOUT_VAR_STEREO,
resembling the current default setting in vlc. But now the user can
change and store the setting (e.g. using the GUI), so that when a new
file starts playing his selected speaker layout (e.g. "5.1" or "Mono")
is set automatically instead of plain "Stereo". Therefore, when watching
movies, the user does not longer have to manually re-set the
audio-device variable to match his setup.
---
 modules/audio_output/alsa.c |  117 +++++++++++++++++++++++++++++++++++--------
 1 files changed, 95 insertions(+), 22 deletions(-)

diff --git a/modules/audio_output/alsa.c b/modules/audio_output/alsa.c
index 2a0f46d..b596455 100644
--- a/modules/audio_output/alsa.c
+++ b/modules/audio_output/alsa.c
@@ -86,6 +86,7 @@ struct aout_sys_t
 /* Right. --Meuuh */
 
 #define DEFAULT_ALSA_DEVICE N_("default")
+#define DEFAULT_ALSA_PREFERRED_LAYOUT AOUT_VAR_STEREO
 
 /*****************************************************************************
  * Local prototypes
@@ -97,12 +98,26 @@ static void* ALSAThread   ( vlc_object_t * );
 static void  ALSAFill     ( aout_instance_t * );
 static int FindDevicesCallback( vlc_object_t *p_this, char const *psz_name,
                                 vlc_value_t newval, vlc_value_t oldval, void *p_unused );
+static int GetPreferredLayoutCallback( vlc_object_t *p_this,
+                                       char const *psz_name,
+				       vlc_value_t newval,
+                                       vlc_value_t oldval, void *p_unused);
 
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
 static const char *const ppsz_devices[] = { "default" };
 static const char *const ppsz_devices_text[] = { N_("Default") };
+
+static const int pi_layouts[] = { AOUT_VAR_MONO,
+                                  AOUT_VAR_STEREO,
+                                  AOUT_VAR_2F2R,
+                                  AOUT_VAR_5_1 };
+static const char *const ppsz_layouts_text[] = { N_("Mono"),
+                                                 N_("Stereo"),
+                                                 N_("2 Front 2 Rear"),
+                                                 N_("5.1"), NULL };
+
 vlc_module_begin();
     set_shortname( "ALSA" );
     set_description( N_("ALSA audio output") );
@@ -114,6 +129,12 @@ vlc_module_begin();
         change_string_list( ppsz_devices, ppsz_devices_text, FindDevicesCallback );
         change_action_add( FindDevicesCallback, N_("Refresh list") );
 
+    add_integer( "alsa-preferred-layout", DEFAULT_ALSA_PREFERRED_LAYOUT, NULL,
+                 N_("Preferred Speaker Layout"), NULL, false );
+
+    change_integer_list( pi_layouts, ppsz_layouts_text,
+                         GetPreferredLayoutCallback );
+
     set_capability( "audio output", 150 );
     set_callbacks( Open, Close );
 vlc_module_end();
@@ -142,7 +163,9 @@ static void Probe( aout_instance_t * p_aout,
                                  SND_PCM_STREAM_PLAYBACK,
                                  SND_PCM_NONBLOCK ) ) )
     {
+        int i;
         int i_channels;
+        int i_preferredLayout;
         snd_pcm_hw_params_t * p_hw;
         snd_pcm_hw_params_alloca (&p_hw);
 
@@ -177,39 +200,41 @@ static void Probe( aout_instance_t * p_aout,
         }
 
         i_channels = aout_FormatNbChannels( &p_aout->output.output );
+        i_preferredLayout = config_GetInt( p_aout, "alsa-preferred-layout" );
 
         while ( i_channels > 0 )
         {
             if ( !snd_pcm_hw_params_test_channels( p_sys->p_snd_pcm, p_hw,
                                                    i_channels ) )
             {
+                /* map channels to layout-list-position */
                 switch ( i_channels )
                 {
-                case 1:
-                    val.i_int = AOUT_VAR_MONO;
-                    text.psz_string = (char*)N_("Mono");
-                    var_Change( p_aout, "audio-device",
-                                VLC_VAR_ADDCHOICE, &val, &text );
+                case 1: /* mono */
+                    i = 0;
                     break;
-                case 2:
-                    val.i_int = AOUT_VAR_STEREO;
-                    text.psz_string = (char*)N_("Stereo");
-                    var_Change( p_aout, "audio-device",
-                                VLC_VAR_ADDCHOICE, &val, &text );
-                    var_Set( p_aout, "audio-device", val );
+                case 2: /* stereo */
+                    i = 1;
                     break;
-                case 4:
-                    val.i_int = AOUT_VAR_2F2R;
-                    text.psz_string = (char*)N_("2 Front 2 Rear");
-                    var_Change( p_aout, "audio-device",
-                                VLC_VAR_ADDCHOICE, &val, &text );
+                case 4: /* 2 front 2 rear */
+                    i = 2;
                     break;
-                case 6:
-                    val.i_int = AOUT_VAR_5_1;
-                    text.psz_string = (char*)"5.1";
-                    var_Change( p_aout, "audio-device",
-                                VLC_VAR_ADDCHOICE, &val, &text );
+                case 6: /* 5.1 */
+                    i = 3;
                     break;
+                default: /* everything else is unsupported */
+                    i = -1;
+                }
+
+		/*  append channel layout to selection list if supported */
+                if(i != -1) {
+                        val.i_int = pi_layouts[i];
+                        text.psz_string = (char*)ppsz_layouts_text[i];
+                        var_Change( p_aout, "audio-device",
+                                        VLC_VAR_ADDCHOICE, &val, &text );
+                        /* if it is our preferred layout, set it */
+                        if(val.i_int == i_preferredLayout)
+                                var_Set( p_aout, "audio-device", val );
                 }
             }
 
@@ -775,7 +800,7 @@ static void* ALSAThread( vlc_object_t* p_this )
     vlc_mutex_unlock( &p_sys->lock );
 
     if( !vlc_object_alive (p_aout) )
-    	goto cleanup;
+        goto cleanup;
 
     mwait( p_sys->start_date - AOUT_PTS_TOLERANCE / 4 );
 
@@ -1040,3 +1065,51 @@ static void GetDevices( module_config_t *p_item )
         }
     }
 }
+
+static int GetPreferredLayoutCallback( vlc_object_t *p_this,
+                                       char const *psz_name,
+				       vlc_value_t newval,
+                                       vlc_value_t oldval, void *p_unused)
+{
+    module_config_t *p_item;
+    int i;
+    (void)newval;
+    (void)oldval;
+    (void)p_unused;
+
+    p_item = config_FindConfig( p_this, psz_name );
+    if( !p_item ) return VLC_SUCCESS;
+
+    /* free existing list and its textual descriptions */
+    if( p_item->i_list )
+    {
+        free( (int *)p_item->pi_list );
+
+        for( i = 1; i < p_item->i_list; i++ )
+            free( (char *)p_item->ppsz_list_text[i] );
+    }
+
+    /* count elements in static layouts_text-list */
+    for( i = 0; ppsz_layouts_text[i]; i++ )
+        ;
+
+    /* resize dropdown list */
+    p_item->i_list = i;
+    p_item->pi_list = (int *)malloc( sizeof(int) * p_item->i_list );
+    p_item->ppsz_list_text =
+        (char **)realloc( p_item->ppsz_list_text,
+                          sizeof(char *) * p_item->i_list );
+
+    /* copy dropdown elements from static list */
+    for( i = 0; i < p_item->i_list; i++)
+    {
+        p_item->pi_list[i] = pi_layouts[i];
+        p_item->ppsz_list_text[i] = strdup( ppsz_layouts_text[i] );
+    }
+
+    /* Signal change to the interface */
+    p_item->b_dirty = true;
+
+    return VLC_SUCCESS;
+}
+
-- 
1.5.6.5




More information about the vlc-devel mailing list