2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/***
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  This  file  is  part  of  PulseAudio . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  Copyright  2004 - 2008  Lennart  Poettering 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  Copyright  2006  Pierre  Ossman  < ossman @ cendio . se >  for  Cendio  AB 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  PulseAudio  is  free  software ;  you  can  redistribute  it  and / or  modify 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  it  under  the  terms  of  the  GNU  Lesser  General  Public  License  as  published 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 20:23:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  by  the  Free  Software  Foundation ;  either  version  2.1  of  the  License , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  or  ( at  your  option )  any  later  version . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  PulseAudio  is  distributed  in  the  hope  that  it  will  be  useful ,  but 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  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 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  You  should  have  received  a  copy  of  the  GNU  Lesser  General  Public  License 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  along  with  PulseAudio ;  if  not ,  write  to  the  Free  Software 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  Foundation ,  Inc . ,  59  Temple  Place ,  Suite  330 ,  Boston ,  MA  02111 - 1307 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  USA . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef HAVE_CONFIG_H 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <config.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-05-31 10:44:22 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <signal.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  <stdio.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <asoundlib.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef HAVE_VALGRIND_MEMCHECK_H 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <valgrind/memcheck.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-04 23:19:53 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulse/rtclock.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulse/timeval.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-13 15:04:33 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulse/volume.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-04 23:19:53 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulse/xmalloc.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-12 16:36:00 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulse/internal.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/core.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-10 10:30:15 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulsecore/i18n.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/module.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/memchunk.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/sink.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/modargs.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-04 23:19:53 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulsecore/core-rtclock.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/core-util.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/sample-util.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/log.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/macro.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/thread.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/thread-mq.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/rtpoll.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pulsecore/time-smoother.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <modules/reserve-wrap.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  "alsa-util.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "alsa-sink.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* #define DEBUG_TIMING */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# define DEFAULT_DEVICE "default" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define DEFAULT_TSCHED_BUFFER_USEC (2*PA_USEC_PER_SEC)              /* 2s    -- Overall buffer size */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define DEFAULT_TSCHED_WATERMARK_USEC (20*PA_USEC_PER_MSEC)         /* 20ms  -- Fill up when only this much is left in the buffer */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define TSCHED_WATERMARK_INC_STEP_USEC (10*PA_USEC_PER_MSEC)        /* 10ms  -- On underrun, increase watermark by this */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define TSCHED_WATERMARK_DEC_STEP_USEC (5*PA_USEC_PER_MSEC)         /* 5ms   -- When everything's great, decrease watermark by this */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define TSCHED_WATERMARK_VERIFY_AFTER_USEC (20*PA_USEC_PER_SEC)     /* 20s   -- How long after a drop out recheck if things are good now */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-24 18:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define TSCHED_WATERMARK_INC_THRESHOLD_USEC (0*PA_USEC_PER_MSEC)    /* 0ms   -- If the buffer level ever below this threshold, increase the watermark */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define TSCHED_WATERMARK_DEC_THRESHOLD_USEC (100*PA_USEC_PER_MSEC)  /* 100ms -- If the buffer level didn't drop below this threshold in the verification time, decrease the watermark */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-24 18:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Note that TSCHED_WATERMARK_INC_THRESHOLD_USEC == 0 means that we
 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-01 04:55:05 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *  will  increase  the  watermark  only  if  we  hit  a  real  underrun .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define TSCHED_MIN_SLEEP_USEC (10*PA_USEC_PER_MSEC)                 /* 10ms  -- Sleep at least 10ms on each iteration */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define TSCHED_MIN_WAKEUP_USEC (4*PA_USEC_PER_MSEC)                 /* 4ms   -- Wakeup at least this long before the buffer runs empty*/ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-09 12:29:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define SMOOTHER_WINDOW_USEC  (10*PA_USEC_PER_SEC)                  /* 10s   -- smoother windows size */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define SMOOTHER_ADJUST_USEC  (1*PA_USEC_PER_SEC)                   /* 1s    -- smoother adjust time */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define SMOOTHER_MIN_INTERVAL (2*PA_USEC_PER_MSEC)                  /* 2ms   -- min smoother update interval */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-22 04:54:24 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define SMOOTHER_MAX_INTERVAL (200*PA_USEC_PER_MSEC)                /* 200ms -- max smoother update interval */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-20 13:40:27 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-19 02:29:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define VOLUME_ACCURACY (PA_VOLUME_NORM / 100)   /* don't require volume adjustments to be perfectly correct. don't necessarily extend granularity in software unless the differences get greater than this level */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-04 11:58:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define DEFAULT_REWIND_SAFEGUARD_BYTES (256U)  /* 1.33ms @48kHz, we'll never rewind less than this */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define DEFAULT_REWIND_SAFEGUARD_USEC (1330)  /* 1.33ms, depending on channels/rate/sample we may rewind more than 256 above */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 10:48:11 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								struct  userdata  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_core  * core ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_module  * module ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink  * sink ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_thread  * thread ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_thread_mq  thread_mq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_rtpoll  * rtpoll ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_t  * pcm_handle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-06 23:09:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    char  * paths_dir ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_alsa_fdlist  * mixer_fdl ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_alsa_mixer_pdata  * mixer_pd ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    snd_mixer_t  * mixer_handle ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_alsa_path_set  * mixer_path_set ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_alsa_path  * mixer_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_cvolume  hardware_volume ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-17 22:46:06 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    unsigned  int  * rates ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-27 01:15:06 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    size_t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        frame_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        fragment_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        hwbuf_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        tsched_watermark , 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-07 18:12:32 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        tsched_watermark_ref , 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-27 01:15:06 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        hwbuf_unused , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        min_sleep , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        min_wakeup , 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        watermark_inc_step , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        watermark_dec_step , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        watermark_inc_threshold , 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 10:48:11 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        watermark_dec_threshold , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        rewind_safeguard ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_usec_t  watermark_dec_not_before ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-07 18:12:32 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_usec_t  min_latency_ref ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-27 01:15:06 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_memchunk  memchunk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    char  * device_name ;   /* name of the PCM device */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  * control_device ;  /* name of the control device */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-03 21:14:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  use_mmap : 1 ,  use_tsched : 1 ,  deferred_volume : 1 ,  fixed_latency_range : 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_bool_t  first ,  after_rewind ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_rtpoll_item  * alsa_rtpoll_item ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_smoother  * smoother ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    uint64_t  write_count ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    uint64_t  since_start ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-20 13:40:27 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_usec_t  smoother_interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_usec_t  last_smoother_update ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-12 16:36:00 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_idxset  * formats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_reserve_wrapper  * reserve ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_hook_slot  * reserve_slot ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-05 19:05:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_reserve_monitor_wrapper  * monitor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_hook_slot  * monitor_slot ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:53:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* ucm context */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_alsa_ucm_mapping_context  * ucm_context ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  userdata_free ( struct  userdata  * u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-12 16:36:00 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* FIXME: Is there a better way to do this than device names? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  pa_bool_t  is_iec958 ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( strncmp ( " iec958 " ,  u - > device_name ,  6 )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  pa_bool_t  is_hdmi ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( strncmp ( " hdmi " ,  u - > device_name ,  4 )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  pa_hook_result_t  reserve_cb ( pa_reserve_wrapper  * r ,  void  * forced ,  struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( r ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-05 19:05:07 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_sink_suspend ( u - > sink ,  TRUE ,  PA_SUSPEND_APPLICATION )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  PA_HOOK_CANCEL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  PA_HOOK_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  reserve_done ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > reserve_slot )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_hook_slot_free ( u - > reserve_slot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > reserve_slot  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > reserve )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_reserve_wrapper_unref ( u - > reserve ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > reserve  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 11:29:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  reserve_update ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  char  * description ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-28 23:45:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! u - > sink  | |  ! u - > reserve ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 11:29:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( description  =  pa_proplist_gets ( u - > sink - > proplist ,  PA_PROP_DEVICE_DESCRIPTION ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_reserve_wrapper_set_application_device_name ( u - > reserve ,  description ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  reserve_init ( struct  userdata  * u ,  const  char  * dname )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  * rname ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( dname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > reserve ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 22:26:15 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_in_system_mode ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! ( rname  =  pa_alsa_get_reserve_name ( dname ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-01 20:20:06 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* We are resuming, try to lock the device */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > reserve  =  pa_reserve_wrapper_get ( u - > core ,  rname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( rname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! ( u - > reserve ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 11:29:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    reserve_update ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( ! u - > reserve_slot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > reserve_slot  =  pa_hook_connect ( pa_reserve_wrapper_hook ( u - > reserve ) ,  PA_HOOK_NORMAL ,  ( pa_hook_cb_t )  reserve_cb ,  u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-05 19:05:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  pa_hook_result_t  monitor_cb ( pa_reserve_monitor_wrapper  * w ,  void *  busy ,  struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_bool_t  b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( w ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    b  =  PA_PTR_TO_UINT ( busy )  & &  ! u - > reserve ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_suspend ( u - > sink ,  b ,  PA_SUSPEND_APPLICATION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  PA_HOOK_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  monitor_done ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > monitor_slot )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_hook_slot_free ( u - > monitor_slot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > monitor_slot  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > monitor )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_reserve_monitor_wrapper_unref ( u - > monitor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > monitor  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  reserve_monitor_init ( struct  userdata  * u ,  const  char  * dname )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  * rname ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( dname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pa_in_system_mode ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! ( rname  =  pa_alsa_get_reserve_name ( dname ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-05-17 19:50:32 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* We are resuming, try to lock the device */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-05 19:05:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > monitor  =  pa_reserve_monitor_wrapper_get ( u - > core ,  rname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( rname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! ( u - > monitor ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ! u - > monitor_slot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > monitor_slot  =  pa_hook_connect ( pa_reserve_monitor_wrapper_hook ( u - > monitor ) ,  PA_HOOK_NORMAL ,  ( pa_hook_cb_t )  monitor_cb ,  u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  fix_min_sleep_wakeup ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    size_t  max_use ,  max_use_2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > use_tsched ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    max_use  =  u - > hwbuf_size  -  u - > hwbuf_unused ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    max_use_2  =  pa_frame_align ( max_use / 2 ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > min_sleep  =  pa_usec_to_bytes ( TSCHED_MIN_SLEEP_USEC ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > min_sleep  =  PA_CLAMP ( u - > min_sleep ,  u - > frame_size ,  max_use_2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > min_wakeup  =  pa_usec_to_bytes ( TSCHED_MIN_WAKEUP_USEC ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > min_wakeup  =  PA_CLAMP ( u - > min_wakeup ,  u - > frame_size ,  max_use_2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								static  void  fix_tsched_watermark ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    size_t  max_use ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > use_tsched ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    max_use  =  u - > hwbuf_size  -  u - > hwbuf_unused ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > tsched_watermark  >  max_use  -  u - > min_sleep ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > tsched_watermark  =  max_use  -  u - > min_sleep ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > tsched_watermark  <  u - > min_wakeup ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > tsched_watermark  =  u - > min_wakeup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  increase_watermark ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    size_t  old_watermark ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_usec_t  old_min_latency ,  new_min_latency ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-27 01:15:06 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > use_tsched ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* First, just try to increase the watermark */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old_watermark  =  u - > tsched_watermark ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > tsched_watermark  =  PA_MIN ( u - > tsched_watermark  *  2 ,  u - > tsched_watermark  +  u - > watermark_inc_step ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    fix_tsched_watermark ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( old_watermark  ! =  u - > tsched_watermark )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Increasing wakeup watermark to %0.2f ms " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    ( double )  pa_bytes_to_usec ( u - > tsched_watermark ,  & u - > sink - > sample_spec )  /  PA_USEC_PER_MSEC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-03 21:14:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Hmm, we cannot increase the watermark any further, hence let's
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								       raise  the  latency ,  unless  doing  so  was  disabled  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								       configuration  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > fixed_latency_range ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    old_min_latency  =  u - > sink - > thread_info . min_latency ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    new_min_latency  =  PA_MIN ( old_min_latency  *  2 ,  old_min_latency  +  TSCHED_WATERMARK_INC_STEP_USEC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-27 01:15:06 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    new_min_latency  =  PA_MIN ( new_min_latency ,  u - > sink - > thread_info . max_latency ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( old_min_latency  ! =  new_min_latency )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Increasing minimal latency to %0.2f ms " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    ( double )  new_min_latency  /  PA_USEC_PER_MSEC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-24 21:06:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_sink_set_latency_range_within_thread ( u - > sink ,  new_min_latency ,  u - > sink - > thread_info . max_latency ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* When we reach this we're officialy fucked! */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  decrease_watermark ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    size_t  old_watermark ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_usec_t  now ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > use_tsched ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    now  =  pa_rtclock_now ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > watermark_dec_not_before  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  restart ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > watermark_dec_not_before  >  now ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old_watermark  =  u - > tsched_watermark ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > tsched_watermark  <  u - > watermark_dec_step ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > tsched_watermark  =  u - > tsched_watermark  /  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > tsched_watermark  =  PA_MAX ( u - > tsched_watermark  /  2 ,  u - > tsched_watermark  -  u - > watermark_dec_step ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fix_tsched_watermark ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( old_watermark  ! =  u - > tsched_watermark ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Decreasing wakeup watermark to %0.2f ms " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    ( double )  pa_bytes_to_usec ( u - > tsched_watermark ,  & u - > sink - > sample_spec )  /  PA_USEC_PER_MSEC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* We don't change the latency range*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								restart : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > watermark_dec_not_before  =  now  +  TSCHED_WATERMARK_VERIFY_AFTER_USEC ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								static  void  hw_sleep_time ( struct  userdata  * u ,  pa_usec_t  * sleep_usec ,  pa_usec_t * process_usec )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_usec_t  usec ,  wm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( sleep_usec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( process_usec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > use_tsched ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    usec  =  pa_sink_get_requested_latency_within_thread ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( usec  = =  ( pa_usec_t )  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        usec  =  pa_bytes_to_usec ( u - > hwbuf_size ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    wm  =  pa_bytes_to_usec ( u - > tsched_watermark ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( wm  >  usec ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        wm  =  usec / 2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    * sleep_usec  =  usec  -  wm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    * process_usec  =  wm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_log_debug ( " Buffer time: %lu ms; Sleep time: %lu ms; Process time: %lu ms " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 ( unsigned  long )  ( usec  /  PA_USEC_PER_MSEC ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 ( unsigned  long )  ( * sleep_usec  /  PA_USEC_PER_MSEC ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 ( unsigned  long )  ( * process_usec  /  PA_USEC_PER_MSEC ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  try_recover ( struct  userdata  * u ,  const  char  * call ,  int  err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( call ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( err  <  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-19 19:22:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_log_debug ( " %s: %s " ,  call ,  pa_alsa_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( err  ! =  - EAGAIN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( err  = =  - EPIPE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " %s: Buffer underrun! " ,  call ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-04 00:23:43 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( err  = =  - ESTRPIPE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " %s: System suspended! " ,  call ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-02 17:52:05 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_pcm_recover ( u - > pcm_handle ,  err ,  1 ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-19 19:22:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log ( " %s: %s " ,  call ,  pa_alsa_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > first  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > since_start  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  size_t  check_left_to_play ( struct  userdata  * u ,  size_t  n_bytes ,  pa_bool_t  on_timeout )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    size_t  left_to_play ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-01 04:54:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  underrun  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* We use <= instead of < for this check here because an underrun
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  only  happens  after  the  last  sample  was  processed ,  not  already  when 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  it  is  removed  from  the  buffer .  This  is  particularly  important 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  when  block  transfer  is  used .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( n_bytes  < =  u - > hwbuf_size ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        left_to_play  =  u - > hwbuf_size  -  n_bytes ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* We got a dropout. What a mess! */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        left_to_play  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-01 04:54:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        underrun  =  TRUE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-12 11:18:25 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								#if 0 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        PA_DEBUG_TRAP ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! u - > first  & &  ! u - > after_rewind ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-22 01:08:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( pa_log_ratelimit ( PA_LOG_INFO ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                pa_log_info ( " Underrun! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-04 20:55:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_log_debug ( " %0.2f ms left to play; inc threshold = %0.2f ms; dec threshold = %0.2f ms " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 ( double )  pa_bytes_to_usec ( left_to_play ,  & u - > sink - > sample_spec )  /  PA_USEC_PER_MSEC , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 ( double )  pa_bytes_to_usec ( u - > watermark_inc_threshold ,  & u - > sink - > sample_spec )  /  PA_USEC_PER_MSEC , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 ( double )  pa_bytes_to_usec ( u - > watermark_dec_threshold ,  & u - > sink - > sample_spec )  /  PA_USEC_PER_MSEC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > use_tsched )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  reset_not_before  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! u - > first  & &  ! u - > after_rewind )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-01 04:54:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( underrun  | |  left_to_play  <  u - > watermark_inc_threshold ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                increase_watermark ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            else  if  ( left_to_play  >  u - > watermark_dec_threshold )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                reset_not_before  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                /* We decrease the watermark only if have actually
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  been  woken  up  by  a  timeout .  If  something  else  woke 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  us  up  it ' s  too  easy  to  fulfill  the  deadlines . . .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                if  ( on_timeout ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    decrease_watermark ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( reset_not_before ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > watermark_dec_not_before  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  left_to_play ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  mmap_write ( struct  userdata  * u ,  pa_usec_t  * sleep_usec ,  pa_bool_t  polled ,  pa_bool_t  on_timeout )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-28 09:57:33 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  work_done  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_usec_t  max_sleep_usec  =  0 ,  process_usec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    size_t  left_to_play ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:11:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    unsigned  j  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_assert_ref ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > use_tsched ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        hw_sleep_time ( u ,  & max_sleep_usec ,  & process_usec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_sframes_t  n ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        size_t  n_bytes ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        int  r ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-24 13:45:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_bool_t  after_avail  =  TRUE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* First we determine how many samples are missing to fill the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  buffer  up  to  100 %  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( PA_UNLIKELY ( ( n  =  pa_alsa_safe_avail ( u - > pcm_handle ,  u - > hwbuf_size ,  & u - > sink - > sample_spec ) )  <  0 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( ( r  =  try_recover ( u ,  " snd_pcm_avail " ,  ( int )  n ) )  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        n_bytes  =  ( size_t )  n  *  u - > frame_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " avail: %lu " ,  ( unsigned  long )  n_bytes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        left_to_play  =  check_left_to_play ( u ,  n_bytes ,  on_timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        on_timeout  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( u - > use_tsched ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* We won't fill up the playback buffer before at least
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            *  half  the  sleep  time  is  over  because  otherwise  we  might 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            *  ask  for  more  data  from  the  clients  then  they  expect .  We 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            *  need  to  guarantee  that  clients  only  have  to  keep  around 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            *  a  single  hw  buffer  length .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ! polled  & & 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                pa_bytes_to_usec ( left_to_play ,  & u - > sink - > sample_spec )  >  process_usec + max_sleep_usec / 2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_log_debug ( " Not filling up, because too early. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( PA_UNLIKELY ( n_bytes  < =  u - > hwbuf_unused ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-21 16:33:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( polled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                PA_ONCE_BEGIN  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-23 22:56:09 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    char  * dn  =  pa_alsa_get_driver_name_by_pcm ( u - > pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    pa_log ( _ ( " ALSA woke us up to write new data to the device, but there was actually nothing to write! \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                             " Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                             " We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail. " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                           pa_strnull ( dn ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    pa_xfree ( dn ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-21 16:33:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                }  PA_ONCE_END ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_debug ( " Not filling up, because not necessary. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:11:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( + + j  >  10 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_debug ( " Not filling up, because already too many iterations. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        n_bytes  - =  u - > hwbuf_unused ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        polled  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Filling up " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_memchunk  chunk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            void  * p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            const  snd_pcm_channel_area_t  * areas ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            snd_pcm_uframes_t  offset ,  frames ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            snd_pcm_sframes_t  sframes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            frames  =  ( snd_pcm_uframes_t )  ( n_bytes  /  u - > frame_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/*             pa_log_debug("%lu frames to write", (unsigned long) frames); */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( PA_UNLIKELY ( ( err  =  pa_alsa_safe_mmap_begin ( u - > pcm_handle ,  & areas ,  & offset ,  & frames ,  u - > hwbuf_size ,  & u - > sink - > sample_spec ) )  <  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-24 13:45:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                if  ( ! after_avail  & &  err  = =  - EAGAIN ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                if  ( ( r  =  try_recover ( u ,  " snd_pcm_mmap_begin " ,  err ) )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* Make sure that if these memblocks need to be copied they will fit into one slot */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-07 10:37:25 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( frames  >  pa_mempool_block_size_max ( u - > core - > mempool ) / u - > frame_size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                frames  =  pa_mempool_block_size_max ( u - > core - > mempool ) / u - > frame_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-24 13:45:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( ! after_avail  & &  frames  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-22 22:38:38 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-24 13:45:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_assert ( frames  >  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            after_avail  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            /* Check these are multiples of 8 bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_assert ( ( areas [ 0 ] . first  &  7 )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_assert ( ( areas [ 0 ] . step  &  7 ) = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* We assume a single interleaved memory buffer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_assert ( ( areas [ 0 ] . first  > >  3 )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_assert ( ( areas [ 0 ] . step  > >  3 )  = =  u - > frame_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            p  =  ( uint8_t * )  areas [ 0 ] . addr  +  ( offset  *  u - > frame_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            chunk . memblock  =  pa_memblock_new_fixed ( u - > core - > mempool ,  p ,  frames  *  u - > frame_size ,  TRUE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            chunk . length  =  pa_memblock_get_length ( chunk . memblock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            chunk . index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_sink_render_into_full ( u - > sink ,  & chunk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_memblock_unref_fixed ( chunk . memblock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( PA_UNLIKELY ( ( sframes  =  snd_pcm_mmap_commit ( u - > pcm_handle ,  offset ,  frames ) )  <  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-06 21:19:34 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                if  ( ! after_avail  & &  ( int )  sframes  = =  - EAGAIN ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                if  ( ( r  =  try_recover ( u ,  " snd_pcm_mmap_commit " ,  ( int )  sframes ) )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            work_done  =  TRUE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            u - > write_count  + =  frames  *  u - > frame_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            u - > since_start  + =  frames  *  u - > frame_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-08 01:56:21 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_log_debug ( " Wrote %lu bytes (of possible %lu bytes) " ,  ( unsigned  long )  ( frames  *  u - > frame_size ) ,  ( unsigned  long )  n_bytes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( ( size_t )  frames  *  u - > frame_size  > =  n_bytes ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            n_bytes  - =  ( size_t )  frames  *  u - > frame_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-23 03:23:22 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > use_tsched )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * sleep_usec  =  pa_bytes_to_usec ( left_to_play ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-09 10:14:40 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        process_usec  =  pa_bytes_to_usec ( u - > tsched_watermark ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-13 03:40:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-23 03:23:22 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( * sleep_usec  >  process_usec ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            * sleep_usec  - =  process_usec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            * sleep_usec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-13 03:40:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        * sleep_usec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  work_done  ?  1  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  unix_write ( struct  userdata  * u ,  pa_usec_t  * sleep_usec ,  pa_bool_t  polled ,  pa_bool_t  on_timeout )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  work_done  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_usec_t  max_sleep_usec  =  0 ,  process_usec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    size_t  left_to_play ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:11:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    unsigned  j  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_assert_ref ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > use_tsched ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        hw_sleep_time ( u ,  & max_sleep_usec ,  & process_usec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_sframes_t  n ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        size_t  n_bytes ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        int  r ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-08 23:47:23 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_bool_t  after_avail  =  TRUE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( PA_UNLIKELY ( ( n  =  pa_alsa_safe_avail ( u - > pcm_handle ,  u - > hwbuf_size ,  & u - > sink - > sample_spec ) )  <  0 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( ( r  =  try_recover ( u ,  " snd_pcm_avail " ,  ( int )  n ) )  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        n_bytes  =  ( size_t )  n  *  u - > frame_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        left_to_play  =  check_left_to_play ( u ,  n_bytes ,  on_timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        on_timeout  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( u - > use_tsched ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* We won't fill up the playback buffer before at least
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            *  half  the  sleep  time  is  over  because  otherwise  we  might 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            *  ask  for  more  data  from  the  clients  then  they  expect .  We 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            *  need  to  guarantee  that  clients  only  have  to  keep  around 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            *  a  single  hw  buffer  length .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ! polled  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_bytes_to_usec ( left_to_play ,  & u - > sink - > sample_spec )  >  process_usec + max_sleep_usec / 2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( PA_UNLIKELY ( n_bytes  < =  u - > hwbuf_unused ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-21 16:33:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( polled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                PA_ONCE_BEGIN  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-23 22:56:09 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    char  * dn  =  pa_alsa_get_driver_name_by_pcm ( u - > pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    pa_log ( _ ( " ALSA woke us up to write new data to the device, but there was actually nothing to write! \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                             " Most likely this is a bug in the ALSA driver '%s'. Please report this issue to the ALSA developers. \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                             " We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() returned 0 or another value < min_avail. " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                           pa_strnull ( dn ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    pa_xfree ( dn ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-21 16:33:46 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                }  PA_ONCE_END ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:11:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( + + j  >  10 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_debug ( " Not filling up, because already too many iterations. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        n_bytes  - =  u - > hwbuf_unused ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        polled  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            snd_pcm_sframes_t  frames ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            void  * p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*         pa_log_debug("%lu frames to write", (unsigned long) frames); */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( u - > memchunk . length  < =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                pa_sink_render ( u - > sink ,  n_bytes ,  & u - > memchunk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_assert ( u - > memchunk . length  >  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            frames  =  ( snd_pcm_sframes_t )  ( u - > memchunk . length  /  u - > frame_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( frames  >  ( snd_pcm_sframes_t )  ( n_bytes / u - > frame_size ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                frames  =  ( snd_pcm_sframes_t )  ( n_bytes / u - > frame_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            p  =  pa_memblock_acquire ( u - > memchunk . memblock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            frames  =  snd_pcm_writei ( u - > pcm_handle ,  ( const  uint8_t * )  p  +  u - > memchunk . index ,  ( snd_pcm_uframes_t )  frames ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_memblock_release ( u - > memchunk . memblock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( PA_UNLIKELY ( frames  <  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-24 13:45:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                if  ( ! after_avail  & &  ( int )  frames  = =  - EAGAIN ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                if  ( ( r  =  try_recover ( u ,  " snd_pcm_writei " ,  ( int )  frames ) )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-24 13:45:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( ! after_avail  & &  frames  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_assert ( frames  >  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            after_avail  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            u - > memchunk . index  + =  ( size_t )  frames  *  u - > frame_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > memchunk . length  - =  ( size_t )  frames  *  u - > frame_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( u - > memchunk . length  < =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_memblock_unref ( u - > memchunk . memblock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_memchunk_reset ( & u - > memchunk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            work_done  =  TRUE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            u - > write_count  + =  frames  *  u - > frame_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > since_start  + =  frames  *  u - > frame_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*         pa_log_debug("wrote %lu frames", (unsigned long) frames); */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( ( size_t )  frames  *  u - > frame_size  > =  n_bytes ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            n_bytes  - =  ( size_t )  frames  *  u - > frame_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-23 03:23:22 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > use_tsched )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        * sleep_usec  =  pa_bytes_to_usec ( left_to_play ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-09 10:14:40 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        process_usec  =  pa_bytes_to_usec ( u - > tsched_watermark ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-13 03:40:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-23 03:23:22 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( * sleep_usec  >  process_usec ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            * sleep_usec  - =  process_usec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            * sleep_usec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-13 03:40:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        * sleep_usec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  work_done  ?  1  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  update_smoother ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_pcm_sframes_t  delay  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int64_t  position ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_usec_t  now1  =  0 ,  now2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_status_t  * status ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-29 19:46:59 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_htimestamp_t  htstamp  =  {  0 ,  0  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_status_alloca ( & status ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Let's update the time smoother */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-29 19:46:59 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( PA_UNLIKELY ( ( err  =  pa_alsa_safe_delay ( u - > pcm_handle ,  status ,  & delay ,  u - > hwbuf_size ,  & u - > sink - > sample_spec ,  FALSE ) )  <  0 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-19 19:22:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Failed to query DSP status data: %s " ,  pa_alsa_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-29 19:46:59 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_pcm_status_get_htstamp ( status ,  & htstamp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    now1  =  pa_timespec_load ( & htstamp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-20 13:40:27 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Hmm, if the timestamp is 0, then it wasn't set and we take the current time */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( now1  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        now1  =  pa_rtclock_now ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* check if the time since the last update is bigger than the interval */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-23 22:34:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > last_smoother_update  >  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-20 13:40:27 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( u - > last_smoother_update  +  u - > smoother_interval  >  now1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    position  =  ( int64_t )  u - > write_count  -  ( ( int64_t )  delay  *  ( int64_t )  u - > frame_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( PA_UNLIKELY ( position  <  0 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        position  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    now2  =  pa_bytes_to_usec ( ( uint64_t )  position ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-23 22:34:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_smoother_put ( u - > smoother ,  now1 ,  now2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-20 13:40:27 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > last_smoother_update  =  now1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* exponentially increase the update interval up to the MAX limit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > smoother_interval  =  PA_MIN  ( u - > smoother_interval  *  2 ,  SMOOTHER_MAX_INTERVAL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  pa_usec_t  sink_get_latency ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_usec_t  r ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    int64_t  delay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_usec_t  now1 ,  now2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-04 22:56:38 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    now1  =  pa_rtclock_now ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    now2  =  pa_smoother_get ( u - > smoother ,  now1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    delay  =  ( int64_t )  pa_bytes_to_usec ( u - > write_count ,  & u - > sink - > sample_spec )  -  ( int64_t )  now2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    r  =  delay  > =  0  ?  ( pa_usec_t )  delay  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > memchunk . memblock ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        r  + =  pa_bytes_to_usec ( u - > memchunk . length ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  build_pollfd ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > alsa_rtpoll_item ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_rtpoll_item_free ( u - > alsa_rtpoll_item ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! ( u - > alsa_rtpoll_item  =  pa_alsa_build_pollfd ( u - > pcm_handle ,  u - > rtpoll ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Called from IO context */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								static  int  suspend ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-04 22:56:38 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_smoother_pause ( u - > smoother ,  pa_rtclock_now ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Let's suspend -- we don't call snd_pcm_drain() here since that might
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  take  awfully  long  with  our  long  buffer  sizes  today .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_close ( u - > pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > pcm_handle  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > alsa_rtpoll_item )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_rtpoll_item_free ( u - > alsa_rtpoll_item ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > alsa_rtpoll_item  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-22 04:54:24 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* We reset max_rewind/max_request here to make sure that while we
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  are  suspended  the  old  max_request / max_rewind  values  set  before 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  the  suspend  can  influence  the  per - stream  buffer  of  newly 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  created  streams ,  without  their  requirements  having  any 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  influence  on  them .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_set_max_rewind_within_thread ( u - > sink ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_set_max_request_within_thread ( u - > sink ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_log_info ( " Device suspended... " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Called from IO context */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								static  int  update_sw_params ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_uframes_t  avail_min ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-24 18:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Use the full buffer if no one asked us for anything specific */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > hwbuf_unused  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > use_tsched )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_usec_t  latency ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( latency  =  pa_sink_get_requested_latency_within_thread ( u - > sink ) )  ! =  ( pa_usec_t )  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            size_t  b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_log_debug ( " Latency set to %0.2fms " ,  ( double )  latency  /  PA_USEC_PER_MSEC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            b  =  pa_usec_to_bytes ( latency ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* We need at least one sample in our buffer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( PA_UNLIKELY ( b  <  u - > frame_size ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                b  =  u - > frame_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            u - > hwbuf_unused  =  PA_LIKELY ( b  <  u - > hwbuf_size )  ?  ( u - > hwbuf_size  -  b )  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        fix_min_sleep_wakeup ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        fix_tsched_watermark ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_log_debug ( " hwbuf_unused=%lu " ,  ( unsigned  long )  u - > hwbuf_unused ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* We need at last one frame in the used part of the buffer */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    avail_min  =  ( snd_pcm_uframes_t )  u - > hwbuf_unused  /  u - > frame_size  +  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > use_tsched )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_usec_t  sleep_usec ,  process_usec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        hw_sleep_time ( u ,  & sleep_usec ,  & process_usec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        avail_min  + =  pa_usec_to_bytes ( sleep_usec ,  & u - > sink - > sample_spec )  /  u - > frame_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_log_debug ( " setting avail_min=%lu " ,  ( unsigned  long )  avail_min ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-06 00:17:24 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  pa_alsa_set_sw_params ( u - > pcm_handle ,  avail_min ,  ! u - > use_tsched ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-19 19:22:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to set software parameters: %s " ,  pa_alsa_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-24 21:13:41 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_sink_set_max_request_within_thread ( u - > sink ,  u - > hwbuf_size  -  u - > hwbuf_unused ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-13 15:27:40 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     if  ( pa_alsa_pcm_is_hw ( u - > pcm_handle ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         pa_sink_set_max_rewind_within_thread ( u - > sink ,  u - > hwbuf_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Disabling rewind_within_thread for device %s " ,  u - > device_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_max_rewind_within_thread ( u - > sink ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-07 18:12:32 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Called from IO Context on unsuspend or from main thread when creating sink */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  reset_watermark ( struct  userdata  * u ,  size_t  tsched_watermark ,  pa_sample_spec  * ss , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                            pa_bool_t  in_thread ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > tsched_watermark  =  pa_usec_to_bytes_round_up ( pa_bytes_to_usec_round_up ( tsched_watermark ,  ss ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                                    & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > watermark_inc_step  =  pa_usec_to_bytes ( TSCHED_WATERMARK_INC_STEP_USEC ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > watermark_dec_step  =  pa_usec_to_bytes ( TSCHED_WATERMARK_DEC_STEP_USEC ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > watermark_inc_threshold  =  pa_usec_to_bytes_round_up ( TSCHED_WATERMARK_INC_THRESHOLD_USEC ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > watermark_dec_threshold  =  pa_usec_to_bytes_round_up ( TSCHED_WATERMARK_DEC_THRESHOLD_USEC ,  & u - > sink - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fix_min_sleep_wakeup ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fix_tsched_watermark ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( in_thread ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_latency_range_within_thread ( u - > sink , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                                u - > min_latency_ref , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                                pa_bytes_to_usec ( u - > hwbuf_size ,  ss ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_latency_range ( u - > sink , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                  pa_bytes_to_usec ( u - > hwbuf_size ,  ss ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* work-around assert in pa_sink_set_latency_within_thead,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								           keep  track  of  min_latency  and  reuse  it  when 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								           this  routine  is  called  from  IO  context  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > min_latency_ref  =  u - > sink - > thread_info . min_latency ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_log_info ( " Time scheduling watermark is %0.2fms " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( double )  pa_bytes_to_usec ( u - > tsched_watermark ,  ss )  /  PA_USEC_PER_MSEC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Called from IO context */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								static  int  unsuspend ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sample_spec  ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_bool_t  b ,  d ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_pcm_uframes_t  period_size ,  buffer_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-17 22:38:43 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    char  * device_name  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ! u - > pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_log_info ( " Trying resume... " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-18 10:23:55 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( is_iec958 ( u )  | |  is_hdmi ( u ) )  & &  pa_sink_is_passthrough ( u - > sink ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-17 22:38:43 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        /* Need to open device in NONAUDIO mode */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        int  len  =  strlen ( u - > device_name )  +  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        device_name  =  pa_xmalloc ( len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_snprintf ( device_name ,  len ,  " %s,AES0=6 " ,  u - > device_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  snd_pcm_open ( & u - > pcm_handle ,  device_name  ?  device_name  :  u - > device_name ,  SND_PCM_STREAM_PLAYBACK , 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:44:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                            SND_PCM_NONBLOCK | 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                            SND_PCM_NO_AUTO_RESAMPLE | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                            SND_PCM_NO_AUTO_CHANNELS | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                            SND_PCM_NO_AUTO_FORMAT ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-19 19:22:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log ( " Error opening PCM device %s: %s " ,  u - > device_name ,  pa_alsa_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss  =  u - > sink - > sample_spec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    period_size  =  u - > fragment_size  /  u - > frame_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    buffer_size  =  u - > hwbuf_size  /  u - > frame_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    b  =  u - > use_mmap ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    d  =  u - > use_tsched ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( err  =  pa_alsa_set_hw_params ( u - > pcm_handle ,  & ss ,  & period_size ,  & buffer_size ,  0 ,  & b ,  & d ,  TRUE ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-19 19:22:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to set hardware parameters: %s " ,  pa_alsa_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( b  ! =  u - > use_mmap  | |  d  ! =  u - > use_tsched )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Resume failed, couldn't get original access mode. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! pa_sample_spec_equal ( & ss ,  & u - > sink - > sample_spec ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Resume failed, couldn't restore original sample settings. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( period_size * u - > frame_size  ! =  u - > fragment_size  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        buffer_size * u - > frame_size  ! =  u - > hwbuf_size )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_warn ( " Resume failed, couldn't restore original fragment settings. (Old: %lu/%lu, New %lu/%lu) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    ( unsigned  long )  u - > hwbuf_size ,  ( unsigned  long )  u - > fragment_size , 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-20 20:00:26 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    ( unsigned  long )  ( buffer_size * u - > frame_size ) ,  ( unsigned  long )  ( period_size * u - > frame_size ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( update_sw_params ( u )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( build_pollfd ( u )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-24 20:13:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > write_count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_smoother_reset ( u - > smoother ,  pa_rtclock_now ( ) ,  TRUE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-20 13:40:27 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > smoother_interval  =  SMOOTHER_MIN_INTERVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > last_smoother_update  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-24 20:13:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    u - > first  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > since_start  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-07 18:12:32 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* reset the watermark to the value defined when sink was created */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > use_tsched ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        reset_watermark ( u ,  u - > tsched_watermark_ref ,  & u - > sink - > sample_spec ,  TRUE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_log_info ( " Resumed successfully... " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-17 22:38:43 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_xfree ( device_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								fail : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > pcm_handle )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_close ( u - > pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > pcm_handle  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-17 22:38:43 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_xfree ( device_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-11 01:22:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  - PA_ERR_IO ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Called from IO context */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								static  int  sink_process_msg ( pa_msgobject  * o ,  int  code ,  void  * data ,  int64_t  offset ,  pa_memchunk  * chunk )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  PA_SINK ( o ) - > userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    switch  ( code )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        case  PA_SINK_MESSAGE_GET_LATENCY :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_usec_t  r  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( u - > pcm_handle ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                r  =  sink_get_latency ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            * ( ( pa_usec_t * )  data )  =  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        case  PA_SINK_MESSAGE_SET_STATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            switch  ( ( pa_sink_state_t )  PA_PTR_TO_UINT ( data ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-11 01:22:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                case  PA_SINK_SUSPENDED :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    int  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                    pa_assert ( PA_SINK_IS_OPENED ( u - > sink - > thread_info . state ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-11 01:22:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    if  ( ( r  =  suspend ( u ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        return  r ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-11 01:22:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                case  PA_SINK_IDLE : 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-11 01:22:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                case  PA_SINK_RUNNING :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    int  r ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    if  ( u - > sink - > thread_info . state  = =  PA_SINK_INIT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        if  ( build_pollfd ( u )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-11 01:22:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                            return  - PA_ERR_IO ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    if  ( u - > sink - > thread_info . state  = =  PA_SINK_SUSPENDED )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-11 01:22:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                        if  ( ( r  =  unsuspend ( u ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                            return  r ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-11 01:22:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                case  PA_SINK_UNLINKED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                case  PA_SINK_INIT : 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-22 00:25:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                case  PA_SINK_INVALID_STATE : 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                    ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  pa_sink_process_msg ( o ,  code ,  data ,  offset ,  chunk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Called from main context */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  sink_set_state_cb ( pa_sink  * s ,  pa_sink_state_t  new_state )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_state_t  old_state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_assert_ref ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert_se ( u  =  s - > userdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old_state  =  pa_sink_get_state ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( PA_SINK_IS_OPENED ( old_state )  & &  new_state  = =  PA_SINK_SUSPENDED ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        reserve_done ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  if  ( old_state  = =  PA_SINK_SUSPENDED  & &  PA_SINK_IS_OPENED ( new_state ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( reserve_init ( u ,  u - > device_name )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-11 01:22:10 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            return  - PA_ERR_BUSY ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  ctl_mixer_callback ( snd_mixer_elem_t  * elem ,  unsigned  int  mask )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  snd_mixer_elem_get_callback_private ( elem ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( mask  = =  SND_CTL_EVENT_MASK_REMOVE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-12 12:57:20 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! PA_SINK_IS_LINKED ( u - > sink - > state ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-04 17:07:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > sink - > suspend_cause  &  PA_SUSPEND_SESSION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_mixer_dirty ( u - > sink ,  TRUE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-13 20:30:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-04 17:07:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-13 20:30:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( mask  &  SND_CTL_EVENT_MASK_VALUE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-19 02:55:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_sink_get_volume ( u - > sink ,  TRUE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_get_mute ( u - > sink ,  TRUE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  io_mixer_callback ( snd_mixer_elem_t  * elem ,  unsigned  int  mask )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  snd_mixer_elem_get_callback_private ( elem ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( mask  = =  SND_CTL_EVENT_MASK_REMOVE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-04 17:07:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > sink - > suspend_cause  &  PA_SUSPEND_SESSION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_mixer_dirty ( u - > sink ,  TRUE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-04 17:07:13 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( mask  &  SND_CTL_EVENT_MASK_VALUE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_update_volume_and_mute ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-27 04:39:07 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  sink_get_volume_cb ( pa_sink  * s )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_cvolume  r ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-18 18:12:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    char  vol_str_pcnt [ PA_CVOLUME_SNPRINT_MAX ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_handle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_alsa_path_get_volume ( u - > mixer_path ,  u - > mixer_handle ,  & s - > channel_map ,  & r )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Shift down by the base volume, so that 0dB becomes maximum volume */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sw_cvolume_multiply_scalar ( & r ,  & r ,  s - > base_volume ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-18 18:12:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_log_debug ( " Read hardware volume: %s " ,  pa_cvolume_snprint ( vol_str_pcnt ,  sizeof ( vol_str_pcnt ) ,  & r ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > mixer_path - > has_dB )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        char  vol_str_db [ PA_SW_CVOLUME_SNPRINT_DB_MAX ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( "                in dB: %s " ,  pa_sw_cvolume_snprint_dB ( vol_str_db ,  sizeof ( vol_str_db ) ,  & r ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_cvolume_equal ( & u - > hardware_volume ,  & r ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-19 02:29:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    s - > real_volume  =  u - > hardware_volume  =  r ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-19 02:29:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Hmm, so the hardware volume changed, let's reset our software volume */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > mixer_path - > has_dB ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_soft_volume ( s ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-27 04:39:07 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  sink_set_volume_cb ( pa_sink  * s )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_cvolume  r ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-18 18:12:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    char  vol_str_pcnt [ PA_CVOLUME_SNPRINT_MAX ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  deferred_volume  =  ! ! ( s - > flags  &  PA_SINK_DEFERRED_VOLUME ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_handle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Shift up by the base volume */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-19 02:29:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_sw_cvolume_divide_scalar ( & r ,  & s - > real_volume ,  s - > base_volume ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_alsa_path_set_volume ( u - > mixer_path ,  u - > mixer_handle ,  & s - > channel_map ,  & r ,  deferred_volume ,  ! deferred_volume )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Shift down by the base volume, so that 0dB becomes maximum volume */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sw_cvolume_multiply_scalar ( & r ,  & r ,  s - > base_volume ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > hardware_volume  =  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > mixer_path - > has_dB )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-19 02:29:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_cvolume  new_soft_volume ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  accurate_enough ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-18 18:12:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        char  vol_str_db [ PA_SW_CVOLUME_SNPRINT_DB_MAX ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* Match exactly what the user requested by software */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-19 02:29:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_sw_cvolume_divide ( & new_soft_volume ,  & s - > real_volume ,  & u - > hardware_volume ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* If the adjustment to do in software is only minimal we
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  can  skip  it .  That  saves  us  CPU  at  the  expense  of  a  bit  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  accuracy  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        accurate_enough  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ( pa_cvolume_min ( & new_soft_volume )  > =  ( PA_VOLUME_NORM  -  VOLUME_ACCURACY ) )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ( pa_cvolume_max ( & new_soft_volume )  < =  ( PA_VOLUME_NORM  +  VOLUME_ACCURACY ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-18 18:12:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Requested volume: %s " ,  pa_cvolume_snprint ( vol_str_pcnt ,  sizeof ( vol_str_pcnt ) ,  & s - > real_volume ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( "            in dB: %s " ,  pa_sw_cvolume_snprint_dB ( vol_str_db ,  sizeof ( vol_str_db ) ,  & s - > real_volume ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Got hardware volume: %s " ,  pa_cvolume_snprint ( vol_str_pcnt ,  sizeof ( vol_str_pcnt ) ,  & u - > hardware_volume ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( "               in dB: %s " ,  pa_sw_cvolume_snprint_dB ( vol_str_db ,  sizeof ( vol_str_db ) ,  & u - > hardware_volume ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Calculated software volume: %s (accurate-enough=%s) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                     pa_cvolume_snprint ( vol_str_pcnt ,  sizeof ( vol_str_pcnt ) ,  & new_soft_volume ) , 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-19 02:29:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                     pa_yes_no ( accurate_enough ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-18 18:12:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_debug ( "                      in dB: %s " ,  pa_sw_cvolume_snprint_dB ( vol_str_db ,  sizeof ( vol_str_db ) ,  & new_soft_volume ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-19 02:29:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! accurate_enough ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            s - > soft_volume  =  new_soft_volume ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-18 18:12:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Wrote hardware volume: %s " ,  pa_cvolume_snprint ( vol_str_pcnt ,  sizeof ( vol_str_pcnt ) ,  & r ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* We can't match exactly what the user requested, hence let's
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  at  least  tell  the  user  about  it  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-19 02:29:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        s - > real_volume  =  r ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  sink_write_volume_cb ( pa_sink  * s )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_cvolume  hw_vol  =  s - > thread_info . current_hw_volume ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_handle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( s - > flags  &  PA_SINK_DEFERRED_VOLUME ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-25 15:15:17 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Shift up by the base volume */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sw_cvolume_divide_scalar ( & hw_vol ,  & hw_vol ,  s - > base_volume ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-12-20 18:25:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_alsa_path_set_volume ( u - > mixer_path ,  u - > mixer_handle ,  & s - > channel_map ,  & hw_vol ,  TRUE ,  TRUE )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_error ( " Writing HW volume failed " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_cvolume  tmp_vol ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_bool_t  accurate_enough ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-18 18:12:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-25 15:15:17 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        /* Shift down by the base volume, so that 0dB becomes maximum volume */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sw_cvolume_multiply_scalar ( & hw_vol ,  & hw_vol ,  s - > base_volume ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_sw_cvolume_divide ( & tmp_vol ,  & hw_vol ,  & s - > thread_info . current_hw_volume ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        accurate_enough  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ( pa_cvolume_min ( & tmp_vol )  > =  ( PA_VOLUME_NORM  -  VOLUME_ACCURACY ) )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ( pa_cvolume_max ( & tmp_vol )  < =  ( PA_VOLUME_NORM  +  VOLUME_ACCURACY ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-18 18:12:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! accurate_enough )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-13 16:44:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            union  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                char  db [ 2 ] [ PA_SW_CVOLUME_SNPRINT_DB_MAX ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                char  pcnt [ 2 ] [ PA_CVOLUME_SNPRINT_MAX ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            }  vol ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-18 18:12:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-25 15:15:17 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_log_debug ( " Written HW volume did not match with the request: %s (request) != %s " , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-13 16:44:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                         pa_cvolume_snprint ( vol . pcnt [ 0 ] ,  sizeof ( vol . pcnt [ 0 ] ) ,  & s - > thread_info . current_hw_volume ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                         pa_cvolume_snprint ( vol . pcnt [ 1 ] ,  sizeof ( vol . pcnt [ 1 ] ) ,  & hw_vol ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-25 15:15:17 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_log_debug ( "                                            in dB: %s (request) != %s " , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-13 16:44:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                         pa_sw_cvolume_snprint_dB ( vol . db [ 0 ] ,  sizeof ( vol . db [ 0 ] ) ,  & s - > thread_info . current_hw_volume ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                         pa_sw_cvolume_snprint_dB ( vol . db [ 1 ] ,  sizeof ( vol . db [ 1 ] ) ,  & hw_vol ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-27 04:39:07 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  sink_get_mute_cb ( pa_sink  * s )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  b ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_handle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_alsa_path_get_mute ( u - > mixer_path ,  u - > mixer_handle ,  & b )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-27 04:39:07 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    s - > muted  =  b ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-27 04:39:07 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  sink_set_mute_cb ( pa_sink  * s )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_handle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_alsa_path_set_mute ( u - > mixer_path ,  u - > mixer_handle ,  s - > muted ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-02 16:23:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  mixer_volume_init ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! u - > mixer_path - > has_volume )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_write_volume_callback ( u - > sink ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_get_volume_callback ( u - > sink ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_set_volume_callback ( u - > sink ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Driver does not support hardware volume control, falling back to software volume control. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_get_volume_callback ( u - > sink ,  sink_get_volume_cb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_set_volume_callback ( u - > sink ,  sink_set_volume_cb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( u - > mixer_path - > has_dB  & &  u - > deferred_volume )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-02 16:23:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_sink_set_write_volume_callback ( u - > sink ,  sink_write_volume_cb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-17 09:28:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_log_info ( " Successfully enabled deferred volume. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-02 16:23:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        }  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_sink_set_write_volume_callback ( u - > sink ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( u - > mixer_path - > has_dB )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_sink_enable_decibel_volume ( u - > sink ,  TRUE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_info ( " Hardware volume ranges from %0.2f dB to %0.2f dB. " ,  u - > mixer_path - > min_dB ,  u - > mixer_path - > max_dB ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > sink - > base_volume  =  pa_sw_volume_from_dB ( - u - > mixer_path - > max_dB ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > sink - > n_volume_steps  =  PA_VOLUME_NORM + 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_info ( " Fixing base volume to %0.2f dB " ,  pa_sw_volume_to_dB ( u - > sink - > base_volume ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_sink_enable_decibel_volume ( u - > sink ,  FALSE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_info ( " Hardware volume ranges from %li to %li. " ,  u - > mixer_path - > min_volume ,  u - > mixer_path - > max_volume ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > sink - > base_volume  =  PA_VOLUME_NORM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > sink - > n_volume_steps  =  u - > mixer_path - > max_volume  -  u - > mixer_path - > min_volume  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Using hardware volume control. Hardware dB scale %s. " ,  u - > mixer_path - > has_dB  ?  " supported "  :  " not supported " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! u - > mixer_path - > has_mute )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_get_mute_callback ( u - > sink ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_set_mute_callback ( u - > sink ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Driver does not support hardware mute control, falling back to software mute control. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_get_mute_callback ( u - > sink ,  sink_get_mute_cb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_set_mute_callback ( u - > sink ,  sink_set_mute_cb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Using hardware mute control. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:53:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  sink_set_port_ucm_cb ( pa_sink  * s ,  pa_device_port  * p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > ucm_context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  pa_alsa_ucm_set_port ( u - > ucm_context ,  p ,  TRUE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  sink_set_port_cb ( pa_sink  * s ,  pa_device_port  * p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_alsa_port_data  * data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > mixer_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    data  =  PA_DEVICE_PORT_DATA ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert_se ( u - > mixer_path  =  data - > path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-22 11:29:12 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_alsa_path_select ( u - > mixer_path ,  data - > setting ,  u - > mixer_handle ,  s - > muted ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-22 11:29:11 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    mixer_volume_init ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( s - > set_mute ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        s - > set_mute ( s ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-03 21:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( s - > flags  &  PA_SINK_DEFERRED_VOLUME )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( s - > write_volume ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            s - > write_volume ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( s - > set_volume ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            s - > set_volume ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  sink_update_requested_latency_cb ( pa_sink  * s )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    size_t  before ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-23 03:23:22 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > use_tsched ) ;  /* only when timer scheduling is used
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                               *  we  can  dynamically  adjust  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                               *  latency  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! u - > pcm_handle ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    before  =  u - > hwbuf_unused ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    update_sw_params ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Let's check whether we now use only a smaller part of the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    buffer  then  before .  If  so ,  we  need  to  make  sure  that  subsequent 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-01 12:35:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    rewinds  are  relative  to  the  new  maximum  fill  level  and  not  to  the 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    current  fill  level .  Thus ,  let ' s  do  a  full  rewind  once ,  to  clear 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    things  up .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > hwbuf_unused  >  before )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Requesting rewind due to latency change. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_request_rewind ( s ,  ( size_t )  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-12 16:36:00 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  pa_idxset *  sink_get_formats ( pa_sink  * s )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_idxset  * ret  =  pa_idxset_new ( NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_format_info  * f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    uint32_t  idx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    PA_IDXSET_FOREACH ( f ,  u - > formats ,  idx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_idxset_put ( ret ,  pa_format_info_copy ( f ) ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  pa_bool_t  sink_set_formats ( pa_sink  * s ,  pa_idxset  * formats )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-17 22:46:06 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_format_info  * f ,  * g ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    uint32_t  idx ,  n ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-12 16:36:00 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* FIXME: also validate sample rates against what the device supports */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    PA_IDXSET_FOREACH ( f ,  formats ,  idx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( is_iec958 ( u )  & &  f - > encoding  = =  PA_ENCODING_EAC3_IEC61937 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* EAC3 cannot be sent over over S/PDIF */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_idxset_free ( u - > formats ,  ( pa_free2_cb_t )  pa_format_info_free2 ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > formats  =  pa_idxset_new ( NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-04 11:05:59 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Note: the logic below won't apply if we're using software encoding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  This  is  fine  for  now  since  we  don ' t  support  that  via  the  passthrough 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  framework ,  but  this  must  be  changed  if  we  do .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-17 22:46:06 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Count how many sample rates we support */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( idx  =  0 ,  n  =  0 ;  u - > rates [ idx ] ;  idx + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        n + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-04 11:05:59 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* First insert non-PCM formats since we prefer those. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    PA_IDXSET_FOREACH ( f ,  formats ,  idx )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-17 22:46:06 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! pa_format_info_is_pcm ( f ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            g  =  pa_format_info_copy ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_format_info_set_prop_int_array ( g ,  PA_PROP_FORMAT_RATE ,  ( int  * )  u - > rates ,  n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_idxset_put ( u - > formats ,  g ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-04 11:05:59 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Now add any PCM formats */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-12 16:36:00 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    PA_IDXSET_FOREACH ( f ,  formats ,  idx )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-17 22:46:06 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( pa_format_info_is_pcm ( f ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* We don't set rates here since we'll just tack on a resampler for
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             *  unsupported  rates  */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-04 11:05:59 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_idxset_put ( u - > formats ,  pa_format_info_copy ( f ) ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-17 22:46:06 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-12 16:36:00 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-02 18:37:29 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  pa_bool_t  sink_update_rate_cb ( pa_sink  * s ,  uint32_t  rate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-17 22:46:06 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_bool_t  supported  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-02 18:37:29 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-17 22:46:06 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    for  ( i  =  0 ;  u - > rates [ i ] ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( u - > rates [ i ]  = =  rate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            supported  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! supported )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Sink does not support sample rate of %d Hz " ,  rate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-02 18:37:29 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! PA_SINK_IS_OPENED ( s - > state ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Updating rate for device %s, new rate is %d " , u - > device_name ,  rate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink - > sample_spec . rate  =  rate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-17 22:46:06 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-02 18:37:29 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								static  int  process_rewind ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snd_pcm_sframes_t  unused ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    size_t  rewind_nbytes ,  unused_nbytes ,  limit_nbytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-30 16:50:13 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! PA_SINK_IS_OPENED ( u - > sink - > thread_info . state ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_process_rewind ( u - > sink ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    /* Figure out how much we shall rewind and reset the counter */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    rewind_nbytes  =  u - > sink - > thread_info . rewind_nbytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_log_debug ( " Requested to rewind %lu bytes. " ,  ( unsigned  long )  rewind_nbytes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-04 02:55:34 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( PA_UNLIKELY ( ( unused  =  pa_alsa_safe_avail ( u - > pcm_handle ,  u - > hwbuf_size ,  & u - > sink - > sample_spec ) )  <  0 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-19 19:22:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log ( " snd_pcm_avail() failed: %s " ,  pa_alsa_strerror ( ( int )  unused ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-23 03:23:22 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    unused_nbytes  =  ( size_t )  unused  *  u - > frame_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 10:48:11 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* make sure rewind doesn't go too far, can cause issues with DMAs */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unused_nbytes  + =  u - > rewind_safeguard ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > hwbuf_size  >  unused_nbytes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        limit_nbytes  =  u - > hwbuf_size  -  unused_nbytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        limit_nbytes  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( rewind_nbytes  >  limit_nbytes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        rewind_nbytes  =  limit_nbytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( rewind_nbytes  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_sframes_t  in_frames ,  out_frames ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Limited to %lu bytes. " ,  ( unsigned  long )  rewind_nbytes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        in_frames  =  ( snd_pcm_sframes_t )  ( rewind_nbytes  /  u - > frame_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " before: %lu " ,  ( unsigned  long )  in_frames ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( out_frames  =  snd_pcm_rewind ( u - > pcm_handle ,  ( snd_pcm_uframes_t )  in_frames ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-19 19:22:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_log ( " snd_pcm_rewind() failed: %s " ,  pa_alsa_strerror ( ( int )  out_frames ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-02 17:52:05 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( try_recover ( u ,  " process_rewind " ,  out_frames )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            out_frames  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-02 17:52:05 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " after: %lu " ,  ( unsigned  long )  out_frames ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        rewind_nbytes  =  ( size_t )  out_frames  *  u - > frame_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( rewind_nbytes  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_info ( " Tried rewind, but was apparently not possible. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-24 20:13:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            u - > write_count  - =  rewind_nbytes ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_debug ( " Rewound %lu bytes. " ,  ( unsigned  long )  rewind_nbytes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_sink_process_rewind ( u - > sink ,  rewind_nbytes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > after_rewind  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Mhmm, actually there is nothing to rewind. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_process_rewind ( u - > sink ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  thread_func ( void  * userdata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  short  revents  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_log_debug ( " Thread starting up " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > core - > realtime_scheduling ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_make_realtime ( u - > core - > realtime_priority ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_thread_mq_install ( & u - > thread_mq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        int  ret ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-22 10:53:32 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_usec_t  rtpoll_sleep  =  0 ,  real_sleep ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Loop " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-30 16:50:13 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( PA_UNLIKELY ( u - > sink - > thread_info . rewind_requested ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( process_rewind ( u )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        /* Render some data and write it to the dsp */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( PA_SINK_IS_OPENED ( u - > sink - > thread_info . state ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            int  work_done ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_usec_t  sleep_usec  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_bool_t  on_timeout  =  pa_rtpoll_timer_elapsed ( u - > rtpoll ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( u - > use_mmap ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                work_done  =  mmap_write ( u ,  & sleep_usec ,  revents  &  POLLOUT ,  on_timeout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            else 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-24 03:26:56 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                work_done  =  unix_write ( u ,  & sleep_usec ,  revents  &  POLLOUT ,  on_timeout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( work_done  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*             pa_log_debug("work_done = %i", work_done); */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( work_done )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( u - > first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    pa_log_info ( " Starting playback. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    snd_pcm_start ( u - > pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-04 22:56:38 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    pa_smoother_resume ( u - > smoother ,  pa_rtclock_now ( ) ,  TRUE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-14 19:44:57 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    u - > first  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                update_smoother ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( u - > use_tsched )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_usec_t  cusec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( u - > since_start  < =  u - > hwbuf_size )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    /* USB devices on ALSA seem to hit a buffer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                     *  underrun  during  the  first  iterations  much 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                     *  quicker  then  we  calculate  here ,  probably  due  to 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-01 12:35:44 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                     *  the  transport  latency .  To  accommodate  for  that 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                     *  we  artificially  decrease  the  sleep  time  until 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                     *  we  have  filled  the  buffer  at  least  once 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                     *  completely . */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-22 01:08:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    if  ( pa_log_ratelimit ( PA_LOG_DEBUG ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-15 00:16:25 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                        pa_log_debug ( " Cutting sleep time for the initial iterations by half. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                    sleep_usec  / =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                /* OK, the playback buffer is now full, let's
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  calculate  when  to  wake  up  next  */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-12 11:18:25 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_log_debug ( " Waking up in %0.2fms (sound card clock). " ,  ( double )  sleep_usec  /  PA_USEC_PER_MSEC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                /* Convert from the sound card time domain to the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  system  time  domain  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-04 22:56:38 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                cusec  =  pa_smoother_translate ( u - > smoother ,  pa_rtclock_now ( ) ,  sleep_usec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-12 11:18:25 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_log_debug ( " Waking up in %0.2fms (system clock). " ,  ( double )  cusec  /  PA_USEC_PER_MSEC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                /* We don't trust the conversion, so we wake up whatever comes first */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                rtpoll_sleep  =  PA_MIN ( sleep_usec ,  cusec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > after_rewind  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( u - > sink - > flags  &  PA_SINK_DEFERRED_VOLUME )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_usec_t  volume_sleep ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_sink_volume_change_apply ( u - > sink ,  & volume_sleep ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-13 17:30:39 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( volume_sleep  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( rtpoll_sleep  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    rtpoll_sleep  =  PA_MIN ( volume_sleep ,  rtpoll_sleep ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    rtpoll_sleep  =  volume_sleep ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-22 10:53:32 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( rtpoll_sleep  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_rtpoll_set_timer_relative ( u - > rtpoll ,  rtpoll_sleep ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-22 10:53:32 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            real_sleep  =  pa_rtclock_now ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        else 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            pa_rtpoll_set_timer_disabled ( u - > rtpoll ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* Hmm, nothing to do. Let's sleep */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( ret  =  pa_rtpoll_run ( u - > rtpoll ,  TRUE ) )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-22 10:53:32 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( rtpoll_sleep  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            real_sleep  =  pa_rtclock_now ( )  -  real_sleep ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef DEBUG_TIMING 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_debug ( " Expected sleep: %0.2fms, real sleep: %0.2fms (diff %0.2f ms) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( double )  rtpoll_sleep  /  PA_USEC_PER_MSEC ,  ( double )  real_sleep  /  PA_USEC_PER_MSEC , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( double )  ( ( int64_t )  real_sleep  -  ( int64_t )  rtpoll_sleep )  /  PA_USEC_PER_MSEC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( u - > use_tsched  & &  real_sleep  >  rtpoll_sleep  +  u - > tsched_watermark ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_log_info ( " Scheduling delay of %0.2fms, you might want to investigate this to improve latency... " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    ( double )  ( real_sleep  -  rtpoll_sleep )  /  PA_USEC_PER_MSEC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( u - > sink - > flags  &  PA_SINK_DEFERRED_VOLUME ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_sink_volume_change_apply ( u - > sink ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ret  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  finish ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* Tell ALSA about this and process its response */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( PA_SINK_IS_OPENED ( u - > sink - > thread_info . state ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            struct  pollfd  * pollfd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            unsigned  n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pollfd  =  pa_rtpoll_item_get_pollfd ( u - > alsa_rtpoll_item ,  & n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( ( err  =  snd_pcm_poll_descriptors_revents ( u - > pcm_handle ,  pollfd ,  n ,  & revents ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-19 19:22:51 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                pa_log ( " snd_pcm_poll_descriptors_revents() failed: %s " ,  pa_alsa_strerror ( err ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( revents  &  ~ POLLOUT )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                if  ( pa_alsa_recover_from_poll ( u - > pcm_handle ,  revents )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                u - > first  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                u - > since_start  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-05 10:33:17 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                revents  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-22 01:08:36 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            }  else  if  ( revents  & &  u - > use_tsched  & &  pa_log_ratelimit ( PA_LOG_DEBUG ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-20 03:21:17 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                pa_log_debug ( " Wakeup from ALSA! " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            revents  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								fail : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* If this was no regular exit from the loop we have to continue
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  processing  messages  until  we  received  PA_MESSAGE_SHUTDOWN  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_asyncmsgq_post ( u - > thread_mq . outq ,  PA_MSGOBJECT ( u - > core ) ,  PA_CORE_MESSAGE_UNLOAD_MODULE ,  u - > module ,  0 ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_asyncmsgq_wait_for ( u - > thread_mq . inq ,  PA_MESSAGE_SHUTDOWN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								finish : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_log_debug ( " Thread shutting down " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-18 03:42:39 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  set_sink_name ( pa_sink_new_data  * data ,  pa_modargs  * ma ,  const  char  * device_id ,  const  char  * device_name ,  pa_alsa_mapping  * mapping )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-22 00:24:13 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    const  char  * n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  * t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( ma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( device_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( n  =  pa_modargs_get_value ( ma ,  " sink_name " ,  NULL ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_new_data_set_name ( data ,  n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        data - > namereg_fail  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( n  =  pa_modargs_get_value ( ma ,  " name " ,  NULL ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        data - > namereg_fail  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        n  =  device_id  ?  device_id  :  device_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        data - > namereg_fail  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-18 03:42:39 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( mapping ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        t  =  pa_sprintf_malloc ( " alsa_output.%s.%s " ,  n ,  mapping - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        t  =  pa_sprintf_malloc ( " alsa_output.%s " ,  n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-22 00:24:13 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_sink_new_data_set_name ( data ,  t ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( t ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  find_mixer ( struct  userdata  * u ,  pa_alsa_mapping  * mapping ,  const  char  * element ,  pa_bool_t  ignore_dB )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-23 07:17:02 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_hctl_t  * hctl ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! mapping  & &  ! element ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-23 07:17:02 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! ( u - > mixer_handle  =  pa_alsa_open_mixer_for_pcm ( u - > pcm_handle ,  & u - > control_device ,  & hctl ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Failed to find a working mixer device. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( element )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! ( u - > mixer_path  =  pa_alsa_path_synthesize ( element ,  PA_ALSA_DIRECTION_OUTPUT ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-23 07:17:02 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( pa_alsa_path_probe ( u - > mixer_path ,  u - > mixer_handle ,  hctl ,  ignore_dB )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( " Probed mixer path %s: " ,  u - > mixer_path - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_alsa_path_dump ( u - > mixer_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-25 15:17:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  if  ( ! ( u - > mixer_path_set  =  mapping - > output_path_set ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								fail : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-25 15:17:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > mixer_path )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_alsa_path_free ( u - > mixer_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > mixer_path  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > mixer_handle )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_mixer_close ( u - > mixer_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > mixer_handle  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-02 16:23:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  setup_mixer ( struct  userdata  * u ,  pa_bool_t  ignore_dB )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_bool_t  need_mixer_callback  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! u - > mixer_handle ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > sink - > active_port )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_alsa_port_data  * data ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        /* We have a list of supported paths, so let's activate the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  one  that  has  been  chosen  as  active  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        data  =  PA_DEVICE_PORT_DATA ( u - > sink - > active_port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > mixer_path  =  data - > path ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-22 11:29:12 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_alsa_path_select ( data - > path ,  data - > setting ,  u - > mixer_handle ,  u - > sink - > muted ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! u - > mixer_path  & &  u - > mixer_path_set ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-25 15:17:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            u - > mixer_path  =  pa_hashmap_first ( u - > mixer_path_set - > paths ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( u - > mixer_path )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* Hmm, we have only a single path, then let's activate it */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-22 11:29:12 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_alsa_path_select ( u - > mixer_path ,  u - > mixer_path - > settings ,  u - > mixer_handle ,  u - > sink - > muted ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-02 16:23:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    mixer_volume_init ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-02 16:23:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Will we need to register callbacks? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > mixer_path_set  & &  u - > mixer_path_set - > paths )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_alsa_path  * p ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-25 15:17:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        void  * state ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-25 15:17:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        PA_HASHMAP_FOREACH ( p ,  u - > mixer_path_set - > paths ,  state )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-02 16:23:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( p - > has_volume  | |  p - > has_mute ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                need_mixer_callback  =  TRUE ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-02 16:23:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    else  if  ( u - > mixer_path ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        need_mixer_callback  =  u - > mixer_path - > has_volume  | |  u - > mixer_path - > has_mute ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-02 16:23:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( need_mixer_callback )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-13 16:44:45 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        int  ( * mixer_callback ) ( snd_mixer_elem_t  * ,  unsigned  int ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( u - > sink - > flags  &  PA_SINK_DEFERRED_VOLUME )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-13 16:44:45 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            u - > mixer_pd  =  pa_alsa_mixer_pdata_new ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            mixer_callback  =  io_mixer_callback ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-13 16:44:45 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( pa_alsa_set_mixer_rtpoll ( u - > mixer_pd ,  u - > mixer_handle ,  u - > rtpoll )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_log ( " Failed to initialize file descriptor monitoring " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > mixer_fdl  =  pa_alsa_fdlist_new ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            mixer_callback  =  ctl_mixer_callback ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-23 07:17:02 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( pa_alsa_fdlist_set_handle ( u - > mixer_fdl ,  u - > mixer_handle ,  NULL ,  u - > core - > mainloop )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-13 16:44:45 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                pa_log ( " Failed to initialize file descriptor monitoring " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-13 16:44:45 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( u - > mixer_path_set ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_alsa_path_set_set_callback ( u - > mixer_path_set ,  u - > mixer_handle ,  mixer_callback ,  u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_alsa_path_set_callback ( u - > mixer_path ,  u - > mixer_handle ,  mixer_callback ,  u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								pa_sink  * pa_alsa_sink_new ( pa_module  * m ,  pa_modargs  * ma ,  const  char * driver ,  pa_card  * card ,  pa_alsa_mapping  * mapping )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-16 15:42:53 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    const  char  * dev_id  =  NULL ,  * key ,  * mod_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-07 18:12:32 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_sample_spec  ss ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-02 18:37:29 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    uint32_t  alternate_sample_rate ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_channel_map  map ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-24 17:47:25 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    uint32_t  nfrags ,  frag_size ,  buffer_size ,  tsched_size ,  tsched_watermark ,  rewind_safeguard ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    snd_pcm_uframes_t  period_frames ,  buffer_frames ,  tsched_frames ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-24 17:47:25 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    size_t  frame_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-03 21:14:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  use_mmap  =  TRUE ,  b ,  use_tsched  =  TRUE ,  d ,  ignore_dB  =  FALSE ,  namereg_fail  =  FALSE ,  deferred_volume  =  FALSE ,  set_formats  =  FALSE ,  fixed_latency_range  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_new_data  data ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_alsa_profile_set  * profile_set  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-03 11:50:29 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    void  * state  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( m ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 02:01:44 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_assert ( ma ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss  =  m - > core - > default_sample_spec ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-21 16:32:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    map  =  m - > core - > default_channel_map ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_sample_spec_and_channel_map ( ma ,  & ss ,  & map ,  PA_CHANNEL_MAP_ALSA )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to parse sample specification and channel map " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-02 18:37:29 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    alternate_sample_rate  =  m - > core - > alternate_sample_rate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_alternate_sample_rate ( ma ,  & alternate_sample_rate )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to parse alternate sample rate " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    frame_size  =  pa_frame_size ( & ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    nfrags  =  m - > core - > default_n_fragments ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    frag_size  =  ( uint32_t )  pa_usec_to_bytes ( m - > core - > default_fragment_size_msec * PA_USEC_PER_MSEC ,  & ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( frag_size  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        frag_size  =  ( uint32_t )  frame_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    tsched_size  =  ( uint32_t )  pa_usec_to_bytes ( DEFAULT_TSCHED_BUFFER_USEC ,  & ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    tsched_watermark  =  ( uint32_t )  pa_usec_to_bytes ( DEFAULT_TSCHED_WATERMARK_USEC ,  & ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_value_u32 ( ma ,  " fragments " ,  & nfrags )  <  0  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_modargs_get_value_u32 ( ma ,  " fragment_size " ,  & frag_size )  <  0  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_modargs_get_value_u32 ( ma ,  " tsched_buffer_size " ,  & tsched_size )  <  0  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_modargs_get_value_u32 ( ma ,  " tsched_buffer_watermark " ,  & tsched_watermark )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to parse buffer metrics " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    buffer_size  =  nfrags  *  frag_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    period_frames  =  frag_size / frame_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    buffer_frames  =  buffer_size / frame_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    tsched_frames  =  tsched_size / frame_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_value_boolean ( ma ,  " mmap " ,  & use_mmap )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to parse mmap argument. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_value_boolean ( ma ,  " tsched " ,  & use_tsched )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to parse tsched argument. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-27 17:55:50 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_value_boolean ( ma ,  " ignore_dB " ,  & ignore_dB )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to parse ignore_dB argument. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-04 11:58:05 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    rewind_safeguard  =  PA_MAX ( DEFAULT_REWIND_SAFEGUARD_BYTES ,  pa_usec_to_bytes ( DEFAULT_REWIND_SAFEGUARD_USEC ,  & ss ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 10:48:11 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_value_u32 ( ma ,  " rewind_safeguard " ,  & rewind_safeguard )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to parse rewind_safeguard argument " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    deferred_volume  =  m - > core - > deferred_volume ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_value_boolean ( ma ,  " deferred_volume " ,  & deferred_volume )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to parse deferred_volume argument. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-03 21:14:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_value_boolean ( ma ,  " fixed_latency_range " ,  & fixed_latency_range )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to parse fixed_latency_range argument. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-05 03:23:08 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    use_tsched  =  pa_alsa_may_tsched ( use_tsched ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u  =  pa_xnew0 ( struct  userdata ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > core  =  m - > core ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > module  =  m ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > use_mmap  =  use_mmap ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > use_tsched  =  use_tsched ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > deferred_volume  =  deferred_volume ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-03 21:14:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > fixed_latency_range  =  fixed_latency_range ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    u - > first  =  TRUE ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 10:48:11 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > rewind_safeguard  =  rewind_safeguard ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    u - > rtpoll  =  pa_rtpoll_new ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_thread_mq_init ( & u - > thread_mq ,  m - > core - > mainloop ,  u - > rtpoll ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-05 02:26:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > smoother  =  pa_smoother_new ( 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-09 12:29:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            SMOOTHER_ADJUST_USEC , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            SMOOTHER_WINDOW_USEC , 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-05 02:26:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            TRUE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            TRUE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            5 , 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-04 22:56:38 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            pa_rtclock_now ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-05 02:26:02 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            TRUE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-20 13:40:27 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > smoother_interval  =  SMOOTHER_MIN_INTERVAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:53:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* use ucm */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( mapping  & &  mapping - > ucm_context . ucm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > ucm_context  =  & mapping - > ucm_context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-05 19:05:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    dev_id  =  pa_modargs_get_value ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ma ,  " device_id " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_modargs_get_value ( ma ,  " device " ,  DEFAULT_DEVICE ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-06 23:09:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > paths_dir  =  pa_xstrdup ( pa_modargs_get_value ( ma ,  " paths_dir " ,  NULL ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-05 19:05:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( reserve_init ( u ,  dev_id )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( reserve_monitor_init ( u ,  dev_id )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    b  =  use_mmap ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    d  =  use_tsched ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( mapping )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 02:01:44 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! ( dev_id  =  pa_modargs_get_value ( ma ,  " device_id " ,  NULL ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log ( " device_id= not set " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-16 15:42:53 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ( mod_name  =  pa_proplist_gets ( mapping - > proplist ,  PA_ALSA_PROP_UCM_MODIFIER ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( snd_use_case_set ( u - > ucm_context - > ucm - > ucm_mgr ,  " _enamod " ,  mod_name )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_log ( " Failed to enable ucm modifier %s " ,  mod_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_log_debug ( " Enabled ucm modifier %s " ,  mod_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! ( u - > pcm_handle  =  pa_alsa_open_by_device_id_mapping ( 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                      dev_id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      & u - > device_name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      & ss ,  & map , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      SND_PCM_STREAM_PLAYBACK , 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                      & period_frames ,  & buffer_frames ,  tsched_frames , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                      & b ,  & d ,  mapping ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( ( dev_id  =  pa_modargs_get_value ( ma ,  " device_id " ,  NULL ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! ( profile_set  =  pa_alsa_profile_set_new ( NULL ,  & map ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! ( u - > pcm_handle  =  pa_alsa_open_by_device_id_auto ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      dev_id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      & u - > device_name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      & ss ,  & map , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      SND_PCM_STREAM_PLAYBACK , 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                      & period_frames ,  & buffer_frames ,  tsched_frames , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                      & b ,  & d ,  profile_set ,  & mapping ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! ( u - > pcm_handle  =  pa_alsa_open_by_device_string ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      pa_modargs_get_value ( ma ,  " device " ,  DEFAULT_DEVICE ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      & u - > device_name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      & ss ,  & map , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      SND_PCM_STREAM_PLAYBACK , 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                      & period_frames ,  & buffer_frames ,  tsched_frames , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								                      & b ,  & d ,  FALSE ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u - > device_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_log_info ( " Successfully opened device %s. " ,  u - > device_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-04 04:12:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_alsa_pcm_is_modem ( u - > pcm_handle ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_notice ( " Device %s is modem, refusing further initialization. " ,  u - > device_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( mapping ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Selected mapping '%s' (%s). " ,  mapping - > description ,  mapping - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( use_mmap  & &  ! b )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Device doesn't support mmap(), falling back to UNIX read/write mode. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > use_mmap  =  use_mmap  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( use_tsched  & &  ( ! b  | |  ! d ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Cannot enable timer-based scheduling, falling back to sound IRQ scheduling. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        u - > use_tsched  =  use_tsched  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > use_mmap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Successfully enabled mmap() mode. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-03 21:14:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > use_tsched )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Successfully enabled timer-based scheduling mode. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-03 21:14:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( u - > fixed_latency_range ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_info ( " Disabling latency range changes on underrun " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-16 11:11:46 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( is_iec958 ( u )  | |  is_hdmi ( u ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        set_formats  =  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-17 22:46:06 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > rates  =  pa_alsa_get_supported_rates ( u - > pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! u - > rates )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_error ( " Failed to find any supported sample rates. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    /* ALSA might tweak the sample spec, so recalculate the frame size */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    frame_size  =  pa_frame_size ( & ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:53:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! u - > ucm_context ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        find_mixer ( u ,  mapping ,  pa_modargs_get_value ( ma ,  " control " ,  NULL ) ,  ignore_dB ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_new_data_init ( & data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 02:02:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    data . driver  =  driver ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    data . module  =  m ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 02:02:30 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    data . card  =  card ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-18 03:42:39 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    set_sink_name ( & data ,  ma ,  dev_id ,  u - > device_name ,  mapping ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-30 18:34:41 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* We need to give pa_modargs_get_value_boolean() a pointer to a local
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  variable  instead  of  using  & data . namereg_fail  directly ,  because 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  data . namereg_fail  is  a  bitfield  and  taking  the  address  of  a  bitfield 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  variable  is  impossible .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    namereg_fail  =  data . namereg_fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_value_boolean ( ma ,  " namereg_fail " ,  & namereg_fail )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-07 21:11:58 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to parse namereg_fail argument. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-30 18:34:41 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_sink_new_data_done ( & data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    data . namereg_fail  =  namereg_fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_new_data_set_sample_spec ( & data ,  & ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_new_data_set_channel_map ( & data ,  & map ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-02 18:37:29 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_sink_new_data_set_alternate_sample_rate ( & data ,  alternate_sample_rate ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_alsa_init_proplist_pcm ( m - > core ,  data . proplist ,  u - > pcm_handle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_proplist_sets ( data . proplist ,  PA_PROP_DEVICE_STRING ,  u - > device_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_proplist_setf ( data . proplist ,  PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE ,  " %lu " ,  ( unsigned  long )  ( buffer_frames  *  frame_size ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_proplist_setf ( data . proplist ,  PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE ,  " %lu " ,  ( unsigned  long )  ( period_frames  *  frame_size ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_proplist_sets ( data . proplist ,  PA_PROP_DEVICE_ACCESS_MODE ,  u - > use_tsched  ?  " mmap+timer "  :  ( u - > use_mmap  ?  " mmap "  :  " serial " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( mapping )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_proplist_sets ( data . proplist ,  PA_PROP_DEVICE_PROFILE_NAME ,  mapping - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_proplist_sets ( data . proplist ,  PA_PROP_DEVICE_PROFILE_DESCRIPTION ,  mapping - > description ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-03 11:50:29 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        while  ( ( key  =  pa_proplist_iterate ( mapping - > proplist ,  & state ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_proplist_sets ( data . proplist ,  key ,  pa_proplist_gets ( mapping - > proplist ,  key ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-01 21:34:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_alsa_init_description ( data . proplist ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-01 20:34:07 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > control_device ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_alsa_init_proplist_ctl ( data . proplist ,  u - > control_device ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-12 22:55:50 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-28 02:39:22 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_proplist ( ma ,  " sink_properties " ,  data . proplist ,  PA_UPDATE_REPLACE )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Invalid properties " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_new_data_done ( & data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:53:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > ucm_context ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_alsa_ucm_add_ports ( & data . ports ,  data . proplist ,  u - > ucm_context ,  TRUE ,  card ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  if  ( u - > mixer_path_set ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-08 21:49:09 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_alsa_add_ports ( & data ,  u - > mixer_path_set ,  card ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-16 11:11:46 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > sink  =  pa_sink_new ( m - > core ,  & data ,  PA_SINK_HARDWARE  |  PA_SINK_LATENCY  |  ( u - > use_tsched  ?  PA_SINK_DYNAMIC_LATENCY  :  0 )  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                          ( set_formats  ?  PA_SINK_SET_FORMATS  :  0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_new_data_done ( & data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! u - > sink )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to create sink object " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_value_u32 ( ma ,  " deferred_volume_safety_margin " , 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                                 & u - > sink - > thread_info . volume_change_safety_margin )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to parse deferred_volume_safety_margin parameter " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_value_s32 ( ma ,  " deferred_volume_extra_delay " , 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                                 & u - > sink - > thread_info . volume_change_extra_delay )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-13 21:15:49 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to parse deferred_volume_extra_delay parameter " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    u - > sink - > parent . process_msg  =  sink_process_msg ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-23 03:23:22 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > use_tsched ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink - > update_requested_latency  =  sink_update_requested_latency_cb ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > sink - > set_state  =  sink_set_state_cb ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:53:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > ucm_context ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink - > set_port  =  sink_set_port_ucm_cb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink - > set_port  =  sink_set_port_cb ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-17 20:01:03 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > sink - > alternate_sample_rate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink - > update_rate  =  sink_update_rate_cb ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    u - > sink - > userdata  =  u ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_set_asyncmsgq ( u - > sink ,  u - > thread_mq . inq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_set_rtpoll ( u - > sink ,  u - > rtpoll ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > frame_size  =  frame_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    u - > fragment_size  =  frag_size  =  ( size_t )  ( period_frames  *  frame_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > hwbuf_size  =  buffer_size  =  ( size_t )  ( buffer_frames  *  frame_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_cvolume_mute ( & u - > hardware_volume ,  u - > sink - > sample_spec . channels ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-09 04:28:52 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_log_info ( " Using %0.1f fragments of size %lu bytes (%0.2fms), buffer size is %lu bytes (%0.2fms) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( double )  u - > hwbuf_size  /  ( double )  u - > fragment_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( long  unsigned )  u - > fragment_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( double )  pa_bytes_to_usec ( u - > fragment_size ,  & ss )  /  PA_USEC_PER_MSEC , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( long  unsigned )  u - > hwbuf_size , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-25 00:41:23 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                ( double )  pa_bytes_to_usec ( u - > hwbuf_size ,  & ss )  /  PA_USEC_PER_MSEC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_set_max_request ( u - > sink ,  u - > hwbuf_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-13 15:27:40 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( pa_alsa_pcm_is_hw ( u - > pcm_handle ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_max_rewind ( u - > sink ,  u - > hwbuf_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_info ( " Disabling rewind for device %s " ,  u - > device_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_max_rewind ( u - > sink ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-25 00:41:23 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-25 16:17:45 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > use_tsched )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-07 18:12:32 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        u - > tsched_watermark_ref  =  tsched_watermark ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        reset_watermark ( u ,  u - > tsched_watermark_ref ,  & ss ,  FALSE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 02:26:59 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-08 01:56:21 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_sink_set_fixed_latency ( u - > sink ,  pa_bytes_to_usec ( u - > hwbuf_size ,  & ss ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 11:29:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    reserve_update ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( update_sw_params ( u )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-05 12:53:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > ucm_context )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( u - > sink - > active_port  & &  pa_alsa_ucm_set_port ( u - > ucm_context ,  u - > sink - > active_port ,  TRUE )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( setup_mixer ( u ,  ignore_dB )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-19 04:04:42 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 01:58:39 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_alsa_dump ( PA_LOG_DEBUG ,  u - > pcm_handle ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-03 13:28:15 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! ( u - > thread  =  pa_thread_new ( " alsa-sink " ,  thread_func ,  u ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( " Failed to create thread. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Get initial mixer settings */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( data . volume_is_set )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( u - > sink - > set_volume ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > sink - > set_volume ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( u - > sink - > get_volume ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > sink - > get_volume ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( data . muted_is_set )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( u - > sink - > set_mute ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > sink - > set_mute ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( u - > sink - > get_mute ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            u - > sink - > get_mute ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-10 10:39:57 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( data . volume_is_set  | |  data . muted_is_set )  & &  u - > sink - > write_volume ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink - > write_volume ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-16 11:11:46 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( set_formats )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-12 16:36:00 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        /* For S/PDIF and HDMI, allow getting/setting custom formats */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_format_info  * format ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* To start with, we only support PCM formats. Other formats may be added
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  with  pa_sink_set_formats ( ) . */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        format  =  pa_format_info_new ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        format - > encoding  =  PA_ENCODING_PCM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > formats  =  pa_idxset_new ( NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_idxset_put ( u - > formats ,  format ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink - > get_formats  =  sink_get_formats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink - > set_formats  =  sink_set_formats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_put ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( profile_set ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_alsa_profile_set_free ( profile_set ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    return  u - > sink ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								fail : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-01 04:11:30 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        userdata_free ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( profile_set ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_alsa_profile_set_free ( profile_set ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  userdata_free ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > sink ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_unlink ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > thread )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_asyncmsgq_send ( u - > thread_mq . inq ,  NULL ,  PA_MESSAGE_SHUTDOWN ,  NULL ,  0 ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_thread_free ( u - > thread ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_thread_mq_done ( & u - > thread_mq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > sink ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_unref ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > memchunk . memblock ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_memblock_unref ( u - > memchunk . memblock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 13:05:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > mixer_pd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_alsa_mixer_pdata_free ( u - > mixer_pd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > alsa_rtpoll_item ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_rtpoll_item_free ( u - > alsa_rtpoll_item ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > rtpoll ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_rtpoll_free ( u - > rtpoll ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > pcm_handle )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_drop ( u - > pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_pcm_close ( u - > pcm_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > mixer_fdl ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_alsa_fdlist_free ( u - > mixer_fdl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-11-25 15:17:16 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > mixer_path  & &  ! u - > mixer_path_set ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        pa_alsa_path_free ( u - > mixer_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > mixer_handle ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        snd_mixer_close ( u - > mixer_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > smoother ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_smoother_free ( u - > smoother ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-12 16:36:00 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > formats ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_idxset_free ( u - > formats ,  ( pa_free2_cb_t )  pa_format_info_free2 ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-17 22:46:06 +05:30 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( u - > rates ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_xfree ( u - > rates ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    reserve_done ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-05 19:05:42 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    monitor_done ( u ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 06:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( u - > device_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 03:45:14 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_xfree ( u - > control_device ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-06 23:09:15 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_xfree ( u - > paths_dir ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-21 00:23:18 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  pa_alsa_sink_free ( pa_sink  * s )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_sink_assert_ref ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_assert_se ( u  =  s - > userdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    userdata_free ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}