2004-07-16 19:56:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/***
 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-19 21:53:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  This  file  is  part  of  PulseAudio . 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-13 15:35:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  Copyright  2004 - 2006  Lennart  Poettering 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  Copyright  2006  Pierre  Ossman  < ossman @ cendio . se >  for  Cendio  AB 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-19 21:53:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  PulseAudio  is  free  software ;  you  can  redistribute  it  and / or  modify 
							 
						 
					
						
							
								
									
										
										
										
											2004-11-14 14:58:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  it  under  the  terms  of  the  GNU  Lesser  General  Public  License  as  published 
							 
						 
					
						
							
								
									
										
										
										
											2004-07-16 19:56:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  by  the  Free  Software  Foundation ;  either  version  2  of  the  License , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  or  ( at  your  option )  any  later  version . 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-19 21:53:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  PulseAudio  is  distributed  in  the  hope  that  it  will  be  useful ,  but 
							 
						 
					
						
							
								
									
										
										
										
											2004-07-16 19:56:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  WITHOUT  ANY  WARRANTY ;  without  even  the  implied  warranty  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  MERCHANTABILITY  or  FITNESS  FOR  A  PARTICULAR  PURPOSE .  See  the  GNU 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  General  Public  License  for  more  details . 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-11-14 14:58:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  You  should  have  received  a  copy  of  the  GNU  Lesser  General  Public  License 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-19 21:53:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  along  with  PulseAudio ;  if  not ,  write  to  the  Free  Software 
							 
						 
					
						
							
								
									
										
										
										
											2004-07-16 19:56:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  Foundation ,  Inc . ,  59  Temple  Place ,  Suite  330 ,  Boston ,  MA  02111 - 1307 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  USA . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-07-16 19:16:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef HAVE_CONFIG_H 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <config.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-11-17 23:11:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <sys/types.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <limits.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2004-07-16 17:03:11 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  <asoundlib.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-19 21:53:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulse/sample.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulse/xmalloc.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-21 20:00:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulse/timeval.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-30 02:24:40 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulse/util.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-17 16:34:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-19 21:53:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulsecore/log.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulsecore/macro.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulsecore/core-util.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulsecore/atomic.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-18 21:49:31 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulsecore/core-error.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-16 22:08:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "alsa-util.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2004-07-16 17:03:11 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-24 01:25:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef HAVE_HAL 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "hal-util.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  pa_alsa_fdlist  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    unsigned  num_fds ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    struct  pollfd  * fds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* This is a temporary buffer used to avoid lots of mallocs */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  pollfd  * work_fds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 21:50:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_mixer_t  * mixer ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_mainloop_api  * m ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_defer_event  * defer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_io_event  * * ios ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  polled ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    void  ( * cb ) ( void  * userdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    void  * userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-09 16:20:29 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  io_cb ( pa_mainloop_api * a ,  pa_io_event *  e ,  int  fd ,  pa_io_event_flags_t  events ,  void  * userdata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  pa_alsa_fdlist  * fdl  =  userdata ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    unsigned  short  revents ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( a ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( fdl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( fdl - > mixer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( fdl - > fds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( fdl - > work_fds ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( fdl - > polled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    fdl - > polled  =  TRUE ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    memcpy ( fdl - > work_fds ,  fdl - > fds ,  sizeof ( struct  pollfd )  *  fdl - > num_fds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    for  ( i  =  0 ;  i  <  fdl - > num_fds ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( e  = =  fdl - > ios [ i ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( events  &  PA_IO_EVENT_INPUT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                fdl - > work_fds [ i ] . revents  | =  POLLIN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( events  &  PA_IO_EVENT_OUTPUT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                fdl - > work_fds [ i ] . revents  | =  POLLOUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( events  &  PA_IO_EVENT_ERROR ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                fdl - > work_fds [ i ] . revents  | =  POLLERR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( events  &  PA_IO_EVENT_HANGUP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                fdl - > work_fds [ i ] . revents  | =  POLLHUP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( i  ! =  fdl - > num_fds ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 21:50:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_mixer_poll_descriptors_revents ( fdl - > mixer ,  fdl - > work_fds ,  fdl - > num_fds ,  & revents ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_error ( " Unable to get poll revent: %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-11 15:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    a - > defer_enable ( fdl - > defer ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( revents ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_mixer_handle_events ( fdl - > mixer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-09 16:20:29 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  defer_cb ( pa_mainloop_api * a ,  pa_defer_event *  e ,  void  * userdata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    struct  pa_alsa_fdlist  * fdl  =  userdata ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    unsigned  num_fds ,  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    struct  pollfd  * temp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( a ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( fdl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( fdl - > mixer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 09:23:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    a - > defer_enable ( fdl - > defer ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    num_fds  =  ( unsigned )  snd_mixer_poll_descriptors_count ( fdl - > mixer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( num_fds  ! =  fdl - > num_fds )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( fdl - > fds ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_xfree ( fdl - > fds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( fdl - > work_fds ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_xfree ( fdl - > work_fds ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        fdl - > fds  =  pa_xnew0 ( struct  pollfd ,  num_fds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        fdl - > work_fds  =  pa_xnew ( struct  pollfd ,  num_fds ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    memset ( fdl - > work_fds ,  0 ,  sizeof ( struct  pollfd )  *  num_fds ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 21:50:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_mixer_poll_descriptors ( fdl - > mixer ,  fdl - > work_fds ,  num_fds ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_error ( " Unable to get poll descriptors: %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    fdl - > polled  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( memcmp ( fdl - > fds ,  fdl - > work_fds ,  sizeof ( struct  pollfd )  *  num_fds )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( fdl - > ios )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        for  ( i  =  0 ;  i  <  fdl - > num_fds ;  i + + ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            a - > io_free ( fdl - > ios [ i ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( num_fds  ! =  fdl - > num_fds )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_xfree ( fdl - > ios ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            fdl - > ios  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! fdl - > ios ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        fdl - > ios  =  pa_xnew ( pa_io_event * ,  num_fds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Swap pointers */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    temp  =  fdl - > work_fds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > work_fds  =  fdl - > fds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > fds  =  temp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > num_fds  =  num_fds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    for  ( i  =  0 ; i  <  num_fds ; i + + ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        fdl - > ios [ i ]  =  a - > io_new ( a ,  fdl - > fds [ i ] . fd , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ( ( fdl - > fds [ i ] . events  &  POLLIN )  ?  PA_IO_EVENT_INPUT  :  0 )  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ( ( fdl - > fds [ i ] . events  &  POLLOUT )  ?  PA_IO_EVENT_OUTPUT  :  0 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            io_cb ,  fdl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  pa_alsa_fdlist  * pa_alsa_fdlist_new ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  pa_alsa_fdlist  * fdl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    fdl  =  pa_xnew0 ( struct  pa_alsa_fdlist ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > num_fds  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > fds  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > work_fds  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 21:50:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    fdl - > mixer  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    fdl - > m  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > defer  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > ios  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    fdl - > polled  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  fdl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  pa_alsa_fdlist_free ( struct  pa_alsa_fdlist  * fdl )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( fdl ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( fdl - > defer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_assert ( fdl - > m ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        fdl - > m - > defer_free ( fdl - > defer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( fdl - > ios )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        unsigned  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_assert ( fdl - > m ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        for  ( i  =  0 ;  i  <  fdl - > num_fds ;  i + + ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-11 16:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            fdl - > m - > io_free ( fdl - > ios [ i ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_xfree ( fdl - > ios ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( fdl - > fds ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_xfree ( fdl - > fds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( fdl - > work_fds ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_xfree ( fdl - > work_fds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( fdl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  pa_alsa_fdlist_set_mixer ( struct  pa_alsa_fdlist  * fdl ,  snd_mixer_t  * mixer_handle ,  pa_mainloop_api *  m )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( fdl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( mixer_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( m ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ! fdl - > m ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 21:50:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > mixer  =  mixer_handle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > m  =  m ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > defer  =  m - > defer_new ( m ,  defer_cb ,  fdl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  set_format ( snd_pcm_t  * pcm_handle ,  snd_pcm_hw_params_t  * hwparams ,  pa_sample_format_t  * f )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-07-16 17:03:11 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    static  const  snd_pcm_format_t  format_trans [ ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_U8 ]  =  SND_PCM_FORMAT_U8 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_ALAW ]  =  SND_PCM_FORMAT_A_LAW , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_ULAW ]  =  SND_PCM_FORMAT_MU_LAW , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_S16LE ]  =  SND_PCM_FORMAT_S16_LE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_S16BE ]  =  SND_PCM_FORMAT_S16_BE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_FLOAT32LE ]  =  SND_PCM_FORMAT_FLOAT_LE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_FLOAT32BE ]  =  SND_PCM_FORMAT_FLOAT_BE , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-09 02:45:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_S32LE ]  =  SND_PCM_FORMAT_S32_LE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_S32BE ]  =  SND_PCM_FORMAT_S32_BE , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 03:15:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_S24LE ]  =  SND_PCM_FORMAT_S24_3LE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_S24BE ]  =  SND_PCM_FORMAT_S24_3BE , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 18:39:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_S24_32LE ]  =  SND_PCM_FORMAT_S24_LE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ PA_SAMPLE_S24_32BE ]  =  SND_PCM_FORMAT_S24_BE , 
							 
						 
					
						
							
								
									
										
										
										
											2004-07-16 17:03:11 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    static  const  pa_sample_format_t  try_order [ ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_FLOAT32NE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_FLOAT32RE , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-09 02:45:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_S32NE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_S32RE , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 18:39:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_S24_32NE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_S24_32RE , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 03:15:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_S24NE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_S24RE , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-09 02:45:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_S16NE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_S16RE , 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_ALAW , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-09 02:45:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_ULAW , 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_U8 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        PA_SAMPLE_INVALID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  i ,  ret ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( ret  =  snd_pcm_hw_params_set_format ( pcm_handle ,  hwparams ,  format_trans [ * f ] ) )  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( * f  = =  PA_SAMPLE_FLOAT32BE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * f  =  PA_SAMPLE_FLOAT32LE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  if  ( * f  = =  PA_SAMPLE_FLOAT32LE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * f  =  PA_SAMPLE_FLOAT32BE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 03:15:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    else  if  ( * f  = =  PA_SAMPLE_S24BE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * f  =  PA_SAMPLE_S24LE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  if  ( * f  = =  PA_SAMPLE_S24LE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * f  =  PA_SAMPLE_S24BE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 18:39:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    else  if  ( * f  = =  PA_SAMPLE_S24_32BE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * f  =  PA_SAMPLE_S24_32LE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  if  ( * f  = =  PA_SAMPLE_S24_32LE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * f  =  PA_SAMPLE_S24_32BE ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    else  if  ( * f  = =  PA_SAMPLE_S16BE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * f  =  PA_SAMPLE_S16LE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  if  ( * f  = =  PA_SAMPLE_S16LE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * f  =  PA_SAMPLE_S16BE ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-09 02:45:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    else  if  ( * f  = =  PA_SAMPLE_S32BE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * f  =  PA_SAMPLE_S32LE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  if  ( * f  = =  PA_SAMPLE_S32LE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * f  =  PA_SAMPLE_S32BE ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  try_auto ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( ret  =  snd_pcm_hw_params_set_format ( pcm_handle ,  hwparams ,  format_trans [ * f ] ) )  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  ret ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								try_auto : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( i  =  0 ;  try_order [ i ]  ! =  PA_SAMPLE_INVALID ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * f  =  try_order [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ( ret  =  snd_pcm_hw_params_set_format ( pcm_handle ,  hwparams ,  format_trans [ * f ] ) )  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Set the hardware parameters of the given ALSA device. Returns the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  selected  fragment  settings  in  * period  and  * period_size  */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  pa_alsa_set_hw_params ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_t  * pcm_handle , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sample_spec  * ss , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        uint32_t  * periods , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_uframes_t  * period_size , 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        snd_pcm_uframes_t  tsched_size , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_bool_t  * use_mmap , 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_bool_t  * use_tsched , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_bool_t  require_exact_channel_number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  ret  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_pcm_uframes_t  _period_size  =  period_size  ?  * period_size  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  int  _periods  =  periods  ?  * periods  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_pcm_uframes_t  buffer_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  int  r  =  ss - > rate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  int  c  =  ss - > channels ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sample_format_t  f  =  ss - > format ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_hw_params_t  * hwparams ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  _use_mmap  =  use_mmap  & &  * use_mmap ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  _use_tsched  =  use_tsched  & &  * use_tsched ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  dir ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_hw_params_alloca ( & hwparams ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-05 18:37:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 23:42:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( ret  =  snd_pcm_hw_params_any ( pcm_handle ,  hwparams ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( ret  =  snd_pcm_hw_params_set_rate_resample ( pcm_handle ,  hwparams ,  0 ) )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( _use_mmap )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-18 21:50:09 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( snd_pcm_hw_params_set_access ( pcm_handle ,  hwparams ,  SND_PCM_ACCESS_MMAP_INTERLEAVED )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* mmap() didn't work, fall back to interleaved */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ( ret  =  snd_pcm_hw_params_set_access ( pcm_handle ,  hwparams ,  SND_PCM_ACCESS_RW_INTERLEAVED ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            _use_mmap  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( ( ret  =  snd_pcm_hw_params_set_access ( pcm_handle ,  hwparams ,  SND_PCM_ACCESS_RW_INTERLEAVED ) )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-17 23:36:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! _use_mmap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        _use_tsched  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-17 23:36:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( ret  =  set_format ( pcm_handle ,  hwparams ,  & f ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( ret  =  snd_pcm_hw_params_set_rate_near ( pcm_handle ,  hwparams ,  & r ,  NULL ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( require_exact_channel_number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( ret  =  snd_pcm_hw_params_set_channels ( pcm_handle ,  hwparams ,  c ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( ret  =  snd_pcm_hw_params_set_channels_near ( pcm_handle ,  hwparams ,  & c ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-17 23:36:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( ret  =  snd_pcm_hw_params_set_periods_integer ( pcm_handle ,  hwparams ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  finish ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( _period_size  & &  tsched_size  & &  _periods )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* Adjust the buffer sizes, if we didn't get the rate we were asking for */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        _period_size  =  ( snd_pcm_uframes_t )  ( ( ( uint64_t )  _period_size  *  r )  /  ss - > rate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        tsched_size  =  ( snd_pcm_uframes_t )  ( ( ( uint64_t )  tsched_size  *  r )  /  ss - > rate ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( _use_tsched )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            _period_size  =  tsched_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            _periods  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_assert_se ( snd_pcm_hw_params_get_buffer_size_max ( hwparams ,  & buffer_size )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_debug ( " Maximum hw buffer size is %u ms " ,  ( unsigned )  buffer_size  *  1000  /  r ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        buffer_size  =  _periods  *  _period_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-17 23:36:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( _periods  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-09 00:04:50 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            /* First we pass 0 as direction to get exactly what we asked
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             *  for .  That  this  is  necessary  is  presumably  a  bug  in  ALSA  */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-09 00:04:50 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            dir  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-09 00:04:50 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( ( ret  =  snd_pcm_hw_params_set_periods_near ( pcm_handle ,  hwparams ,  & _periods ,  & dir ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                dir  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( ( ret  =  snd_pcm_hw_params_set_periods_near ( pcm_handle ,  hwparams ,  & _periods ,  & dir ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    dir  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    if  ( ( ret  =  snd_pcm_hw_params_set_periods_near ( pcm_handle ,  hwparams ,  & _periods ,  & dir ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-09 00:04:50 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( _period_size  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ( ret  =  snd_pcm_hw_params_set_buffer_size_near ( pcm_handle ,  hwparams ,  & buffer_size ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-17 23:36:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if   ( ( ret  =  snd_pcm_hw_params ( pcm_handle ,  hwparams ) )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-11-20 22:17:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        goto  finish ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-20 23:47:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ss - > rate  ! =  r ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Device %s doesn't support %u Hz, changed to %u Hz. " ,  snd_pcm_name ( pcm_handle ) ,  ss - > rate ,  r ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-30 22:05:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ss - > channels  ! =  c ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Device %s doesn't support %u channels, changed to %u. " ,  snd_pcm_name ( pcm_handle ) ,  ss - > channels ,  c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ss - > format  ! =  f ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Device %s doesn't support sample format %s, changed to %s. " ,  snd_pcm_name ( pcm_handle ) ,  pa_sample_format_to_string ( ss - > format ) ,  pa_sample_format_to_string ( f ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-05 18:35:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( ret  =  snd_pcm_prepare ( pcm_handle ) )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-11-20 22:17:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( ret  =  snd_pcm_hw_params_get_period_size ( hwparams ,  & _period_size ,  & dir ) )  <  0  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( ret  =  snd_pcm_hw_params_get_periods ( hwparams ,  & _periods ,  & dir ) )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-11-20 22:17:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        goto  finish ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* If the sample rate deviates too much, we need to resample */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( r  <  ss - > rate * .95  | |  r  >  ss - > rate * 1.05 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ss - > rate  =  r ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ss - > channels  =  ( uint8_t )  c ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ss - > format  =  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( _periods  >  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( _period_size  >  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( periods ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * periods  =  _periods ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( period_size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * period_size  =  _period_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( use_mmap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * use_mmap  =  _use_mmap ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( use_tsched ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * use_tsched  =  _use_tsched ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-11-20 22:17:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_pcm_nonblock ( pcm_handle ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-11-20 22:17:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								finish : 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-07-16 17:03:11 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  pa_alsa_set_sw_params ( snd_pcm_t  * pcm ,  snd_pcm_uframes_t  avail_min )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_pcm_sw_params_t  * swparams ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( pcm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_sw_params_alloca ( & swparams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_pcm_sw_params_current ( pcm ,  swparams )  <  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Unable to determine current swparams: %s \n " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_pcm_sw_params_set_stop_threshold ( pcm ,  swparams ,  ( snd_pcm_uframes_t )  - 1 ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Unable to set stop threshold: %s \n " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_pcm_sw_params_set_start_threshold ( pcm ,  swparams ,  ( snd_pcm_uframes_t )  - 1 ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Unable to set start threshold: %s \n " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_pcm_sw_params_set_avail_min ( pcm ,  swparams ,  avail_min ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_error ( " snd_pcm_sw_params_set_avail_min() failed: %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_pcm_sw_params ( pcm ,  swparams ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Unable to set sw params: %s \n " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  const  struct  pa_alsa_profile_info  device_table [ ]  =  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { {  1 ,  {  PA_CHANNEL_POSITION_MONO  } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " hw " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " Analog Mono " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 20:35:18 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     " analog-mono " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     1  } , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  2 ,  {  PA_CHANNEL_POSITION_LEFT ,  PA_CHANNEL_POSITION_RIGHT  } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " front " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " Analog Stereo " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 20:35:18 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     " analog-stereo " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     10  } , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  2 ,  {  PA_CHANNEL_POSITION_LEFT ,  PA_CHANNEL_POSITION_RIGHT  } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " iec958 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " IEC958 Digital Stereo " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 20:35:18 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     " iec958-stereo " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     5  } , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  2 ,  {  PA_CHANNEL_POSITION_LEFT ,  PA_CHANNEL_POSITION_RIGHT  } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " hdmi " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " HDMI Digital Stereo " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 20:35:18 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     " hdmi-stereo " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     4  } , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  4 ,  {  PA_CHANNEL_POSITION_FRONT_LEFT ,  PA_CHANNEL_POSITION_FRONT_RIGHT , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_REAR_LEFT ,  PA_CHANNEL_POSITION_REAR_RIGHT  } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " surround40 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " Analog Surround 4.0 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 20:35:18 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     " analog-surround-40 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     7  } , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  4 ,  {  PA_CHANNEL_POSITION_FRONT_LEFT ,  PA_CHANNEL_POSITION_FRONT_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_REAR_LEFT ,  PA_CHANNEL_POSITION_REAR_RIGHT  } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " a52 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " IEC958/AC3 Digital Surround 4.0 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 20:35:18 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     " iec958-ac3-surround-40 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     2  } , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  5 ,  {  PA_CHANNEL_POSITION_FRONT_LEFT ,  PA_CHANNEL_POSITION_FRONT_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_REAR_LEFT ,  PA_CHANNEL_POSITION_REAR_RIGHT , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_LFE  } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " surround41 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " Analog Surround 4.1 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 20:35:18 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     " analog-surround-41 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     7  } , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  5 ,  {  PA_CHANNEL_POSITION_FRONT_LEFT ,  PA_CHANNEL_POSITION_FRONT_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_REAR_LEFT ,  PA_CHANNEL_POSITION_REAR_RIGHT , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_CENTER  } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " surround50 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " Analog Surround 5.0 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 20:35:18 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     " analog-surround-50 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     7  } , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  6 ,  {  PA_CHANNEL_POSITION_FRONT_LEFT ,  PA_CHANNEL_POSITION_FRONT_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_REAR_LEFT ,  PA_CHANNEL_POSITION_REAR_RIGHT , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_CENTER ,  PA_CHANNEL_POSITION_LFE  } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " surround51 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " Analog Surround 5.1 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 20:35:18 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     " analog-surround-51 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     8  } , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  6 ,  {  PA_CHANNEL_POSITION_FRONT_LEFT ,  PA_CHANNEL_POSITION_FRONT_CENTER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_FRONT_RIGHT ,  PA_CHANNEL_POSITION_REAR_LEFT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_REAR_RIGHT ,  PA_CHANNEL_POSITION_LFE } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " a52 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " IEC958/AC3 Digital Surround 5.1 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 20:35:18 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     " iec958-ac3-surround-51 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     3  } , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  8 ,  {  PA_CHANNEL_POSITION_FRONT_LEFT ,  PA_CHANNEL_POSITION_FRONT_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_REAR_LEFT ,  PA_CHANNEL_POSITION_REAR_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_CENTER ,  PA_CHANNEL_POSITION_LFE , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_SIDE_LEFT ,  PA_CHANNEL_POSITION_SIDE_RIGHT  } } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " surround71 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     " Analog Surround 7.1 " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 20:35:18 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     " analog-surround-71 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     7  } , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 20:35:18 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { {  0 ,  {  0  } } ,  NULL ,  NULL ,  NULL ,  0  } 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 21:36:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								snd_pcm_t  * pa_alsa_open_by_device_id_auto ( 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        const  char  * dev_id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        char  * * dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sample_spec  * ss , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_channel_map *  map , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        int  mode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        uint32_t  * nfrags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_uframes_t  * period_size , 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        snd_pcm_uframes_t  tsched_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  * use_mmap , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_bool_t  * use_tsched , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 21:36:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        const  pa_alsa_profile_info  * * profile )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  direction  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  * d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_t  * pcm_handle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( dev_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( map ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( nfrags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( period_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* First we try to find a device string with a superset of the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  requested  channel  map  and  open  it  without  the  plug :  prefix .  We 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  iterate  through  our  device  table  from  top  to  bottom  and  take 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  the  first  that  matches .  If  we  didn ' t  find  a  working  device  that 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  way ,  we  iterate  backwards ,  and  check  all  devices  that  do  not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  provide  a  superset  of  the  requested  channel  map . */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 21:00:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ( direction  >  0 )  = =  pa_channel_map_superset ( & device_table [ i ] . map ,  map ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 22:01:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_sample_spec  try_ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_log_debug ( " Checking for %s (%s) " ,  device_table [ i ] . name ,  device_table [ i ] . alsa_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            d  =  pa_sprintf_malloc ( " %s:%s " ,  device_table [ i ] . alsa_name ,  dev_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 22:01:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            try_ss . channels  =  device_table [ i ] . map . channels ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            try_ss . rate  =  ss - > rate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            try_ss . format  =  ss - > format ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pcm_handle  =  pa_alsa_open_by_device_string ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    d , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    & try_ss , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    map , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    mode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    nfrags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    period_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    tsched_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    use_mmap , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    use_tsched , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    TRUE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 22:01:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_xfree ( d ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 22:01:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( pcm_handle )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-23 15:14:28 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                * ss  =  try_ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                * map  =  device_table [ i ] . map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_assert ( map - > channels  = =  ss - > channels ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 22:01:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 21:36:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                if  ( profile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    * profile  =  & device_table [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 22:01:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                return  pcm_handle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( direction  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ! device_table [ i + 1 ] . alsa_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                /* OK, so we are at the end of our list. Let's turn
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  back .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                direction  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                /* We are not at the end of the list, so let's simply
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  try  the  next  entry  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                i + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( direction  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( device_table [ i + 1 ] . alsa_name  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                device_table [ i ] . map . channels  = =  device_table [ i + 1 ] . map . channels )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                /* OK, the next entry has the same number of channels,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  let ' s  try  it  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                i + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                /* Hmm, so the next entry does not have the same
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  number  of  channels ,  so  let ' s  go  backwards  until  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  find  the  next  entry  with  a  differnt  number  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  channels  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                for  ( i - - ;  i  > =  0 ;  i - - ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    if  ( device_table [ i ] . map . channels  ! =  device_table [ i + 1 ] . map . channels ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                /* Hmm, there is no entry with a different number of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  entries ,  then  we ' re  done  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( i  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                /* OK, now lets find go back as long as we have the same number of channels */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                for  ( ;  i  >  0 ;  i - - ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    if  ( device_table [ i ] . map . channels  ! =  device_table [ i - 1 ] . map . channels ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* OK, we didn't find any good device, so let's try the raw plughw: stuff */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    d  =  pa_sprintf_malloc ( " hw:%s " ,  dev_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_log_debug ( " Trying %s as last resort... " ,  d ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 22:01:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pcm_handle  =  pa_alsa_open_by_device_string ( d ,  dev ,  ss ,  map ,  mode ,  nfrags ,  period_size ,  tsched_size ,  use_mmap ,  use_tsched ,  FALSE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_xfree ( d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-20 21:36:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pcm_handle  & &  profile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * profile  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  pcm_handle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								snd_pcm_t  * pa_alsa_open_by_device_id_profile ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  char  * dev_id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        char  * * dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sample_spec  * ss , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_channel_map *  map , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        int  mode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        uint32_t  * nfrags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_uframes_t  * period_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_uframes_t  tsched_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  * use_mmap , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  * use_tsched , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  pa_alsa_profile_info  * profile )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  * d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_t  * pcm_handle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sample_spec  try_ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( dev_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( map ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( nfrags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( period_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( profile ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    d  =  pa_sprintf_malloc ( " %s:%s " ,  profile - > alsa_name ,  dev_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try_ss . channels  =  profile - > map . channels ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try_ss . rate  =  ss - > rate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try_ss . format  =  ss - > format ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pcm_handle  =  pa_alsa_open_by_device_string ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            d , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            & try_ss , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            map , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            mode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            nfrags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            period_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            tsched_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            use_mmap , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            use_tsched , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            TRUE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! pcm_handle ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    * ss  =  try_ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    * map  =  profile - > map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( map - > channels  = =  ss - > channels ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-15 23:46:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  pcm_handle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								snd_pcm_t  * pa_alsa_open_by_device_string ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  char  * device , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        char  * * dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sample_spec  * ss , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_channel_map *  map , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        int  mode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        uint32_t  * nfrags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_uframes_t  * period_size , 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        snd_pcm_uframes_t  tsched_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  * use_mmap , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 22:01:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_bool_t  * use_tsched , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  require_exact_channel_number )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  * d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_t  * pcm_handle ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-23 15:14:28 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  reformat  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( device ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( map ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    d  =  pa_xstrdup ( device ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-23 15:14:28 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Trying %s %s SND_PCM_NO_AUTO_FORMAT ... " ,  d ,  reformat  ?  " without "  :  " with " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* We don't pass SND_PCM_NONBLOCK here, since alsa-lib <=
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  1.0 .17 a  would  then  ignore  the  SND_PCM_NO_xxx  flags .  Instead 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  we  enable  nonblock  mode  afterwards  via 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  snd_pcm_nonblock ( ) .  Also  see 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  http : //mailman.alsa-project.org/pipermail/alsa-devel/2008-August/010258.html */
 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ( err  =  snd_pcm_open ( & pcm_handle ,  d ,  mode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                /*SND_PCM_NONBLOCK|*/ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                                SND_PCM_NO_AUTO_RESAMPLE | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                SND_PCM_NO_AUTO_CHANNELS | 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-23 15:14:28 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                                ( reformat  ?  0  :  SND_PCM_NO_AUTO_FORMAT ) ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_log_info ( " Error opening PCM device %s: %s " ,  d ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-18 21:50:09 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 22:01:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ( err  =  pa_alsa_set_hw_params ( pcm_handle ,  ss ,  nfrags ,  period_size ,  tsched_size ,  use_mmap ,  use_tsched ,  require_exact_channel_number ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-23 15:14:28 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( ! reformat )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                reformat  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                snd_pcm_close ( pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            /* Hmm, some hw is very exotic, so we retry with plug, if without it didn't work */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( ! pa_startswith ( d ,  " plug: " )  & &  ! pa_startswith ( d ,  " plughw: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                char  * t ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                t  =  pa_sprintf_malloc ( " plug:%s " ,  d ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                pa_xfree ( d ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                d  =  t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-23 15:14:28 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                reformat  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                snd_pcm_close ( pcm_handle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_log_info ( " Failed to set hardware parameters on %s: %s " ,  d ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-31 16:25:37 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            snd_pcm_close ( pcm_handle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-18 21:50:09 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            * dev  =  d ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-22 00:24:28 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_xfree ( d ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-18 23:44:26 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ss - > channels  ! =  map - > channels ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_channel_map_init_extend ( map ,  ss - > channels ,  PA_CHANNEL_MAP_ALSA ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  pcm_handle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-18 21:50:09 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								fail : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  pa_alsa_probe_profiles ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  char  * dev_id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  pa_sample_spec  * ss , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        void  ( * cb ) ( const  pa_alsa_profile_info  * sink ,  const  pa_alsa_profile_info  * source ,  void  * userdata ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        void  * userdata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  pa_alsa_profile_info  * i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( dev_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( cb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* We try each combination of playback/capture. We also try to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  open  only  for  capture  resp .  only  for  sink .  Don ' t  get  confused 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  by  the  trailing  entry  in  device_table  we  use  for  this !  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( i  =  device_table ;  i  <  device_table  +  PA_ELEMENTSOF ( device_table ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  pa_alsa_profile_info  * j ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_t  * pcm_i  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( i - > alsa_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            char  * id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_sample_spec  try_ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_channel_map  try_map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_debug ( " Checking for playback on %s (%s) " ,  i - > name ,  i - > alsa_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            id  =  pa_sprintf_malloc ( " %s:%s " ,  i - > alsa_name ,  dev_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            try_ss  =  * ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            try_ss . channels  =  i - > map . channels ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            try_map  =  i - > map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pcm_i  =  pa_alsa_open_by_device_string ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    id ,  NULL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    & try_ss ,  & try_map , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    SND_PCM_STREAM_PLAYBACK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    NULL ,  NULL ,  0 ,  NULL ,  NULL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    TRUE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_xfree ( id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ! pcm_i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        for  ( j  =  device_table ;  j  <  device_table  +  PA_ELEMENTSOF ( device_table ) ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            snd_pcm_t  * pcm_j  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( j - > alsa_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                char  * jd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_sample_spec  try_ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_channel_map  try_map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_log_debug ( " Checking for capture on %s (%s) " ,  j - > name ,  j - > alsa_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                jd  =  pa_sprintf_malloc ( " %s:%s " ,  j - > alsa_name ,  dev_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                try_ss  =  * ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                try_ss . channels  =  j - > map . channels ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                try_map  =  j - > map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pcm_j  =  pa_alsa_open_by_device_string ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        jd ,  NULL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        & try_ss ,  & try_map , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        SND_PCM_STREAM_CAPTURE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        NULL ,  NULL ,  0 ,  NULL ,  NULL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        TRUE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_xfree ( jd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( ! pcm_j ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( pcm_j ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                snd_pcm_close ( pcm_j ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-17 02:01:37 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( i - > alsa_name  | |  j - > alsa_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                cb ( i - > alsa_name  ?  i  :  NULL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                   j - > alsa_name  ?  j  :  NULL ,  userdata ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-16 23:33:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( pcm_i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            snd_pcm_close ( pcm_i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 17:57:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  pa_alsa_prepare_mixer ( snd_mixer_t  * mixer ,  const  char  * dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( mixer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 17:57:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_mixer_attach ( mixer ,  dev ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 23:42:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Unable to attach to mixer %s: %s " ,  dev ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 17:57:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_mixer_selem_register ( mixer ,  NULL ,  NULL ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-18 21:38:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Unable to register mixer: %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 17:57:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_mixer_load ( mixer ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-18 21:38:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Unable to load mixer: %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 17:57:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 23:42:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_log_info ( " Successfully attached to mixer '%s' " ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 17:57:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-08 01:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  pa_bool_t  elem_has_volume ( snd_mixer_elem_t  * elem ,  pa_bool_t  playback )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( elem ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( playback  & &  snd_mixer_selem_has_playback_volume ( elem ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! playback  & &  snd_mixer_selem_has_capture_volume ( elem ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  pa_bool_t  elem_has_switch ( snd_mixer_elem_t  * elem ,  pa_bool_t  playback )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( elem ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( playback  & &  snd_mixer_selem_has_playback_switch ( elem ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! playback  & &  snd_mixer_selem_has_capture_switch ( elem ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								snd_mixer_elem_t  * pa_alsa_find_elem ( snd_mixer_t  * mixer ,  const  char  * name ,  const  char  * fallback ,  pa_bool_t  playback )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_mixer_elem_t  * elem  =  NULL ,  * fallback_elem  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-30 22:48:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_mixer_selem_id_t  * sid  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 17:57:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_mixer_selem_id_alloca ( & sid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( mixer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 17:57:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_mixer_selem_id_set_name ( sid ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-08 01:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( elem  =  snd_mixer_find_selem ( mixer ,  sid ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( elem_has_volume ( elem ,  playback )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            elem_has_switch ( elem ,  playback ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  success ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! elem_has_volume ( elem ,  playback )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ! elem_has_switch ( elem ,  playback ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            elem  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_log_info ( " Cannot find mixer control  \" %s \"  or mixer control is no combination of switch/volume. " ,  snd_mixer_selem_id_get_name ( sid ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( fallback )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_mixer_selem_id_set_name ( sid ,  fallback ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-30 22:48:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-08 01:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ( fallback_elem  =  snd_mixer_find_selem ( mixer ,  sid ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( elem_has_volume ( fallback_elem ,  playback )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                elem_has_switch ( fallback_elem ,  playback ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                elem  =  fallback_elem ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                goto  success ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-08 01:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( ! elem_has_volume ( fallback_elem ,  playback )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ! elem_has_switch ( fallback_elem ,  playback ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                fallback_elem  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-30 22:48:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-08 01:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Cannot find fallback mixer control  \" %s \"  or mixer control is no combination of switch/volume. " ,  snd_mixer_selem_id_get_name ( sid ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-30 22:48:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-08 01:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( elem  & &  fallback_elem )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* Hmm, so we have both elements, but neither has both mute
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  and  volume .  Let ' s  prefer  the  one  with  the  volume  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( elem_has_volume ( elem ,  playback ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  success ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( elem_has_volume ( fallback_elem ,  playback ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            elem  =  fallback_elem ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  success ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! elem  & &  fallback_elem ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        elem  =  fallback_elem ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								success : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-30 22:48:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( elem ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-18 21:38:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Using mixer control  \" %s \" . " ,  snd_mixer_selem_id_get_name ( sid ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 17:57:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  elem ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 23:42:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-14 00:21:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  pa_alsa_find_mixer_and_elem ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_t  * pcm , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_mixer_t  * * _m , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_mixer_elem_t  * * _e )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_mixer_t  * m ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_mixer_elem_t  * e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_bool_t  found  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  char  * dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( pcm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( _m ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( _e ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_mixer_open ( & m ,  0 ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Error opening mixer: %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* First, try by name */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( dev  =  snd_pcm_name ( pcm ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( pa_alsa_prepare_mixer ( m ,  dev )  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            found  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Then, try by card index */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! found )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_info_t *  info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_info_alloca ( & info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( snd_pcm_info ( pcm ,  info )  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            char  * md ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            int  card_idx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ( card_idx  =  snd_pcm_info_get_card ( info ) )  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                md  =  pa_sprintf_malloc ( " hw:%i " ,  card_idx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( ! dev  | |  ! pa_streq ( dev ,  md ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    if  ( pa_alsa_prepare_mixer ( m ,  md )  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        found  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_xfree ( md ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! found )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_mixer_close ( m ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    switch  ( snd_pcm_stream ( pcm ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        case  SND_PCM_STREAM_PLAYBACK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            e  =  pa_alsa_find_elem ( m ,  " Master " ,  " PCM " ,  TRUE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        case  SND_PCM_STREAM_CAPTURE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            e  =  pa_alsa_find_elem ( m ,  " Capture " ,  " Mic " ,  FALSE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_assert_not_reached ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! e )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_mixer_close ( m ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( e  & &  m ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    * _m  =  m ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    * _e  =  e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 23:42:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  const  snd_mixer_selem_channel_id_t  alsa_channel_ids [ PA_CHANNEL_POSITION_MAX ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_MONO ]  =  SND_MIXER_SCHN_MONO ,  /* The ALSA name is just an alias! */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_FRONT_CENTER ]  =  SND_MIXER_SCHN_FRONT_CENTER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_FRONT_LEFT ]  =  SND_MIXER_SCHN_FRONT_LEFT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_FRONT_RIGHT ]  =  SND_MIXER_SCHN_FRONT_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_REAR_CENTER ]  =  SND_MIXER_SCHN_REAR_CENTER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_REAR_LEFT ]  =  SND_MIXER_SCHN_REAR_LEFT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_REAR_RIGHT ]  =  SND_MIXER_SCHN_REAR_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_LFE ]  =  SND_MIXER_SCHN_WOOFER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_SIDE_LEFT ]  =  SND_MIXER_SCHN_SIDE_LEFT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_SIDE_RIGHT ]  =  SND_MIXER_SCHN_SIDE_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX0 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX1 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX2 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX3 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX4 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX5 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX6 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX7 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX8 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX9 ]  =   SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX10 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX11 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX12 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX13 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX14 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX15 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX16 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX17 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX18 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX19 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX20 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX21 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX22 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX23 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX24 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX25 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX26 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX27 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX28 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX29 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX30 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_AUX31 ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_TOP_CENTER ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_TOP_FRONT_CENTER ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_TOP_FRONT_LEFT ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_TOP_FRONT_RIGHT ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_TOP_REAR_CENTER ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_TOP_REAR_LEFT ]  =  SND_MIXER_SCHN_UNKNOWN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ PA_CHANNEL_POSITION_TOP_REAR_RIGHT ]  =  SND_MIXER_SCHN_UNKNOWN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  pa_alsa_calc_mixer_map ( snd_mixer_elem_t  * elem ,  const  pa_channel_map  * channel_map ,  snd_mixer_selem_channel_id_t  mixer_map [ ] ,  pa_bool_t  playback )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_bool_t  alsa_channel_used [ SND_MIXER_SCHN_LAST ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_bool_t  mono_used  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( elem ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( channel_map ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( mixer_map ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    memset ( & alsa_channel_used ,  0 ,  sizeof ( alsa_channel_used ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( channel_map - > channels  >  1  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( ( playback  & &  snd_mixer_selem_has_playback_volume_joined ( elem ) )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         ( ! playback  & &  snd_mixer_selem_has_capture_volume_joined ( elem ) ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-13 13:53:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_info ( " ALSA device lacks independant volume controls for each channel. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 23:42:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( i  =  0 ;  i  <  channel_map - > channels ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_mixer_selem_channel_id_t  id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  is_mono ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        is_mono  =  channel_map - > map [ i ]  = =  PA_CHANNEL_POSITION_MONO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        id  =  alsa_channel_ids [ channel_map - > map [ i ] ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! is_mono  & &  id  = =  SND_MIXER_SCHN_UNKNOWN )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-13 13:53:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_log_info ( " Configured channel map contains channel '%s' that is unknown to the ALSA mixer. " ,  pa_channel_position_to_string ( channel_map - > map [ i ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 23:42:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( is_mono  & &  mono_used )  | |  ( ! is_mono  & &  alsa_channel_used [ id ] ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_log_info ( " Channel map has duplicate channel '%s', falling back to software volume control. " ,  pa_channel_position_to_string ( channel_map - > map [ i ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 23:42:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( playback  & &  ( ! snd_mixer_selem_has_playback_channel ( elem ,  id )  | |  ( is_mono  & &  ! snd_mixer_selem_is_playback_mono ( elem ) ) ) )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ( ! playback  & &  ( ! snd_mixer_selem_has_capture_channel ( elem ,  id )  | |  ( is_mono  & &  ! snd_mixer_selem_is_capture_mono ( elem ) ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-13 13:53:31 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_log_info ( " ALSA device lacks separate volumes control for channel '%s' " ,  pa_channel_position_to_string ( channel_map - > map [ i ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 23:42:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( is_mono )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            mixer_map [ i ]  =  SND_MIXER_SCHN_MONO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            mono_used  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            mixer_map [ i ]  =  id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            alsa_channel_used [ id ]  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_log_info ( " All %u channels can be mapped to mixer channels. " ,  channel_map - > channels ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 23:42:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  pa_alsa_dump ( snd_pcm_t  * pcm )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_output_t  * out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( pcm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert_se ( snd_output_buffer_open ( & out )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_pcm_dump ( pcm ,  out ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " snd_pcm_dump(): %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        char  * s  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_output_buffer_string ( out ,  & s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " snd_pcm_dump(): \n %s " ,  pa_strnull ( s ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert_se ( snd_output_close ( out )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  pa_alsa_dump_status ( snd_pcm_t  * pcm )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_output_t  * out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_status_t  * status ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( pcm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_status_alloca ( & status ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert_se ( snd_output_buffer_open ( & out )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert_se ( snd_pcm_status ( pcm ,  status )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_pcm_status_dump ( status ,  out ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " snd_pcm_dump(): %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        char  * s  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_output_buffer_string ( out ,  & s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " snd_pcm_dump(): \n %s " ,  pa_strnull ( s ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert_se ( snd_output_close ( out )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  alsa_error_handler ( const  char  * file ,  int  line ,  const  char  * function ,  int  err ,  const  char  * fmt , . . . )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    va_list  ap ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-26 23:19:43 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    char  * alsa_file ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    alsa_file  =  pa_sprintf_malloc ( " (alsa-lib)%s " ,  file ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    va_start ( ap ,  fmt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-26 23:19:43 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_log_levelv_meta ( PA_LOG_INFO ,  alsa_file ,  line ,  function ,  fmt ,  ap ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    va_end ( ap ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-26 23:19:43 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( alsa_file ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  pa_atomic_t  n_error_handler_installed  =  PA_ATOMIC_INIT ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  pa_alsa_redirect_errors_inc ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* This is not really thread safe, but we do our best */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pa_atomic_inc ( & n_error_handler_installed )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_lib_error_set_handler ( alsa_error_handler ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  pa_alsa_redirect_errors_dec ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert_se ( ( r  =  pa_atomic_dec ( & n_error_handler_installed ) )  > =  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( r  = =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_lib_error_set_handler ( NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-24 01:25:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  pa_alsa_init_proplist_card ( pa_core  * c ,  pa_proplist  * p ,  int  card )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-30 02:24:58 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    char  * cn ,  * lcn ,  * dn ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-17 02:00:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( card  > =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_proplist_setf ( p ,  " alsa.card " ,  " %i " ,  card ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( snd_card_get_name ( card ,  & cn )  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_proplist_sets ( p ,  " alsa.card_name " ,  cn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        free ( cn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( snd_card_get_longname ( card ,  & lcn )  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_proplist_sets ( p ,  " alsa.long_card_name " ,  lcn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        free ( lcn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-24 01:25:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-30 02:24:58 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( dn  =  pa_alsa_get_driver_name ( card ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_proplist_sets ( p ,  " alsa.driver_name " ,  dn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_xfree ( dn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-24 01:25:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef HAVE_HAL 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_hal_get_info ( c ,  p ,  card ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-17 02:00:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-18 21:49:31 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  pa_alsa_init_proplist_pcm_info ( pa_core  * c ,  pa_proplist  * p ,  snd_pcm_info_t  * pcm_info )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    static  const  char  *  const  alsa_class_table [ SND_PCM_CLASS_LAST + 1 ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ SND_PCM_CLASS_GENERIC ]  =  " generic " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ SND_PCM_CLASS_MULTI ]  =  " multi " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ SND_PCM_CLASS_MODEM ]  =  " modem " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ SND_PCM_CLASS_DIGITIZER ]  =  " digitizer " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    static  const  char  *  const  class_table [ SND_PCM_CLASS_LAST + 1 ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ SND_PCM_CLASS_GENERIC ]  =  " sound " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ SND_PCM_CLASS_MULTI ]  =  NULL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ SND_PCM_CLASS_MODEM ]  =  " modem " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ SND_PCM_CLASS_DIGITIZER ]  =  NULL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    static  const  char  *  const  alsa_subclass_table [ SND_PCM_SUBCLASS_LAST + 1 ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ SND_PCM_SUBCLASS_GENERIC_MIX ]  =  " generic-mix " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ SND_PCM_SUBCLASS_MULTI_MIX ]  =  " multi-mix " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_class_t  class ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_subclass_t  subclass ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-17 02:00:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    const  char  * n ,  * id ,  * sdn ,  * cn ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  card ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( pcm_info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_proplist_sets ( p ,  PA_PROP_DEVICE_API ,  " alsa " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    class  =  snd_pcm_info_get_class ( pcm_info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( class  < =  SND_PCM_CLASS_LAST )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( class_table [ class ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_proplist_sets ( p ,  PA_PROP_DEVICE_CLASS ,  class_table [ class ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( alsa_class_table [ class ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_proplist_sets ( p ,  " alsa.class " ,  alsa_class_table [ class ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    subclass  =  snd_pcm_info_get_subclass ( pcm_info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( subclass  < =  SND_PCM_SUBCLASS_LAST ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( alsa_subclass_table [ subclass ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_proplist_sets ( p ,  " alsa.subclass " ,  alsa_subclass_table [ subclass ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( n  =  snd_pcm_info_get_name ( pcm_info ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_proplist_sets ( p ,  " alsa.name " ,  n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( id  =  snd_pcm_info_get_id ( pcm_info ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_proplist_sets ( p ,  " alsa.id " ,  id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_proplist_setf ( p ,  " alsa.subdevice " ,  " %u " ,  snd_pcm_info_get_subdevice ( pcm_info ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( sdn  =  snd_pcm_info_get_subdevice_name ( pcm_info ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_proplist_sets ( p ,  " alsa.subdevice_name " ,  sdn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_proplist_setf ( p ,  " alsa.device " ,  " %u " ,  snd_pcm_info_get_device ( pcm_info ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( card  =  snd_pcm_info_get_card ( pcm_info ) )  > =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-24 01:25:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_alsa_init_proplist_card ( c ,  p ,  card ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-17 02:00:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        cn  =  pa_proplist_gets ( p ,  " alsa.card_name " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( cn  & &  n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_proplist_setf ( p ,  PA_PROP_DEVICE_DESCRIPTION ,  " %s - %s " ,  cn ,  n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  if  ( cn ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_proplist_sets ( p ,  PA_PROP_DEVICE_DESCRIPTION ,  cn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  if  ( n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_proplist_sets ( p ,  PA_PROP_DEVICE_DESCRIPTION ,  n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-18 21:49:31 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  pa_alsa_init_proplist_pcm ( pa_core  * c ,  pa_proplist  * p ,  snd_pcm_t  * pcm )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_hw_params_t  * hwparams ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_info_t  * info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  bits ,  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_hw_params_alloca ( & hwparams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_info_alloca ( & info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_pcm_hw_params_current ( pcm ,  hwparams ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Error fetching hardware parameter info: %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( bits  =  snd_pcm_hw_params_get_sbits ( hwparams ) )  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_proplist_setf ( p ,  " alsa.resolution_bits " ,  " %i " ,  bits ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_pcm_info ( pcm ,  info ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Error fetching PCM info: %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_alsa_init_proplist_pcm_info ( c ,  p ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  pa_alsa_recover_from_poll ( snd_pcm_t  * pcm ,  int  revents )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_state_t  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( pcm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( revents  &  POLLERR ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 22:58:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Got POLLERR from ALSA " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( revents  &  POLLNVAL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Got POLLNVAL from ALSA " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( revents  &  POLLHUP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Got POLLHUP from ALSA " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-22 23:55:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( revents  &  POLLPRI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Got POLLPRI from ALSA " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( revents  &  POLLIN ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 22:58:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Got POLLIN from ALSA " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-22 23:55:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( revents  &  POLLOUT ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 22:58:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Got POLLOUT from ALSA " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    state  =  snd_pcm_state ( pcm ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 22:58:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_log_debug ( " PCM state is %s " ,  snd_pcm_state_name ( state ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Try to recover from this error */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    switch  ( state )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        case  SND_PCM_STATE_XRUN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ( err  =  snd_pcm_recover ( pcm ,  - EPIPE ,  1 ) )  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_log_warn ( " Could not recover from POLLERR|POLLNVAL|POLLHUP and XRUN: %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        case  SND_PCM_STATE_SUSPENDED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ( err  =  snd_pcm_recover ( pcm ,  - ESTRPIPE ,  1 ) )  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_log_warn ( " Could not recover from POLLERR|POLLNVAL|POLLHUP and SUSPENDED: %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            snd_pcm_drop ( pcm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ( err  =  snd_pcm_prepare ( pcm ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_log_warn ( " Could not recover from POLLERR|POLLNVAL|POLLHUP with snd_pcm_prepare(): %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								pa_rtpoll_item *  pa_alsa_build_pollfd ( snd_pcm_t  * pcm ,  pa_rtpoll  * rtpoll )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  n ,  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  pollfd  * pollfd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_rtpoll_item  * item ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( pcm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( n  =  snd_pcm_poll_descriptors_count ( pcm ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " snd_pcm_poll_descriptors_count() failed: %s " ,  snd_strerror ( n ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    item  =  pa_rtpoll_item_new ( rtpoll ,  PA_RTPOLL_NEVER ,  ( unsigned )  n ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pollfd  =  pa_rtpoll_item_get_pollfd ( item ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-19 22:39:54 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_pcm_poll_descriptors ( pcm ,  pollfd ,  ( unsigned )  n ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 23:34:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log ( " snd_pcm_poll_descriptors() failed: %s " ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_rtpoll_item_free ( item ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  item ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-21 20:00:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								snd_pcm_sframes_t  pa_alsa_safe_avail_update ( snd_pcm_t  * pcm ,  size_t  hwbuf_size ,  const  pa_sample_spec  * ss )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_sframes_t  n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    size_t  k ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( pcm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( hwbuf_size  >  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Some ALSA driver expose weird bugs, let's inform the user about
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  what  is  going  on  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    n  =  snd_pcm_avail_update ( pcm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( n  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    k  =  ( size_t )  n  *  pa_frame_size ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( k  > =  hwbuf_size  *  3  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        k  > =  pa_bytes_per_second ( ss ) * 10 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " snd_pcm_avail_update() returned a value that is exceptionally large: %lu bytes (%lu ms)  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								               " Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers. " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-23 15:15:21 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								               ( unsigned  long )  k ,  ( unsigned  long )  ( pa_bytes_to_usec ( k ,  ss )  /  PA_USEC_PER_MSEC ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-21 20:00:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  pa_alsa_safe_mmap_begin ( snd_pcm_t  * pcm ,  const  snd_pcm_channel_area_t  * * areas ,  snd_pcm_uframes_t  * offset ,  snd_pcm_uframes_t  * frames ,  size_t  hwbuf_size ,  const  pa_sample_spec  * ss )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_uframes_t  before ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    size_t  k ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( pcm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( areas ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( offset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( frames ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( hwbuf_size  >  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    before  =  * frames ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    r  =  snd_pcm_mmap_begin ( pcm ,  areas ,  offset ,  frames ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( r  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    k  =  ( size_t )  * frames  *  pa_frame_size ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( * frames  >  before  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        k  > =  hwbuf_size  *  3  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        k  > =  pa_bytes_per_second ( ss ) * 10 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes (%lu ms)  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								               " Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers. " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-23 15:15:21 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								               ( unsigned  long )  k ,  ( unsigned  long )  ( pa_bytes_to_usec ( k ,  ss )  /  PA_USEC_PER_MSEC ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-21 20:00:36 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-30 02:24:40 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								char  * pa_alsa_get_driver_name ( int  card )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  * t ,  * m ,  * n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( card  > =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    t  =  pa_sprintf_malloc ( " /sys/class/sound/card%i/device/driver/module " ,  card ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m  =  pa_readlink ( t ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( t ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! m ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    n  =  pa_xstrdup ( pa_path_get_filename ( m ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( m ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}