2004-07-16 19:56:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* $Id$ */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/***
 
							 
						 
					
						
							
								
									
										
										
										
											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> 
 
							 
						 
					
						
							
								
									
										
										
										
											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> 
 
							 
						 
					
						
							
								
									
										
										
										
											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> 
 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-16 22:08:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "alsa-util.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2004-07-16 17:03:11 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  pa_alsa_fdlist  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  num_fds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  polled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    void  ( * cb ) ( void  * userdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    void  * userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 19:31:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  io_cb ( pa_mainloop_api * a ,  pa_io_event *  e ,  PA_GCC_UNUSED  int  fd ,  pa_io_event_flags_t  events ,  void  * userdata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  pa_alsa_fdlist  * fdl  =  userdata ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  err ,  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > polled  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    memcpy ( fdl - > work_fds ,  fdl - > fds ,  sizeof ( struct  pollfd )  *  fdl - > num_fds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00: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 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 19:31:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  defer_cb ( pa_mainloop_api * a ,  PA_GCC_UNUSED  pa_defer_event *  e ,  void  * userdata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    struct  pa_alsa_fdlist  * fdl  =  userdata ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  num_fds ,  i ,  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    num_fds  =  snd_mixer_poll_descriptors_count ( fdl - > mixer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( num_fds  >  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > polled  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fdl - > polled  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        int  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_assert ( fdl - > m ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 19:09:26 +00: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 , 
							 
						 
					
						
							
								
									
										
										
										
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  * use_mmap , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  require_exact_channel_number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-16 19:33:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  ret  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( periods ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( period_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_hw_params_alloca ( & hwparams ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-05 18:37:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    buffer_size  =  * periods  *  * period_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( ret  =  snd_pcm_hw_params_any ( pcm_handle ,  hwparams ) )  <  0  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( ret  =  snd_pcm_hw_params_set_rate_resample ( pcm_handle ,  hwparams ,  0 ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( _use_mmap )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ( ret  =  snd_pcm_hw_params_set_access ( pcm_handle ,  hwparams ,  SND_PCM_ACCESS_MMAP_INTERLEAVED ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* 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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( * period_size  >  0  & &  ( ret  =  snd_pcm_hw_params_set_period_size_near ( pcm_handle ,  hwparams ,  period_size ,  NULL ) )  <  0 )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( * periods  >  0  & &  ( ret  =  snd_pcm_hw_params_set_buffer_size_near ( pcm_handle ,  hwparams ,  & buffer_size ) )  <  0 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " 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 ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " 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 ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " 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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-05 18:35:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( ret  =  snd_pcm_hw_params_get_buffer_size ( hwparams ,  & buffer_size ) )  <  0  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( ret  =  snd_pcm_hw_params_get_period_size ( hwparams ,  period_size ,  NULL ) )  <  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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss - > channels  =  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss - > format  =  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( buffer_size  >  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( * period_size  >  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-11-20 22:17:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    * periods  =  buffer_size  /  * period_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( * periods  >  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( use_mmap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * use_mmap  =  _use_mmap ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-11-20 22:17:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ret  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  pa_alsa_set_sw_params ( snd_pcm_t  * pcm )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  device_info  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_channel_map  map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  char  * name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  const  struct  device_info  device_table [ ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  2 ,  {  PA_CHANNEL_POSITION_LEFT ,  PA_CHANNEL_POSITION_RIGHT  }  } ,  " front "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  4 ,  {  PA_CHANNEL_POSITION_FRONT_LEFT ,  PA_CHANNEL_POSITION_FRONT_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_REAR_LEFT ,  PA_CHANNEL_POSITION_REAR_RIGHT  } } ,  " surround40 "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  5 ,  {  PA_CHANNEL_POSITION_FRONT_LEFT ,  PA_CHANNEL_POSITION_FRONT_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_REAR_LEFT ,  PA_CHANNEL_POSITION_REAR_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_LFE  } } ,  " surround41 "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  5 ,  {  PA_CHANNEL_POSITION_FRONT_LEFT ,  PA_CHANNEL_POSITION_FRONT_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_REAR_LEFT ,  PA_CHANNEL_POSITION_REAR_RIGHT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_CENTER  } } ,  " surround50 "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  6 ,  {  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  } } ,  " surround51 "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            PA_CHANNEL_POSITION_SIDE_LEFT ,  PA_CHANNEL_POSITION_SIDE_RIGHT  } }  ,  " surround71 "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { {  0 ,  {  0  } } ,  NULL  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  pa_bool_t  channel_map_superset ( const  pa_channel_map  * a ,  const  pa_channel_map  * b )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_bool_t  in_a [ PA_CHANNEL_POSITION_MAX ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( a ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( b ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    memset ( in_a ,  0 ,  sizeof ( in_a ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( i  =  0 ;  i  <  a - > channels ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        in_a [ a - > map [ i ] ]  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( i  =  0 ;  i  <  b - > channels ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! in_a [ b - > map [ i ] ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								snd_pcm_t  * pa_alsa_open_by_device_id ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  * use_mmap )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  direction  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 . */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( i  =  0 ; ;  i  + =  direction )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sample_spec  try_ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( i  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_assert ( direction  = =  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* OK, so we iterated backwards, and now are at the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             *  beginning  of  our  list .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  if  ( ! device_table [ i ] . name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_assert ( direction  = =  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* OK, so we are at the end of our list. at iterated
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             *  forwards .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            i - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            direction  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( direction  >  0 )  = =  ! channel_map_superset ( & device_table [ i ] . map ,  map ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        d  =  pa_sprintf_malloc ( " %s:%s " ,  device_table [ i ] . name ,  dev_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Trying %s... " ,  d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( err  =  snd_pcm_open ( & pcm_handle ,  d ,  mode ,  SND_PCM_NONBLOCK ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_info ( " Couldn't open PCM device %s: %s " ,  d ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_xfree ( d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        try_ss . channels  =  device_table [ i ] . map . channels ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        try_ss . rate  =  ss - > rate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        try_ss . format  =  ss - > format ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( err  =  pa_alsa_set_hw_params ( pcm_handle ,  & try_ss ,  nfrags ,  period_size ,  use_mmap ,  TRUE ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_info ( " PCM device %s refused our hw parameters: %s " ,  d ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_xfree ( d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            snd_pcm_close ( pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * ss  =  try_ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * map  =  device_table [ i ] . map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_assert ( map - > channels  = =  ss - > channels ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * dev  =  d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  pcm_handle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* OK, we didn't find any good device, so let's try the raw hw: stuff */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    d  =  pa_sprintf_malloc ( " hw:%s " ,  dev_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_log_debug ( " Trying %s as last resort... " ,  d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pcm_handle  =  pa_alsa_open_by_device_string ( d ,  dev ,  ss ,  map ,  mode ,  nfrags ,  period_size ,  use_mmap ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  * use_mmap )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  * d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_t  * pcm_handle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( device ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( map ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( nfrags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( period_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    d  =  pa_xstrdup ( device ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( err  =  snd_pcm_open ( & pcm_handle ,  d ,  mode ,  SND_PCM_NONBLOCK ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log ( " Error opening PCM device %s: %s " ,  d ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_xfree ( d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( err  =  pa_alsa_set_hw_params ( pcm_handle ,  ss ,  nfrags ,  period_size ,  use_mmap ,  FALSE ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( err  = =  - EPERM )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                /* Hmm, some hw is very exotic, so we retry with plug, if without it didn't work */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( pa_startswith ( d ,  " hw: " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    char  * t  =  pa_sprintf_malloc ( " plughw:%s " ,  d + 3 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    pa_log_debug ( " Opening the device as '%s' didn't work, retrying with '%s'. " ,  d ,  t ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    pa_xfree ( d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    d  =  t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    snd_pcm_close ( pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_log ( " Failed to set hardware parameters on %s: %s " ,  d ,  snd_strerror ( err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_xfree ( d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                snd_pcm_close ( pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * dev  =  d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ss - > channels  ! =  map - > channels ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_channel_map_init_auto ( map ,  ss - > channels ,  PA_CHANNEL_MAP_ALSA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  pcm_handle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-18 21:38:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " 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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-30 22:48:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								snd_mixer_elem_t  * pa_alsa_find_elem ( snd_mixer_t  * mixer ,  const  char  * name ,  const  char  * fallback )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-26 17:57:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_mixer_elem_t  * elem ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-30 22:48:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! ( elem  =  snd_mixer_find_selem ( mixer ,  sid ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-18 21:38:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Cannot find mixer control  \" %s \" . " ,  snd_mixer_selem_id_get_name ( sid ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-30 22:48:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( fallback )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            snd_mixer_selem_id_set_name ( sid ,  fallback ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-30 22:48:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( ! ( elem  =  snd_mixer_find_selem ( mixer ,  sid ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-18 21:38:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                pa_log_warn ( " Cannot find fallback mixer control  \" %s \" . " ,  snd_mixer_selem_id_get_name ( sid ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}