-#ifdef HAVE_ALSA
-/*****************************************************************************
- * ResolveALSADeviceName: Change any . to : in the ALSA device name
- *****************************************************************************/
-static char *ResolveALSADeviceName( const char *psz_device )
-{
- char* psz_alsa_name = strdup( psz_device );
- for( unsigned int i = 0; i < strlen( psz_device ); i++ )
- {
- if( psz_alsa_name[i] == '.' ) psz_alsa_name[i] = ':';
- }
- return psz_alsa_name;
-}
-#endif
-
-/*****************************************************************************
- * OpenAudioDev: open and set up the audio device and probe for capabilities
- *****************************************************************************/
-#ifdef HAVE_ALSA
-static int OpenAudioDevAlsa( vlc_object_t *p_this, demux_sys_t *p_sys,
- vlc_bool_t b_demux )
-{
- char *psz_device = p_sys->psz_adev;
- int i_fd = 0;
- p_sys->p_alsa_pcm = NULL;
- char* psz_alsa_device_name = NULL;
- snd_pcm_hw_params_t *p_hw_params = NULL;
- snd_pcm_uframes_t buffer_size;
- snd_pcm_uframes_t chunk_size;
-
- /* ALSA */
- int i_err;
- psz_alsa_device_name =
- ResolveALSADeviceName( psz_device?: ALSA_DEFAULT );
-
- if( ( i_err = snd_pcm_open( &p_sys->p_alsa_pcm, psz_alsa_device_name,
- SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK ) ) < 0)
- {
- msg_Err( p_this, "Cannot open ALSA audio device %s (%s)",
- psz_alsa_device_name, snd_strerror( i_err ) );
- goto adev_fail;
- }
-
- if( ( i_err = snd_pcm_nonblock( p_sys->p_alsa_pcm, 1 ) ) < 0)
- {
- msg_Err( p_this, "Cannot set ALSA nonblock (%s)",
- snd_strerror( i_err ) );
- goto adev_fail;
- }
-
- /* Begin setting hardware parameters */
-
- if( ( i_err = snd_pcm_hw_params_malloc( &p_hw_params ) ) < 0 )
- {
- msg_Err( p_this,
- "ALSA: cannot allocate hardware parameter structure (%s)",
- snd_strerror( i_err ) );
- goto adev_fail;
- }
-
- if( ( i_err = snd_pcm_hw_params_any( p_sys->p_alsa_pcm, p_hw_params ) ) < 0 )
- {
- msg_Err( p_this,
- "ALSA: cannot initialize hardware parameter structure (%s)",
- snd_strerror( i_err ) );
- goto adev_fail;
- }
-
- /* Set Interleaved access */
- if( ( i_err = snd_pcm_hw_params_set_access( p_sys->p_alsa_pcm, p_hw_params, SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
- {
- msg_Err( p_this, "ALSA: cannot set access type (%s)",
- snd_strerror( i_err ) );
- goto adev_fail;
- }
-
- /* Set 16 bit little endian */
- if( ( i_err = snd_pcm_hw_params_set_format( p_sys->p_alsa_pcm, p_hw_params, SND_PCM_FORMAT_S16_LE ) ) < 0 )
- {
- msg_Err( p_this, "ALSA: cannot set sample format (%s)",
- snd_strerror( i_err ) );
- goto adev_fail;
- }
-
- /* Set sample rate */
-#ifdef HAVE_ALSA_NEW_API
- i_err = snd_pcm_hw_params_set_rate_near( p_sys->p_alsa_pcm, p_hw_params, &p_sys->i_sample_rate, NULL );
-#else
- i_err = snd_pcm_hw_params_set_rate_near( p_sys->p_alsa_pcm, p_hw_params, p_sys->i_sample_rate, NULL );
-#endif
- if( i_err < 0 )
- {
- msg_Err( p_this, "ALSA: cannot set sample rate (%s)",
- snd_strerror( i_err ) );
- goto adev_fail;
- }
-
- /* Set channels */
- unsigned int channels = p_sys->b_stereo ? 2 : 1;
- if( ( i_err = snd_pcm_hw_params_set_channels( p_sys->p_alsa_pcm, p_hw_params, channels ) ) < 0 )
- {
- channels = ( channels==1 ) ? 2 : 1;
- msg_Warn( p_this, "ALSA: cannot set channel count (%s). "
- "Trying with channels=%d",
- snd_strerror( i_err ),
- channels );
- if( ( i_err = snd_pcm_hw_params_set_channels( p_sys->p_alsa_pcm, p_hw_params, channels ) ) < 0 )
- {
- msg_Err( p_this, "ALSA: cannot set channel count (%s)",
- snd_strerror( i_err ) );
- goto adev_fail;
- }
- p_sys->b_stereo = ( channels == 2 );
- }
-
- /* Set metrics for buffer calculations later */
- unsigned int buffer_time;
- if( ( i_err = snd_pcm_hw_params_get_buffer_time_max(p_hw_params, &buffer_time, 0) ) < 0 )
- {
- msg_Err( p_this, "ALSA: cannot get buffer time max (%s)",
- snd_strerror( i_err ) );
- goto adev_fail;
- }
- if (buffer_time > 500000) buffer_time = 500000;
-
- /* Set period time */
- unsigned int period_time = buffer_time / 4;
-#ifdef HAVE_ALSA_NEW_API
- i_err = snd_pcm_hw_params_set_period_time_near( p_sys->p_alsa_pcm, p_hw_params, &period_time, 0 );
-#else
- i_err = snd_pcm_hw_params_set_period_time_near( p_sys->p_alsa_pcm, p_hw_params, period_time, 0 );
-#endif
- if( i_err < 0 )
- {
- msg_Err( p_this, "ALSA: cannot set period time (%s)",
- snd_strerror( i_err ) );
- goto adev_fail;
- }
-
- /* Set buffer time */
-#ifdef HAVE_ALSA_NEW_API
- i_err = snd_pcm_hw_params_set_buffer_time_near( p_sys->p_alsa_pcm, p_hw_params, &buffer_time, 0 );
-#else
- i_err = snd_pcm_hw_params_set_buffer_time_near( p_sys->p_alsa_pcm, p_hw_params, buffer_time, 0 );
-#endif
- if( i_err < 0 )
- {
- msg_Err( p_this, "ALSA: cannot set buffer time (%s)",
- snd_strerror( i_err ) );
- goto adev_fail;
- }
-
- /* Apply new hardware parameters */
- if( ( i_err = snd_pcm_hw_params( p_sys->p_alsa_pcm, p_hw_params ) ) < 0 )
- {
- msg_Err( p_this, "ALSA: cannot set hw parameters (%s)",
- snd_strerror( i_err ) );
- goto adev_fail;
- }
-
- /* Get various buffer metrics */
- snd_pcm_hw_params_get_period_size( p_hw_params, &chunk_size, 0 );
- snd_pcm_hw_params_get_buffer_size( p_hw_params, &buffer_size );
- if( chunk_size == buffer_size )
- {
- msg_Err( p_this,
- "ALSA: period cannot equal buffer size (%lu == %lu)",
- chunk_size, buffer_size);
- goto adev_fail;
- }
-
- int bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16_LE);
- int bits_per_frame = bits_per_sample * channels;
-
- p_sys->i_alsa_chunk_size = chunk_size;
- p_sys->i_alsa_frame_size = bits_per_frame / 8;
- p_sys->i_audio_max_frame_size = chunk_size * bits_per_frame / 8;
-
- snd_pcm_hw_params_free( p_hw_params );
- p_hw_params = NULL;
-
- /* Prep device */
- if( ( i_err = snd_pcm_prepare( p_sys->p_alsa_pcm ) ) < 0 )
- {
- msg_Err( p_this,
- "ALSA: cannot prepare audio interface for use (%s)",
- snd_strerror( i_err ) );
- goto adev_fail;
- }
-
- /* Return a fake handle so other tests work */
- i_fd = 1;
-
- free( psz_alsa_device_name );
-
- if( !p_sys->psz_adev )
- p_sys->psz_adev = strdup( ALSA_DEFAULT );
- return i_fd;
-
- adev_fail:
-
- if( i_fd >= 0 ) close( i_fd );
-
- if( p_hw_params ) snd_pcm_hw_params_free( p_hw_params );
- if( p_sys->p_alsa_pcm ) snd_pcm_close( p_sys->p_alsa_pcm );
- free( psz_alsa_device_name );
-
- return -1;
-
-}
-#endif
-
-static int OpenAudioDevOss( vlc_object_t *p_this, demux_sys_t *p_sys,
- vlc_bool_t b_demux )
-{
- char *psz_device = p_sys->psz_adev;
- int i_fd = 0;
- int i_format;
- /* OSS */
- if( !psz_device ) psz_device = strdup( OSS_DEFAULT ); /* FIXME leak */
-
- if( (i_fd = open( psz_device, O_RDONLY | O_NONBLOCK )) < 0 )
- {
- msg_Err( p_this, "cannot open OSS audio device (%m)" );
- goto adev_fail;
- }
-
- i_format = AFMT_S16_LE;
- if( ioctl( i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0
- || i_format != AFMT_S16_LE )
- {
- msg_Err( p_this,
- "cannot set audio format (16b little endian) (%m)" );
- goto adev_fail;
- }
-
- if( ioctl( i_fd, SNDCTL_DSP_STEREO,
- &p_sys->b_stereo ) < 0 )
- {
- msg_Err( p_this, "cannot set audio channels count (%m)" );
- goto adev_fail;
- }
-
- if( ioctl( i_fd, SNDCTL_DSP_SPEED,
- &p_sys->i_sample_rate ) < 0 )
- {
- msg_Err( p_this, "cannot set audio sample rate (%m)" );
- goto adev_fail;
- }
-
- p_sys->i_audio_max_frame_size = 6 * 1024;
-
- if( !p_sys->psz_adev )
- p_sys->psz_adev = strdup( OSS_DEFAULT );
- return i_fd;
-
- adev_fail:
-
- if( i_fd >= 0 ) close( i_fd );
- return -1;
-
-}
-
-static int OpenAudioDev( vlc_object_t *p_this, demux_sys_t *p_sys,
- vlc_bool_t b_demux )
-{
- char *psz_device;
- int i_fd = -1;
-
-#ifdef HAVE_ALSA
- if( ( p_sys->i_audio_method & AUDIO_METHOD_ALSA ) && i_fd < 0 )
- i_fd = OpenAudioDevAlsa( p_this, p_sys, b_demux );
-#endif
-
- if( ( p_sys->i_audio_method & AUDIO_METHOD_OSS ) && i_fd < 0 )
- i_fd = OpenAudioDevOss( p_this, p_sys, b_demux );
-
- if( i_fd < 0 )
- return i_fd;
-
- psz_device = p_sys->psz_adev;
-
- msg_Dbg( p_this, "opened adev=`%s' %s %dHz",
- psz_device, p_sys->b_stereo ? "stereo" : "mono",
- p_sys->i_sample_rate );
-
- es_format_t fmt;
- es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC('a','r','a','w') );
-
- fmt.audio.i_channels = p_sys->b_stereo ? 2 : 1;
- fmt.audio.i_rate = p_sys->i_sample_rate;
- fmt.audio.i_bitspersample = 16;
- fmt.audio.i_blockalign = fmt.audio.i_channels * fmt.audio.i_bitspersample / 8;
- fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate * fmt.audio.i_bitspersample;
-
- msg_Dbg( p_this, "new audio es %d channels %dHz",
- fmt.audio.i_channels, fmt.audio.i_rate );
-
- if( b_demux )
- {
- demux_t *p_demux = (demux_t *)p_this;
- p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
- }
-
- return i_fd;
-}
-