2006-01-27 16:25:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* $Id$ */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/***
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  This  file  is  part  of  polypaudio . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  polypaudio  is  free  software ;  you  can  redistribute  it  and / or  modify 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  it  under  the  terms  of  the  GNU  Lesser  General  Public  License  as  published 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  by  the  Free  Software  Foundation ;  either  version  2  of  the  License , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  or  ( at  your  option )  any  later  version . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  polypaudio  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  polypaudio ;  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 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <windows.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <mmsystem.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <assert.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "sink.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "source.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "module.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "mainloop-api.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "modargs.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "sample-util.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "util.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "log.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "xmalloc.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "module-waveout-symdef.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								PA_MODULE_AUTHOR ( " Pierre Ossman " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								PA_MODULE_DESCRIPTION ( " Windows waveOut Sink/Source " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								PA_MODULE_VERSION ( PACKAGE_VERSION ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								PA_MODULE_USAGE ( " sink_name=<name for the sink> source_name=<name for the source> record=<enable source?> playback=<enable sink?> format=<sample format> channels=<number of channels> rate=<sample rate> fragments=<number of fragments> fragment_size=<fragment size> " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define DEFAULT_SINK_NAME "wave_output" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define DEFAULT_SOURCE_NAME "wave_input" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  userdata  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_sink  * sink ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_source  * source ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_core  * core ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_time_event  * event ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_defer_event  * defer ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_usec_t  poll_timeout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    uint32_t  fragments ,  fragment_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    uint32_t  free_ofrags ,  free_ifrags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    DWORD  written_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  cur_ohdr ,  cur_ihdr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  int  oremain ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    WAVEHDR  * ohdrs ,  * ihdrs ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_memchunk  silence ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    HWAVEOUT  hwo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    HWAVEIN  hwi ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_module  * module ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    CRITICAL_SECTION  crit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  const  char *  const  valid_modargs [ ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    " sink_name " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    " source_name " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    " record " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    " playback " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    " fragments " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    " fragment_size " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    " format " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    " rate " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    " channels " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  update_usage ( struct  userdata  * u )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   pa_module_set_used ( u - > module , 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                      ( u - > sink  ?  pa_idxset_size ( u - > sink - > inputs )  :  0 )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      ( u - > sink  ?  pa_idxset_size ( u - > sink - > monitor_source - > outputs )  :  0 )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      ( u - > source  ?  pa_idxset_size ( u - > source - > outputs )  :  0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  do_write ( struct  userdata  * u ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    uint32_t  free_frags ,  remain ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_memchunk  memchunk ,  * cur_chunk ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    WAVEHDR  * hdr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    MMRESULT  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! u - > sink ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    EnterCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    free_frags  =  u - > free_ofrags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > free_ofrags  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    LeaveCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    while  ( free_frags )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        hdr  =  & u - > ohdrs [ u - > cur_ohdr ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( hdr - > dwFlags  &  WHDR_PREPARED ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            waveOutUnprepareHeader ( u - > hwo ,  hdr ,  sizeof ( WAVEHDR ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        remain  =  u - > oremain ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        while  ( remain )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            cur_chunk  =  & memchunk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( pa_sink_render ( u - > sink ,  remain ,  cur_chunk )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                /*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  Don ' t  fill  with  silence  unless  we ' re  getting  close  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 *  underflowing . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( free_frags  >  u - > fragments / 2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    cur_chunk  =  & u - > silence ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    EnterCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    u - > free_ofrags  + =  free_frags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    LeaveCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    u - > oremain  =  remain ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            assert ( cur_chunk - > memblock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            assert ( cur_chunk - > memblock - > data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            assert ( cur_chunk - > length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            memcpy ( hdr - > lpData  +  u - > fragment_size  -  remain , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( char * ) cur_chunk - > memblock - > data  +  cur_chunk - > index , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( cur_chunk - > length  <  remain ) ? cur_chunk - > length : remain ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            remain  - =  ( cur_chunk - > length  <  remain ) ? cur_chunk - > length : remain ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( cur_chunk  ! =  & u - > silence )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                pa_memblock_unref ( cur_chunk - > memblock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                cur_chunk - > memblock  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        res  =  waveOutPrepareHeader ( u - > hwo ,  hdr ,  sizeof ( WAVEHDR ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( res  ! =  MMSYSERR_NOERROR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_error ( __FILE__  " : ERROR: Unable to prepare waveOut block: %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                res ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        res  =  waveOutWrite ( u - > hwo ,  hdr ,  sizeof ( WAVEHDR ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( res  ! =  MMSYSERR_NOERROR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_error ( __FILE__  " : ERROR: Unable to write waveOut block: %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                res ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > written_bytes  + =  u - > fragment_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        free_frags - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > cur_ohdr + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > cur_ohdr  % =  u - > fragments ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > oremain  =  u - > fragment_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  do_read ( struct  userdata  * u ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    uint32_t  free_frags ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_memchunk  memchunk ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    WAVEHDR  * hdr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    MMRESULT  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! u - > source ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    EnterCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    free_frags  =  u - > free_ifrags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > free_ifrags  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    LeaveCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    while  ( free_frags )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        hdr  =  & u - > ihdrs [ u - > cur_ihdr ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( hdr - > dwFlags  &  WHDR_PREPARED ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            waveInUnprepareHeader ( u - > hwi ,  hdr ,  sizeof ( WAVEHDR ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( hdr - > dwBytesRecorded )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            memchunk . memblock  =  pa_memblock_new ( hdr - > dwBytesRecorded ,  u - > core - > memblock_stat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            assert ( memchunk . memblock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            memcpy ( ( char * ) memchunk . memblock - > data ,  hdr - > lpData ,  hdr - > dwBytesRecorded ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            memchunk . length  =  memchunk . memblock - > length  =  hdr - > dwBytesRecorded ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            memchunk . index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_source_post ( u - > source ,  & memchunk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_memblock_unref ( memchunk . memblock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        res  =  waveInPrepareHeader ( u - > hwi ,  hdr ,  sizeof ( WAVEHDR ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( res  ! =  MMSYSERR_NOERROR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_error ( __FILE__  " : ERROR: Unable to prepare waveIn block: %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                res ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        res  =  waveInAddBuffer ( u - > hwi ,  hdr ,  sizeof ( WAVEHDR ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( res  ! =  MMSYSERR_NOERROR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pa_log_error ( __FILE__  " : ERROR: Unable to add waveIn block: %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                res ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        free_frags - - ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > cur_ihdr + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > cur_ihdr  % =  u - > fragments ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  poll_cb ( pa_mainloop_api * a ,  pa_time_event  * e ,  const  struct  timeval  * tv ,  void  * userdata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  timeval  ntv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    update_usage ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    do_write ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    do_read ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_gettimeofday ( & ntv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_timeval_add ( & ntv ,  u - > poll_timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a - > time_restart ( e ,  & ntv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  defer_cb ( pa_mainloop_api * a ,  pa_defer_event  * e ,  void  * userdata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a - > defer_enable ( e ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    do_write ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    do_read ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  CALLBACK  chunk_done_cb ( HWAVEOUT  hwo ,  UINT  msg ,  DWORD_PTR  inst ,  DWORD  param1 ,  DWORD  param2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  ( struct  userdata  * ) inst ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( msg  ! =  WOM_DONE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    EnterCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > free_ofrags + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( u - > free_ofrags  < =  u - > fragments ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    LeaveCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  CALLBACK  chunk_ready_cb ( HWAVEIN  hwi ,  UINT  msg ,  DWORD_PTR  inst ,  DWORD  param1 ,  DWORD  param2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  ( struct  userdata  * ) inst ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( msg  ! =  WIM_DATA ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    EnterCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > free_ifrags + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( u - > free_ifrags  < =  u - > fragments ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    LeaveCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  pa_usec_t  sink_get_latency_cb ( pa_sink  * s )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    uint32_t  free_frags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    MMTIME  mmt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( s  & &  u  & &  u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    memset ( & mmt ,  0 ,  sizeof ( mmt ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    mmt . wType  =  TIME_BYTES ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( waveOutGetPosition ( u - > hwo ,  & mmt ,  sizeof ( mmt ) )  = =  MMSYSERR_NOERROR ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  pa_bytes_to_usec ( u - > written_bytes  -  mmt . u . cb ,  & s - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        EnterCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        free_frags  =  u - > free_ofrags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        LeaveCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  pa_bytes_to_usec ( ( u - > fragments  -  free_frags )  *  u - > fragment_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                              & s - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  pa_usec_t  source_get_latency_cb ( pa_source  * s )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    pa_usec_t  r  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    uint32_t  free_frags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( s  & &  u  & &  u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    EnterCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    free_frags  =  u - > free_ifrags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    LeaveCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    r  + =  pa_bytes_to_usec ( ( free_frags  +  1 )  *  u - > fragment_size ,  & s - > sample_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fprintf ( stderr ,  " Latency: %d us \n " ,  ( int ) r ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  r ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  notify_sink_cb ( pa_sink  * s )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > core - > mainloop - > defer_enable ( u - > defer ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  notify_source_cb ( pa_source  * s )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  s - > userdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > core - > mainloop - > defer_enable ( u - > defer ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  ss_to_waveformat ( pa_sample_spec  * ss ,  LPWAVEFORMATEX  wf )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    wf - > wFormatTag  =  WAVE_FORMAT_PCM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ss - > channels  >  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_error ( __FILE__ " : ERROR: More than two channels not supported. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    wf - > nChannels  =  ss - > channels ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    switch  ( ss - > rate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    case  8000 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    case  11025 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    case  22005 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    case  44100 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_error ( __FILE__ " : ERROR: Unsupported sample rate. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    wf - > nSamplesPerSec  =  ss - > rate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ss - > format  = =  PA_SAMPLE_U8 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        wf - > wBitsPerSample  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  if  ( ss - > format  = =  PA_SAMPLE_S16NE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        wf - > wBitsPerSample  =  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_error ( __FILE__ " : ERROR: Unsupported sample format. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    wf - > nBlockAlign  =  wf - > nChannels  *  wf - > wBitsPerSample / 8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    wf - > nAvgBytesPerSec  =  wf - > nSamplesPerSec  *  wf - > nBlockAlign ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    wf - > cbSize  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  pa__init ( pa_core  * c ,  pa_module * m )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    HWAVEOUT  hwo  =  INVALID_HANDLE_VALUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    HWAVEIN  hwi  =  INVALID_HANDLE_VALUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    WAVEFORMATEX  wf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  nfrags ,  frag_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  record  =  1 ,  playback  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_sample_spec  ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_modargs  * ma  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  timeval  tv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( c  & &  m ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! ( ma  =  pa_modargs_new ( m - > argument ,  valid_modargs ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( __FILE__ " : failed to parse module arguments. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_value_boolean ( ma ,  " record " ,  & record )  <  0  | |  pa_modargs_get_value_boolean ( ma ,  " playback " ,  & playback )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( __FILE__ " : record= and playback= expect boolean argument. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! playback  & &  ! record )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( __FILE__ " : neither playback nor record enabled for device. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    nfrags  =  20 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    frag_size  =  1024 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_value_s32 ( ma ,  " fragments " ,  & nfrags )  <  0  | |  pa_modargs_get_value_s32 ( ma ,  " fragment_size " ,  & frag_size )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( __FILE__ " : failed to parse fragments arguments \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ss  =  c - > default_sample_spec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pa_modargs_get_sample_spec ( ma ,  & ss )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log ( __FILE__ " : failed to parse sample specification \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ss_to_waveformat ( & ss ,  & wf )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u  =  pa_xmalloc ( sizeof ( struct  userdata ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( record )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( waveInOpen ( & hwi ,  WAVE_MAPPER ,  & wf ,  ( DWORD_PTR ) chunk_ready_cb ,  ( DWORD_PTR ) u ,  CALLBACK_FUNCTION )  ! =  MMSYSERR_NOERROR ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( waveInStart ( hwi )  ! =  MMSYSERR_NOERROR ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( __FILE__ " : Opened waveIn subsystem. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( playback )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( waveOutOpen ( & hwo ,  WAVE_MAPPER ,  & wf ,  ( DWORD_PTR ) chunk_done_cb ,  ( DWORD_PTR ) u ,  CALLBACK_FUNCTION )  ! =  MMSYSERR_NOERROR ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            goto  fail ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_log_debug ( __FILE__ " : Opened waveOut subsystem. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    InitializeCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( hwi  ! =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 12:58:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        u - > source  =  pa_source_new ( c ,  __FILE__ ,  pa_modargs_get_value ( ma ,  " source_name " ,  DEFAULT_SOURCE_NAME ) ,  0 ,  & ss ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        assert ( u - > source ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > source - > userdata  =  u ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > source - > notify  =  notify_source_cb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > source - > get_latency  =  source_get_latency_cb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_source_set_owner ( u - > source ,  m ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > source - > description  =  pa_sprintf_malloc ( " Windows waveIn PCM " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > source  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( hwo  ! =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 12:58:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        u - > sink  =  pa_sink_new ( c ,  __FILE__ ,  pa_modargs_get_value ( ma ,  " sink_name " ,  DEFAULT_SINK_NAME ) ,  0 ,  & ss ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        assert ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink - > notify  =  notify_sink_cb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink - > get_latency  =  sink_get_latency_cb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink - > userdata  =  u ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_set_owner ( u - > sink ,  m ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink - > description  =  pa_sprintf_malloc ( " Windows waveOut PCM " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > sink  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( u - > source  | |  u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > core  =  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > hwi  =  hwi ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > hwo  =  hwo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > fragments  =  nfrags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > free_ifrags  =  u - > fragments ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > free_ofrags  =  u - > fragments ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > fragment_size  =  frag_size  -  ( frag_size  %  pa_frame_size ( & ss ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > written_bytes  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > oremain  =  u - > fragment_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > poll_timeout  =  pa_bytes_to_usec ( u - > fragments  *  u - > fragment_size  /  3 ,  & ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_gettimeofday ( & tv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_timeval_add ( & tv ,  u - > poll_timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > event  =  c - > mainloop - > time_new ( c - > mainloop ,  & tv ,  poll_cb ,  u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( u - > event ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > defer  =  c - > mainloop - > defer_new ( c - > mainloop ,  defer_cb ,  u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( u - > defer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    c - > mainloop - > defer_enable ( u - > defer ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > cur_ihdr  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > cur_ohdr  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > ihdrs  =  pa_xmalloc0 ( sizeof ( WAVEHDR )  *  u - > fragments ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( u - > ihdrs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > ohdrs  =  pa_xmalloc0 ( sizeof ( WAVEHDR )  *  u - > fragments ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( u - > ohdrs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( i  =  0 ; i  <  u - > fragments ; i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > ihdrs [ i ] . dwBufferLength  =  u - > fragment_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > ohdrs [ i ] . dwBufferLength  =  u - > fragment_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > ihdrs [ i ] . lpData  =  pa_xmalloc ( u - > fragment_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        assert ( u - > ihdrs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        u - > ohdrs [ i ] . lpData  =  pa_xmalloc ( u - > fragment_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        assert ( u - > ohdrs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > silence . length  =  u - > fragment_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > silence . memblock  =  pa_memblock_new ( u - > silence . length ,  u - > core - > memblock_stat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( u - > silence . memblock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_silence_memblock ( u - > silence . memblock ,  & ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > silence . index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    u - > module  =  m ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    m - > userdata  =  u ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_modargs_free ( ma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								fail : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   if  ( hwi  ! =  INVALID_HANDLE_VALUE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        waveInClose ( hwi ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   if  ( hwo  ! =  INVALID_HANDLE_VALUE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        waveOutClose ( hwo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_xfree ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ma ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_modargs_free ( ma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 01:17:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  pa__done ( pa_core  * c ,  pa_module * m )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-10 17:51:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  userdata  * u ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    assert ( c  & &  m ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! ( u  =  m - > userdata ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > event ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        c - > mainloop - > time_free ( u - > event ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > defer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        c - > mainloop - > defer_free ( u - > defer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > sink )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_disconnect ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_sink_unref ( u - > sink ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > source )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_source_disconnect ( u - > source ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_source_unref ( u - > source ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > hwi  ! =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        waveInReset ( u - > hwi ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        waveInClose ( u - > hwi ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( u - > hwo  ! =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        waveOutReset ( u - > hwo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        waveOutClose ( u - > hwo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( i  =  0 ; i  <  u - > fragments ; i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_xfree ( u - > ihdrs [ i ] . lpData ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pa_xfree ( u - > ohdrs [ i ] . lpData ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( u - > ihdrs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( u - > ohdrs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    DeleteCriticalSection ( & u - > crit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_xfree ( u ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}