Up-to-date ALSA audio output module.

parent 3820b435
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* alsa.c : alsa plugin for vlc * alsa.c : alsa plugin for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * Copyright (C) 2000-2001 VideoLAN
* $Id: alsa.c,v 1.12 2002/09/30 21:32:32 massiot Exp $ * $Id: alsa.c,v 1.13 2002/10/05 03:44:50 bozo Exp $
* *
* Authors: Henri Fallon <henri@videolan.org> - Original Author * Authors: Henri Fallon <henri@videolan.org> - Original Author
* Jeffrey Baker <jwbaker@acm.org> - Port to ALSA 1.0 API * Jeffrey Baker <jwbaker@acm.org> - Port to ALSA 1.0 API
...@@ -100,12 +100,15 @@ static int Open( vlc_object_t *p_this ) ...@@ -100,12 +100,15 @@ static int Open( vlc_object_t *p_this )
aout_instance_t * p_aout = (aout_instance_t *)p_this; aout_instance_t * p_aout = (aout_instance_t *)p_this;
struct aout_sys_t * p_sys; struct aout_sys_t * p_sys;
int i_snd_rc; int i_snd_rc = -1;
char * psz_device; char * psz_device = NULL;
char psz_alsadev[128]; char psz_alsadev[128];
char * psz_userdev; char * psz_userdev;
int i_format_tries[2];
int i_tries_count, i;
int i_format; int i_format;
int i_channels; int i_channels;
...@@ -126,17 +129,26 @@ static int Open( vlc_object_t *p_this ) ...@@ -126,17 +129,26 @@ static int Open( vlc_object_t *p_this )
snd_output_stdio_attach( &p_sys->p_snd_stderr, stderr, 0 ); snd_output_stdio_attach( &p_sys->p_snd_stderr, stderr, 0 );
#endif #endif
i_tries_count = 0;
i_format_tries[i_tries_count++] = p_aout->output.output.i_format;
if( i_format_tries[0] == VLC_FOURCC('s','p','d','i') )
{
/* Try S/PDIF, and then FLOAT32 */
i_format_tries[i_tries_count++] = VLC_FOURCC('f','l','3','2');
}
/* Read in ALSA device preferences from configuration */ /* Read in ALSA device preferences from configuration */
psz_userdev = config_GetPsz( p_aout, "alsa-device" ); psz_userdev = config_GetPsz( p_aout, "alsa-device" );
for( i = 0 ; ( i_snd_rc < 0 ) && ( i < i_tries_count ) ; ++i )
{
if( i_format_tries[i] == VLC_FOURCC('s','p','d','i') )
{
if( psz_userdev ) if( psz_userdev )
{ {
psz_device = psz_userdev; psz_device = psz_userdev;
} }
else else
{
/* Use the internal logic to decide on the device name */
if ( p_aout->output.output.i_format == VLC_FOURCC('s','p','d','i') )
{ {
/* Will probably need some little modification in the case /* Will probably need some little modification in the case
we want to send some data at a different rate we want to send some data at a different rate
...@@ -150,20 +162,21 @@ static int Open( vlc_object_t *p_this ) ...@@ -150,20 +162,21 @@ static int Open( vlc_object_t *p_this )
"iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x", "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x",
s[0], s[1], s[2], s[3] ); s[0], s[1], s[2], s[3] );
psz_device = psz_alsadev; psz_device = psz_alsadev;
}
aout_VolumeNoneInit( p_aout );
} }
else else
{ {
if( psz_userdev )
psz_device = psz_userdev;
else
psz_device = "default"; psz_device = "default";
aout_VolumeSoftInit( p_aout );
}
} }
/* Open device */ /* Open device */
i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_device, i_snd_rc = snd_pcm_open( &p_sys->p_snd_pcm, psz_device,
SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
}
if( i_snd_rc < 0 ) if( i_snd_rc < 0 )
{ {
msg_Err( p_aout, "cannot open ALSA device `%s' (%s)", msg_Err( p_aout, "cannot open ALSA device `%s' (%s)",
...@@ -177,6 +190,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -177,6 +190,8 @@ static int Open( vlc_object_t *p_this )
if( psz_userdev ) if( psz_userdev )
free( psz_userdev ); free( psz_userdev );
p_aout->output.output.i_format = i_format_tries[i - 1];
/* Default settings */ /* Default settings */
p_sys->b_can_sleek = VLC_FALSE; p_sys->b_can_sleek = VLC_FALSE;
i_channels = p_aout->output.output.i_channels; i_channels = p_aout->output.output.i_channels;
...@@ -184,14 +199,15 @@ static int Open( vlc_object_t *p_this ) ...@@ -184,14 +199,15 @@ static int Open( vlc_object_t *p_this )
{ {
p_sys->i_buffer_size = ALSA_SPDIF_BUFFER_SIZE; p_sys->i_buffer_size = ALSA_SPDIF_BUFFER_SIZE;
p_aout->output.i_nb_samples = ALSA_SPDIF_PERIOD_SIZE; p_aout->output.i_nb_samples = ALSA_SPDIF_PERIOD_SIZE;
aout_VolumeNoneInit( p_aout );
} }
else else
{ {
p_sys->i_buffer_size = ALSA_DEFAULT_BUFFER_SIZE; p_sys->i_buffer_size = ALSA_DEFAULT_BUFFER_SIZE;
p_aout->output.i_nb_samples = ALSA_DEFAULT_PERIOD_SIZE; p_aout->output.i_nb_samples = ALSA_DEFAULT_PERIOD_SIZE;
aout_VolumeSoftInit( p_aout );
} }
/* Compute the settings */ /* Compute the settings */
switch (p_aout->output.output.i_format) switch (p_aout->output.output.i_format)
{ {
...@@ -208,8 +224,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -208,8 +224,8 @@ static int Open( vlc_object_t *p_this )
p_aout->output.output.i_frame_length = ALSA_SPDIF_PERIOD_SIZE; p_aout->output.output.i_frame_length = ALSA_SPDIF_PERIOD_SIZE;
break; break;
default: default:
msg_Err( p_aout, "audio output format 0x%x not supported", msg_Err( p_aout, "audio output format '%.4s' not supported",
p_aout->output.output.i_format ); &p_aout->output.output.i_format );
return -1; return -1;
break; break;
} }
...@@ -247,13 +263,15 @@ static int Open( vlc_object_t *p_this ) ...@@ -247,13 +263,15 @@ static int Open( vlc_object_t *p_this )
return -1; return -1;
} }
i_snd_rc = snd_pcm_hw_params_set_rate( p_sys->p_snd_pcm, p_hw, i_snd_rc = snd_pcm_hw_params_set_rate_near( p_sys->p_snd_pcm, p_hw,
p_aout->output.output.i_rate, 0 ); p_aout->output.output.i_rate,
NULL );
if( i_snd_rc < 0 ) if( i_snd_rc < 0 )
{ {
msg_Err( p_aout, "unable to set sample rate" ); msg_Err( p_aout, "unable to set sample rate" );
return -1; return -1;
} }
p_aout->output.output.i_rate = i_snd_rc;
i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm, p_hw, i_snd_rc = snd_pcm_hw_params_set_buffer_size_near( p_sys->p_snd_pcm, p_hw,
p_sys->i_buffer_size ); p_sys->i_buffer_size );
...@@ -265,14 +283,13 @@ static int Open( vlc_object_t *p_this ) ...@@ -265,14 +283,13 @@ static int Open( vlc_object_t *p_this )
p_sys->i_buffer_size = i_snd_rc; p_sys->i_buffer_size = i_snd_rc;
i_snd_rc = snd_pcm_hw_params_set_period_size_near( i_snd_rc = snd_pcm_hw_params_set_period_size_near(
p_sys->p_snd_pcm, p_hw, p_aout->output.i_nb_samples, 0 ); p_sys->p_snd_pcm, p_hw, p_aout->output.i_nb_samples, NULL );
if( i_snd_rc < 0 ) if( i_snd_rc < 0 )
{ {
msg_Err( p_aout, "unable to set period size" ); msg_Err( p_aout, "unable to set period size" );
return -1; return -1;
} }
p_aout->output.i_nb_samples = i_snd_rc; p_aout->output.i_nb_samples = i_snd_rc;
p_sys->i_period_time = snd_pcm_hw_params_get_period_time( p_hw, 0 );
i_snd_rc = snd_pcm_hw_params( p_sys->p_snd_pcm, p_hw ); i_snd_rc = snd_pcm_hw_params( p_sys->p_snd_pcm, p_hw );
if (i_snd_rc < 0) if (i_snd_rc < 0)
...@@ -281,6 +298,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -281,6 +298,8 @@ static int Open( vlc_object_t *p_this )
return -1; return -1;
} }
p_sys->i_period_time = snd_pcm_hw_params_get_period_time( p_hw, NULL );
snd_pcm_sw_params_current( p_sys->p_snd_pcm, p_sw ); snd_pcm_sw_params_current( p_sys->p_snd_pcm, p_sw );
i_snd_rc = snd_pcm_sw_params_set_sleep_min( p_sys->p_snd_pcm, p_sw, 0 ); i_snd_rc = snd_pcm_sw_params_set_sleep_min( p_sys->p_snd_pcm, p_sw, 0 );
...@@ -455,7 +474,7 @@ static void ALSAFill( aout_instance_t * p_aout ) ...@@ -455,7 +474,7 @@ static void ALSAFill( aout_instance_t * p_aout )
return; return;
i_snd_rc = snd_pcm_writei( p_sys->p_snd_pcm, p_buffer->p_buffer, i_snd_rc = snd_pcm_writei( p_sys->p_snd_pcm, p_buffer->p_buffer,
p_buffer->i_nb_samples ); p_buffer->i_nb_bytes );
if( i_snd_rc < 0 ) if( i_snd_rc < 0 )
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment