# include "config.h"
#endif
+#include <assert.h>
+
#include <vlc_common.h>
#include <vlc_plugin.h>
#define ALSA_PCM_NEW_HW_PARAMS_API
#define ALSA_PCM_NEW_SW_PARAMS_API
#include <alsa/asoundlib.h>
+#include <alsa/version.h>
/*#define ALSA_DEBUG*/
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 void GetDevicesForCard( vlc_object_t *, module_config_t *, int card );
+static void GetDevices( vlc_object_t *, module_config_t * );
/*****************************************************************************
* Module descriptor
text.psz_string = (char*)N_("A/52 over S/PDIF");
var_Change( p_aout, "audio-device",
VLC_VAR_ADDCHOICE, &val, &text );
- if( config_GetInt( p_aout, "spdif" ) )
+ if( var_InheritInteger( p_aout, "spdif" ) )
var_Set( p_aout, "audio-device", val );
snd_pcm_close( p_sys->p_snd_pcm );
}
var_Change( p_aout, "audio-device", VLC_VAR_CHOICESCOUNT, &val, NULL );
+#if (SND_LIB_VERSION <= 0x010015)
+# warning Please update alsa-lib to version > 1.0.21a.
+ var_Create( p_aout->p_libvlc, "alsa-working", VLC_VAR_BOOL );
+ if( val.i_int <= 0 )
+ {
+ if( var_GetBool( p_aout->p_libvlc, "alsa-working" ) )
+ dialog_FatalWait( p_aout, "ALSA version problem",
+ "VLC failed to re-initialize your sound output device.\n"
+ "Please update alsa-lib to version 1.0.22 or higher "
+ "to fix this issue." );
+ }
+ else
+ var_SetBool( p_aout->p_libvlc, "alsa-working", true );
+#endif
if( val.i_int <= 0 )
{
/* Probe() has failed. */
- msg_Dbg( p_aout, "failed to find a usable alsa configuration" );
+ msg_Dbg( p_aout, "failed to find a usable ALSA configuration" );
var_Destroy( p_aout, "audio-device" );
+ GetDevices( VLC_OBJECT(p_aout), NULL );
return;
}
return VLC_ENOMEM;
/* Get device name */
- if( (psz_device = config_GetPsz( p_aout, "alsa-audio-device" )) == NULL )
+ if( (psz_device = var_InheritString( p_aout, "alsa-audio-device" )) == NULL )
{
msg_Err( p_aout, "no audio device given (maybe \"default\" ?)" );
dialog_Fatal( p_aout, _("No Audio Device"), "%s",
msleep(p_sys->i_period_time / 2);
}
-static void GetDevicesForCard( module_config_t *p_item, int i_card );
-static void GetDevices( module_config_t *p_item );
-
/*****************************************************************************
* config variable callback
*****************************************************************************/
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;
/* Clear-up the current list */
if( p_item->i_list )
{
+ int i;
+
/* Keep the first entrie */
for( i = 1; i < p_item->i_list; i++ )
{
}
p_item->i_list = 1;
- GetDevices( p_item );
+ GetDevices( p_this, p_item );
/* Signal change to the interface */
p_item->b_dirty = true;
}
-static void GetDevicesForCard( module_config_t *p_item, int i_card )
+static void GetDevicesForCard( vlc_object_t *obj, module_config_t *p_item,
+ int i_card )
{
int i_pcm_device = -1;
int i_err = 0;
if( ( i_err = snd_ctl_pcm_info( p_ctl, p_pcm_info ) ) < 0 )
{
if( i_err != -ENOENT )
- {
- /*printf( "get_devices_for_card(): "
- "snd_ctl_pcm_info() "
- "failed (%d:%d): %s.\n", i_card,
- i_pcm_device, snd_strerror( -i_err ) );*/
- }
+ msg_Err( obj, "cannot get PCM device %d:%d infos: %s", i_card,
+ i_pcm_device, snd_strerror( -i_err ) );
continue;
}
break;
}
- p_item->ppsz_list =
- (char **)realloc( p_item->ppsz_list,
- (p_item->i_list + 2) * sizeof(char *) );
- p_item->ppsz_list_text =
- (char **)realloc( p_item->ppsz_list_text,
- (p_item->i_list + 2) * sizeof(char *) );
- p_item->ppsz_list[ p_item->i_list ] = psz_device;
- p_item->ppsz_list_text[ p_item->i_list ] = psz_descr;
- p_item->i_list++;
- p_item->ppsz_list[ p_item->i_list ] = NULL;
- p_item->ppsz_list_text[ p_item->i_list ] = NULL;
+ msg_Dbg( obj, " %s", psz_descr );
+
+ if( p_item )
+ {
+ p_item->ppsz_list = xrealloc( p_item->ppsz_list,
+ (p_item->i_list + 2) * sizeof(char *) );
+ p_item->ppsz_list_text = xrealloc( p_item->ppsz_list_text,
+ (p_item->i_list + 2) * sizeof(char *) );
+ p_item->ppsz_list[ p_item->i_list ] = psz_device;
+ p_item->ppsz_list_text[ p_item->i_list ] = psz_descr;
+ p_item->i_list++;
+ p_item->ppsz_list[ p_item->i_list ] = NULL;
+ p_item->ppsz_list_text[ p_item->i_list ] = NULL;
+ }
+ else
+ {
+ free( psz_device );
+ free( psz_descr );
+ }
}
snd_ctl_close( p_ctl );
}
-
-static void GetDevices( module_config_t *p_item )
+static void GetDevices( vlc_object_t *obj, module_config_t *p_item )
{
int i_card = -1;
- int i_err = 0;
+ int i_err;
- if( ( i_err = snd_card_next( &i_card ) ) != 0 )
- {
- /*printf( "snd_card_next() failed: %s", snd_strerror( -i_err ) );*/
- return;
- }
+ msg_Dbg( obj, "Available alsa output devices:" );
+ while( (i_err = snd_card_next( &i_card )) == 0 && i_card > -1 )
+ GetDevicesForCard( obj, p_item, i_card );
- while( i_card > -1 )
- {
- GetDevicesForCard( p_item, i_card );
- if( ( i_err = snd_card_next( &i_card ) ) != 0 )
- {
- /*printf( "snd_card_next() failed: %s", snd_strerror( -i_err ) );*/
- break;
- }
- }
+ if( i_err )
+ msg_Err( obj, "cannot enumerate cards: %s", snd_strerror( -i_err ) );
}