alsa.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:21k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * alsa.c : Alsa input module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2002-2009 the VideoLAN team
  5.  * $Id: b71a304ea96864a0b96d2edecb73eaae30bc59e1 $
  6.  *
  7.  * Authors: Benjamin Pracht <bigben at videolan dot org>
  8.  *          Richard Hosking <richard at hovis dot net>
  9.  *          Antoine Cellerier <dionoea at videolan d.t org>
  10.  *          Dennis Lou <dlou99 at yahoo dot com>
  11.  *
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2 of the License, or
  15.  * (at your option) any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; if not, write to the Free Software
  24.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  25.  *****************************************************************************/
  26. /*
  27.  * ALSA support based on parts of
  28.  * http://www.equalarea.com/paul/alsa-audio.html
  29.  * and hints taken from alsa-utils (aplay/arecord)
  30.  * http://www.alsa-project.org
  31.  */
  32. /*****************************************************************************
  33.  * Preamble
  34.  *****************************************************************************/
  35. #ifdef HAVE_CONFIG_H
  36. # include "config.h"
  37. #endif
  38. #include <vlc_common.h>
  39. #include <vlc_plugin.h>
  40. #include <vlc_access.h>
  41. #include <vlc_demux.h>
  42. #include <vlc_input.h>
  43. #include <vlc_vout.h>
  44. #include <ctype.h>
  45. #include <fcntl.h>
  46. #include <unistd.h>
  47. #include <sys/ioctl.h>
  48. #include <sys/mman.h>
  49. #include <sys/soundcard.h>
  50. #define ALSA_PCM_NEW_HW_PARAMS_API
  51. #define ALSA_PCM_NEW_SW_PARAMS_API
  52. #include <alsa/asoundlib.h>
  53. #include <poll.h>
  54. /*****************************************************************************
  55.  * Module descriptior
  56.  *****************************************************************************/
  57. static int  DemuxOpen ( vlc_object_t * );
  58. static void DemuxClose( vlc_object_t * );
  59. #define STEREO_TEXT N_( "Stereo" )
  60. #define STEREO_LONGTEXT N_( 
  61.     "Capture the audio stream in stereo." )
  62. #define SAMPLERATE_TEXT N_( "Samplerate" )
  63. #define SAMPLERATE_LONGTEXT N_( 
  64.     "Samplerate of the captured audio stream, in Hz (eg: 11025, 22050, 44100, 48000)" )
  65. #define CACHING_TEXT N_("Caching value in ms")
  66. #define CACHING_LONGTEXT N_( 
  67.     "Caching value for Alsa captures. This " 
  68.     "value should be set in milliseconds." )
  69. #define ALSA_DEFAULT "hw"
  70. #define CFG_PREFIX "alsa-"
  71. vlc_module_begin()
  72.     set_shortname( N_("Alsa") )
  73.     set_description( N_("Alsa audio capture input") )
  74.     set_category( CAT_INPUT )
  75.     set_subcategory( SUBCAT_INPUT_ACCESS )
  76.     add_shortcut( "alsa" )
  77.     set_capability( "access_demux", 10 )
  78.     set_callbacks( DemuxOpen, DemuxClose )
  79.     add_bool( CFG_PREFIX "stereo", true, NULL, STEREO_TEXT, STEREO_LONGTEXT,
  80.                 true )
  81.     add_integer( CFG_PREFIX "samplerate", 48000, NULL, SAMPLERATE_TEXT,
  82.                 SAMPLERATE_LONGTEXT, true )
  83.     add_integer( CFG_PREFIX "caching", DEFAULT_PTS_DELAY / 1000, NULL,
  84.                 CACHING_TEXT, CACHING_LONGTEXT, true )
  85. vlc_module_end()
  86. /*****************************************************************************
  87.  * Access: local prototypes
  88.  *****************************************************************************/
  89. static int DemuxControl( demux_t *, int, va_list );
  90. static int Demux( demux_t * );
  91. static block_t* GrabAudio( demux_t *p_demux );
  92. static int OpenAudioDev( demux_t * );
  93. static bool ProbeAudioDevAlsa( demux_t *, const char *psz_device );
  94. struct demux_sys_t
  95. {
  96.     const char *psz_device;  /* Alsa device from MRL */
  97.     /* Audio */
  98.     int i_cache;
  99.     unsigned int i_sample_rate;
  100.     bool b_stereo;
  101.     size_t i_max_frame_size;
  102.     block_t *p_block;
  103.     es_out_id_t *p_es;
  104.     /* ALSA Audio */
  105.     snd_pcm_t *p_alsa_pcm;
  106.     size_t i_alsa_frame_size;
  107.     int i_alsa_chunk_size;
  108.     int64_t i_next_demux_date; /* Used to handle alsa:// as input-slave properly */
  109. };
  110. static int FindMainDevice( demux_t *p_demux )
  111. {
  112.     /* TODO: if using default device, loop through all alsa devices until
  113.      * one works. */
  114.     msg_Dbg( p_demux, "opening device '%s'", p_demux->p_sys->psz_device );
  115.     if( ProbeAudioDevAlsa( p_demux, p_demux->p_sys->psz_device ) )
  116.     {
  117.         msg_Dbg( p_demux, "'%s' is an audio device",
  118.                  p_demux->p_sys->psz_device );
  119.         OpenAudioDev( p_demux );
  120.     }
  121.     if( p_demux->p_sys->p_alsa_pcm == NULL )
  122.         return VLC_EGENERIC;
  123.     return VLC_SUCCESS;
  124. }
  125. static void ListAvailableDevices( demux_t *p_demux )
  126. {
  127.     snd_ctl_card_info_t *p_info = NULL;
  128.     snd_ctl_card_info_alloca( &p_info );
  129.     snd_pcm_info_t *p_pcminfo = NULL;
  130.     snd_pcm_info_alloca( &p_pcminfo );
  131.     msg_Dbg( p_demux, "Available alsa capture devices:" );
  132.     int i_card = -1;
  133.     while( !snd_card_next( &i_card ) && i_card >= 0 )
  134.     {
  135.         char psz_devname[10];
  136.         snprintf( psz_devname, 10, "hw:%d", i_card );
  137.         snd_ctl_t *p_ctl = NULL;
  138.         if( snd_ctl_open( &p_ctl, psz_devname, 0 ) < 0 ) continue;
  139.         snd_ctl_card_info( p_ctl, p_info );
  140.         msg_Dbg( p_demux, "  %s (%s)",
  141.                  snd_ctl_card_info_get_id( p_info ),
  142.                  snd_ctl_card_info_get_name( p_info ) );
  143.         int i_dev = -1;
  144.         while( !snd_ctl_pcm_next_device( p_ctl, &i_dev ) && i_dev >= 0 )
  145.         {
  146.             snd_pcm_info_set_device( p_pcminfo, i_dev );
  147.             snd_pcm_info_set_subdevice( p_pcminfo, 0 );
  148.             snd_pcm_info_set_stream( p_pcminfo, SND_PCM_STREAM_CAPTURE );
  149.             if( snd_ctl_pcm_info( p_ctl, p_pcminfo ) < 0 ) continue;
  150.             msg_Dbg( p_demux, "    hw:%d,%d : %s (%s)", i_card, i_dev,
  151.                      snd_pcm_info_get_id( p_pcminfo ),
  152.                      snd_pcm_info_get_name( p_pcminfo ) );
  153.         }
  154.         snd_ctl_close( p_ctl );
  155.     }
  156. }
  157. /*****************************************************************************
  158.  * DemuxOpen: opens alsa device, access_demux callback
  159.  *****************************************************************************
  160.  *
  161.  * url: <alsa device>::::
  162.  *
  163.  *****************************************************************************/
  164. static int DemuxOpen( vlc_object_t *p_this )
  165. {
  166.     demux_t     *p_demux = (demux_t*)p_this;
  167.     demux_sys_t *p_sys;
  168.     /* Only when selected */
  169.     if( *p_demux->psz_access == '' ) return VLC_EGENERIC;
  170.     /* Set up p_demux */
  171.     p_demux->pf_control = DemuxControl;
  172.     p_demux->pf_demux = Demux;
  173.     p_demux->info.i_update = 0;
  174.     p_demux->info.i_title = 0;
  175.     p_demux->info.i_seekpoint = 0;
  176.     p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
  177.     if( p_sys == NULL ) return VLC_ENOMEM;
  178.     p_sys->i_sample_rate = var_CreateGetInteger( p_demux, CFG_PREFIX "samplerate" );
  179.     p_sys->b_stereo = var_CreateGetBool( p_demux, CFG_PREFIX "stereo" );
  180.     p_sys->i_cache = var_CreateGetInteger( p_demux, CFG_PREFIX "caching" );
  181.     p_sys->p_es = NULL;
  182.     p_sys->p_block = NULL;
  183.     p_sys->i_next_demux_date = -1;
  184.     if( p_demux->psz_path && *p_demux->psz_path )
  185.         p_sys->psz_device = p_demux->psz_path;
  186.     else
  187.     {
  188.         p_sys->psz_device = ALSA_DEFAULT;
  189.         ListAvailableDevices( p_demux );
  190.     }
  191.     if( FindMainDevice( p_demux ) != VLC_SUCCESS )
  192.     {
  193.         DemuxClose( p_this );
  194.         return VLC_EGENERIC;
  195.     }
  196.     return VLC_SUCCESS;
  197. }
  198. /*****************************************************************************
  199.  * Close: close device, free resources
  200.  *****************************************************************************/
  201. static void DemuxClose( vlc_object_t *p_this )
  202. {
  203.     demux_t     *p_demux = (demux_t *)p_this;
  204.     demux_sys_t *p_sys   = p_demux->p_sys;
  205.     if( p_sys->p_alsa_pcm )
  206.     {
  207.         snd_pcm_close( p_sys->p_alsa_pcm );
  208.     }
  209.     if( p_sys->p_block ) block_Release( p_sys->p_block );
  210.     free( p_sys );
  211. }
  212. /*****************************************************************************
  213.  * DemuxControl:
  214.  *****************************************************************************/
  215. static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
  216. {
  217.     demux_sys_t *p_sys = p_demux->p_sys;
  218.     bool *pb;
  219.     int64_t *pi64;
  220.     switch( i_query )
  221.     {
  222.         /* Special for access_demux */
  223.         case DEMUX_CAN_PAUSE:
  224.         case DEMUX_CAN_SEEK:
  225.         case DEMUX_SET_PAUSE_STATE:
  226.         case DEMUX_CAN_CONTROL_PACE:
  227.             pb = (bool*)va_arg( args, bool * );
  228.             *pb = false;
  229.             return VLC_SUCCESS;
  230.         case DEMUX_GET_PTS_DELAY:
  231.             pi64 = (int64_t*)va_arg( args, int64_t * );
  232.             *pi64 = (int64_t)p_sys->i_cache * 1000;
  233.             return VLC_SUCCESS;
  234.         case DEMUX_GET_TIME:
  235.             pi64 = (int64_t*)va_arg( args, int64_t * );
  236.             *pi64 = mdate();
  237.             return VLC_SUCCESS;
  238.         case DEMUX_SET_NEXT_DEMUX_TIME:
  239.             p_sys->i_next_demux_date = (int64_t)va_arg( args, int64_t );
  240.             return VLC_SUCCESS;
  241.         /* TODO implement others */
  242.         default:
  243.             return VLC_EGENERIC;
  244.     }
  245.     return VLC_EGENERIC;
  246. }
  247. /*****************************************************************************
  248.  * Demux: Processes the audio frame
  249.  *****************************************************************************/
  250. static int Demux( demux_t *p_demux )
  251. {
  252.     demux_sys_t *p_sys = p_demux->p_sys;
  253.     block_t *p_block = NULL;
  254.     do
  255.     {
  256.         if( p_block )
  257.         {
  258.             es_out_Send( p_demux->out, p_sys->p_es, p_block );
  259.             p_block = NULL;
  260.         }
  261.         /* Wait for data */
  262.         int i_wait = snd_pcm_wait( p_sys->p_alsa_pcm, 10 ); /* See poll() comment in oss.c */
  263.         switch( i_wait )
  264.         {
  265.             case 1:
  266.             {
  267.                 p_block = GrabAudio( p_demux );
  268.                 if( p_block )
  269.                     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
  270.             }
  271.             /* FIXME: this is a copy paste from below. Shouldn't be needed
  272.              * twice. */
  273.             case -EPIPE:
  274.                 /* xrun */
  275.                 snd_pcm_prepare( p_sys->p_alsa_pcm );
  276.                 break;
  277.             case -ESTRPIPE:
  278.             {
  279.                 /* suspend */
  280.                 int i_resume = snd_pcm_resume( p_sys->p_alsa_pcm );
  281.                 if( i_resume < 0 && i_resume != -EAGAIN ) snd_pcm_prepare( p_sys->p_alsa_pcm );
  282.                 break;
  283.             }
  284.             /* </FIXME> */
  285.         }
  286.     } while( p_block && p_sys->i_next_demux_date > 0 &&
  287.              p_block->i_pts < p_sys->i_next_demux_date );
  288.     if( p_block )
  289.         es_out_Send( p_demux->out, p_sys->p_es, p_block );
  290.     return 1;
  291. }
  292. /*****************************************************************************
  293.  * GrabAudio: Grab an audio frame
  294.  *****************************************************************************/
  295. static block_t* GrabAudio( demux_t *p_demux )
  296. {
  297.     demux_sys_t *p_sys = p_demux->p_sys;
  298.     int i_read, i_correct;
  299.     block_t *p_block;
  300.     if( p_sys->p_block ) p_block = p_sys->p_block;
  301.     else p_block = block_New( p_demux, p_sys->i_max_frame_size );
  302.     if( !p_block )
  303.     {
  304.         msg_Warn( p_demux, "cannot get block" );
  305.         return 0;
  306.     }
  307.     p_sys->p_block = p_block;
  308.     /* ALSA */
  309.     i_read = snd_pcm_readi( p_sys->p_alsa_pcm, p_block->p_buffer, p_sys->i_alsa_chunk_size );
  310.     if( i_read <= 0 )
  311.     {
  312.         int i_resume;
  313.         switch( i_read )
  314.         {
  315.             case -EAGAIN:
  316.                 break;
  317.             case -EPIPE:
  318.                 /* xrun */
  319.                 snd_pcm_prepare( p_sys->p_alsa_pcm );
  320.                 break;
  321.             case -ESTRPIPE:
  322.                 /* suspend */
  323.                 i_resume = snd_pcm_resume( p_sys->p_alsa_pcm );
  324.                 if( i_resume < 0 && i_resume != -EAGAIN ) snd_pcm_prepare( p_sys->p_alsa_pcm );
  325.                 break;
  326.             default:
  327.                 msg_Err( p_demux, "Failed to read alsa frame (%s)", snd_strerror( i_read ) );
  328.                 return 0;
  329.         }
  330.     }
  331.     else
  332.     {
  333.         /* convert from frames to bytes */
  334.         i_read *= p_sys->i_alsa_frame_size;
  335.     }
  336.     if( i_read <= 0 ) return 0;
  337.     p_block->i_buffer = i_read;
  338.     p_sys->p_block = 0;
  339.     /* Correct the date because of kernel buffering */
  340.     i_correct = i_read;
  341.     /* ALSA */
  342.     int i_err;
  343.     snd_pcm_sframes_t delay = 0;
  344.     if( ( i_err = snd_pcm_delay( p_sys->p_alsa_pcm, &delay ) ) >= 0 )
  345.     {
  346.         size_t i_correction_delta = delay * p_sys->i_alsa_frame_size;
  347.         /* Test for overrun */
  348.         if( i_correction_delta > p_sys->i_max_frame_size )
  349.         {
  350.             msg_Warn( p_demux, "ALSA read overrun (%zu > %zu)",
  351.                       i_correction_delta, p_sys->i_max_frame_size );
  352.             i_correction_delta = p_sys->i_max_frame_size;
  353.             snd_pcm_prepare( p_sys->p_alsa_pcm );
  354.         }
  355.         i_correct += i_correction_delta;
  356.     }
  357.     else
  358.     {
  359.         /* delay failed so reset */
  360.         msg_Warn( p_demux, "ALSA snd_pcm_delay failed (%s)", snd_strerror( i_err ) );
  361.         snd_pcm_prepare( p_sys->p_alsa_pcm );
  362.     }
  363.     /* Timestamp */
  364.     p_block->i_pts = p_block->i_dts =
  365.         mdate() - INT64_C(1000000) * (mtime_t)i_correct /
  366.         2 / ( p_sys->b_stereo ? 2 : 1) / p_sys->i_sample_rate;
  367.     return p_block;
  368. }
  369. /*****************************************************************************
  370.  * OpenAudioDev: open and set up the audio device and probe for capabilities
  371.  *****************************************************************************/
  372. static int OpenAudioDevAlsa( demux_t *p_demux )
  373. {
  374.     demux_sys_t *p_sys = p_demux->p_sys;
  375.     const char *psz_device = p_sys->psz_device;
  376.     p_sys->p_alsa_pcm = NULL;
  377.     snd_pcm_hw_params_t *p_hw_params = NULL;
  378.     snd_pcm_uframes_t buffer_size;
  379.     snd_pcm_uframes_t chunk_size;
  380.     /* ALSA */
  381.     int i_err;
  382.     if( ( i_err = snd_pcm_open( &p_sys->p_alsa_pcm, psz_device,
  383.         SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK ) ) < 0)
  384.     {
  385.         msg_Err( p_demux, "Cannot open ALSA audio device %s (%s)",
  386.                  psz_device, snd_strerror( i_err ) );
  387.         goto adev_fail;
  388.     }
  389.     if( ( i_err = snd_pcm_nonblock( p_sys->p_alsa_pcm, 1 ) ) < 0)
  390.     {
  391.         msg_Err( p_demux, "Cannot set ALSA nonblock (%s)",
  392.                  snd_strerror( i_err ) );
  393.         goto adev_fail;
  394.     }
  395.     /* Begin setting hardware parameters */
  396.     if( ( i_err = snd_pcm_hw_params_malloc( &p_hw_params ) ) < 0 )
  397.     {
  398.         msg_Err( p_demux,
  399.                  "ALSA: cannot allocate hardware parameter structure (%s)",
  400.                  snd_strerror( i_err ) );
  401.         goto adev_fail;
  402.     }
  403.     if( ( i_err = snd_pcm_hw_params_any( p_sys->p_alsa_pcm, p_hw_params ) ) < 0 )
  404.     {
  405.         msg_Err( p_demux,
  406.                 "ALSA: cannot initialize hardware parameter structure (%s)",
  407.                  snd_strerror( i_err ) );
  408.         goto adev_fail;
  409.     }
  410.     /* Set Interleaved access */
  411.     if( ( i_err = snd_pcm_hw_params_set_access( p_sys->p_alsa_pcm, p_hw_params, SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
  412.     {
  413.         msg_Err( p_demux, "ALSA: cannot set access type (%s)",
  414.                  snd_strerror( i_err ) );
  415.         goto adev_fail;
  416.     }
  417.     /* Set 16 bit little endian */
  418.     if( ( i_err = snd_pcm_hw_params_set_format( p_sys->p_alsa_pcm, p_hw_params, SND_PCM_FORMAT_S16_LE ) ) < 0 )
  419.     {
  420.         msg_Err( p_demux, "ALSA: cannot set sample format (%s)",
  421.                  snd_strerror( i_err ) );
  422.         goto adev_fail;
  423.     }
  424.     /* Set sample rate */
  425. #ifdef HAVE_ALSA_NEW_API
  426.     i_err = snd_pcm_hw_params_set_rate_near( p_sys->p_alsa_pcm, p_hw_params, &p_sys->i_sample_rate, NULL );
  427. #else
  428.     i_err = snd_pcm_hw_params_set_rate_near( p_sys->p_alsa_pcm, p_hw_params, p_sys->i_sample_rate, NULL );
  429. #endif
  430.     if( i_err < 0 )
  431.     {
  432.         msg_Err( p_demux, "ALSA: cannot set sample rate (%s)",
  433.                  snd_strerror( i_err ) );
  434.         goto adev_fail;
  435.     }
  436.     /* Set channels */
  437.     unsigned int channels = p_sys->b_stereo ? 2 : 1;
  438.     if( ( i_err = snd_pcm_hw_params_set_channels( p_sys->p_alsa_pcm, p_hw_params, channels ) ) < 0 )
  439.     {
  440.         channels = ( channels==1 ) ? 2 : 1;
  441.         msg_Warn( p_demux, "ALSA: cannot set channel count (%s). "
  442.                   "Trying with channels=%d",
  443.                   snd_strerror( i_err ),
  444.                   channels );
  445.         if( ( i_err = snd_pcm_hw_params_set_channels( p_sys->p_alsa_pcm, p_hw_params, channels ) ) < 0 )
  446.         {
  447.             msg_Err( p_demux, "ALSA: cannot set channel count (%s)",
  448.                      snd_strerror( i_err ) );
  449.             goto adev_fail;
  450.         }
  451.         p_sys->b_stereo = ( channels == 2 );
  452.     }
  453.     /* Set metrics for buffer calculations later */
  454.     unsigned int buffer_time;
  455.     if( ( i_err = snd_pcm_hw_params_get_buffer_time_max(p_hw_params, &buffer_time, 0) ) < 0 )
  456.     {
  457.         msg_Err( p_demux, "ALSA: cannot get buffer time max (%s)",
  458.                  snd_strerror( i_err ) );
  459.         goto adev_fail;
  460.     }
  461.     if( buffer_time > 500000 ) buffer_time = 500000;
  462.     /* Set period time */
  463.     unsigned int period_time = buffer_time / 4;
  464. #ifdef HAVE_ALSA_NEW_API
  465.     i_err = snd_pcm_hw_params_set_period_time_near( p_sys->p_alsa_pcm, p_hw_params, &period_time, 0 );
  466. #else
  467.     i_err = snd_pcm_hw_params_set_period_time_near( p_sys->p_alsa_pcm, p_hw_params, period_time, 0 );
  468. #endif
  469.     if( i_err < 0 )
  470.     {
  471.         msg_Err( p_demux, "ALSA: cannot set period time (%s)",
  472.                  snd_strerror( i_err ) );
  473.         goto adev_fail;
  474.     }
  475.     /* Set buffer time */
  476. #ifdef HAVE_ALSA_NEW_API
  477.     i_err = snd_pcm_hw_params_set_buffer_time_near( p_sys->p_alsa_pcm, p_hw_params, &buffer_time, 0 );
  478. #else
  479.     i_err = snd_pcm_hw_params_set_buffer_time_near( p_sys->p_alsa_pcm, p_hw_params, buffer_time, 0 );
  480. #endif
  481.     if( i_err < 0 )
  482.     {
  483.         msg_Err( p_demux, "ALSA: cannot set buffer time (%s)",
  484.                  snd_strerror( i_err ) );
  485.         goto adev_fail;
  486.     }
  487.     /* Apply new hardware parameters */
  488.     if( ( i_err = snd_pcm_hw_params( p_sys->p_alsa_pcm, p_hw_params ) ) < 0 )
  489.     {
  490.         msg_Err( p_demux, "ALSA: cannot set hw parameters (%s)",
  491.                  snd_strerror( i_err ) );
  492.         goto adev_fail;
  493.     }
  494.     /* Get various buffer metrics */
  495.     snd_pcm_hw_params_get_period_size( p_hw_params, &chunk_size, 0 );
  496.     snd_pcm_hw_params_get_buffer_size( p_hw_params, &buffer_size );
  497.     if( chunk_size == buffer_size )
  498.     {
  499.         msg_Err( p_demux,
  500.                  "ALSA: period cannot equal buffer size (%lu == %lu)",
  501.                  chunk_size, buffer_size);
  502.         goto adev_fail;
  503.     }
  504.     int bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16_LE);
  505.     int bits_per_frame = bits_per_sample * channels;
  506.     p_sys->i_alsa_chunk_size = chunk_size;
  507.     p_sys->i_alsa_frame_size = bits_per_frame / 8;
  508.     p_sys->i_max_frame_size = chunk_size * bits_per_frame / 8;
  509.     snd_pcm_hw_params_free( p_hw_params );
  510.     p_hw_params = NULL;
  511.     /* Prep device */
  512.     if( ( i_err = snd_pcm_prepare( p_sys->p_alsa_pcm ) ) < 0 )
  513.     {
  514.         msg_Err( p_demux,
  515.                  "ALSA: cannot prepare audio interface for use (%s)",
  516.                  snd_strerror( i_err ) );
  517.         goto adev_fail;
  518.     }
  519.     snd_pcm_start( p_sys->p_alsa_pcm );
  520.     return VLC_SUCCESS;
  521.  adev_fail:
  522.     if( p_hw_params ) snd_pcm_hw_params_free( p_hw_params );
  523.     if( p_sys->p_alsa_pcm ) snd_pcm_close( p_sys->p_alsa_pcm );
  524.     p_sys->p_alsa_pcm = NULL;
  525.     return VLC_EGENERIC;
  526. }
  527. static int OpenAudioDev( demux_t *p_demux )
  528. {
  529.     demux_sys_t *p_sys = p_demux->p_sys;
  530.     if( OpenAudioDevAlsa( p_demux ) != VLC_SUCCESS )
  531.         return VLC_EGENERIC;
  532.     msg_Dbg( p_demux, "opened adev=`%s' %s %dHz",
  533.              p_sys->psz_device, p_sys->b_stereo ? "stereo" : "mono",
  534.              p_sys->i_sample_rate );
  535.     es_format_t fmt;
  536.     es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC('a','r','a','w') );
  537.     fmt.audio.i_channels = p_sys->b_stereo ? 2 : 1;
  538.     fmt.audio.i_rate = p_sys->i_sample_rate;
  539.     fmt.audio.i_bitspersample = 16;
  540.     fmt.audio.i_blockalign = fmt.audio.i_channels * fmt.audio.i_bitspersample / 8;
  541.     fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate * fmt.audio.i_bitspersample;
  542.     msg_Dbg( p_demux, "new audio es %d channels %dHz",
  543.              fmt.audio.i_channels, fmt.audio.i_rate );
  544.     p_sys->p_es = es_out_Add( p_demux->out, &fmt );
  545.     return VLC_SUCCESS;
  546. }
  547. /*****************************************************************************
  548.  * ProbeAudioDevAlsa: probe audio for capabilities
  549.  *****************************************************************************/
  550. static bool ProbeAudioDevAlsa( demux_t *p_demux, const char *psz_device )
  551. {
  552.     int i_err;
  553.     snd_pcm_t *p_alsa_pcm;
  554.     if( ( i_err = snd_pcm_open( &p_alsa_pcm, psz_device, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK ) ) < 0 )
  555.     {
  556.         msg_Err( p_demux, "cannot open device %s for ALSA audio (%s)", psz_device, snd_strerror( i_err ) );
  557.         return false;
  558.     }
  559.     snd_pcm_close( p_alsa_pcm );
  560.     return true;
  561. }