]> git.sesse.net Git - vlc/blob - modules/access/alsa.c
Split Alsa access module from v4l2.
[vlc] / modules / access / alsa.c
1 /*****************************************************************************
2  * alsa.c : Alsa input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2002-2009 the VideoLAN team
5  * $Id$
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 /*
28  * ALSA support based on parts of
29  * http://www.equalarea.com/paul/alsa-audio.html
30  * and hints taken from alsa-utils (aplay/arecord)
31  * http://www.alsa-project.org
32  */
33
34 /*****************************************************************************
35  * Preamble
36  *****************************************************************************/
37
38 #ifdef HAVE_CONFIG_H
39 # include "config.h"
40 #endif
41
42 #include <vlc_common.h>
43 #include <vlc_plugin.h>
44 #include <vlc_access.h>
45 #include <vlc_demux.h>
46 #include <vlc_input.h>
47 #include <vlc_vout.h>
48
49 #include <ctype.h>
50 #include <fcntl.h>
51 #include <unistd.h>
52 #include <sys/ioctl.h>
53 #include <sys/mman.h>
54
55 #include <sys/soundcard.h>
56
57 #define ALSA_PCM_NEW_HW_PARAMS_API
58 #define ALSA_PCM_NEW_SW_PARAMS_API
59 #include <alsa/asoundlib.h>
60
61 #include <poll.h>
62
63 /*****************************************************************************
64  * Module descriptior
65  *****************************************************************************/
66
67 static int  DemuxOpen ( vlc_object_t * );
68 static void DemuxClose( vlc_object_t * );
69
70 #define STEREO_TEXT N_( "Stereo" )
71 #define STEREO_LONGTEXT N_( \
72     "Capture the audio stream in stereo." )
73
74 #define SAMPLERATE_TEXT N_( "Samplerate" )
75 #define SAMPLERATE_LONGTEXT N_( \
76     "Samplerate of the captured audio stream, in Hz (eg: 11025, 22050, 44100, 48000)" )
77
78 #define CACHING_TEXT N_("Caching value in ms")
79 #define CACHING_LONGTEXT N_( \
80     "Caching value for Alsa captures. This " \
81     "value should be set in milliseconds." )
82
83 #define ALSA_DEFAULT "hw"
84 #define CFG_PREFIX "alsa-"
85
86 vlc_module_begin();
87     set_shortname( N_("Alsa") );
88     set_description( N_("Alsa audio capture input") );
89     set_category( CAT_INPUT );
90     set_subcategory( SUBCAT_INPUT_ACCESS );
91
92     add_shortcut( "alsa" );
93     set_capability( "access_demux", 10 );
94     set_callbacks( DemuxOpen, DemuxClose );
95
96     add_bool( CFG_PREFIX "stereo", true, NULL, STEREO_TEXT, STEREO_LONGTEXT,
97                 true );
98     add_integer( CFG_PREFIX "samplerate", 48000, NULL, SAMPLERATE_TEXT,
99                 SAMPLERATE_LONGTEXT, true );
100     add_integer( CFG_PREFIX "caching", DEFAULT_PTS_DELAY / 1000, NULL,
101                 CACHING_TEXT, CACHING_LONGTEXT, true );
102 vlc_module_end();
103
104 /*****************************************************************************
105  * Access: local prototypes
106  *****************************************************************************/
107
108 static int DemuxControl( demux_t *, int, va_list );
109
110 static int Demux( demux_t * );
111
112 static block_t* GrabAudio( demux_t *p_demux );
113
114 static int OpenAudioDev( vlc_object_t *, demux_sys_t * );
115 static bool ProbeAudioDevAlsa( vlc_object_t *, const char *psz_device );
116
117 struct demux_sys_t
118 {
119     const char *psz_device;  /* Alsa device from MRL */
120     int  i_fd_audio;
121
122     /* Audio */
123     int i_pts;
124     unsigned int i_sample_rate;
125     bool b_stereo;
126     size_t i_audio_max_frame_size;
127     block_t *p_block_audio;
128     es_out_id_t *p_es_audio;
129
130     int i_audio_method;
131
132     /* ALSA Audio */
133     snd_pcm_t *p_alsa_pcm;
134     size_t i_alsa_frame_size;
135     int i_alsa_chunk_size;
136 };
137
138 static int FindMainDevice( vlc_object_t *p_this, demux_sys_t *p_sys )
139 {
140     msg_Dbg( p_this, "opening device '%s'", p_sys->psz_device );
141     if( ProbeAudioDevAlsa( p_this, p_sys->psz_device ) )
142     {
143         msg_Dbg( p_this, "'%s' is an audio device", p_sys->psz_device );
144         p_sys->i_fd_audio = OpenAudioDev( p_this, p_sys );
145     }
146
147     if( p_sys->i_fd_audio < 0 )
148         return VLC_EGENERIC;
149     return VLC_SUCCESS;
150 }
151
152 /*****************************************************************************
153  * DemuxOpen: opens alsa device, access_demux callback
154  *****************************************************************************
155  *
156  * url: <alsa device>::::
157  *
158  *****************************************************************************/
159 static int DemuxOpen( vlc_object_t *p_this )
160 {
161     demux_t     *p_demux = (demux_t*)p_this;
162     demux_sys_t *p_sys;
163
164     /* Only when selected */
165     if( *p_demux->psz_access == '\0' ) return VLC_EGENERIC;
166
167     /* Set up p_demux */
168     p_demux->pf_control = DemuxControl;
169     p_demux->pf_demux = Demux;
170     p_demux->info.i_update = 0;
171     p_demux->info.i_title = 0;
172     p_demux->info.i_seekpoint = 0;
173
174     p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
175     if( p_sys == NULL ) return VLC_ENOMEM;
176
177     p_sys->i_sample_rate = var_CreateGetInteger( p_demux, CFG_PREFIX "samplerate" );
178     p_sys->b_stereo = var_CreateGetBool( p_demux, CFG_PREFIX "stereo" );
179     p_sys->i_pts = var_CreateGetInteger( p_demux, CFG_PREFIX "caching" );
180     p_sys->psz_device = NULL;
181     p_sys->i_fd_audio = -1;
182     p_sys->p_es_audio = NULL;
183     p_sys->p_block_audio = NULL;
184
185     if( p_demux->psz_path && *p_demux->psz_path )
186         p_sys->psz_device = p_demux->psz_path;
187     else
188         p_sys->psz_device = ALSA_DEFAULT;
189     msg_Err( p_this, "Device is %s", p_sys->psz_device );
190
191     if( FindMainDevice( p_this, p_sys ) != VLC_SUCCESS )
192     {
193         DemuxClose( p_this );
194         return VLC_EGENERIC;
195     }
196
197     return VLC_SUCCESS;
198 }
199
200 /*****************************************************************************
201  * Close: close device, free resources
202  *****************************************************************************/
203 static void DemuxClose( vlc_object_t *p_this )
204 {
205     demux_t     *p_demux = (demux_t *)p_this;
206     demux_sys_t *p_sys   = p_demux->p_sys;
207
208     if( p_sys->p_alsa_pcm )
209     {
210         snd_pcm_close( p_sys->p_alsa_pcm );
211         p_sys->i_fd_audio = -1;
212     }
213     if( p_sys->i_fd_audio >= 0 ) close( p_sys->i_fd_audio );
214
215     if( p_sys->p_block_audio ) block_Release( p_sys->p_block_audio );
216     free( p_sys );
217 }
218
219 /*****************************************************************************
220  * DemuxControl:
221  *****************************************************************************/
222 static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
223 {
224     demux_sys_t *p_sys = p_demux->p_sys;
225     bool *pb;
226     int64_t *pi64;
227
228     switch( i_query )
229     {
230         /* Special for access_demux */
231         case DEMUX_CAN_PAUSE:
232         case DEMUX_CAN_SEEK:
233         case DEMUX_SET_PAUSE_STATE:
234         case DEMUX_CAN_CONTROL_PACE:
235             pb = (bool*)va_arg( args, bool * );
236             *pb = false;
237             return VLC_SUCCESS;
238
239         case DEMUX_GET_PTS_DELAY:
240             pi64 = (int64_t*)va_arg( args, int64_t * );
241             *pi64 = (int64_t)p_sys->i_pts * 1000;
242             return VLC_SUCCESS;
243
244         case DEMUX_GET_TIME:
245             pi64 = (int64_t*)va_arg( args, int64_t * );
246             *pi64 = mdate();
247             return VLC_SUCCESS;
248
249         /* TODO implement others */
250         default:
251             return VLC_EGENERIC;
252     }
253
254     return VLC_EGENERIC;
255 }
256
257 /*****************************************************************************
258  * Demux: Processes the audio frame
259  *****************************************************************************/
260 static int Demux( demux_t *p_demux )
261 {
262     demux_sys_t *p_sys = p_demux->p_sys;
263
264     struct pollfd fd;
265     fd.fd = p_sys->i_fd_audio;
266     fd.events = POLLIN|POLLPRI;
267     fd.revents = 0;
268
269     /* Wait for data */
270     if( poll( &fd, 1, 500 ) ) /* Timeout after 0.5 seconds since I don't know if pf_demux can be blocking. */
271     {
272         if( fd.revents & (POLLIN|POLLPRI) )
273         {
274             block_t *p_block = GrabAudio( p_demux );
275             if( p_block )
276             {
277                 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
278                 es_out_Send( p_demux->out, p_sys->p_es_audio, p_block );
279             }
280         }
281     }
282
283     return 1;
284 }
285
286
287 /*****************************************************************************
288  * GrabAudio: Grab an audio frame
289  *****************************************************************************/
290 static block_t* GrabAudio( demux_t *p_demux )
291 {
292     demux_sys_t *p_sys = p_demux->p_sys;
293     int i_read = 0, i_correct;
294     block_t *p_block;
295
296     printf("%s %d\n",__func__,__LINE__);
297     if( p_sys->p_block_audio ) p_block = p_sys->p_block_audio;
298     else p_block = block_New( p_demux, p_sys->i_audio_max_frame_size );
299
300     if( !p_block )
301     {
302         msg_Warn( p_demux, "cannot get block" );
303         return 0;
304     }
305
306     p_sys->p_block_audio = p_block;
307
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
337     if( i_read <= 0 ) return 0;
338
339     p_block->i_buffer = i_read;
340     p_sys->p_block_audio = 0;
341
342     /* Correct the date because of kernel buffering */
343     i_correct = i_read;
344     /* ALSA */
345     int i_err;
346     snd_pcm_sframes_t delay = 0;
347     if( ( i_err = snd_pcm_delay( p_sys->p_alsa_pcm, &delay ) ) >= 0 )
348     {
349         size_t i_correction_delta = delay * p_sys->i_alsa_frame_size;
350         /* Test for overrun */
351         if( i_correction_delta > p_sys->i_audio_max_frame_size )
352         {
353             msg_Warn( p_demux, "ALSA read overrun (%zu > %zu)",
354                       i_correction_delta, p_sys->i_audio_max_frame_size );
355             i_correction_delta = p_sys->i_audio_max_frame_size;
356             snd_pcm_prepare( p_sys->p_alsa_pcm );
357         }
358         i_correct += i_correction_delta;
359     }
360     else
361     {
362         /* delay failed so reset */
363         msg_Warn( p_demux, "ALSA snd_pcm_delay failed (%s)", snd_strerror( i_err ) );
364         snd_pcm_prepare( p_sys->p_alsa_pcm );
365     }
366
367     /* Timestamp */
368     p_block->i_pts = p_block->i_dts =
369         mdate() - INT64_C(1000000) * (mtime_t)i_correct /
370         2 / ( p_sys->b_stereo ? 2 : 1) / p_sys->i_sample_rate;
371
372     return p_block;
373 }
374
375 /*****************************************************************************
376  * OpenAudioDev: open and set up the audio device and probe for capabilities
377  *****************************************************************************/
378 static int OpenAudioDevAlsa( vlc_object_t *p_this, demux_sys_t *p_sys )
379 {
380     const char *psz_device = p_sys->psz_device;
381     p_sys->p_alsa_pcm = NULL;
382     snd_pcm_hw_params_t *p_hw_params = NULL;
383     snd_pcm_uframes_t buffer_size;
384     snd_pcm_uframes_t chunk_size;
385
386     /* ALSA */
387     int i_err;
388
389     if( ( i_err = snd_pcm_open( &p_sys->p_alsa_pcm, psz_device,
390         SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK ) ) < 0)
391     {
392         msg_Err( p_this, "Cannot open ALSA audio device %s (%s)",
393                  psz_device, snd_strerror( i_err ) );
394         goto adev_fail;
395     }
396
397     if( ( i_err = snd_pcm_nonblock( p_sys->p_alsa_pcm, 1 ) ) < 0)
398     {
399         msg_Err( p_this, "Cannot set ALSA nonblock (%s)",
400                  snd_strerror( i_err ) );
401         goto adev_fail;
402     }
403
404     /* Begin setting hardware parameters */
405
406     if( ( i_err = snd_pcm_hw_params_malloc( &p_hw_params ) ) < 0 )
407     {
408         msg_Err( p_this,
409                  "ALSA: cannot allocate hardware parameter structure (%s)",
410                  snd_strerror( i_err ) );
411         goto adev_fail;
412     }
413
414     if( ( i_err = snd_pcm_hw_params_any( p_sys->p_alsa_pcm, p_hw_params ) ) < 0 )
415     {
416         msg_Err( p_this,
417                 "ALSA: cannot initialize hardware parameter structure (%s)",
418                  snd_strerror( i_err ) );
419         goto adev_fail;
420     }
421
422     /* Set Interleaved access */
423     if( ( i_err = snd_pcm_hw_params_set_access( p_sys->p_alsa_pcm, p_hw_params, SND_PCM_ACCESS_RW_INTERLEAVED ) ) < 0 )
424     {
425         msg_Err( p_this, "ALSA: cannot set access type (%s)",
426                  snd_strerror( i_err ) );
427         goto adev_fail;
428     }
429
430     /* Set 16 bit little endian */
431     if( ( i_err = snd_pcm_hw_params_set_format( p_sys->p_alsa_pcm, p_hw_params, SND_PCM_FORMAT_S16_LE ) ) < 0 )
432     {
433         msg_Err( p_this, "ALSA: cannot set sample format (%s)",
434                  snd_strerror( i_err ) );
435         goto adev_fail;
436     }
437
438     /* Set sample rate */
439 #ifdef HAVE_ALSA_NEW_API
440     i_err = snd_pcm_hw_params_set_rate_near( p_sys->p_alsa_pcm, p_hw_params, &p_sys->i_sample_rate, NULL );
441 #else
442     i_err = snd_pcm_hw_params_set_rate_near( p_sys->p_alsa_pcm, p_hw_params, p_sys->i_sample_rate, NULL );
443 #endif
444     if( i_err < 0 )
445     {
446         msg_Err( p_this, "ALSA: cannot set sample rate (%s)",
447                  snd_strerror( i_err ) );
448         goto adev_fail;
449     }
450
451     /* Set channels */
452     unsigned int channels = p_sys->b_stereo ? 2 : 1;
453     if( ( i_err = snd_pcm_hw_params_set_channels( p_sys->p_alsa_pcm, p_hw_params, channels ) ) < 0 )
454     {
455         channels = ( channels==1 ) ? 2 : 1;
456         msg_Warn( p_this, "ALSA: cannot set channel count (%s). "
457                   "Trying with channels=%d",
458                   snd_strerror( i_err ),
459                   channels );
460         if( ( i_err = snd_pcm_hw_params_set_channels( p_sys->p_alsa_pcm, p_hw_params, channels ) ) < 0 )
461         {
462             msg_Err( p_this, "ALSA: cannot set channel count (%s)",
463                      snd_strerror( i_err ) );
464             goto adev_fail;
465         }
466         p_sys->b_stereo = ( channels == 2 );
467     }
468
469     /* Set metrics for buffer calculations later */
470     unsigned int buffer_time;
471     if( ( i_err = snd_pcm_hw_params_get_buffer_time_max(p_hw_params, &buffer_time, 0) ) < 0 )
472     {
473         msg_Err( p_this, "ALSA: cannot get buffer time max (%s)",
474                  snd_strerror( i_err ) );
475         goto adev_fail;
476     }
477     if( buffer_time > 500000 ) buffer_time = 500000;
478
479     /* Set period time */
480     unsigned int period_time = buffer_time / 4;
481 #ifdef HAVE_ALSA_NEW_API
482     i_err = snd_pcm_hw_params_set_period_time_near( p_sys->p_alsa_pcm, p_hw_params, &period_time, 0 );
483 #else
484     i_err = snd_pcm_hw_params_set_period_time_near( p_sys->p_alsa_pcm, p_hw_params, period_time, 0 );
485 #endif
486     if( i_err < 0 )
487     {
488         msg_Err( p_this, "ALSA: cannot set period time (%s)",
489                  snd_strerror( i_err ) );
490         goto adev_fail;
491     }
492
493     /* Set buffer time */
494 #ifdef HAVE_ALSA_NEW_API
495     i_err = snd_pcm_hw_params_set_buffer_time_near( p_sys->p_alsa_pcm, p_hw_params, &buffer_time, 0 );
496 #else
497     i_err = snd_pcm_hw_params_set_buffer_time_near( p_sys->p_alsa_pcm, p_hw_params, buffer_time, 0 );
498 #endif
499     if( i_err < 0 )
500     {
501         msg_Err( p_this, "ALSA: cannot set buffer time (%s)",
502                  snd_strerror( i_err ) );
503         goto adev_fail;
504     }
505
506     /* Apply new hardware parameters */
507     if( ( i_err = snd_pcm_hw_params( p_sys->p_alsa_pcm, p_hw_params ) ) < 0 )
508     {
509         msg_Err( p_this, "ALSA: cannot set hw parameters (%s)",
510                  snd_strerror( i_err ) );
511         goto adev_fail;
512     }
513
514     /* Get various buffer metrics */
515     snd_pcm_hw_params_get_period_size( p_hw_params, &chunk_size, 0 );
516     snd_pcm_hw_params_get_buffer_size( p_hw_params, &buffer_size );
517     if( chunk_size == buffer_size )
518     {
519         msg_Err( p_this,
520                  "ALSA: period cannot equal buffer size (%lu == %lu)",
521                  chunk_size, buffer_size);
522         goto adev_fail;
523     }
524
525     int bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16_LE);
526     int bits_per_frame = bits_per_sample * channels;
527
528     p_sys->i_alsa_chunk_size = chunk_size;
529     p_sys->i_alsa_frame_size = bits_per_frame / 8;
530     p_sys->i_audio_max_frame_size = chunk_size * bits_per_frame / 8;
531
532     snd_pcm_hw_params_free( p_hw_params );
533     p_hw_params = NULL;
534
535     /* Prep device */
536     if( ( i_err = snd_pcm_prepare( p_sys->p_alsa_pcm ) ) < 0 )
537     {
538         msg_Err( p_this,
539                  "ALSA: cannot prepare audio interface for use (%s)",
540                  snd_strerror( i_err ) );
541         goto adev_fail;
542     }
543
544     if( !p_sys->psz_device )
545         p_sys->psz_device = strdup( ALSA_DEFAULT );
546
547     /* Return a fake handle so other tests work */
548     return 1;
549
550  adev_fail:
551
552     if( p_hw_params ) snd_pcm_hw_params_free( p_hw_params );
553     if( p_sys->p_alsa_pcm ) snd_pcm_close( p_sys->p_alsa_pcm );
554
555     return -1;
556
557 }
558
559 static int OpenAudioDev( vlc_object_t *p_this, demux_sys_t *p_sys )
560 {
561     int i_fd  = OpenAudioDevAlsa( p_this, p_sys );
562
563     if( i_fd < 0 )
564         return i_fd;
565
566     msg_Dbg( p_this, "opened adev=`%s' %s %dHz",
567              p_sys->psz_device, p_sys->b_stereo ? "stereo" : "mono",
568              p_sys->i_sample_rate );
569
570     es_format_t fmt;
571     es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC('a','r','a','w') );
572
573     fmt.audio.i_channels = p_sys->b_stereo ? 2 : 1;
574     fmt.audio.i_rate = p_sys->i_sample_rate;
575     fmt.audio.i_bitspersample = 16;
576     fmt.audio.i_blockalign = fmt.audio.i_channels * fmt.audio.i_bitspersample / 8;
577     fmt.i_bitrate = fmt.audio.i_channels * fmt.audio.i_rate * fmt.audio.i_bitspersample;
578
579     msg_Dbg( p_this, "new audio es %d channels %dHz",
580              fmt.audio.i_channels, fmt.audio.i_rate );
581
582     demux_t *p_demux = (demux_t *)p_this;
583     p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );
584
585     return i_fd;
586 }
587
588 /*****************************************************************************
589  * ProbeAudioDevAlsa: probe audio for capabilities
590  *****************************************************************************/
591 static bool ProbeAudioDevAlsa( vlc_object_t *p_this, const char *psz_device )
592 {
593     int i_err;
594     snd_pcm_t *p_alsa_pcm;
595
596     if( ( i_err = snd_pcm_open( &p_alsa_pcm, psz_device, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK ) ) < 0 )
597     {
598         msg_Err( p_this, "cannot open device %s for ALSA audio (%s)", psz_device, snd_strerror( i_err ) );
599         return false;
600     }
601
602     snd_pcm_close( p_alsa_pcm );
603
604     return true;
605 }