- if( i_fd >= 0 ) close( i_fd );
- return -1;
-
-}
-
-#ifdef HAVE_ALSA
-/*****************************************************************************
- * ResolveALSADeviceName: Change any . to : in the ALSA device name
- *****************************************************************************/
-char* ResolveALSADeviceName( 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
- *****************************************************************************/
-int OpenAudioDev( demux_t *p_demux, char *psz_device )
-{
- demux_sys_t *p_sys = p_demux->p_sys;
- int i_fd = 0;
- int i_format;
-#ifdef HAVE_ALSA
- p_sys->p_alsa_pcm = NULL;
- char* psz_alsa_device_name = ResolveALSADeviceName( psz_device );
- snd_pcm_hw_params_t *p_hw_params = NULL;
- snd_pcm_uframes_t buffer_size;
- snd_pcm_uframes_t chunk_size;
-#endif
-
-#ifdef HAVE_ALSA
- if( p_sys->b_use_alsa )
- {
- /* ALSA */
-
- int i_err;
-
- 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_demux, "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_demux, "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_demux, "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_demux, "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_demux, "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_demux, "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_demux, "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_demux, "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_demux, "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_demux, "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_demux, "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_demux, "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_demux, "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_demux, "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_sample / 8) * channels;
- 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_demux, "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;
-
- }
- else
-#endif /* HAVE_ALSA */
- {
- /* OSS */
-
- if( (i_fd = open( psz_device, O_RDONLY | O_NONBLOCK )) < 0 )
- {
- msg_Err( p_demux, "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_demux, "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_demux, "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_demux, "cannot set audio sample rate (%m)" );
- goto adev_fail;
- }
-
- p_sys->i_audio_max_frame_size = 6 * 1024;
- }
-
- msg_Dbg( p_demux, "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_demux, "new audio es %d channels %dHz",
- fmt.audio.i_channels, fmt.audio.i_rate );
-
- p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
-
-#ifdef HAVE_ALSA
- free( psz_alsa_device_name );
-#endif
-
- return i_fd;
-
- adev_fail:
-
- if( i_fd >= 0 ) close( i_fd );
-
-#ifdef HAVE_ALSA
- 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 );
-#endif
-