1 
2 /*
3  * Copyright (c) 1999-2006, Regents of the University of California
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *  Redistributions of source code must retain the above copyright
11  *  notice, this list of conditions and the following disclaimer.
12  *
13  *  Redistributions in binary form must reproduce the above copyright
14  *  notice, this list of conditions and the following disclaimer in the
15  *  documentation and/or other materials provided with the distribution.
16  *
17  *  Neither the name of the University of California, Berkeley nor the
18  *  names of its contributors may be used to endorse or promote products
19  *  derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Automatically generated library file psys
34 
35  * The drivers embedded in this file may be covered by a different
36  * license.  Scroll down to see the license appearing before each
37  * driver, or see sfront/src/lib/ directories for driver source file.
38 
39  */
40 
41 #include "tree.h"
42 
43 
44 
45 void makepa_hosthdr(void)
46 {
47   int lc = 0;
48 
49   z[lc++]="#ifndef PA_HOST_H";
50   z[lc++]="#define PA_HOST_H";
51   z[lc++]="";
52   z[lc++]="/*";
53   z[lc++]=" * Host dependant internal API for PortAudio";
54   z[lc++]=" *";
55   z[lc++]=" * Author: Phil Burk  <philburk@softsynth.com>";
56   z[lc++]=" *";
57   z[lc++]=" * PortAudio Portable Real-Time Audio Library";
58   z[lc++]=" * Latest Version at: http://www.softsynth.com/portaudio/";
59   z[lc++]=" * DirectSound and Macintosh Implementation";
60   z[lc++]=" * Copyright (c) 1999-2000 Phil Burk";
61   z[lc++]=" *";
62   z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
63   z[lc++]=" * a copy of this software and associated documentation files";
64   z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
65   z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
66   z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
67   z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
68   z[lc++]=" * subject to the following conditions:";
69   z[lc++]=" *";
70   z[lc++]=" * The above copyright notice and this permission notice shall be";
71   z[lc++]=" * included in all copies or substantial portions of the Software.";
72   z[lc++]=" *";
73   z[lc++]=" * Any person wishing to distribute modifications to the Software is";
74   z[lc++]=" * requested to send the modifications to the original developer so that";
75   z[lc++]=" * they can be incorporated into the canonical version.";
76   z[lc++]=" *";
77   z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
78   z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
79   z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
80   z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
81   z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
82   z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
83   z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
84   z[lc++]=" *";
85   z[lc++]=" */";
86   z[lc++]="";
87   z[lc++]="#ifdef __cplusplus";
ExecVacuum(ParseState * pstate,VacuumStmt * vacstmt,bool isTopLevel)88   z[lc++]="extern \"C\" {";
89   z[lc++]="#endif /* __cplusplus */";
90   z[lc++]="";
91   z[lc++]="#ifndef SUPPORT_AUDIO_CAPTURE";
92   z[lc++]="#define SUPPORT_AUDIO_CAPTURE  (1)";
93   z[lc++]="#endif";
94   z[lc++]="";
95   z[lc++]="#ifndef int32";
96   z[lc++]="typedef long int32;";
97   z[lc++]="#endif";
98   z[lc++]="#ifndef uint32";
99   z[lc++]="typedef unsigned long uint32;";
100   z[lc++]="#endif";
101   z[lc++]="#ifndef int16";
102   z[lc++]="typedef short int16;";
103   z[lc++]="#endif";
104   z[lc++]="#ifndef uint16";
105   z[lc++]="typedef unsigned short uint16;";
106   z[lc++]="#endif";
107   z[lc++]="";
108   z[lc++]="#define PA_MAGIC    (0x18273645)";
109   z[lc++]="";
110   z[lc++]="/************************************************************************************/";
111   z[lc++]="/****************** Structures ******************************************************/";
112   z[lc++]="/************************************************************************************/";
113   z[lc++]=" ";
114   z[lc++]="typedef struct internalPortAudioStream";
115   z[lc++]="{";
116   z[lc++]="	uint32                    past_Magic;  /* ID for struct to catch bugs. */";
117   z[lc++]="/* User specified information. */";
118   z[lc++]="	uint32                    past_FramesPerUserBuffer;";
119   z[lc++]="	uint32                    past_NumUserBuffers;";
120   z[lc++]="	double                    past_SampleRate;     /* Closest supported sample rate. */";
121   z[lc++]="	int                       past_NumInputChannels;";
122   z[lc++]="	int                       past_NumOutputChannels;";
123   z[lc++]="	PaDeviceID                past_InputDeviceID;";
124   z[lc++]="	PaDeviceID                past_OutputDeviceID;";
125   z[lc++]="	PaSampleFormat            past_InputSampleFormat;";
126   z[lc++]="	PaSampleFormat            past_OutputSampleFormat;";
127   z[lc++]="	void                     *past_DeviceData;";
128   z[lc++]="	PortAudioCallback        *past_Callback;";
129   z[lc++]="	void                     *past_UserData;";
130   z[lc++]="	uint32                    past_Flags;";
131   z[lc++]="/* Flags for communicating between foreground and background. */";
132   z[lc++]="	volatile int              past_IsActive;      /* Background is still playing. */";
133   z[lc++]="	volatile int              past_StopSoon;      /* Background should keep playing when buffers empty. */";
134   z[lc++]="	volatile int              past_StopNow;       /* Background should stop playing now. */";
135   z[lc++]="/* These buffers are used when the native format does not match the user format. */";
136   z[lc++]="	void                     *past_InputBuffer;";
137   z[lc++]="	uint32                    past_InputBufferSize;";
138   z[lc++]="	void                     *past_OutputBuffer;";
139   z[lc++]="	uint32                    past_OutputBufferSize;";
140   z[lc++]="/* Measurements */";
141   z[lc++]="	uint32                    past_NumCallbacks;";
142   z[lc++]="	PaTimestamp               past_FrameCount;    /* Frames output to buffer. */";
143   z[lc++]="/* For measuring CPU utilization. */";
144   z[lc++]="	double                    past_AverageInsideCount;";
145   z[lc++]="	double                    past_AverageTotalCount;";
146   z[lc++]="	double                    past_Usage;";
147   z[lc++]="	int                       past_IfLastExitValid;";
148   z[lc++]="} internalPortAudioStream;";
149   z[lc++]="";
150   z[lc++]="/************************************************************************************/";
151   z[lc++]="/****************** Prototypes ******************************************************/";
152   z[lc++]="/************************************************************************************/";
153   z[lc++]="";
154   z[lc++]="PaError PaHost_Init( void );";
155   z[lc++]="PaError PaHost_Term( void );";
156   z[lc++]="";
157   z[lc++]="PaError PaHost_OpenStream( internalPortAudioStream   *past );";
158   z[lc++]="PaError PaHost_CloseStream( internalPortAudioStream   *past );";
159   z[lc++]="";
160   z[lc++]="PaError PaHost_StartOutput( internalPortAudioStream   *past );";
161   z[lc++]="PaError PaHost_StopOutput( internalPortAudioStream   *past, int abort );";
162   z[lc++]="PaError PaHost_StartInput( internalPortAudioStream   *past );";
163   z[lc++]="PaError PaHost_StopInput( internalPortAudioStream   *past, int abort );";
164   z[lc++]="PaError PaHost_StartEngine( internalPortAudioStream   *past );";
165   z[lc++]="PaError PaHost_StopEngine( internalPortAudioStream *past, int abort );";
166   z[lc++]="PaError PaHost_StreamActive( internalPortAudioStream   *past );";
167   z[lc++]="";
168   z[lc++]="long Pa_CallConvertInt16( internalPortAudioStream   *past, ";
169   z[lc++]="            short *nativeInputBuffer,";
170   z[lc++]="            short *nativeOutputBuffer );";
171   z[lc++]="";
172   z[lc++]="long Pa_CallConvertFloat32( internalPortAudioStream   *past, ";
173   z[lc++]="            float *nativeInputBuffer,";
174   z[lc++]="            float *nativeOutputBuffer );";
175   z[lc++]="";
176   z[lc++]="void   *PaHost_AllocateFastMemory( long numBytes );";
177   z[lc++]="void    PaHost_FreeFastMemory( void *addr, long numBytes );";
178   z[lc++]="";
179   z[lc++]="PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate,";
180   z[lc++]="            double *closestFrameRatePtr );";
181   z[lc++]="int PaHost_FindClosestTableEntry( double allowableError,  const double *rateTable,";
182   z[lc++]="            int numRates, double frameRate );";
183   z[lc++]="";
184   z[lc++]="#ifdef __cplusplus";
185   z[lc++]="}";
186   z[lc++]="#endif /* __cplusplus */";
187   z[lc++]="#endif /* PA_HOST_H */";
188   printlib(lc);
189 }
190 
191 
192 void makepa_porthdr(void)
193 {
194   int lc = 0;
195 
196   z[lc++]="#ifndef PORT_AUDIO_H";
197   z[lc++]="#define PORT_AUDIO_H";
198   z[lc++]="";
199   z[lc++]="#ifdef __cplusplus";
200   z[lc++]="extern \"C\" {";
201   z[lc++]="#endif /* __cplusplus */";
202   z[lc++]="";
203   z[lc++]="/*";
204   z[lc++]=" * PortAudio Portable Real-Time Audio Library";
205   z[lc++]=" * PortAudio API Header File";
206   z[lc++]=" * Latest version available at: http://www.audiomulch.com/portaudio/";
207   z[lc++]=" *";
208   z[lc++]=" * Copyright (c) 1999-2000 Ross Bencina and Phil Burk";
209   z[lc++]=" *";
210   z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
211   z[lc++]=" * a copy of this software and associated documentation files";
212   z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
213   z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
214   z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
215   z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
216   z[lc++]=" * subject to the following conditions:";
217   z[lc++]=" *";
218   z[lc++]=" * The above copyright notice and this permission notice shall be";
219   z[lc++]=" * included in all copies or substantial portions of the Software.";
220   z[lc++]=" *";
221   z[lc++]=" * Any person wishing to distribute modifications to the Software is";
vacuum(List * relations,VacuumParams * params,BufferAccessStrategy bstrategy,bool isTopLevel)222   z[lc++]=" * requested to send the modifications to the original developer so that";
223   z[lc++]=" * they can be incorporated into the canonical version.";
224   z[lc++]=" *";
225   z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
226   z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
227   z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
228   z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
229   z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
230   z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
231   z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
232   z[lc++]=" *";
233   z[lc++]=" */";
234   z[lc++]="";
235   z[lc++]="typedef int PaError;";
236   z[lc++]="typedef enum {";
237   z[lc++]="	paNoError = 0,";
238   z[lc++]="";
239   z[lc++]="	paHostError = -10000,";
240   z[lc++]="	paInvalidChannelCount,";
241   z[lc++]="	paInvalidSampleRate,";
242   z[lc++]="	paInvalidDeviceId,";
243   z[lc++]="	paInvalidFlag,";
244   z[lc++]="	paSampleFormatNotSupported,";
245   z[lc++]="	paBadIODeviceCombination,";
246   z[lc++]="	paInsufficientMemory,";
247   z[lc++]="	paBufferTooBig,";
248   z[lc++]="	paBufferTooSmall,";
249   z[lc++]="	paNullCallback,";
250   z[lc++]="	paBadStreamPtr,";
251   z[lc++]="	paTimedOut,";
252   z[lc++]="	paInternalError";
253   z[lc++]="} PaErrorNum;";
254   z[lc++]="";
255   z[lc++]="/*";
256   z[lc++]="	Pa_Initialize() is the library initialisation function - call this before";
257   z[lc++]="	using the library.";
258   z[lc++]="*/";
259   z[lc++]="";
260   z[lc++]="PaError Pa_Initialize( void );";
261   z[lc++]="";
262   z[lc++]="/*";
263   z[lc++]="	Pa_Terminate() is the library termination function - call this after";
264   z[lc++]="	using the library.";
265   z[lc++]="*/";
266   z[lc++]="";
267   z[lc++]="PaError Pa_Terminate( void );";
268   z[lc++]="";
269   z[lc++]="/*";
270   z[lc++]="	Return host specific error.";
271   z[lc++]="	This can be called after receiving a paHostError.";
272   z[lc++]="*/";
273   z[lc++]="long Pa_GetHostError( void );";
274   z[lc++]="";
275   z[lc++]="/*";
276   z[lc++]="	Translate the error number into a human readable message.";
277   z[lc++]="*/";
278   z[lc++]="const char *Pa_GetErrorText( PaError errnum );";
279   z[lc++]="";
280   z[lc++]="/*";
281   z[lc++]="	Sample formats";
282   z[lc++]="";
283   z[lc++]="	These are formats used to pass sound data between the callback and the";
284   z[lc++]="	stream. Each device has a \"native\" format which may be used when optimum";
285   z[lc++]="	efficiency or control over conversion is required.";
286   z[lc++]="";
287   z[lc++]="	Formats marked \"always available\" are supported (emulated) by all devices.";
288   z[lc++]="";
289   z[lc++]="	The floating point representation uses +1.0 and -1.0 as the respective";
290   z[lc++]="	maximum and minimum.";
291   z[lc++]="	";
292   z[lc++]="*/";
293   z[lc++]="";
294   z[lc++]="typedef unsigned long PaSampleFormat;";
295   z[lc++]="#define paFloat32      ((PaSampleFormat) (1<<0))	/*always available*/";
296   z[lc++]="#define paInt16        ((PaSampleFormat) (1<<1))	/*always available*/";
297   z[lc++]="#define paInt32        ((PaSampleFormat) (1<<2))	/*always available*/";
298   z[lc++]="#define paInt24        ((PaSampleFormat) (1<<3))";
299   z[lc++]="#define paPackedInt24  ((PaSampleFormat) (1<<4))";
300   z[lc++]="#define paInt8         ((PaSampleFormat) (1<<5))";
301   z[lc++]="#define paUInt8        ((PaSampleFormat) (1<<6))    /* unsigned 8 bit, 128 is \"ground\" */";
302   z[lc++]="#define paCustomFormat ((PaSampleFormat) (1<<16))";
303   z[lc++]="";
304   z[lc++]="/*";
305   z[lc++]="	Device enumeration mechanism.";
306   z[lc++]="";
307   z[lc++]="   	Device ids range from 0 to Pa_CountDevices()-1.";
308   z[lc++]="";
309   z[lc++]="	Devices may support input, output or both. Device 0 is always the \"default\"";
310   z[lc++]="	device and should support at least stereo in and out if that is available";
311   z[lc++]="	on the taget platform _even_ if this involves kludging an input/output";
312   z[lc++]="	device on platforms that usually separate input from output. Other platform";
313   z[lc++]="	specific devices are specified by positive device ids.";
314   z[lc++]="*/";
315   z[lc++]="";
316   z[lc++]="typedef int PaDeviceID;";
317   z[lc++]="#define paNoDevice -1";
318   z[lc++]="";
319   z[lc++]="typedef struct{";
320   z[lc++]="	int structVersion; ";
321   z[lc++]="	const char *name;";
322   z[lc++]="	int maxInputChannels;";
323   z[lc++]="	int maxOutputChannels;";
324   z[lc++]="/* Number of discrete rates, or -1 if range supported. */";
325   z[lc++]="	int numSampleRates;";
326   z[lc++]="/* Array of supported sample rates, or {min,max} if range supported. */";
327   z[lc++]="	const double *sampleRates;";
328   z[lc++]="	PaSampleFormat nativeSampleFormats;";
329   z[lc++]="} PaDeviceInfo;";
330   z[lc++]="";
331   z[lc++]="";
332   z[lc++]="int Pa_CountDevices();";
333   z[lc++]="/*";
334   z[lc++]="	Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID()";
335   z[lc++]="";
336   z[lc++]="	Return the default device ID or paNoDevice if there is no devices.";
337   z[lc++]="	The result can be passed to Pa_OpenStream().";
338   z[lc++]="	";
339   z[lc++]="	On the PC, the user can specify a default device by";
340   z[lc++]="	setting an environment variable. For example, to use device #1.";
341   z[lc++]="";
342   z[lc++]="		set PA_RECOMMENDED_OUTPUT_DEVICE=1";
343   z[lc++]="	";
344   z[lc++]="	The user should first determine the available device ID by using";
345   z[lc++]="	the supplied application \"pa_devs\".";
346   z[lc++]="*/";
347   z[lc++]="PaDeviceID Pa_GetDefaultInputDeviceID( void );";
348   z[lc++]="PaDeviceID Pa_GetDefaultOutputDeviceID( void );";
349   z[lc++]="";
350   z[lc++]="/*";
351   z[lc++]="	PaTimestamp is used to represent a continuous sample clock with arbitrary";
352   z[lc++]="	start time useful for syncronisation. The type is used in the outTime";
353   z[lc++]="	argument to the callback function and the result of Pa_StreamTime()";
354   z[lc++]="*/";
355   z[lc++]="";
356   z[lc++]="typedef double PaTimestamp;";
357   z[lc++]="";
358   z[lc++]="/*";
359   z[lc++]="	Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure";
360   z[lc++]="	referring to the device specified by id.";
361   z[lc++]="	If id is out of range the function returns NULL.";
362   z[lc++]="";
363   z[lc++]="	The returned structure is owned by the PortAudio implementation and must";
364   z[lc++]="	not be manipulated or freed. The pointer is guaranteed to be valid until";
365   z[lc++]="	between calls to Pa_Initialize() and Pa_Terminate().";
366   z[lc++]="*/";
367   z[lc++]="";
368   z[lc++]="const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID devID );";
369   z[lc++]="";
370   z[lc++]="/*";
371   z[lc++]="	PortAudioCallback is implemented by clients of the portable audio api.";
372   z[lc++]="";
373   z[lc++]="	inputBuffer and outputBuffer are arrays of interleaved samples,";
374   z[lc++]="	the format, packing and number of channels used by the buffers are";
375   z[lc++]="	determined by parameters to Pa_OpenStream() (see below).";
376   z[lc++]="";
377   z[lc++]="	framesPerBuffer is the number of sample frames to be processed by the callback.";
378   z[lc++]="";
379   z[lc++]="	outTime is the time in samples when the buffer(s) processed by";
380   z[lc++]="	this callback will begin being played at the audio output.";
381   z[lc++]="	See also Pa_StreamTime()";
382   z[lc++]="";
383   z[lc++]="	userData is the value of a user supplied pointer passed to Pa_OpenStream()";
384   z[lc++]="	intended for storing synthesis data etc.";
385   z[lc++]="";
386   z[lc++]="	return value:";
387   z[lc++]="	The callback can return a nonzero value to stop the stream. This may be";
388   z[lc++]="	useful in applications such as soundfile players where a specific duration";
389   z[lc++]="	of output is required. However, it is not necessary to utilise this mechanism";
390   z[lc++]="	as StopStream() will also terminate the stream. A callback returning a";
391   z[lc++]="	nonzero value must fill the entire outputBuffer.";
392   z[lc++]="";
393   z[lc++]="	NOTE: None of the other stream functions may be called from within the";
394   z[lc++]="	callback function except for Pa_GetCPULoad().";
395   z[lc++]="";
396   z[lc++]="*/";
397   z[lc++]="";
398   z[lc++]="typedef int (PortAudioCallback)(";
399   z[lc++]="		void *inputBuffer, void *outputBuffer,";
400   z[lc++]="		unsigned long framesPerBuffer,";
401   z[lc++]="		PaTimestamp outTime, void *userData );";
402   z[lc++]="";
403   z[lc++]="";
404   z[lc++]="/*";
405   z[lc++]="	Stream flags";
406   z[lc++]="";
407   z[lc++]="	These flags may be supplied (ored together) in the streamFlags argument to";
408   z[lc++]="	the Pa_OpenStream() function.";
409   z[lc++]="";
410   z[lc++]="	[ suggestions? ]";
411   z[lc++]="*/";
412   z[lc++]="";
413   z[lc++]="#define   paNoFlag      (0)";
414   z[lc++]="#define   paClipOff     (1<<0)   /* disable defult clipping of out of range samples */";
415   z[lc++]="#define   paDitherOff   (1<<1)   /* disable default dithering */";
416   z[lc++]="#define   paPlatformSpecificFlags (0x00010000)";
417   z[lc++]="typedef   unsigned long PaStreamFlags;";
418   z[lc++]="";
419   z[lc++]="/*";
420   z[lc++]="	A single PortAudioStream provides multiple channels of real-time";
421   z[lc++]="	input and output audio streaming to a client application.";
422   z[lc++]="	Pointers to PortAudioStream objects are passed between PortAudio functions.";
423   z[lc++]="*/";
424   z[lc++]="";
425   z[lc++]="typedef void PortAudioStream;";
426   z[lc++]="#define PaStream PortAudioStream";
427   z[lc++]="";
428   z[lc++]="/*";
429   z[lc++]="	Pa_OpenStream() opens a stream for either input, output or both.";
430   z[lc++]="";
431   z[lc++]="	stream is the address of a PortAudioStream pointer which will receive";
432   z[lc++]="	a pointer to the newly opened stream.";
433   z[lc++]="";
434   z[lc++]="	inputDevice is the id of the device used for input (see PaDeviceID above.)";
435   z[lc++]="	inputDevice may be paNoDevice to indicate that an input device is not required.";
436   z[lc++]="";
437   z[lc++]="	numInputChannels is the number of channels of sound to be delivered to the";
438   z[lc++]="	callback. It can range from 1 to the value of maxInputChannels in the";
439   z[lc++]="	device input record for the device specified in the inputDevice parameter.";
440   z[lc++]="	If inputDevice is paNoDevice numInputChannels is ignored.";
441   z[lc++]="";
442   z[lc++]="	inputSampleFormat is the format of inputBuffer provided to the callback";
443   z[lc++]="	function. inputSampleFormat may be any of the formats described by the";
444   z[lc++]="	PaSampleFormat enumeration (see above). PortAudio guarantees support for";
445   z[lc++]="	the sound devices native formats (nativeSampleFormats in the device info";
446   z[lc++]="	record) and additionally 16 and 32 bit integer and 32 bit floating point";
447   z[lc++]="	formats. Support for other formats is implementation defined.";
448   z[lc++]="";
449   z[lc++]="	inputDriverInfo is a pointer to an optional driver specific data structure";
450   z[lc++]="	containing additional information for device setup or stream processing.";
451   z[lc++]="	inputDriverInfo is never required for correct operation. If not used";
452   z[lc++]="	inputDriverInfo should be NULL.";
453   z[lc++]="";
454   z[lc++]="	outputDevice is the id of the device used for output (see PaDeviceID above.)";
455   z[lc++]="	outputDevice may be paNoDevice to indicate that an output device is not required.";
456   z[lc++]="";
457   z[lc++]="	numOutputChannels is the number of channels of sound to be supplied by the";
458   z[lc++]="	callback. See the definition of numInputChannels above for more details.";
459   z[lc++]="";
460   z[lc++]="	outputSampleFormat is the sample format of the outputBuffer filled by the";
461   z[lc++]="	callback function. See the definition of inputSampleFormat above for more";
462   z[lc++]="	details.";
463   z[lc++]="";
464   z[lc++]="	outputDriverInfo is a pointer to an optional driver specific data structure";
465   z[lc++]="	containing additional information for device setup or stream processing.";
466   z[lc++]="	outputDriverInfo is never required for correct operation. If not used";
467   z[lc++]="	outputDriverInfo should be NULL.";
468   z[lc++]="";
469   z[lc++]="	sampleRate is the desired sampleRate for input and output";
470   z[lc++]="";
471   z[lc++]="	framesPerBuffer is the length in sample frames of all internal sample buffers";
472   z[lc++]="	used for communication with platform specific audio routines. Wherever";
473   z[lc++]="	possible this corresponds to the framesPerBuffer parameter passed to the";
474   z[lc++]="	callback function.";
475   z[lc++]="";
476   z[lc++]="	numberOfBuffers is the number of buffers used for multibuffered";
477   z[lc++]="	communication with the platform specific audio routines. This parameter is";
478   z[lc++]="	provided only as a guide - and does not imply that an implementation must";
479   z[lc++]="	use multibuffered i/o when reliable double buffering is available (such as";
480   z[lc++]="	SndPlayDoubleBuffer() on the Macintosh.)";
481   z[lc++]="";
482   z[lc++]="	streamFlags may contain a combination of flags ORed together.";
483   z[lc++]="	These flags modify the behavior of the";
vacuum_is_relation_owner(Oid relid,Form_pg_class reltuple,int options)484   z[lc++]="	streaming process. Some flags may only be relevant to certain buffer formats.";
485   z[lc++]="";
486   z[lc++]="	callback is a pointer to a client supplied function that is responsible";
487   z[lc++]="	for processing and filling input and output buffers (see above for details.)";
488   z[lc++]="";
489   z[lc++]="	userData is a client supplied pointer which is passed to the callback";
490   z[lc++]="	function. It could for example, contain a pointer to instance data necessary";
491   z[lc++]="	for processing the audio buffers.";
492   z[lc++]="";
493   z[lc++]="	return value:";
494   z[lc++]="	Apon success Pa_OpenStream() returns PaNoError and places a pointer to a";
495   z[lc++]="	valid PortAudioStream in the stream argument. The stream is inactive (stopped).";
496   z[lc++]="	If a call to Pa_OpenStream() fails a nonzero error code is returned (see";
497   z[lc++]="	PAError above) and the value of stream is invalid.";
498   z[lc++]="";
499   z[lc++]="*/";
500   z[lc++]="";
501   z[lc++]="PaError Pa_OpenStream( PortAudioStream** stream,";
502   z[lc++]="				PaDeviceID inputDevice,";
503   z[lc++]="				int numInputChannels,";
504   z[lc++]="				PaSampleFormat inputSampleFormat,";
505   z[lc++]="				void *inputDriverInfo,";
506   z[lc++]="				PaDeviceID outputDevice,";
507   z[lc++]="				int numOutputChannels,";
508   z[lc++]="				PaSampleFormat outputSampleFormat,";
509   z[lc++]="				void *outputDriverInfo,";
510   z[lc++]="				double sampleRate,";
511   z[lc++]="				unsigned long framesPerBuffer,";
512   z[lc++]="				unsigned long numberOfBuffers,";
513   z[lc++]="				PaStreamFlags streamFlags,";
514   z[lc++]="				PortAudioCallback *callback,";
515   z[lc++]="				void *userData );";
516   z[lc++]="";
517   z[lc++]="";
518   z[lc++]="/*";
519   z[lc++]="	Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that";
520   z[lc++]="	opens the default input and/or ouput devices. Most parameters have";
521   z[lc++]="	identical meaning to their Pa_OpenStream() counterparts, with the following";
522   z[lc++]="	exceptions:";
523   z[lc++]="";
524   z[lc++]="	If either numInputChannels or numOutputChannels is 0 the respective device";
525   z[lc++]="	is not opened (same as passing paNoDevice in the device arguments to Pa_OpenStream() )";
526   z[lc++]="";
527   z[lc++]="	sampleFormat applies to both the input and output buffers.";
528   z[lc++]="*/";
529   z[lc++]="";
530   z[lc++]="PaError Pa_OpenDefaultStream( PortAudioStream** stream,";
531   z[lc++]="				int numInputChannels,";
532   z[lc++]="				int numOutputChannels,";
533   z[lc++]="				PaSampleFormat sampleFormat,";
534   z[lc++]="				double sampleRate,";
535   z[lc++]="				unsigned long framesPerBuffer,";
536   z[lc++]="				unsigned long numberOfBuffers,";
537   z[lc++]="				PortAudioCallback *callback,";
538   z[lc++]="				void *userData );";
539   z[lc++]="	   ";
540   z[lc++]="/*";
541   z[lc++]="	Pa_CloseStream() closes an audio stream, flushing any pending buffers.";
542   z[lc++]="*/";
543   z[lc++]="";
544   z[lc++]="PaError Pa_CloseStream( PortAudioStream* );";
545   z[lc++]="";
546   z[lc++]="/*";
547   z[lc++]=" 	Pa_StartStream() and Pa_StopStream() begin and terminate audio processing.";
548   z[lc++]="	Pa_StopStream() waits until all pending audio buffers have been played.";
549   z[lc++]="    Pa_AbortStream() stops playing immediately without waiting for pending";
550   z[lc++]="    buffers to complete.";
551   z[lc++]="*/";
552   z[lc++]="";
553   z[lc++]="PaError Pa_StartStream( PortAudioStream *stream );";
554   z[lc++]="";
555   z[lc++]="PaError Pa_StopStream( PortAudioStream *stream );";
556   z[lc++]="";
557   z[lc++]="PaError Pa_AbortStream( PortAudioStream *stream );";
vacuum_open_relation(Oid relid,RangeVar * relation,int options,bool verbose,LOCKMODE lmode)558   z[lc++]="";
559   z[lc++]="/*";
560   z[lc++]="	Pa_StreamActive() returns one when the stream is playing audio,";
561   z[lc++]="	zero when not playing, or a negative error number if the";
562   z[lc++]="	stream is invalid.";
563   z[lc++]="	The stream is active between calls to Pa_StartStream() and Pa_StopStream(),";
564   z[lc++]="	but may also become inactive if the callback returns a non-zero value.";
565   z[lc++]="	In the latter case, the stream is considered inactive after the last";
566   z[lc++]="	buffer has finished playing.";
567   z[lc++]="*/";
568   z[lc++]="";
569   z[lc++]="PaError Pa_StreamActive( PortAudioStream *stream );";
570   z[lc++]="";
571   z[lc++]="/*";
572   z[lc++]="	Pa_StreamTime() returns the current output time for the stream in samples.";
573   z[lc++]="	This time may be used as a time reference (for example syncronising audio to";
574   z[lc++]="	MIDI).";
575   z[lc++]="*/";
576   z[lc++]="";
577   z[lc++]="PaTimestamp Pa_StreamTime( PortAudioStream *stream );";
578   z[lc++]="";
579   z[lc++]="/*";
580   z[lc++]="	The \"CPU Load\" is a fraction of total CPU time consumed by the";
581   z[lc++]="	stream's audio processing.";
582   z[lc++]="	A value of 0.5 would imply that PortAudio and the sound generating";
583   z[lc++]="	callback was consuming roughly 50% of the available CPU time.";
584   z[lc++]="	This function may be called from the callback function or the application.";
585   z[lc++]="*/";
586   z[lc++]="double Pa_GetCPULoad( PortAudioStream* stream );";
587   z[lc++]="";
588   z[lc++]="/*";
589   z[lc++]="	Use Pa_GetMinNumBuffers() to determine minimum number of buffers required for";
590   z[lc++]="	the current host based on minimum latency. ";
591   z[lc++]="	On the PC, for the DirectSound implementation, latency can be optionally set";
592   z[lc++]="	by user by setting an environment variable.";
593   z[lc++]="	For example, to set latency to 200 msec, put:";
594   z[lc++]="	";
595   z[lc++]="	   set PA_MIN_LATENCY_MSEC=200";
596   z[lc++]="	";
597   z[lc++]="	in the AUTOEXEC.BAT file and reboot.";
598   z[lc++]="	If the environment variable is not set, then the latency will be determined";
599   z[lc++]="	based on the OS. Windows NT has higher latency than Win95.";
600   z[lc++]="*/";
601   z[lc++]="";
602   z[lc++]="int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate );";
603   z[lc++]="";
604   z[lc++]="/*";
605   z[lc++]="	Sleep for at least 'msec' milliseconds.";
606   z[lc++]="	You may sleep longer than the requested time so don't rely";
607   z[lc++]="	on this for accurate musical timing.";
608   z[lc++]="*/";
609   z[lc++]="void Pa_Sleep( long msec );";
610   z[lc++]="";
611   z[lc++]="/*";
612   z[lc++]="	Return size in bytes of a single sample in a given PaSampleFormat";
613   z[lc++]="	or paSampleFormatNotSupported. ";
614   z[lc++]="*/";
615   z[lc++]="PaError Pa_GetSampleSize( PaSampleFormat format );";
616   z[lc++]="";
617   z[lc++]="#ifdef __cplusplus";
618   z[lc++]="}";
619   z[lc++]="#endif /* __cplusplus */";
620   z[lc++]="#endif /* PORT_AUDIO_H */";
621   printlib(lc);
622 }
623 
624 
625 void makepa_tracehdr(void)
626 {
627   int lc = 0;
628 
629   z[lc++]="#ifndef PA_TRACE_H";
630   z[lc++]="#define PA_TRACE_H";
631   z[lc++]="/*";
632   z[lc++]=" * Portable Audio I/O Library Trace Facility";
633   z[lc++]=" * Store trace information in real-time for later printing.";
634   z[lc++]=" *";
635   z[lc++]=" * Based on the Open Source API proposed by Ross Bencina";
636   z[lc++]=" * Copyright (c) 1999-2000 Phil Burk";
637   z[lc++]=" *";
638   z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
639   z[lc++]=" * a copy of this software and associated documentation files";
640   z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
641   z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
642   z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
643   z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
644   z[lc++]=" * subject to the following conditions:";
645   z[lc++]=" *";
646   z[lc++]=" * The above copyright notice and this permission notice shall be";
647   z[lc++]=" * included in all copies or substantial portions of the Software.";
648   z[lc++]=" *";
649   z[lc++]=" * Any person wishing to distribute modifications to the Software is";
650   z[lc++]=" * requested to send the modifications to the original developer so that";
651   z[lc++]=" * they can be incorporated into the canonical version.";
652   z[lc++]=" *";
653   z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
654   z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
655   z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
656   z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
657   z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
658   z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
659   z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
660   z[lc++]=" */";
661   z[lc++]="";
662   z[lc++]="";
663   z[lc++]="#define TRACE_REALTIME_EVENTS     (0)   /* Keep log of various real-time events. */";
664   z[lc++]="#define MAX_TRACE_RECORDS      (2048)";
665   z[lc++]="";
666   z[lc++]="#ifdef __cplusplus";
667   z[lc++]="extern \"C\" {";
668   z[lc++]="#endif /* __cplusplus */";
669   z[lc++]="";
expand_vacuum_rel(VacuumRelation * vrel,int options)670   z[lc++]="";
671   z[lc++]="/************************************************************************************/";
672   z[lc++]="/****************** Prototypes ******************************************************/";
673   z[lc++]="/************************************************************************************/";
674   z[lc++]="";
675   z[lc++]="#if TRACE_REALTIME_EVENTS";
676   z[lc++]="";
677   z[lc++]="void DumpTraceMessages();";
678   z[lc++]="void ResetTraceMessages();";
679   z[lc++]="void AddTraceMessage( char *msg, int data );";
680   z[lc++]="";
681   z[lc++]="#else";
682   z[lc++]="";
683   z[lc++]="#define AddTraceMessage(msg,data) /* noop */";
684   z[lc++]="#define ResetTraceMessages() /* noop */";
685   z[lc++]="#define DumpTraceMessages() /* noop */";
686   z[lc++]="";
687   z[lc++]="#endif";
688   z[lc++]="";
689   z[lc++]="#ifdef __cplusplus";
690   z[lc++]="}";
691   z[lc++]="#endif /* __cplusplus */";
692   z[lc++]="";
693   z[lc++]="#endif /* PA_TRACE_H */";
694   printlib(lc);
695 }
696 
697 
698 void makepa_lib(void)
699 {
700   int lc = 0;
701 
702   z[lc++]="/*";
703   z[lc++]=" * Portable Audio I/O Library";
704   z[lc++]=" * Host Independant Layer";
705   z[lc++]=" *";
706   z[lc++]=" * Based on the Open Source API proposed by Ross Bencina";
707   z[lc++]=" * Copyright (c) 1999-2000 Phil Burk";
708   z[lc++]=" *";
709   z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
710   z[lc++]=" * a copy of this software and associated documentation files";
711   z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
712   z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
713   z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
714   z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
715   z[lc++]=" * subject to the following conditions:";
716   z[lc++]=" *";
717   z[lc++]=" * The above copyright notice and this permission notice shall be";
718   z[lc++]=" * included in all copies or substantial portions of the Software.";
719   z[lc++]=" *";
720   z[lc++]=" * Any person wishing to distribute modifications to the Software is";
721   z[lc++]=" * requested to send the modifications to the original developer so that";
722   z[lc++]=" * they can be incorporated into the canonical version.";
723   z[lc++]=" *";
724   z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
725   z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
726   z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
727   z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
728   z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
729   z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
730   z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
731   z[lc++]=" *";
732   z[lc++]=" */";
733   z[lc++]="";
734   z[lc++]="/* Modification History:";
735   z[lc++]=" PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC";
736   z[lc++]=" PLB20010820 - fix dither and shift for recording PaUInt8 format ";
737   z[lc++]="*/";
738   z[lc++]="";
739   z[lc++]="#include <stdio.h>";
740   z[lc++]="#include <stdlib.h>";
741   z[lc++]="#include <string.h>";
742   z[lc++]="#include <math.h>";
743   z[lc++]="";
744   z[lc++]="/* PLB20010422 - \"memory.h\" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */";
745   z[lc++]="#ifdef _WIN32";
746   z[lc++]="#ifndef __MWERKS__";
747   z[lc++]="#include <memory.h>";
748   z[lc++]="#endif  /* __MWERKS__ */";
749   z[lc++]="#else   /* !_WIN32 */";
750   z[lc++]="#include <memory.h>";
751   z[lc++]="#endif  /* _WIN32 */";
752   z[lc++]="";
753   z[lc++]="#if 0";
754   z[lc++]="#include \"portaudio.h\"";
755   z[lc++]="#include \"pa_host.h\"";
756   z[lc++]="#include \"pa_trace.h\"";
757   z[lc++]="#endif";
758   z[lc++]="";
759   z[lc++]="/* The reason we might NOT want to validate the rate before opening the stream";
760   z[lc++]=" * is because many DirectSound drivers lie about the rates they actually support.";
761   z[lc++]=" */";
762   z[lc++]="#define PA_VALIDATE_RATE    (0)   /* If true validate sample rate against driver info. */";
763   z[lc++]="";
764   z[lc++]="/*";
765   z[lc++]="O- maybe not allocate past_InputBuffer and past_OutputBuffer if not needed for conversion";
766   z[lc++]="*/";
767   z[lc++]="";
768   z[lc++]="#ifndef FALSE";
769   z[lc++]="	#define FALSE  (0)";
770   z[lc++]="	#define TRUE   (!FALSE)";
771   z[lc++]="#endif";
772   z[lc++]="";
773   z[lc++]="#define PRINT(x) { printf x; fflush(stdout); }";
774   z[lc++]="#define ERR_RPT(x) PRINT(x)";
775   z[lc++]="#define DBUG(x)  /* PRINT(x) */";
776   z[lc++]="#define DBUGX(x) /* PRINT(x) */";
777   z[lc++]="";
778   z[lc++]="static int gInitCount = 0; /* Count number of times Pa_Initialize() called to allow nesting and overlapping. */";
779   z[lc++]="";
780   z[lc++]="static PaError Pa_KillStream(  PortAudioStream *stream, int abort );";
781   z[lc++]="";
782   z[lc++]="/***********************************************************************/";
783   z[lc++]="int PaHost_FindClosestTableEntry( double allowableError,  const double *rateTable, int numRates, double frameRate )";
784   z[lc++]="{";
785   z[lc++]="	double err, minErr = allowableError;";
786   z[lc++]="	int i, bestFit = -1;";
787   z[lc++]="	";
788   z[lc++]="	for( i=0; i<numRates; i++ )";
789   z[lc++]="	{";
790   z[lc++]="		err = fabs( frameRate - rateTable[i] );";
791   z[lc++]="		if( err < minErr )";
792   z[lc++]="		{";
793   z[lc++]="			minErr = err;";
794   z[lc++]="			bestFit = i;";
795   z[lc++]="		}";
796   z[lc++]="	}";
797   z[lc++]="	return bestFit;";
798   z[lc++]="}";
799   z[lc++]="";
800   z[lc++]="/**************************************************************************";
801   z[lc++]="** Make sure sample rate is legal and also convert to enumeration for driver.";
802   z[lc++]="*/";
803   z[lc++]="PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate,";
804   z[lc++]="	double *closestFrameRatePtr )";
805   z[lc++]="{";
806   z[lc++]="	long bestRateIndex;";
807   z[lc++]="	const PaDeviceInfo *pdi;";
808   z[lc++]="	pdi = Pa_GetDeviceInfo( id );";
get_all_vacuum_rels(int options)809   z[lc++]="	if( pdi == NULL )";
810   z[lc++]="	{";
811   z[lc++]="		return paInvalidDeviceId;";
812   z[lc++]="	}";
813   z[lc++]="";
814   z[lc++]="	if( pdi->numSampleRates == -1 )";
815   z[lc++]="	{";
816   z[lc++]="	/* Is it out of range? */";
817   z[lc++]="		if( (requestedFrameRate < pdi->sampleRates[0]) ||";
818   z[lc++]="			(requestedFrameRate > pdi->sampleRates[1]) )";
819   z[lc++]="		{";
820   z[lc++]="			return paInvalidSampleRate;";
821   z[lc++]="		}";
822   z[lc++]="		";
823   z[lc++]="		*closestFrameRatePtr = requestedFrameRate;";
824   z[lc++]="	}";
825   z[lc++]="	else";
826   z[lc++]="	{";
827   z[lc++]="		bestRateIndex = PaHost_FindClosestTableEntry( 1.0, pdi->sampleRates, pdi->numSampleRates, requestedFrameRate );";
828   z[lc++]="		if( bestRateIndex < 0 ) return paInvalidSampleRate;";
829   z[lc++]="		*closestFrameRatePtr = pdi->sampleRates[bestRateIndex];";
830   z[lc++]="	}";
831   z[lc++]="	return paNoError;";
832   z[lc++]="}";
833   z[lc++]="";
834   z[lc++]="/*************************************************************************/";
835   z[lc++]="PaError Pa_OpenStream(";
836   z[lc++]="		PortAudioStream** streamPtrPtr,";
837   z[lc++]="		PaDeviceID inputDeviceID,";
838   z[lc++]="		int numInputChannels,";
839   z[lc++]="		PaSampleFormat inputSampleFormat,";
840   z[lc++]="		void *inputDriverInfo,";
841   z[lc++]="		PaDeviceID outputDeviceID,";
842   z[lc++]="		int numOutputChannels,";
843   z[lc++]="		PaSampleFormat outputSampleFormat,";
844   z[lc++]="		void *outputDriverInfo,";
845   z[lc++]="		double sampleRate,";
846   z[lc++]="		unsigned long framesPerBuffer,";
847   z[lc++]="		unsigned long numberOfBuffers,";
848   z[lc++]="		unsigned long streamFlags,";
849   z[lc++]="		PortAudioCallback *callback,";
850   z[lc++]="		void *userData )";
851   z[lc++]="{";
852   z[lc++]="	internalPortAudioStream   *past = NULL;";
853   z[lc++]="	PaError                    result = paNoError;";
854   z[lc++]="	int                        bitsPerInputSample;";
855   z[lc++]="	int                        bitsPerOutputSample;";
856   z[lc++]="/* Print passed parameters. */";
857   z[lc++]="	DBUG((\"Pa_OpenStream( %p, %d, %d, %d, %p, /* input */ \\n\",";
858   z[lc++]="			streamPtrPtr, inputDeviceID, numInputChannels,";
859   z[lc++]="			inputSampleFormat, inputDriverInfo ));";
860   z[lc++]="	DBUG((\"               %d, %d, %d, %p, /* output */\\n\",";
861   z[lc++]="			outputDeviceID, numOutputChannels,";
862   z[lc++]="			outputSampleFormat, outputDriverInfo ));";
863   z[lc++]="	DBUG((\"               %g, %d, %d, 0x%x, , %p )\\n\",";
864   z[lc++]="			sampleRate, framesPerBuffer, numberOfBuffers,";
865   z[lc++]="			streamFlags, userData ));";
866   z[lc++]="";
867   z[lc++]="/* Check for parameter errors. */";
868   z[lc++]="	if( (streamFlags & ~(paClipOff | paDitherOff)) != 0 ) return paInvalidFlag;";
869   z[lc++]="	if( streamPtrPtr == NULL ) return paBadStreamPtr;";
870   z[lc++]="	if( inputDriverInfo != NULL ) return paHostError; /* REVIEW */";
871   z[lc++]="	if( outputDriverInfo != NULL ) return paHostError; /* REVIEW */";
872   z[lc++]="	if( (inputDeviceID < 0) && ( outputDeviceID < 0) ) return paInvalidDeviceId;";
873   z[lc++]="	if( (outputDeviceID >= Pa_CountDevices()) || (inputDeviceID >= Pa_CountDevices()) )";
874   z[lc++]="	{";
875   z[lc++]="		return paInvalidDeviceId;";
876   z[lc++]="	}";
877   z[lc++]="	if( (numInputChannels <= 0) && ( numOutputChannels <= 0) ) return paInvalidChannelCount;";
878   z[lc++]="";
879   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
vacuum_set_xid_limits(Relation rel,int freeze_min_age,int freeze_table_age,int multixact_freeze_min_age,int multixact_freeze_table_age,TransactionId * oldestXmin,TransactionId * freezeLimit,TransactionId * xidFullScanLimit,MultiXactId * multiXactCutoff,MultiXactId * mxactFullScanLimit)880   z[lc++]="	if( inputDeviceID >= 0 )";
881   z[lc++]="	{";
882   z[lc++]="		PaError size = Pa_GetSampleSize( inputSampleFormat );";
883   z[lc++]="		if( size < 0 ) return size;";
884   z[lc++]="		bitsPerInputSample = 8 * size;";
885   z[lc++]="		if( (numInputChannels <= 0) ) return paInvalidChannelCount;";
886   z[lc++]="	}";
887   z[lc++]="#else";
888   z[lc++]="	if( inputDeviceID >= 0 )";
889   z[lc++]="	{";
890   z[lc++]="		return paInvalidChannelCount;";
891   z[lc++]="	}";
892   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
893   z[lc++]="	else";
894   z[lc++]="	{";
895   z[lc++]="		if( numInputChannels > 0 ) return paInvalidChannelCount;";
896   z[lc++]="		bitsPerInputSample = 0;";
897   z[lc++]="	}";
898   z[lc++]="";
899   z[lc++]="	if( outputDeviceID >= 0 )";
900   z[lc++]="	{";
901   z[lc++]="		PaError size = Pa_GetSampleSize( outputSampleFormat );";
902   z[lc++]="		if( size < 0 ) return size;";
903   z[lc++]="		bitsPerOutputSample = 8 * size;";
904   z[lc++]="		if( (numOutputChannels <= 0) ) return paInvalidChannelCount;";
905   z[lc++]="	}";
906   z[lc++]="	else";
907   z[lc++]="	{";
908   z[lc++]="		if( numOutputChannels > 0 ) return paInvalidChannelCount;";
909   z[lc++]="		bitsPerOutputSample = 0;";
910   z[lc++]="	}";
911   z[lc++]="";
912   z[lc++]="	if( callback == NULL ) return paNullCallback;";
913   z[lc++]="";
914   z[lc++]="/* Allocate and clear stream structure. */";
915   z[lc++]="	past = (internalPortAudioStream *) PaHost_AllocateFastMemory( sizeof(internalPortAudioStream) );";
916   z[lc++]="	if( past == NULL ) return paInsufficientMemory;";
917   z[lc++]="	memset( past, 0, sizeof(internalPortAudioStream) );";
918   z[lc++]="	AddTraceMessage(\"Pa_OpenStream: past\", (long) past );";
919   z[lc++]="	";
920   z[lc++]="	past->past_Magic = PA_MAGIC;  /* Set ID to catch bugs. */";
921   z[lc++]="	past->past_FramesPerUserBuffer = framesPerBuffer;";
922   z[lc++]="	past->past_NumUserBuffers = numberOfBuffers; /* NOTE - PaHost_OpenStream() NMUST CHECK FOR ZERO! */";
923   z[lc++]="	past->past_Callback = callback;";
924   z[lc++]="	past->past_UserData = userData;";
925   z[lc++]="	past->past_OutputSampleFormat = outputSampleFormat;";
926   z[lc++]="	past->past_InputSampleFormat = inputSampleFormat;";
927   z[lc++]="	past->past_OutputDeviceID = outputDeviceID;";
928   z[lc++]="	past->past_InputDeviceID = inputDeviceID;";
929   z[lc++]="	past->past_NumInputChannels = numInputChannels;";
930   z[lc++]="	past->past_NumOutputChannels = numOutputChannels;";
931   z[lc++]="	past->past_Flags = streamFlags;";
932   z[lc++]="";
933   z[lc++]="/* Check for absurd sample rates. */";
934   z[lc++]="	if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )";
935   z[lc++]="	{";
936   z[lc++]="		result = paInvalidSampleRate;";
937   z[lc++]="		goto cleanup;";
938   z[lc++]="	}";
939   z[lc++]="";
940   z[lc++]="/* Allocate buffers that may be used for format conversion from user to native buffers. */";
941   z[lc++]="	if( numInputChannels > 0 )";
942   z[lc++]="	{";
943   z[lc++]="	";
944   z[lc++]="#if PA_VALIDATE_RATE";
945   z[lc++]="		result = PaHost_ValidateSampleRate( inputDeviceID, sampleRate, &past->past_SampleRate );";
946   z[lc++]="		if( result < 0 )";
947   z[lc++]="		{";
948   z[lc++]="			goto cleanup;";
949   z[lc++]="		}";
950   z[lc++]="#else";
951   z[lc++]="		past->past_SampleRate = sampleRate;";
952   z[lc++]="#endif";
953   z[lc++]="/* Allocate single Input buffer. */";
954   z[lc++]="		past->past_InputBufferSize = framesPerBuffer * numInputChannels * ((bitsPerInputSample+7) / 8);";
955   z[lc++]="		past->past_InputBuffer = PaHost_AllocateFastMemory(past->past_InputBufferSize);";
956   z[lc++]="		if( past->past_InputBuffer == NULL )";
957   z[lc++]="		{";
958   z[lc++]="			result = paInsufficientMemory;";
959   z[lc++]="			goto cleanup;";
960   z[lc++]="		}";
961   z[lc++]="	}";
962   z[lc++]="	else";
963   z[lc++]="	{";
964   z[lc++]="		past->past_InputBuffer = NULL;";
965   z[lc++]="	}";
966   z[lc++]="";
967   z[lc++]="/* Allocate single Output buffer. */";
968   z[lc++]="	if( numOutputChannels > 0 )";
969   z[lc++]="	{";
970   z[lc++]="#if PA_VALIDATE_RATE";
971   z[lc++]="		result = PaHost_ValidateSampleRate( outputDeviceID, sampleRate, &past->past_SampleRate );";
972   z[lc++]="		if( result < 0 )";
973   z[lc++]="		{";
974   z[lc++]="			goto cleanup;";
975   z[lc++]="		}";
976   z[lc++]="#else";
977   z[lc++]="		past->past_SampleRate = sampleRate;";
978   z[lc++]="#endif";
979   z[lc++]="		past->past_OutputBufferSize = framesPerBuffer * numOutputChannels * ((bitsPerOutputSample+7) / 8);";
980   z[lc++]="		past->past_OutputBuffer = PaHost_AllocateFastMemory(past->past_OutputBufferSize);";
981   z[lc++]="		if( past->past_OutputBuffer == NULL )";
982   z[lc++]="		{";
983   z[lc++]="			result = paInsufficientMemory;";
984   z[lc++]="			goto cleanup;";
985   z[lc++]="		}";
986   z[lc++]="	}";
987   z[lc++]="	else";
988   z[lc++]="	{";
989   z[lc++]="		past->past_OutputBuffer = NULL;";
990   z[lc++]="	}";
991   z[lc++]="";
992   z[lc++]="	result = PaHost_OpenStream( past );";
993   z[lc++]="	if( result < 0 ) goto cleanup;";
994   z[lc++]="";
995   z[lc++]="	*streamPtrPtr = (void *) past;";
996   z[lc++]="";
997   z[lc++]="	return result;";
998   z[lc++]="";
999   z[lc++]="cleanup:";
1000   z[lc++]="	if( past != NULL ) Pa_CloseStream( past );";
1001   z[lc++]="	*streamPtrPtr = NULL;";
1002   z[lc++]="	return result;";
1003   z[lc++]="}";
1004   z[lc++]="";
1005   z[lc++]="";
1006   z[lc++]="/*************************************************************************/";
1007   z[lc++]="PaError Pa_OpenDefaultStream( PortAudioStream** stream,";
1008   z[lc++]="		int numInputChannels,";
1009   z[lc++]="		int numOutputChannels,";
1010   z[lc++]="		PaSampleFormat sampleFormat,";
1011   z[lc++]="		double sampleRate,";
1012   z[lc++]="		unsigned long framesPerBuffer,";
1013   z[lc++]="		unsigned long numberOfBuffers,";
1014   z[lc++]="		PortAudioCallback *callback,";
1015   z[lc++]="		void *userData )";
1016   z[lc++]="{";
1017   z[lc++]="	return Pa_OpenStream(";
1018   z[lc++]="		stream,";
1019   z[lc++]="		((numInputChannels > 0) ? Pa_GetDefaultInputDeviceID() : paNoDevice),";
1020   z[lc++]="		numInputChannels, sampleFormat, NULL,";
1021   z[lc++]="		((numOutputChannels > 0) ? Pa_GetDefaultOutputDeviceID() : paNoDevice),";
1022   z[lc++]="		numOutputChannels, sampleFormat, NULL,";
1023   z[lc++]="		sampleRate, framesPerBuffer, numberOfBuffers, paNoFlag, callback, userData );";
1024   z[lc++]="}";
1025   z[lc++]="";
1026   z[lc++]="/*************************************************************************/";
1027   z[lc++]="PaError Pa_CloseStream( PortAudioStream* stream)";
1028   z[lc++]="{";
1029   z[lc++]="	PaError   result;";
1030   z[lc++]="	internalPortAudioStream   *past;";
1031   z[lc++]="	";
1032   z[lc++]="	DBUG((\"Pa_CloseStream()\\n\"));";
1033   z[lc++]="	if( stream == NULL ) return paBadStreamPtr;";
1034   z[lc++]="	past = (internalPortAudioStream *) stream;";
1035   z[lc++]="";
1036   z[lc++]="	Pa_AbortStream( past );";
1037   z[lc++]="	result = PaHost_CloseStream( past );";
1038   z[lc++]="	";
1039   z[lc++]="	if( past->past_InputBuffer ) PaHost_FreeFastMemory( past->past_InputBuffer, past->past_InputBufferSize );";
1040   z[lc++]="	if( past->past_OutputBuffer ) PaHost_FreeFastMemory( past->past_OutputBuffer, past->past_OutputBufferSize );";
1041   z[lc++]="	PaHost_FreeFastMemory( past, sizeof(internalPortAudioStream) );";
1042   z[lc++]="";
1043   z[lc++]="	return result;";
1044   z[lc++]="}";
1045   z[lc++]="";
1046   z[lc++]="/*************************************************************************/";
1047   z[lc++]="PaError Pa_StartStream( PortAudioStream *stream )";
1048   z[lc++]="{";
1049   z[lc++]="	PaError result = paHostError;";
1050   z[lc++]="	internalPortAudioStream   *past;";
1051   z[lc++]="";
1052   z[lc++]="	if( stream == NULL ) return paBadStreamPtr;";
1053   z[lc++]="	past = (internalPortAudioStream *) stream;";
1054   z[lc++]="";
1055   z[lc++]="	past->past_FrameCount = 0.0;";
1056   z[lc++]="";
1057   z[lc++]="	if( past->past_NumInputChannels > 0 )";
1058   z[lc++]="	{";
1059   z[lc++]="		result = PaHost_StartInput( past );";
1060   z[lc++]="		DBUG((\"Pa_StartStream: PaHost_StartInput returned = 0x%X.\\n\", result));";
1061   z[lc++]="		if( result < 0 ) goto error;";
1062   z[lc++]="	}";
1063   z[lc++]="";
1064   z[lc++]="	if( past->past_NumOutputChannels > 0 )";
1065   z[lc++]="	{";
1066   z[lc++]="		result = PaHost_StartOutput( past );";
1067   z[lc++]="		DBUG((\"Pa_StartStream: PaHost_StartOutput returned = 0x%X.\\n\", result));";
1068   z[lc++]="		if( result < 0 ) goto error;";
1069   z[lc++]="	}";
1070   z[lc++]="";
1071   z[lc++]="	result = PaHost_StartEngine( past );";
vac_estimate_reltuples(Relation relation,BlockNumber total_pages,BlockNumber scanned_pages,double scanned_tuples)1072   z[lc++]="	DBUG((\"Pa_StartStream: PaHost_StartEngine returned = 0x%X.\\n\", result));";
1073   z[lc++]="	if( result < 0 ) goto error;";
1074   z[lc++]="";
1075   z[lc++]="	return paNoError;";
1076   z[lc++]="";
1077   z[lc++]="error:";
1078   z[lc++]="	return result;";
1079   z[lc++]="}";
1080   z[lc++]="";
1081   z[lc++]="/*************************************************************************/";
1082   z[lc++]="PaError Pa_StopStream(  PortAudioStream *stream )";
1083   z[lc++]="{";
1084   z[lc++]="	return Pa_KillStream( stream, 0 );";
1085   z[lc++]="}";
1086   z[lc++]="";
1087   z[lc++]="/*************************************************************************/";
1088   z[lc++]="PaError Pa_AbortStream(  PortAudioStream *stream )";
1089   z[lc++]="{";
1090   z[lc++]="	return Pa_KillStream( stream, 1 );";
1091   z[lc++]="}";
1092   z[lc++]="";
1093   z[lc++]="/*************************************************************************/";
1094   z[lc++]="static PaError Pa_KillStream(  PortAudioStream *stream, int abort )";
1095   z[lc++]="{";
1096   z[lc++]="	PaError result = paNoError;";
1097   z[lc++]="	internalPortAudioStream   *past;";
1098   z[lc++]="";
1099   z[lc++]="	DBUG((\"Pa_StopStream().\\n\"));";
1100   z[lc++]="	if( stream == NULL ) return paBadStreamPtr;";
1101   z[lc++]="	past = (internalPortAudioStream *) stream;";
1102   z[lc++]="";
1103   z[lc++]="	if( (past->past_NumInputChannels > 0) || (past->past_NumOutputChannels > 0) )";
1104   z[lc++]="	{";
1105   z[lc++]="		result = PaHost_StopEngine( past, abort );";
1106   z[lc++]="		DBUG((\"Pa_StopStream: PaHost_StopEngine returned = 0x%X.\\n\", result));";
1107   z[lc++]="		if( result < 0 ) goto error;";
1108   z[lc++]="	}";
1109   z[lc++]="";
1110   z[lc++]="	if( past->past_NumInputChannels > 0 )";
1111   z[lc++]="	{";
1112   z[lc++]="		result = PaHost_StopInput( past, abort );";
1113   z[lc++]="		DBUG((\"Pa_StopStream: PaHost_StopInput returned = 0x%X.\\n\", result));";
1114   z[lc++]="		if( result != paNoError ) goto error;";
1115   z[lc++]="	}";
1116   z[lc++]="";
1117   z[lc++]="	if( past->past_NumOutputChannels > 0 )";
1118   z[lc++]="	{";
1119   z[lc++]="		result = PaHost_StopOutput( past, abort );";
1120   z[lc++]="		DBUG((\"Pa_StopStream: PaHost_StopOutput returned = 0x%X.\\n\", result));";
1121   z[lc++]="		if( result != paNoError ) goto error;";
1122   z[lc++]="	}";
1123   z[lc++]="";
1124   z[lc++]="error:";
1125   z[lc++]="	past->past_Usage = 0;";
1126   z[lc++]="	past->past_IfLastExitValid = 0;";
1127   z[lc++]="	";
1128   z[lc++]="	return result;";
1129   z[lc++]="}";
1130   z[lc++]="";
1131   z[lc++]="/*************************************************************************/";
1132   z[lc++]="PaError Pa_StreamActive( PortAudioStream *stream )";
1133   z[lc++]="{";
1134   z[lc++]="	internalPortAudioStream   *past;";
1135   z[lc++]="	if( stream == NULL ) return paBadStreamPtr;";
1136   z[lc++]="	past = (internalPortAudioStream *) stream;";
1137   z[lc++]="	return PaHost_StreamActive( past );";
1138   z[lc++]="}";
1139   z[lc++]="";
1140   z[lc++]="/*************************************************************************/";
1141   z[lc++]="const char *Pa_GetErrorText( PaError errnum )";
1142   z[lc++]="{";
1143   z[lc++]="	const char *msg;";
1144   z[lc++]="";
1145   z[lc++]="	switch(errnum)";
1146   z[lc++]="	{";
1147   z[lc++]="	case paNoError:                  msg = \"Success\"; break;";
1148   z[lc++]="	case paHostError:                msg = \"Host error.\"; break;";
1149   z[lc++]="	case paInvalidChannelCount:      msg = \"Invalid number of channels.\"; break;";
1150   z[lc++]="	case paInvalidSampleRate:        msg = \"Invalid sample rate.\"; break;";
1151   z[lc++]="	case paInvalidDeviceId:          msg = \"Invalid device ID.\"; break;";
1152   z[lc++]="	case paInvalidFlag:              msg = \"Invalid flag.\"; break;";
1153   z[lc++]="	case paSampleFormatNotSupported: msg = \"Sample format not supported\"; break;";
1154   z[lc++]="	case paBadIODeviceCombination:   msg = \"Illegal combination of I/O devices.\"; break;";
1155   z[lc++]="	case paInsufficientMemory:       msg = \"Insufficient memory.\"; break;";
1156   z[lc++]="	case paBufferTooBig:             msg = \"Buffer too big.\"; break;";
vac_update_relstats(Relation relation,BlockNumber num_pages,double num_tuples,BlockNumber num_all_visible_pages,bool hasindex,TransactionId frozenxid,MultiXactId minmulti,bool in_outer_xact)1157   z[lc++]="	case paBufferTooSmall:           msg = \"Buffer too small.\"; break;";
1158   z[lc++]="	case paNullCallback:             msg = \"No callback routine specified.\"; break;";
1159   z[lc++]="	case paBadStreamPtr:             msg = \"Invalid stream pointer.\"; break;";
1160   z[lc++]="	case paTimedOut    :             msg = \"Wait Timed Out.\"; break;";
1161   z[lc++]="	case paInternalError:            msg = \"Internal PortAudio Error.\"; break;";
1162   z[lc++]="	default:                         msg = \"Illegal error number.\"; break;";
1163   z[lc++]="	}";
1164   z[lc++]="	return msg;";
1165   z[lc++]="}";
1166   z[lc++]="";
1167   z[lc++]="/*";
1168   z[lc++]="	Get CPU Load as a fraction of total CPU time.";
1169   z[lc++]="	A value of 0.5 would imply that PortAudio and the sound generating";
1170   z[lc++]="	callback was consuming roughly 50% of the available CPU time.";
1171   z[lc++]="	The amount may vary depending on CPU load.";
1172   z[lc++]="	This function may be called from the callback function.";
1173   z[lc++]="*/";
1174   z[lc++]="double Pa_GetCPULoad(  PortAudioStream* stream)";
1175   z[lc++]="{";
1176   z[lc++]="	internalPortAudioStream   *past;";
1177   z[lc++]="	if( stream == NULL ) return (double) paBadStreamPtr;";
1178   z[lc++]="	past = (internalPortAudioStream *) stream;";
1179   z[lc++]="	return past->past_Usage;";
1180   z[lc++]="}";
1181   z[lc++]="";
1182   z[lc++]="/*************************************************************";
1183   z[lc++]="** Calculate 2 LSB dither signal with a triangular distribution.";
1184   z[lc++]="** Ranged properly for adding to a 32 bit integer prior to >>15.";
1185   z[lc++]="*/";
1186   z[lc++]="#define DITHER_BITS   (15)";
1187   z[lc++]="#define DITHER_SCALE  (1.0f / ((1<<DITHER_BITS)-1))";
1188   z[lc++]="static long Pa_TriangularDither( void )";
1189   z[lc++]="{";
1190   z[lc++]="	static unsigned long previous = 0;";
1191   z[lc++]="	static unsigned long randSeed1 = 22222;";
1192   z[lc++]="	static unsigned long randSeed2 = 5555555;";
1193   z[lc++]="	long current, highPass;";
1194   z[lc++]="/* Generate two random numbers. */";
1195   z[lc++]="	randSeed1 = (randSeed1 * 196314165) + 907633515;";
1196   z[lc++]="	randSeed2 = (randSeed2 * 196314165) + 907633515;";
1197   z[lc++]="/* Generate triangular distribution about 0. */";
1198   z[lc++]="	current = (((long)randSeed1)>>(32-DITHER_BITS)) + (((long)randSeed2)>>(32-DITHER_BITS));";
1199   z[lc++]=" /* High pass filter to reduce audibility. */";
1200   z[lc++]="	highPass = current - previous;";
1201   z[lc++]="	previous = current;";
1202   z[lc++]="	return highPass;";
1203   z[lc++]="}";
1204   z[lc++]="";
1205   z[lc++]="/*************************************************************************";
1206   z[lc++]="** Called by host code.";
1207   z[lc++]="** Convert input from Int16, call user code, then convert output";
1208   z[lc++]="** to Int16 format for native use.";
1209   z[lc++]="** Assumes host native format is paInt16.";
1210   z[lc++]="** Returns result from user callback.";
1211   z[lc++]="*/";
1212   z[lc++]="long Pa_CallConvertInt16( internalPortAudioStream   *past, ";
1213   z[lc++]="	short *nativeInputBuffer,";
1214   z[lc++]="	short *nativeOutputBuffer )";
1215   z[lc++]="{";
1216   z[lc++]="	long              temp;";
1217   z[lc++]="	long              bytesEmpty = 0;";
1218   z[lc++]="	long              bytesFilled = 0;";
1219   z[lc++]="	int               userResult;";
1220   z[lc++]="	unsigned int      i;";
1221   z[lc++]="	void             *inputBuffer = NULL;";
1222   z[lc++]="	void             *outputBuffer = NULL;";
1223   z[lc++]="	";
1224   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
1225   z[lc++]="/* Get native data from DirectSound. */";
1226   z[lc++]="	if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )";
1227   z[lc++]="	{";
1228   z[lc++]="/* Convert from native format to PA format. */";
1229   z[lc++]="		unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels;";
1230   z[lc++]="		switch(past->past_InputSampleFormat)";
1231   z[lc++]="		{";
1232   z[lc++]="		";
1233   z[lc++]="		case paFloat32:";
1234   z[lc++]="			{";
1235   z[lc++]="				float *inBufPtr = (float *) past->past_InputBuffer;";
1236   z[lc++]="				inputBuffer = past->past_InputBuffer;";
1237   z[lc++]="				for( i=0; i<samplesPerBuffer; i++ )";
1238   z[lc++]="				{";
1239   z[lc++]="					inBufPtr[i] = nativeInputBuffer[i] * (1.0f / 32767.0f);";
1240   z[lc++]="				}";
1241   z[lc++]="				break;";
1242   z[lc++]="			}";
1243   z[lc++]="			";
1244   z[lc++]="		case paInt32:";
1245   z[lc++]="			{";
1246   z[lc++]="			/* Convert 16 bit data to 32 bit integers */";
1247   z[lc++]="				int *inBufPtr = (int *) past->past_InputBuffer;";
1248   z[lc++]="				inputBuffer = past->past_InputBuffer;";
1249   z[lc++]="				for( i=0; i<samplesPerBuffer; i++ )";
1250   z[lc++]="				{";
1251   z[lc++]="					inBufPtr[i] = nativeInputBuffer[i] << 16;";
1252   z[lc++]="				}";
1253   z[lc++]="				break;";
1254   z[lc++]="			}";
1255   z[lc++]="			";
1256   z[lc++]="		case paInt16:";
1257   z[lc++]="			{";
1258   z[lc++]="			/* Already in correct format so don't copy. */";
1259   z[lc++]="				inputBuffer = nativeInputBuffer;";
1260   z[lc++]="				break;";
1261   z[lc++]="			}";
1262   z[lc++]="";
1263   z[lc++]="		case paInt8:";
1264   z[lc++]="			{";
1265   z[lc++]="			/* Convert 16 bit data to 8 bit chars */";
1266   z[lc++]="				char *inBufPtr = (char *) past->past_InputBuffer;";
1267   z[lc++]="				inputBuffer = past->past_InputBuffer;";
1268   z[lc++]="				if( past->past_Flags & paDitherOff )";
1269   z[lc++]="				{";
1270   z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
1271   z[lc++]="					{";
1272   z[lc++]="						inBufPtr[i] = (char)(nativeInputBuffer[i] >> 8);";
1273   z[lc++]="					}";
1274   z[lc++]="				}";
1275   z[lc++]="				else";
1276   z[lc++]="				{";
1277   z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
1278   z[lc++]="					{";
1279   z[lc++]="						temp = nativeInputBuffer[i];";
1280   z[lc++]="						temp += Pa_TriangularDither() >> 8; /* PLB20010820 */";
1281   z[lc++]="						temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));";
1282   z[lc++]="						inBufPtr[i] = (char)(temp >> 8);";
1283   z[lc++]="					}";
vac_update_datfrozenxid(void)1284   z[lc++]="				}";
1285   z[lc++]="				break;";
1286   z[lc++]="			}";
1287   z[lc++]="";
1288   z[lc++]="		case paUInt8:";
1289   z[lc++]="			{";
1290   z[lc++]="			/* Convert 16 bit data to 8 bit unsigned chars */";
1291   z[lc++]="				unsigned char *inBufPtr = (unsigned char *) past->past_InputBuffer;";
1292   z[lc++]="				inputBuffer = past->past_InputBuffer;";
1293   z[lc++]="				if( past->past_Flags & paDitherOff )";
1294   z[lc++]="				{";
1295   z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
1296   z[lc++]="					{";
1297   z[lc++]="						inBufPtr[i] = ((unsigned char)(nativeInputBuffer[i] >> 8)) + 0x80;";
1298   z[lc++]="					}";
1299   z[lc++]="				}";
1300   z[lc++]="				else";
1301   z[lc++]="				{";
1302   z[lc++]="			/* If you dither then you have to clip because dithering could push the signal out of range! */";
1303   z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
1304   z[lc++]="					{";
1305   z[lc++]="						temp = nativeInputBuffer[i];";
1306   z[lc++]="						temp += Pa_TriangularDither() >> 8; /* PLB20010820 */";
1307   z[lc++]="						temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));";
1308   z[lc++]="						inBufPtr[i] = (unsigned char)((temp>>8) + 0x80); /* PLB20010820 */";
1309   z[lc++]="					}";
1310   z[lc++]="				}";
1311   z[lc++]="				break;";
1312   z[lc++]="			}";
1313   z[lc++]="			";
1314   z[lc++]="		default:";
1315   z[lc++]="			break;";
1316   z[lc++]="		}";
1317   z[lc++]="	}";
1318   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
1319   z[lc++]="";
1320   z[lc++]="/* Are we doing output time? */";
1321   z[lc++]="	if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )";
1322   z[lc++]="	{";
1323   z[lc++]="	/* May already be in native format so just write directly to native buffer. */";
1324   z[lc++]="		outputBuffer = (past->past_OutputSampleFormat == paInt16) ?";
1325   z[lc++]="			nativeOutputBuffer : past->past_OutputBuffer;";
1326   z[lc++]="	}";
1327   z[lc++]="/*	";
1328   z[lc++]="	AddTraceMessage(\"Pa_CallConvertInt16: inputBuffer = \", (int) inputBuffer );";
1329   z[lc++]="	AddTraceMessage(\"Pa_CallConvertInt16: outputBuffer = \", (int) outputBuffer );";
1330   z[lc++]="*/	";
1331   z[lc++]="/* Call user callback routine. */";
1332   z[lc++]="	userResult = past->past_Callback(";
1333   z[lc++]="			inputBuffer,";
1334   z[lc++]="			outputBuffer,";
1335   z[lc++]="			past->past_FramesPerUserBuffer,";
1336   z[lc++]="			past->past_FrameCount,";
1337   z[lc++]="			past->past_UserData );";
1338   z[lc++]="";
1339   z[lc++]="	past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;";
1340   z[lc++]="";
1341   z[lc++]="/* Convert to native format if necessary. */";
1342   z[lc++]="	if( outputBuffer != NULL )";
1343   z[lc++]="	{";
1344   z[lc++]="		unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels;";
1345   z[lc++]="		switch(past->past_OutputSampleFormat)";
1346   z[lc++]="		{";
1347   z[lc++]="		case paFloat32:";
1348   z[lc++]="			{";
1349   z[lc++]="				float *outBufPtr = (float *) past->past_OutputBuffer;";
1350   z[lc++]="				if( past->past_Flags & paDitherOff )";
1351   z[lc++]="				{";
1352   z[lc++]="					if( past->past_Flags & paClipOff ) /* NOTHING */";
1353   z[lc++]="					{";
1354   z[lc++]="						for( i=0; i<samplesPerBuffer; i++ )";
1355   z[lc++]="						{";
1356   z[lc++]="							*nativeOutputBuffer++ = (short) (outBufPtr[i] * (32767.0f));";
1357   z[lc++]="						}";
1358   z[lc++]="					}";
1359   z[lc++]="					else /* CLIP */";
1360   z[lc++]="					{";
1361   z[lc++]="						for( i=0; i<samplesPerBuffer; i++ )";
1362   z[lc++]="						{";
1363   z[lc++]="							temp = (long)(outBufPtr[i] * 32767.0f);";
1364   z[lc++]="							*nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));";
1365   z[lc++]="						}";
1366   z[lc++]="					}";
1367   z[lc++]="				}";
1368   z[lc++]="				else";
1369   z[lc++]="				{";
1370   z[lc++]="			/* If you dither then you have to clip because dithering could push the signal out of range! */";
1371   z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
1372   z[lc++]="					{";
1373   z[lc++]="						float dither  = Pa_TriangularDither()*DITHER_SCALE;";
1374   z[lc++]="						float dithered = (outBufPtr[i] * (32767.0f)) + dither;";
1375   z[lc++]="						temp = (long) (dithered);";
1376   z[lc++]="						*nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));";
1377   z[lc++]="					}";
1378   z[lc++]="				}";
1379   z[lc++]="				break;";
1380   z[lc++]="			}";
1381   z[lc++]="			";
1382   z[lc++]="		case paInt32:";
1383   z[lc++]="			{";
1384   z[lc++]="				int *outBufPtr = (int *) past->past_OutputBuffer;";
1385   z[lc++]="				if( past->past_Flags & paDitherOff )";
1386   z[lc++]="				{";
1387   z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
1388   z[lc++]="					{";
1389   z[lc++]="						*nativeOutputBuffer++ = (short) (outBufPtr[i] >> 16 );";
1390   z[lc++]="					}";
1391   z[lc++]="				}";
1392   z[lc++]="				else";
1393   z[lc++]="				{";
1394   z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
1395   z[lc++]="					{";
1396   z[lc++]="				/* Shift one bit down before dithering so that we have room for overflow from add. */";
1397   z[lc++]="						temp = (outBufPtr[i] >> 1) + Pa_TriangularDither();";
1398   z[lc++]="						temp = temp >> 15;";
1399   z[lc++]="						*nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));";
1400   z[lc++]="					}";
1401   z[lc++]="				}";
1402   z[lc++]="				break;";
1403   z[lc++]="			}";
1404   z[lc++]="";
1405   z[lc++]="		case paInt8:";
1406   z[lc++]="			{";
1407   z[lc++]="				char *outBufPtr = (char *) past->past_OutputBuffer;";
1408   z[lc++]="				for( i=0; i<samplesPerBuffer; i++ )";
1409   z[lc++]="				{";
1410   z[lc++]="					*nativeOutputBuffer++ = ((short)outBufPtr[i]) << 8;";
1411   z[lc++]="				}";
1412   z[lc++]="				break;";
1413   z[lc++]="			}";
1414   z[lc++]="";
1415   z[lc++]="		case paUInt8:";
1416   z[lc++]="			{";
1417   z[lc++]="				unsigned char *outBufPtr = (unsigned char *) past->past_OutputBuffer;";
1418   z[lc++]="				for( i=0; i<samplesPerBuffer; i++ )";
1419   z[lc++]="				{";
1420   z[lc++]="					*nativeOutputBuffer++ = ((short)(outBufPtr[i] - 0x80)) << 8;";
1421   z[lc++]="				}";
1422   z[lc++]="				break;";
1423   z[lc++]="			}";
1424   z[lc++]="";
1425   z[lc++]="		default:";
1426   z[lc++]="			break;";
1427   z[lc++]="		}";
1428   z[lc++]="";
1429   z[lc++]="	}";
1430   z[lc++]="	";
1431   z[lc++]="	return userResult;";
1432   z[lc++]="}";
1433   z[lc++]="";
1434   z[lc++]="/*************************************************************************";
1435   z[lc++]="** Called by host code.";
1436   z[lc++]="** Convert input from Float32, call user code, then convert output";
1437   z[lc++]="** to Float32 format for native use.";
1438   z[lc++]="** Assumes host native format is Float32.";
1439   z[lc++]="** Returns result from user callback.";
1440   z[lc++]="** FIXME - Unimplemented for formats other than paFloat32!!!!";
1441   z[lc++]="*/";
1442   z[lc++]="long Pa_CallConvertFloat32( internalPortAudioStream   *past, ";
1443   z[lc++]="	float *nativeInputBuffer,";
1444   z[lc++]="	float *nativeOutputBuffer )";
1445   z[lc++]="{";
1446   z[lc++]="	long              bytesEmpty = 0;";
1447   z[lc++]="	long              bytesFilled = 0;";
1448   z[lc++]="	int               userResult;";
1449   z[lc++]="	void             *inputBuffer = NULL;";
1450   z[lc++]="	void             *outputBuffer = NULL;";
1451   z[lc++]="	";
1452   z[lc++]="/* Get native data from DirectSound. */";
1453   z[lc++]="	if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )";
1454   z[lc++]="	{";
1455   z[lc++]="		inputBuffer = nativeInputBuffer;  /* FIXME */";
1456   z[lc++]="	}";
1457   z[lc++]="	";
1458   z[lc++]="/* Are we doing output time? */";
1459   z[lc++]="	if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )";
1460   z[lc++]="	{";
1461   z[lc++]="	/* May already be in native format so just write directly to native buffer. */";
1462   z[lc++]="		outputBuffer = (past->past_OutputSampleFormat == paFloat32) ?";
1463   z[lc++]="			nativeOutputBuffer : past->past_OutputBuffer;";
1464   z[lc++]="	}";
1465   z[lc++]="/*	";
1466   z[lc++]="	AddTraceMessage(\"Pa_CallConvertInt16: inputBuffer = \", (int) inputBuffer );";
1467   z[lc++]="	AddTraceMessage(\"Pa_CallConvertInt16: outputBuffer = \", (int) outputBuffer );";
1468   z[lc++]="*/	";
1469   z[lc++]="/* Call user callback routine. */";
1470   z[lc++]="	userResult = past->past_Callback(";
1471   z[lc++]="			inputBuffer,";
1472   z[lc++]="			outputBuffer,";
1473   z[lc++]="			past->past_FramesPerUserBuffer,";
1474   z[lc++]="			past->past_FrameCount,";
1475   z[lc++]="			past->past_UserData );";
1476   z[lc++]="";
1477   z[lc++]="	past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;";
1478   z[lc++]="";
1479   z[lc++]="/* Convert to native format if necessary. */  /* FIXME */	";
1480   z[lc++]="	return userResult;";
vac_truncate_clog(TransactionId frozenXID,MultiXactId minMulti,TransactionId lastSaneFrozenXid,MultiXactId lastSaneMinMulti)1481   z[lc++]="}";
1482   z[lc++]="";
1483   z[lc++]="/*************************************************************************/";
1484   z[lc++]="PaError Pa_Initialize( void )";
1485   z[lc++]="{";
1486   z[lc++]="	if( gInitCount++ > 0 ) return paNoError;";
1487   z[lc++]="	ResetTraceMessages();";
1488   z[lc++]="	return PaHost_Init();";
1489   z[lc++]="}";
1490   z[lc++]="";
1491   z[lc++]="PaError Pa_Terminate( void )";
1492   z[lc++]="{";
1493   z[lc++]="	PaError result = paNoError;";
1494   z[lc++]="";
1495   z[lc++]="	if( gInitCount == 0 ) return paNoError;";
1496   z[lc++]="	else if( --gInitCount == 0 )";
1497   z[lc++]="	{";
1498   z[lc++]="		result = PaHost_Term();";
1499   z[lc++]="		DumpTraceMessages();";
1500   z[lc++]="	}";
1501   z[lc++]="	return result;";
1502   z[lc++]="}";
1503   z[lc++]="";
1504   z[lc++]="/*************************************************************************/";
1505   z[lc++]="PaError Pa_GetSampleSize( PaSampleFormat format )";
1506   z[lc++]="{";
1507   z[lc++]="	int size;";
1508   z[lc++]="	switch(format )";
1509   z[lc++]="	{";
1510   z[lc++]="";
1511   z[lc++]="	case paUInt8:";
1512   z[lc++]="	case paInt8:";
1513   z[lc++]="		size = 1;";
1514   z[lc++]="		break;";
1515   z[lc++]="";
1516   z[lc++]="	case paInt16:";
1517   z[lc++]="		size = 2;";
1518   z[lc++]="		break;";
1519   z[lc++]="";
1520   z[lc++]="	case paPackedInt24:";
1521   z[lc++]="		size = 3;";
1522   z[lc++]="		break;";
1523   z[lc++]="";
1524   z[lc++]="	case paFloat32:";
1525   z[lc++]="	case paInt32:";
1526   z[lc++]="	case paInt24:";
1527   z[lc++]="		size = 4;";
1528   z[lc++]="		break;";
1529   z[lc++]="";
1530   z[lc++]="	default:";
1531   z[lc++]="		size = paSampleFormatNotSupported;";
1532   z[lc++]="		break;";
1533   z[lc++]="	}";
1534   z[lc++]="	return (PaError) size;";
1535   z[lc++]="}";
1536   z[lc++]="";
1537   z[lc++]="";
1538   printlib(lc);
1539 }
1540 
1541 
1542 void makepa_unix_oss(void)
1543 {
1544   int lc = 0;
1545 
1546   z[lc++]="/*";
1547   z[lc++]=" * PortAudio Portable Real-Time Audio Library";
1548   z[lc++]=" * Latest Version at: http://www.portaudio.com";
1549   z[lc++]=" * Linux OSS Implementation by douglas repetto and Phil Burk";
1550   z[lc++]=" *";
1551   z[lc++]=" * Copyright (c) 1999-2000 Phil Burk";
1552   z[lc++]=" *";
1553   z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
1554   z[lc++]=" * a copy of this software and associated documentation files";
1555   z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
1556   z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
1557   z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
1558   z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
1559   z[lc++]=" * subject to the following conditions:";
1560   z[lc++]=" *";
1561   z[lc++]=" * The above copyright notice and this permission notice shall be";
1562   z[lc++]=" * included in all copies or substantial portions of the Software.";
1563   z[lc++]=" *";
1564   z[lc++]=" * Any person wishing to distribute modifications to the Software is";
1565   z[lc++]=" * requested to send the modifications to the original developer so that";
1566   z[lc++]=" * they can be incorporated into the canonical version.";
1567   z[lc++]=" *";
1568   z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
1569   z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
1570   z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
1571   z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
1572   z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
1573   z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
1574   z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
1575   z[lc++]=" *";
1576   z[lc++]=" */";
1577   z[lc++]="/*";
1578   z[lc++]="Modfication History";
1579   z[lc++]="  1/2001 - Phil Burk - initial hack for Linux";
1580   z[lc++]="  2/2001 - Douglas Repetto - many improvements, initial query support";
1581   z[lc++]="  4/2/2001 - Phil - stop/abort thread control, separate in/out native buffers";
1582   z[lc++]="  5/28/2001 - Phil - use pthread_create() instead of clone(). Thanks Stephen Brandon!";
1583   z[lc++]="		     use pthread_join() after thread shutdown.";
1584   z[lc++]="  5/29/2001 - Phil - query for multiple devices, multiple formats,";
1585   z[lc++]="                     input mode and input+output mode working,";
1586   z[lc++]="		     Pa_GetCPULoad() implemented.";
1587   z[lc++]="  PLB20010817 - Phil & Janos Haber - don't halt if test of sample rate fails.";
1588   z[lc++]="  SB20010904 - Stephen Brandon - mods needed for GNUSTEP and SndKit";
1589   z[lc++]="  JH20010905 - Janos Haber - FreeBSD mods";
1590   z[lc++]="  2001-09-22 - Heiko - (i.e. Heiko Purnhagen <purnhage@tnt.uni-hannover.de> ;-)";
1591   z[lc++]="                       added 24k and 16k to ratesToTry[]";
1592   z[lc++]="		       fixed Pa_GetInternalDevice()";
1593   z[lc++]="		       changed DEVICE_NAME_BASE from /dev/audio to /dev/dsp";
1594   z[lc++]="		       handled SNDCTL_DSP_SPEED in Pq_QueryDevice() more graceful";
1595   z[lc++]="		       fixed Pa_StreamTime() for paqa_errs.c";
1596   z[lc++]="		       fixed numCannel=2 oddity and error handling in Pa_SetupDeviceFormat()";
1597   z[lc++]="		       grep also for HP20010922 ...";
1598   z[lc++]="  PLB20010924 - Phil - merged Heiko's changes";
1599   z[lc++]="                       removed sNumDevices and potential related bugs,";
1600   z[lc++]="		       use getenv(\"PA_MIN_LATENCY_MSEC\") to set desired latency,";
1601   z[lc++]="		       simplify CPU Load calculation by comparing real-time to framesPerBuffer,";
1602   z[lc++]="		       always close device when querying even if error occurs,";
1603   z[lc++]="  PLB20010927 - Phil - Improved negotiation for numChannels.";
1604   z[lc++]="		       ";
1605   z[lc++]="  ";
1606   z[lc++]="TODO";
1607   z[lc++]="O- change Pa_StreamTime() to query device (patest_sync.c)";
1608   z[lc++]="O- put semaphore lock around shared data?";
1609   z[lc++]="O- handle native formats better";
1610   z[lc++]="O- handle stereo-only device better ???";
1611   z[lc++]="O- what if input and output of a device capabilities differ (e.g. es1371) ???";
1612   z[lc++]="*/";
1613   z[lc++]="/*";
1614   z[lc++]="	PROPOSED - should we add this to \"portaudio.h\". Problem with ";
1615   z[lc++]="	Pa_QueryDevice() not having same driver name os Pa_OpenStream().";
1616   z[lc++]="";
1617   z[lc++]="	A PaDriverInfo structure can be passed to the underlying device";
1618   z[lc++]="	on the Pa_OpenStream() call. The contents and interpretation of";
1619   z[lc++]="	the structure is determined by the PA implementation.";
1620   z[lc++]="*/";
1621   z[lc++]="typedef struct PaDriverInfo /* PROPOSED */";
1622   z[lc++]="{";
1623   z[lc++]="/* Size of structure. Allows driver to extend the structure without breaking existing applications. */";
1624   z[lc++]="	int           size;";
1625   z[lc++]="/* Can be used to request a specific device name. */";
1626   z[lc++]="	const char   *name;";
1627   z[lc++]="	unsigned long data;";
1628   z[lc++]="} PaDriverInfo;";
1629   z[lc++]="";
1630   z[lc++]="";
1631   z[lc++]="";
vacuum_rel(Oid relid,RangeVar * relation,VacuumParams * params)1632   z[lc++]="#include <stdio.h>";
1633   z[lc++]="#include <stdlib.h>";
1634   z[lc++]="#include <malloc.h>";
1635   z[lc++]="#include <memory.h>";
1636   z[lc++]="#include <math.h>";
1637   z[lc++]="#if 0";
1638   z[lc++]="#include \"portaudio.h\"";
1639   z[lc++]="#include \"pa_host.h\"";
1640   z[lc++]="#include \"pa_trace.h\"";
1641   z[lc++]="#endif";
1642   z[lc++]="#include <sys/ioctl.h>";
1643   z[lc++]="#include <sys/time.h>";
1644   z[lc++]="#include <fcntl.h> ";
1645   z[lc++]="#include <unistd.h> ";
1646   z[lc++]="#include <signal.h> ";
1647   z[lc++]="#include <stdio.h> ";
1648   z[lc++]="#include <stdlib.h>";
1649   z[lc++]="";
1650   z[lc++]="#ifdef __linux__";
1651   z[lc++]="#include <linux/soundcard.h>";
1652   z[lc++]="#else";
1653   z[lc++]="#include <machine/soundcard.h> /* JH20010905 */";
1654   z[lc++]="#endif";
1655   z[lc++]="";
1656   z[lc++]="#include <sched.h> ";
1657   z[lc++]="#include <pthread.h> ";
1658   z[lc++]="                     ";
1659   z[lc++]="/* Some versions of OSS do not define AFMT_S16_NE. Assume little endian. FIXME - check CPU*/     ";
1660   z[lc++]="#ifndef AFMT_S16_NE";
1661   z[lc++]="	#define AFMT_S16_NE AFMT_S16_LE";
1662   z[lc++]="#endif";
1663   z[lc++]="";
1664   z[lc++]="#define PRINT(x)   { printf x; fflush(stdout); }";
1665   z[lc++]="#define ERR_RPT(x) PRINT(x)";
1666   z[lc++]="#define DBUG(x)    /* PRINT(x) */";
1667   z[lc++]="#define DBUGX(x)   /* PRINT(x) */";
1668   z[lc++]="";
1669   z[lc++]="#define BAD_DEVICE_ID (-1)";
1670   z[lc++]="";
1671   z[lc++]="#define MIN_LATENCY_MSEC   (2)";
1672   z[lc++]="#define MIN_TIMEOUT_MSEC   (100)";
1673   z[lc++]="#define MAX_TIMEOUT_MSEC   (1000)";
1674   z[lc++]="";
1675   z[lc++]="/************************************************* Definitions ********/";
1676   z[lc++]="#ifdef __linux__";
1677   z[lc++]="	#define DEVICE_NAME_BASE            \"/dev/dsp\"";
1678   z[lc++]="#else";
1679   z[lc++]="	#define DEVICE_NAME_BASE            \"/dev/audio\"";
1680   z[lc++]="#endif";
1681   z[lc++]="";
1682   z[lc++]="#define MAX_CHARS_DEVNAME           (32)";
1683   z[lc++]="#define MAX_SAMPLE_RATES            (10)";
1684   z[lc++]="typedef struct internalPortAudioDevice";
1685   z[lc++]="{";
1686   z[lc++]="	struct internalPortAudioDevice *pad_Next; /* Singly linked list. */";
1687   z[lc++]="	double          pad_SampleRates[MAX_SAMPLE_RATES]; /* for pointing to from pad_Info */";
1688   z[lc++]="	char            pad_DeviceName[MAX_CHARS_DEVNAME];";
1689   z[lc++]="	PaDeviceInfo    pad_Info;";
1690   z[lc++]="} internalPortAudioDevice;";
1691   z[lc++]="";
1692   z[lc++]="/* Define structure to contain all OSS and Linux specific data. */";
1693   z[lc++]="typedef struct PaHostSoundControl";
1694   z[lc++]="{";
1695   z[lc++]="	int              pahsc_OutputHandle;";
1696   z[lc++]="	int              pahsc_InputHandle;";
1697   z[lc++]="	pthread_t        pahsc_ThreadPID;";
1698   z[lc++]="	short           *pahsc_NativeInputBuffer;";
1699   z[lc++]="	short           *pahsc_NativeOutputBuffer;";
1700   z[lc++]="	unsigned int     pahsc_BytesPerInputBuffer;    /* native buffer size in bytes */";
1701   z[lc++]="	unsigned int     pahsc_BytesPerOutputBuffer;   /* native buffer size in bytes */";
1702   z[lc++]="/* For measuring CPU utilization. */";
1703   z[lc++]="	struct timeval   pahsc_EntryTime;";
1704   z[lc++]="	double           pahsc_InverseMicrosPerBuffer; /* 1/Microseconds of real-time audio per user buffer. */";
1705   z[lc++]="} PaHostSoundControl;";
1706   z[lc++]="";
1707   z[lc++]="/************************************************* Shared Data ********/";
1708   z[lc++]="/* FIXME - put Mutex around this shared data. */";
1709   z[lc++]="static int sDeviceIndex = 0;";
1710   z[lc++]="static internalPortAudioDevice *sDeviceList = NULL;";
1711   z[lc++]="static int sDefaultInputDeviceID = paNoDevice;";
1712   z[lc++]="static int sDefaultOutputDeviceID = paNoDevice;";
1713   z[lc++]="static int sEnumerationError;";
1714   z[lc++]="static int sPaHostError = 0;";
1715   z[lc++]="";
1716   z[lc++]="/************************************************* Prototypes **********/";
1717   z[lc++]="";
1718   z[lc++]="static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id );";
1719   z[lc++]="static Pa_QueryDevices( void );";
1720   z[lc++]="static PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *pad );";
1721   z[lc++]="static PaError Pa_SetupDeviceFormat( int devHandle, int numChannels, int sampleRate );";
1722   z[lc++]="";
1723   z[lc++]="/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/";
1724   z[lc++]="static void Pa_StartUsageCalculation( internalPortAudioStream   *past )";
1725   z[lc++]="{";
1726   z[lc++]="	struct itimerval itimer;";
1727   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
1728   z[lc++]="	if( pahsc == NULL ) return;";
1729   z[lc++]="/* Query system timer for usage analysis and to prevent overuse of CPU. */";
1730   z[lc++]="	gettimeofday( &pahsc->pahsc_EntryTime, NULL );";
1731   z[lc++]="}";
1732   z[lc++]="";
1733   z[lc++]="static long SubtractTime_AminusB( struct timeval *timeA, struct timeval *timeB )";
1734   z[lc++]="{";
1735   z[lc++]="	long secs = timeA->tv_sec - timeB->tv_sec;";
1736   z[lc++]="	long usecs = secs * 1000000;";
1737   z[lc++]="	usecs += (timeA->tv_usec - timeB->tv_usec);";
1738   z[lc++]="	return usecs;";
1739   z[lc++]="}";
1740   z[lc++]="";
1741   z[lc++]="/******************************************************************************";
1742   z[lc++]="** Measure fractional CPU load based on real-time it took to calculate";
1743   z[lc++]="** buffers worth of output.";
1744   z[lc++]="*/";
1745   z[lc++]="static void Pa_EndUsageCalculation( internalPortAudioStream   *past )";
1746   z[lc++]="{";
1747   z[lc++]="	struct timeval currentTime;";
1748   z[lc++]="	long  usecsElapsed;";
1749   z[lc++]="	double newUsage;";
1750   z[lc++]="";
1751   z[lc++]="#define LOWPASS_COEFFICIENT_0   (0.95)";
1752   z[lc++]="#define LOWPASS_COEFFICIENT_1   (0.99999 - LOWPASS_COEFFICIENT_0)";
1753   z[lc++]="";
1754   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
1755   z[lc++]="	if( pahsc == NULL ) return;";
1756   z[lc++]="";
1757   z[lc++]="	if( gettimeofday( &currentTime, NULL ) == 0 )";
1758   z[lc++]="	{";
1759   z[lc++]="		usecsElapsed = SubtractTime_AminusB( &currentTime, &pahsc->pahsc_EntryTime );";
1760   z[lc++]="	/* Use inverse because it is faster than the divide. */";
1761   z[lc++]="		newUsage =  usecsElapsed * pahsc->pahsc_InverseMicrosPerBuffer;";
1762   z[lc++]="		";
1763   z[lc++]="		past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +";
1764   z[lc++]="			(LOWPASS_COEFFICIENT_1 * newUsage);";
1765   z[lc++]="	}";
1766   z[lc++]="}";
1767   z[lc++]="/****************************************** END CPU UTILIZATION *******/";
1768   z[lc++]="";
1769   z[lc++]="/*********************************************************************";
1770   z[lc++]=" * Try to open the named device.";
1771   z[lc++]=" * If it opens, try to set various rates and formats and fill in ";
1772   z[lc++]=" * the device info structure.";
1773   z[lc++]=" */";
1774   z[lc++]="static PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *pad )";
1775   z[lc++]="{";
1776   z[lc++]="	int result = paHostError;";
1777   z[lc++]="	int numBytes;";
1778   z[lc++]="	int tempDevHandle;";
1779   z[lc++]="	int numChannels, maxNumChannels;";
1780   z[lc++]="	int format;";
1781   z[lc++]="	int numSampleRates;";
1782   z[lc++]="	int sampleRate;";
1783   z[lc++]="	int numRatesToTry;";
1784   z[lc++]="	int ratesToTry[9] = {96000, 48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000};";
1785   z[lc++]="	int i;";
1786   z[lc++]="";
1787   z[lc++]="/* douglas: ";
1788   z[lc++]="	we have to do this querying in a slightly different order. apparently";
1789   z[lc++]="	some sound cards will give you different info based on their settins. ";
1790   z[lc++]="	e.g. a card might give you stereo at 22kHz but only mono at 44kHz.";
1791   z[lc++]="	the correct order for OSS is: format, channels, sample rate";
1792   z[lc++]="";
1793   z[lc++]="*/";
1794   z[lc++]="	if ( (tempDevHandle = open(deviceName,O_WRONLY))  == -1 )";
1795   z[lc++]="	{";
1796   z[lc++]="		DBUG((\"Pa_QueryDevice: could not open %s\\n\", deviceName ));";
1797   z[lc++]="		return paHostError;";
1798   z[lc++]="	}";
1799   z[lc++]="	";
1800   z[lc++]="/*  Ask OSS what formats are supported by the hardware. */";
1801   z[lc++]="	pad->pad_Info.nativeSampleFormats = 0;";
1802   z[lc++]="	if (ioctl(tempDevHandle, SNDCTL_DSP_GETFMTS, &format) == -1)";
1803   z[lc++]="	{";
1804   z[lc++]="		ERR_RPT((\"Pa_QueryDevice: could not get format info\\n\" ));";
1805   z[lc++]="		goto error;";
1806   z[lc++]="	}";
1807   z[lc++]="	if( format & AFMT_U8 )     pad->pad_Info.nativeSampleFormats |= paUInt8;";
1808   z[lc++]="	if( format & AFMT_S16_NE ) pad->pad_Info.nativeSampleFormats |= paInt16;";
1809   z[lc++]="";
1810   z[lc++]="/* Negotiate for the maximum number of channels for this device. PLB20010927";
1811   z[lc++]=" * Start with 16 as a hard coded upper number of channels.";
1812   z[lc++]=" * Variable numChannels should contain the actual upper limit after the call.";
1813   z[lc++]=" * Thanks to John Lazzaro and Heiko Purnhagen for suggestions.";
1814   z[lc++]=" */";
1815   z[lc++]="	maxNumChannels = 0;";
1816   z[lc++]="	for( numChannels = 1; numChannels <= 16; numChannels++ )";
1817   z[lc++]="	{";
1818   z[lc++]="		int temp = numChannels;";
1819   z[lc++]="		DBUG((\"Pa_QueryDevice: use SNDCTL_DSP_CHANNELS, numChannels = %d\\n\", numChannels ))";
1820   z[lc++]="		if(ioctl(tempDevHandle, SNDCTL_DSP_CHANNELS, &temp) < 0 )";
1821   z[lc++]="		{";
1822   z[lc++]="		/* ioctl() failed so bail out if we already have stereo */";
1823   z[lc++]="			if( numChannels > 2 ) break;";
1824   z[lc++]="		}";
1825   z[lc++]="		else";
1826   z[lc++]="		{";
1827   z[lc++]="		/* ioctl() worked but bail out if it does not support numChannels.";
1828   z[lc++]="		 * We don't want to leave gaps in the numChannels supported.";
1829   z[lc++]="		 */";
1830   z[lc++]="			if( (numChannels > 2) && (temp != numChannels) ) break;";
1831   z[lc++]="			DBUG((\"Pa_QueryDevice: temp = %d\\n\", temp ))";
1832   z[lc++]="			if( temp > maxNumChannels ) maxNumChannels = temp; /* Save maximum. */";
1833   z[lc++]="		}";
1834   z[lc++]="	}";
1835   z[lc++]="/* The above negotiation may fail for an old driver so try this older technique. */";
1836   z[lc++]="	if( maxNumChannels < 1 )";
1837   z[lc++]="	{";
1838   z[lc++]="		int stereo = 1;";
1839   z[lc++]="		if(ioctl(tempDevHandle, SNDCTL_DSP_STEREO, &stereo) < 0)";
1840   z[lc++]="		{";
1841   z[lc++]="			maxNumChannels = 1;";
1842   z[lc++]="		}";
1843   z[lc++]="		else";
1844   z[lc++]="		{";
1845   z[lc++]="			maxNumChannels = (stereo) ? 2 : 1;";
1846   z[lc++]="		}";
1847   z[lc++]="		DBUG((\"Pa_QueryDevice: use SNDCTL_DSP_STEREO, maxNumChannels = %d\\n\", maxNumChannels ))";
1848   z[lc++]="	}";
1849   z[lc++]="	";
1850   z[lc++]="	pad->pad_Info.maxOutputChannels = maxNumChannels;";
1851   z[lc++]="	DBUG((\"Pa_QueryDevice: maxNumChannels = %d\\n\", maxNumChannels))";
1852   z[lc++]="		";
1853   z[lc++]="/* FIXME - for now, assume maxInputChannels = maxOutputChannels.";
1854   z[lc++]=" *    Eventually do separate queries for O_WRONLY and O_RDONLY";
1855   z[lc++]="*/";
1856   z[lc++]="	pad->pad_Info.maxInputChannels = pad->pad_Info.maxOutputChannels;";
1857   z[lc++]="	";
1858   z[lc++]="	DBUG((\"Pa_QueryDevice: maxInputChannels = %d\\n\", ";
1859   z[lc++]="		pad->pad_Info.maxInputChannels))";
1860   z[lc++]="";
1861   z[lc++]="";
1862   z[lc++]="/* Determine available sample rates by trying each one and seeing result.";
1863   z[lc++]=" */";
1864   z[lc++]="	numSampleRates = 0;";
1865   z[lc++]="	numRatesToTry = sizeof(ratesToTry)/sizeof(int);";
1866   z[lc++]="	for (i = 0; i < numRatesToTry; i++)";
1867   z[lc++]="	{";
1868   z[lc++]="		sampleRate = ratesToTry[i];";
1869   z[lc++]="		";
1870   z[lc++]="		if (ioctl(tempDevHandle, SNDCTL_DSP_SPEED, &sampleRate) >= 0 ) // PLB20010817";
1871   z[lc++]="		{";
1872   z[lc++]="			if (sampleRate == ratesToTry[i])";
1873   z[lc++]="			{";
1874   z[lc++]="				DBUG((\"Pa_QueryDevice: got sample rate: %d\\n\", sampleRate))";
1875   z[lc++]="				pad->pad_SampleRates[numSampleRates] = (float)ratesToTry[i];";
1876   z[lc++]="				numSampleRates++;";
1877   z[lc++]="			}";
1878   z[lc++]="		}";
1879   z[lc++]="	}";
1880   z[lc++]="";
1881   z[lc++]="	DBUG((\"Pa_QueryDevice: final numSampleRates = %d\\n\", numSampleRates))";
1882   z[lc++]="	if (numSampleRates==0)   /* HP20010922 */";
1883   z[lc++]="	{";
1884   z[lc++]="		ERR_RPT((\"Pa_QueryDevice: no supported sample rate (or SNDCTL_DSP_SPEED ioctl call failed).\\n\" ));";
1885   z[lc++]="		goto error;";
1886   z[lc++]="	}";
1887   z[lc++]="";
1888   z[lc++]="	pad->pad_Info.numSampleRates = numSampleRates;";
1889   z[lc++]="	pad->pad_Info.sampleRates = pad->pad_SampleRates;";
1890   z[lc++]="	";
1891   z[lc++]="	pad->pad_Info.name = deviceName;";
1892   z[lc++]="";
1893   z[lc++]="	result = paNoError;";
1894   z[lc++]="	";
vac_open_indexes(Relation relation,LOCKMODE lockmode,int * nindexes,Relation ** Irel)1895   z[lc++]="error:";
1896   z[lc++]="/* We MUST close the handle here or we won't be able to reopen it later!!!  */";
1897   z[lc++]="	close(tempDevHandle);";
1898   z[lc++]="";
1899   z[lc++]="	return result;";
1900   z[lc++]="}";
1901   z[lc++]="";
1902   z[lc++]="/*********************************************************************";
1903   z[lc++]=" * Determines the number of available devices by trying to open";
1904   z[lc++]=" * each \"/dev/dsp#\" or \"/dsp/audio#\" in order until it fails.";
1905   z[lc++]=" * Add each working device to a singly linked list of devices.";
1906   z[lc++]=" */";
1907   z[lc++]="static PaError Pa_QueryDevices( void )";
1908   z[lc++]="{";
1909   z[lc++]="	internalPortAudioDevice *pad, *lastPad;";
1910   z[lc++]="	int      numBytes;";
1911   z[lc++]="	int      go = 1;";
1912   z[lc++]="	int      numDevices = 0;";
1913   z[lc++]="	PaError  testResult;";
1914   z[lc++]="	PaError  result = paNoError;";
1915   z[lc++]="	";
1916   z[lc++]="	sDefaultInputDeviceID = paNoDevice;";
1917   z[lc++]="	sDefaultOutputDeviceID = paNoDevice;";
1918   z[lc++]="";
1919   z[lc++]="	lastPad = NULL;";
1920   z[lc++]="	";
1921   z[lc++]="	while( go )";
1922   z[lc++]="	{";
1923   z[lc++]="/* Allocate structure to hold device info. */";
1924   z[lc++]="		pad = PaHost_AllocateFastMemory( sizeof(internalPortAudioDevice) );";
1925   z[lc++]="		if( pad == NULL ) return paInsufficientMemory;";
1926   z[lc++]="		memset( pad, 0, sizeof(internalPortAudioDevice) );";
1927   z[lc++]="		";
1928   z[lc++]="/* Build name for device. */";
1929   z[lc++]="		if( numDevices == 0 )";
1930   z[lc++]="		{";
1931   z[lc++]="			sprintf( pad->pad_DeviceName, DEVICE_NAME_BASE);";
1932   z[lc++]="		}";
1933   z[lc++]="		else";
1934   z[lc++]="		{";
1935   z[lc++]="			sprintf( pad->pad_DeviceName, DEVICE_NAME_BASE \"%d\", numDevices );";
1936   z[lc++]="		}";
1937   z[lc++]="		";
vac_close_indexes(int nindexes,Relation * Irel,LOCKMODE lockmode)1938   z[lc++]="		DBUG((\"Try device %s\\n\", pad->pad_DeviceName ));";
1939   z[lc++]="		testResult = Pa_QueryDevice( pad->pad_DeviceName, pad );";
1940   z[lc++]="		DBUG((\"Pa_QueryDevice returned %d\\n\", testResult ));";
1941   z[lc++]="		if( testResult != paNoError )";
1942   z[lc++]="		{";
1943   z[lc++]="			if( lastPad == NULL )";
1944   z[lc++]="			{";
1945   z[lc++]="				result = testResult; /* No good devices! */";
1946   z[lc++]="			}";
1947   z[lc++]="			go = 0;";
1948   z[lc++]="			PaHost_FreeFastMemory( pad, sizeof(internalPortAudioDevice) );";
1949   z[lc++]="		}";
1950   z[lc++]="		else";
1951   z[lc++]="		{";
1952   z[lc++]="			numDevices += 1;";
1953   z[lc++]="		/* Add to linked list of devices. */";
1954   z[lc++]="			if( lastPad )";
1955   z[lc++]="			{";
1956   z[lc++]="				lastPad->pad_Next = pad;";
1957   z[lc++]="			}";
1958   z[lc++]="			else";
vacuum_delay_point(void)1959   z[lc++]="			{";
1960   z[lc++]="				sDeviceList = pad; /* First element in linked list. */";
1961   z[lc++]="			}";
1962   z[lc++]="			lastPad = pad;";
1963   z[lc++]="		}";
1964   z[lc++]="	}";
1965   z[lc++]="	";
1966   z[lc++]="	return result;";
1967   z[lc++]="	";
1968   z[lc++]="}";
1969   z[lc++]="";
1970   z[lc++]="/*************************************************************************/";
1971   z[lc++]="int Pa_CountDevices()";
1972   z[lc++]="{";
1973   z[lc++]="	int numDevices = 0;";
1974   z[lc++]="	internalPortAudioDevice *pad;";
1975   z[lc++]="	";
1976   z[lc++]="	if( sDeviceList == NULL ) Pa_Initialize();";
1977   z[lc++]="/* Count devices in list. */";
1978   z[lc++]="	pad = sDeviceList;";
1979   z[lc++]="	while( pad != NULL )";
1980   z[lc++]="	{";
1981   z[lc++]="		pad = pad->pad_Next;";
1982   z[lc++]="		numDevices++;";
1983   z[lc++]="	}";
1984   z[lc++]="	";
1985   z[lc++]="	return numDevices;";
1986   z[lc++]="}";
1987   z[lc++]="";
1988   z[lc++]="static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id )";
1989   z[lc++]="{";
1990   z[lc++]="	internalPortAudioDevice *pad;";
1991   z[lc++]="	if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;";
1992   z[lc++]="	pad = sDeviceList;";
get_vacopt_ternary_value(DefElem * def)1993   z[lc++]="	while( id > 0 )";
1994   z[lc++]="	{";
1995   z[lc++]="		pad = pad->pad_Next;";
1996   z[lc++]="		id--;";
1997   z[lc++]="	}";
1998   z[lc++]="	return pad;";
1999   z[lc++]="}";
2000   z[lc++]="";
2001   z[lc++]="/*************************************************************************/";
2002   z[lc++]="const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )";
2003   z[lc++]="{";
2004   z[lc++]="	internalPortAudioDevice *pad;";
2005   z[lc++]="	if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;";
2006   z[lc++]="	pad = Pa_GetInternalDevice( id );";
2007   z[lc++]="	return  &pad->pad_Info ;";
2008   z[lc++]="}";
2009   z[lc++]="";
2010   z[lc++]="static PaError Pa_MaybeQueryDevices( void )";
2011   z[lc++]="{";
2012   z[lc++]="	if( sDeviceList == NULL )";
2013   z[lc++]="	{";
2014   z[lc++]="		return Pa_QueryDevices();";
2015   z[lc++]="	}";
2016   z[lc++]="	return 0;";
2017   z[lc++]="}";
2018   z[lc++]="";
2019   z[lc++]="PaDeviceID Pa_GetDefaultInputDeviceID( void )";
2020   z[lc++]="{";
2021   z[lc++]="	/* return paNoDevice; */";
2022   z[lc++]="	return 0;";
2023   z[lc++]="}";
2024   z[lc++]="";
2025   z[lc++]="PaDeviceID Pa_GetDefaultOutputDeviceID( void )";
2026   z[lc++]="{";
2027   z[lc++]="	return 0;";
2028   z[lc++]="}";
2029   z[lc++]="";
2030   z[lc++]="/**********************************************************************";
2031   z[lc++]="** Make sure that we have queried the device capabilities.";
2032   z[lc++]="*/";
2033   z[lc++]="";
2034   z[lc++]="PaError PaHost_Init( void )";
2035   z[lc++]="{";
2036   z[lc++]="	return Pa_MaybeQueryDevices();";
2037   z[lc++]="}";
2038   z[lc++]="";
2039   z[lc++]="/*******************************************************************************************/";
2040   z[lc++]="static PaError Pa_AudioThreadProc( internalPortAudioStream   *past )";
2041   z[lc++]="{";
2042   z[lc++]="	PaError				result = 0;";
2043   z[lc++]="	PaHostSoundControl             *pahsc;";
2044   z[lc++]=" 	short				bytes_read = 0;";
2045   z[lc++]=" ";
2046   z[lc++]="#ifdef GNUSTEP";
2047   z[lc++]="	GSRegisterCurrentThread(); /* SB20010904 */";
2048   z[lc++]="#endif";
2049   z[lc++]="	";
2050   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
2051   z[lc++]="	if( pahsc == NULL ) return paInternalError;";
2052   z[lc++]="";
2053   z[lc++]="	past->past_IsActive = 1;";
2054   z[lc++]="	DBUG((\"entering thread.\\n\"));";
2055   z[lc++]="	";
2056   z[lc++]="	while( (past->past_StopNow == 0) && (past->past_StopSoon == 0) )";
2057   z[lc++]="	{";
2058   z[lc++]="";
2059   z[lc++]="		DBUG((\"go!\\n\"));";
2060   z[lc++]="	/* Read data from device */";
2061   z[lc++]="		if(pahsc->pahsc_NativeInputBuffer)";
2062   z[lc++]="		{";
2063   z[lc++]="	           	bytes_read = read(pahsc->pahsc_InputHandle,";
2064   z[lc++]="				(void *)pahsc->pahsc_NativeInputBuffer,";
2065   z[lc++]="				pahsc->pahsc_BytesPerInputBuffer);  ";
2066   z[lc++]="            	";
2067   z[lc++]="			DBUG((\"bytes_read: %d\\n\", bytes_read));";
2068   z[lc++]="		}";
2069   z[lc++]="	";
2070   z[lc++]="	/* Convert 16 bit native data to user data and call user routine. */";
2071   z[lc++]="		DBUG((\"converting...\\n\"));";
2072   z[lc++]="		Pa_StartUsageCalculation( past );";
2073   z[lc++]="		result = Pa_CallConvertInt16( past,";
2074   z[lc++]="				pahsc->pahsc_NativeInputBuffer,";
2075   z[lc++]="				pahsc->pahsc_NativeOutputBuffer );";
2076   z[lc++]="		Pa_EndUsageCalculation( past );";
2077   z[lc++]="		if( result != 0) ";
2078   z[lc++]="		{";
2079   z[lc++]="			DBUG((\"hmm, Pa_CallConvertInt16() says: %d. i'm bailing.\\n\",";
2080   z[lc++]="				result));";
2081   z[lc++]="			break;";
2082   z[lc++]="		}";
2083   z[lc++]="";
2084   z[lc++]="	/* Write data to device. */";
2085   z[lc++]="		if( pahsc->pahsc_NativeOutputBuffer )";
2086   z[lc++]="		{";
2087   z[lc++]="";
2088   z[lc++]="            		write(pahsc->pahsc_OutputHandle,";
2089   z[lc++]="				(void *)pahsc->pahsc_NativeOutputBuffer,";
2090   z[lc++]="            			pahsc->pahsc_BytesPerOutputBuffer);  	";
2091   z[lc++]="		}";
2092   z[lc++]="	}";
2093   z[lc++]="";
2094   z[lc++]="	past->past_IsActive = 0;";
2095   z[lc++]="	DBUG((\"leaving thread.\\n\"));";
2096   z[lc++]="	";
2097   z[lc++]="#ifdef GNUSTEP";
2098   z[lc++]="	GSUnregisterCurrentThread();  /* SB20010904 */";
2099   z[lc++]="#endif";
2100   z[lc++]="	return 0;";
2101   z[lc++]="}";
2102   z[lc++]="";
2103   z[lc++]="/*******************************************************************************************/";
2104   z[lc++]="static PaError Pa_SetupDeviceFormat( int devHandle, int numChannels, int sampleRate )";
2105   z[lc++]="{";
2106   z[lc++]="	PaError result = paNoError;";
2107   z[lc++]="	int     tmp;";
2108   z[lc++]="";
2109   z[lc++]="/* Set format, channels, and rate in this order to keep OSS happy. */";
2110   z[lc++]="/* Set data format. FIXME - handle more native formats. */";
2111   z[lc++]="	tmp = AFMT_S16_NE;		";
2112   z[lc++]="	if( ioctl(devHandle,SNDCTL_DSP_SETFMT,&tmp) == -1)";
2113   z[lc++]="	{";
2114   z[lc++]="		ERR_RPT((\"Pa_SetupDeviceFormat: could not SNDCTL_DSP_SETFMT\\n\" ));";
2115   z[lc++]="		return paHostError;";
2116   z[lc++]="	}";
2117   z[lc++]="	if( tmp != AFMT_S16_NE)";
2118   z[lc++]="	{";
2119   z[lc++]="		ERR_RPT((\"Pa_SetupDeviceFormat: HW does not support AFMT_S16_NE\\n\" ));";
2120   z[lc++]="		return paHostError;";
2121   z[lc++]="	}";
2122   z[lc++]="	";
2123   z[lc++]="";
2124   z[lc++]="/* Set number of channels. */";
2125   z[lc++]="	tmp = numChannels;";
2126   z[lc++]="	if (ioctl(devHandle, SNDCTL_DSP_CHANNELS, &numChannels) == -1)";
2127   z[lc++]="	{";
2128   z[lc++]="		ERR_RPT((\"Pa_SetupDeviceFormat: could not SNDCTL_DSP_CHANNELS\\n\" ));";
2129   z[lc++]="		return paHostError;";
2130   z[lc++]="	}";
2131   z[lc++]="	if( tmp != numChannels)";
2132   z[lc++]="	{";
2133   z[lc++]="		ERR_RPT((\"Pa_SetupDeviceFormat: HW does not support %d channels\\n\", numChannels ));";
2134   z[lc++]="		return paHostError;";
2135   z[lc++]="	}";
2136   z[lc++]="	";
2137   z[lc++]="/* Set playing frequency. 44100, 22050 and 11025 are safe bets. */";
2138   z[lc++]="	tmp = sampleRate;";
2139   z[lc++]=" 	if( ioctl(devHandle,SNDCTL_DSP_SPEED,&tmp) == -1)";
2140   z[lc++]=" 	{";
2141   z[lc++]="		ERR_RPT((\"Pa_SetupDeviceFormat: could not SNDCTL_DSP_SPEED\\n\" ));";
2142   z[lc++]="		return paHostError;";
2143   z[lc++]="	}";
2144   z[lc++]="	if( tmp != sampleRate)";
2145   z[lc++]="	{";
2146   z[lc++]="		ERR_RPT((\"Pa_SetupDeviceFormat: HW does not support %d Hz sample rate\\n\",sampleRate ));";
2147   z[lc++]="		return paHostError;";
2148   z[lc++]="	}";
2149   z[lc++]="	";
2150   z[lc++]="	return result;";
2151   z[lc++]="}		";
2152   z[lc++]="";
2153   z[lc++]="static int CalcHigherLogTwo( int n )";
2154   z[lc++]="{";
2155   z[lc++]="	int log2 = 0;";
2156   z[lc++]="	while( (1<<log2) < n ) log2++;";
2157   z[lc++]="	return log2;";
2158   z[lc++]="}";
2159   z[lc++]="";
2160   z[lc++]="/*******************************************************************************************";
2161   z[lc++]="** Set number of fragments and size of fragments to achieve desired latency.";
2162   z[lc++]="*/";
2163   z[lc++]="static void Pa_SetLatency( int devHandle, int numBuffers, int framesPerBuffer, int channelsPerFrame  )";
2164   z[lc++]="{";
2165   z[lc++]="	int     tmp;";
2166   z[lc++]="	int     numFrames , bufferSize, powerOfTwo;";
2167   z[lc++]="";
2168   z[lc++]="/* Increase size of buffers and reduce number of buffers to reduce latency inside driver. */";
2169   z[lc++]="	while( numBuffers > 8 )";
2170   z[lc++]="	{";
2171   z[lc++]="		numBuffers = (numBuffers + 1) >> 1;";
2172   z[lc++]="		framesPerBuffer = framesPerBuffer << 1;";
2173   z[lc++]="	}";
2174   z[lc++]="	";
2175   z[lc++]="/* calculate size of buffers in bytes */";
2176   z[lc++]="	bufferSize = framesPerBuffer * channelsPerFrame * sizeof(short); /* FIXME */";
2177   z[lc++]="	";
2178   z[lc++]="/* Calculate next largest power of two */";
2179   z[lc++]="	powerOfTwo = CalcHigherLogTwo( bufferSize );";
2180   z[lc++]="	DBUG((\"Pa_SetLatency: numBuffers = %d, framesPerBuffer = %d, powerOfTwo = %d\\n\",";
2181   z[lc++]="		numBuffers, framesPerBuffer, powerOfTwo ));";
2182   z[lc++]="";
2183   z[lc++]="/* Encode info into a single int */";
2184   z[lc++]="	tmp=(numBuffers<<16) + powerOfTwo;";
2185   z[lc++]="	";
2186   z[lc++]="	if(ioctl(devHandle,SNDCTL_DSP_SETFRAGMENT,&tmp) == -1)";
2187   z[lc++]="	{";
2188   z[lc++]="		ERR_RPT((\"Pa_SetLatency: could not SNDCTL_DSP_SETFRAGMENT\\n\" ));";
2189   z[lc++]="		/* Don't return an error. Best to just continue and hope for the best. */";
2190   z[lc++]="		ERR_RPT((\"Pa_SetLatency: numBuffers = %d, framesPerBuffer = %d, powerOfTwo = %d\\n\",";
2191   z[lc++]="			numBuffers, framesPerBuffer, powerOfTwo ));";
2192   z[lc++]="	}";
2193   z[lc++]="}";
2194   z[lc++]="";
2195   z[lc++]="/*************************************************************************";
2196   z[lc++]="** Determine minimum number of buffers required for this host based";
2197   z[lc++]="** on minimum latency. Latency can be optionally set by user by setting";
2198   z[lc++]="** an environment variable. For example, to set latency to 200 msec, put:";
2199   z[lc++]="**";
2200   z[lc++]="**    set PA_MIN_LATENCY_MSEC=200";
2201   z[lc++]="**";
2202   z[lc++]="** in the cshrc file.";
2203   z[lc++]="*/";
2204   z[lc++]="#define PA_LATENCY_ENV_NAME  (\"PA_MIN_LATENCY_MSEC\")";
2205   z[lc++]="";
2206   z[lc++]="int Pa_GetMinNumBuffers( int framesPerBuffer, double framesPerSecond )";
2207   z[lc++]="{";
2208   z[lc++]="	int minBuffers;";
2209   z[lc++]="	int minLatencyMsec = MIN_LATENCY_MSEC;";
2210   z[lc++]="	char *minLatencyText = getenv(PA_LATENCY_ENV_NAME);";
2211   z[lc++]="	if( minLatencyText != NULL )";
2212   z[lc++]="	{";
2213   z[lc++]="		PRINT((\"PA_MIN_LATENCY_MSEC = %s\\n\", minLatencyText ));";
2214   z[lc++]="		minLatencyMsec = atoi( minLatencyText );";
2215   z[lc++]="		if( minLatencyMsec < 1 ) minLatencyMsec = 1;";
2216   z[lc++]="		else if( minLatencyMsec > 5000 ) minLatencyMsec = 5000;";
2217   z[lc++]="	}";
2218   z[lc++]="	";
2219   z[lc++]="	minBuffers = (int) ((minLatencyMsec * framesPerSecond) / ( 1000.0 * framesPerBuffer ));";
2220   z[lc++]="	if( minBuffers < 2 ) minBuffers = 2;";
2221   z[lc++]="	return minBuffers;";
2222   z[lc++]="}";
2223   z[lc++]="";
2224   z[lc++]="/*******************************************************************/";
2225   z[lc++]="PaError PaHost_OpenStream( internalPortAudioStream   *past )";
2226   z[lc++]="{";
2227   z[lc++]="	PaError          result = paNoError;";
2228   z[lc++]="	PaHostSoundControl *pahsc;";
2229   z[lc++]="	int tmp;";
2230   z[lc++]="	int flags;";
2231   z[lc++]="	int              numBytes, maxChannels;";
2232   z[lc++]="	unsigned int     minNumBuffers;";
2233   z[lc++]="	internalPortAudioDevice *pad;";
2234   z[lc++]="	DBUG((\"PaHost_OpenStream() called.\\n\" ));";
2235   z[lc++]="";
2236   z[lc++]="/* Allocate and initialize host data. */";
2237   z[lc++]="	pahsc = (PaHostSoundControl *) malloc(sizeof(PaHostSoundControl));";
2238   z[lc++]="	if( pahsc == NULL )";
2239   z[lc++]="	{";
2240   z[lc++]="		result = paInsufficientMemory;";
2241   z[lc++]="		goto error;";
2242   z[lc++]="	}";
2243   z[lc++]="	memset( pahsc, 0, sizeof(PaHostSoundControl) );";
2244   z[lc++]="	past->past_DeviceData = (void *) pahsc;";
2245   z[lc++]="";
2246   z[lc++]="	pahsc->pahsc_OutputHandle = BAD_DEVICE_ID; /* No device currently opened. */";
2247   z[lc++]="	pahsc->pahsc_InputHandle = BAD_DEVICE_ID;";
2248   z[lc++]="	";
2249   z[lc++]="/* Allocate native buffers. */";
2250   z[lc++]="	pahsc->pahsc_BytesPerInputBuffer = past->past_FramesPerUserBuffer *";
2251   z[lc++]="		past->past_NumInputChannels * sizeof(short);";
2252   z[lc++]="	if( past->past_NumInputChannels > 0)";
2253   z[lc++]="	{";
2254   z[lc++]="		pahsc->pahsc_NativeInputBuffer = (short *) malloc(pahsc->pahsc_BytesPerInputBuffer);";
2255   z[lc++]="		if( pahsc->pahsc_NativeInputBuffer == NULL )";
2256   z[lc++]="		{";
2257   z[lc++]="			result = paInsufficientMemory;";
2258   z[lc++]="			goto error;";
2259   z[lc++]="		}";
2260   z[lc++]="	}";
2261   z[lc++]="	pahsc->pahsc_BytesPerOutputBuffer = past->past_FramesPerUserBuffer *";
2262   z[lc++]="		past->past_NumOutputChannels * sizeof(short);";
2263   z[lc++]="	if( past->past_NumOutputChannels > 0)";
2264   z[lc++]="	{";
2265   z[lc++]="		pahsc->pahsc_NativeOutputBuffer = (short *) malloc(pahsc->pahsc_BytesPerOutputBuffer);";
2266   z[lc++]="		if( pahsc->pahsc_NativeOutputBuffer == NULL )";
2267   z[lc++]="		{";
2268   z[lc++]="			result = paInsufficientMemory;";
2269   z[lc++]="			goto error;";
2270   z[lc++]="		}";
2271   z[lc++]="	}";
2272   z[lc++]="	";
2273   z[lc++]="	/* DBUG((\"PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\\n\", pahsc->pahsc_MinFramesPerHostBuffer )); */";
2274   z[lc++]="	minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );";
2275   z[lc++]="	past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;";
2276   z[lc++]="";
2277   z[lc++]="	pahsc->pahsc_InverseMicrosPerBuffer = past->past_SampleRate / (1000000.0 * past->past_FramesPerUserBuffer);";
2278   z[lc++]="	DBUG((\"pahsc_InverseMicrosPerBuffer = %g\\n\", pahsc->pahsc_InverseMicrosPerBuffer ));";
2279   z[lc++]="	";
2280   z[lc++]="/* ------------------------- OPEN DEVICE -----------------------*/";
2281   z[lc++]="	    ";
2282   z[lc++]="	/* just output */";
2283   z[lc++]="	if (past->past_OutputDeviceID == past->past_InputDeviceID)";
2284   z[lc++]="	{";
2285   z[lc++]="	";
2286   z[lc++]="		if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0) )";
2287   z[lc++]="		{";
2288   z[lc++]="			pad = Pa_GetInternalDevice( past->past_OutputDeviceID );";
2289   z[lc++]="			DBUG((\"PaHost_OpenStream: attempt to open %s for O_RDWR\\n\", pad->pad_DeviceName ));";
2290   z[lc++]="			pahsc->pahsc_OutputHandle = pahsc->pahsc_InputHandle =";
2291   z[lc++]="				open(pad->pad_DeviceName,O_RDWR); ";
2292   z[lc++]="			if(pahsc->pahsc_InputHandle==-1)";
2293   z[lc++]="			{";
2294   z[lc++]="				ERR_RPT((\"PaHost_OpenStream: could not open %s for O_RDWR\\n\", pad->pad_DeviceName ));";
2295   z[lc++]="				result = paHostError;";
2296   z[lc++]="				goto error;";
2297   z[lc++]="			} ";
2298   z[lc++]="			Pa_SetLatency( pahsc->pahsc_OutputHandle,";
2299   z[lc++]="				past->past_NumUserBuffers, past->past_FramesPerUserBuffer,";
2300   z[lc++]="				past->past_NumOutputChannels );";
2301   z[lc++]="			result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle,";
2302   z[lc++]="				past->past_NumOutputChannels, (int)past->past_SampleRate );";
2303   z[lc++]="		}";
2304   z[lc++]="	}";
2305   z[lc++]="	else";
2306   z[lc++]="	{";
2307   z[lc++]="		if (past->past_NumOutputChannels > 0)";
2308   z[lc++]="		{	    ";
2309   z[lc++]="			pad = Pa_GetInternalDevice( past->past_OutputDeviceID );";
2310   z[lc++]="			DBUG((\"PaHost_OpenStream: attempt to open %s for O_WRONLY\\n\", pad->pad_DeviceName ));";
2311   z[lc++]="			pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY); ";
2312   z[lc++]="			if(pahsc->pahsc_OutputHandle==-1)";
2313   z[lc++]="			{";
2314   z[lc++]="				ERR_RPT((\"PaHost_OpenStream: could not open %s for O_WRONLY\\n\", pad->pad_DeviceName ));";
2315   z[lc++]="				result = paHostError;";
2316   z[lc++]="				goto error;";
2317   z[lc++]="			} ";
2318   z[lc++]="			Pa_SetLatency( pahsc->pahsc_OutputHandle,";
2319   z[lc++]="				past->past_NumUserBuffers, past->past_FramesPerUserBuffer,";
2320   z[lc++]="				past->past_NumOutputChannels );";
2321   z[lc++]="			result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle,";
2322   z[lc++]="				past->past_NumOutputChannels, (int)past->past_SampleRate );";
2323   z[lc++]="		}";
2324   z[lc++]="";
2325   z[lc++]="		if (past->past_NumInputChannels > 0)";
2326   z[lc++]="		{	    ";
2327   z[lc++]="			pad = Pa_GetInternalDevice( past->past_InputDeviceID );";
2328   z[lc++]="			DBUG((\"PaHost_OpenStream: attempt to open %s for O_RDONLY\\n\", pad->pad_DeviceName ));";
2329   z[lc++]="			pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY); ";
2330   z[lc++]="			if(pahsc->pahsc_InputHandle==-1)";
2331   z[lc++]="			{";
2332   z[lc++]="				ERR_RPT((\"PaHost_OpenStream: could not open %s for O_RDONLY\\n\", pad->pad_DeviceName ));";
2333   z[lc++]="				result = paHostError;";
2334   z[lc++]="				goto error;";
2335   z[lc++]="			} ";
2336   z[lc++]="			Pa_SetLatency( pahsc->pahsc_OutputHandle,";
2337   z[lc++]="				past->past_NumUserBuffers, past->past_FramesPerUserBuffer,";
2338   z[lc++]="				past->past_NumInputChannels );";
2339   z[lc++]="			result = Pa_SetupDeviceFormat( pahsc->pahsc_InputHandle,";
2340   z[lc++]="				past->past_NumInputChannels, (int)past->past_SampleRate );";
2341   z[lc++]="		}";
2342   z[lc++]="	}";
2343   z[lc++]=" 		";
2344   z[lc++]=" ";
2345   z[lc++]="	DBUG((\"PaHost_OpenStream: SUCCESS - result = %d\\n\", result ));";
2346   z[lc++]="	return result;";
2347   z[lc++]="	";
2348   z[lc++]="error:";
2349   z[lc++]="	ERR_RPT((\"PaHost_OpenStream: ERROR - result = %d\\n\", result ));";
2350   z[lc++]="	PaHost_CloseStream( past );";
2351   z[lc++]="	return result;";
2352   z[lc++]="}";
2353   z[lc++]="";
2354   z[lc++]="/*************************************************************************/";
2355   z[lc++]="PaError PaHost_StartOutput( internalPortAudioStream *past )";
2356   z[lc++]="{";
2357   z[lc++]="	return paNoError;";
2358   z[lc++]="}";
2359   z[lc++]="";
2360   z[lc++]="/*************************************************************************/";
2361   z[lc++]="PaError PaHost_StartInput( internalPortAudioStream *past )";
2362   z[lc++]="{";
2363   z[lc++]="	return paNoError;";
2364   z[lc++]="}";
2365   z[lc++]="";
2366   z[lc++]="/*************************************************************************/";
2367   z[lc++]="PaError PaHost_StartEngine( internalPortAudioStream *past )";
2368   z[lc++]="{";
2369   z[lc++]="	PaHostSoundControl *pahsc;";
2370   z[lc++]="	PaError             result = paNoError;";
2371   z[lc++]="	int                 hres;";
2372   z[lc++]="	";
2373   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
2374   z[lc++]="";
2375   z[lc++]="	past->past_StopSoon = 0;";
2376   z[lc++]="	past->past_StopNow = 0;";
2377   z[lc++]="        past->past_IsActive = 1; ";
2378   z[lc++]="";
2379   z[lc++]="/* Use pthread_create() instead of __clone() because:";
2380   z[lc++]=" *   - pthread_create also works for other UNIX systems like Solaris,";
2381   z[lc++]=" *   - the Java HotSpot VM crashes in pthread_setcanceltype() when using __clone()";
2382   z[lc++]=" */";
2383   z[lc++]="	hres = pthread_create(&(pahsc->pahsc_ThreadPID),";
2384   z[lc++]="		NULL /*pthread_attr_t * attr*/,";
2385   z[lc++]="		(void*)Pa_AudioThreadProc, past);";
2386   z[lc++]="	if( hres != 0 )";
2387   z[lc++]="	{";
2388   z[lc++]="		result = paHostError;";
2389   z[lc++]="		sPaHostError = hres;";
2390   z[lc++]="		goto error;";
2391   z[lc++]="	}";
2392   z[lc++]="";
2393   z[lc++]="error:";
2394   z[lc++]="	return result;";
2395   z[lc++]="}";
2396   z[lc++]="";
2397   z[lc++]="/*************************************************************************/";
2398   z[lc++]="PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )";
2399   z[lc++]="{";
2400   z[lc++]="	int                 hres;";
2401   z[lc++]="	long                timeOut;";
2402   z[lc++]="	PaError             result = paNoError;";
2403   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
2404   z[lc++]="	";
2405   z[lc++]="	if( pahsc == NULL ) return paNoError;";
2406   z[lc++]=" ";
2407   z[lc++]="/* Tell background thread to stop generating more data and to let current data play out. */";
2408   z[lc++]="        past->past_StopSoon = 1;";
2409   z[lc++]="/* If aborting, tell background thread to stop NOW! */";
2410   z[lc++]="        if( abort ) past->past_StopNow = 1;";
2411   z[lc++]="";
2412   z[lc++]="/* Join thread to recover memory resources. */";
2413   z[lc++]="	if( pahsc->pahsc_ThreadPID != -1 )";
2414   z[lc++]="	{";
2415   z[lc++]="	/* This check is needed for GNUSTEP - SB20010904 */";
2416   z[lc++]="		if ( !pthread_equal( pahsc->pahsc_ThreadPID, pthread_self() ) )";
2417   z[lc++]="		{";
2418   z[lc++]="			hres = pthread_join( pahsc->pahsc_ThreadPID, NULL );";
2419   z[lc++]="		}";
2420   z[lc++]="		else {";
2421   z[lc++]="			DBUG((\"Play thread was stopped from itself - can't do pthread_join()\\n\"));";
2422   z[lc++]="			hres = 0;";
2423   z[lc++]="		}";
2424   z[lc++]="";
2425   z[lc++]="		if( hres != 0 )";
2426   z[lc++]="		{";
2427   z[lc++]="			result = paHostError;";
2428   z[lc++]="			sPaHostError = hres;";
2429   z[lc++]="		}";
2430   z[lc++]="		pahsc->pahsc_ThreadPID = -1;";
2431   z[lc++]="	}";
2432   z[lc++]="	";
2433   z[lc++]="        past->past_IsActive = 0;      ";
2434   z[lc++]="";
2435   z[lc++]="	return result;";
2436   z[lc++]="}";
2437   z[lc++]="";
2438   z[lc++]="/*************************************************************************/";
2439   z[lc++]="PaError PaHost_StopInput( internalPortAudioStream *past, int abort )";
2440   z[lc++]="{";
2441   z[lc++]="	return paNoError;";
2442   z[lc++]="}";
2443   z[lc++]="";
2444   z[lc++]="/*************************************************************************/";
2445   z[lc++]="PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )";
2446   z[lc++]="{";
2447   z[lc++]="	return paNoError;";
2448   z[lc++]="}";
2449   z[lc++]="";
2450   z[lc++]="/*******************************************************************/";
2451   z[lc++]="PaError PaHost_CloseStream( internalPortAudioStream   *past )";
2452   z[lc++]="{";
2453   z[lc++]="	PaHostSoundControl *pahsc;";
2454   z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
2455   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
2456   z[lc++]="	if( pahsc == NULL ) return paNoError;";
2457   z[lc++]="";
2458   z[lc++]="	if( pahsc->pahsc_OutputHandle != BAD_DEVICE_ID )";
2459   z[lc++]="	{";
2460   z[lc++]="		int err;";
2461   z[lc++]="		DBUG((\"PaHost_CloseStream: attempt to close output device handle = %d\\n\",";
2462   z[lc++]="			pahsc->pahsc_OutputHandle ));";
2463   z[lc++]="		err = close(pahsc->pahsc_OutputHandle);";
2464   z[lc++]="		if( err < 0 )";
2465   z[lc++]="		{";
2466   z[lc++]="			ERR_RPT((\"PaHost_CloseStream: warning, closing output device failed.\\n\"));";
2467   z[lc++]="		}";
2468   z[lc++]="	}";
2469   z[lc++]="	";
2470   z[lc++]="	if( (pahsc->pahsc_InputHandle != BAD_DEVICE_ID) &&";
2471   z[lc++]="	    (pahsc->pahsc_InputHandle != pahsc->pahsc_OutputHandle) )";
2472   z[lc++]="	{";
2473   z[lc++]="		int err;";
2474   z[lc++]="		DBUG((\"PaHost_CloseStream: attempt to close input device handle = %d\\n\",";
2475   z[lc++]="			pahsc->pahsc_InputHandle ));";
2476   z[lc++]="		err = close(pahsc->pahsc_InputHandle);";
2477   z[lc++]="		if( err < 0 )";
2478   z[lc++]="		{";
2479   z[lc++]="			ERR_RPT((\"PaHost_CloseStream: warning, closing input device failed.\\n\"));";
2480   z[lc++]="		}";
2481   z[lc++]="	}";
2482   z[lc++]="	pahsc->pahsc_OutputHandle = BAD_DEVICE_ID;";
2483   z[lc++]="	pahsc->pahsc_InputHandle = BAD_DEVICE_ID;";
2484   z[lc++]="	";
2485   z[lc++]="	if( pahsc->pahsc_NativeInputBuffer )";
2486   z[lc++]="	{";
2487   z[lc++]="		free( pahsc->pahsc_NativeInputBuffer );";
2488   z[lc++]="		pahsc->pahsc_NativeInputBuffer = NULL;";
2489   z[lc++]="	}";
2490   z[lc++]="	if( pahsc->pahsc_NativeOutputBuffer )";
2491   z[lc++]="	{";
2492   z[lc++]="		free( pahsc->pahsc_NativeOutputBuffer );";
2493   z[lc++]="		pahsc->pahsc_NativeOutputBuffer = NULL;";
2494   z[lc++]="	}";
2495   z[lc++]="";
2496   z[lc++]="	free( pahsc );";
2497   z[lc++]="	past->past_DeviceData = NULL;";
2498   z[lc++]="	return paNoError;";
2499   z[lc++]="}";
2500   z[lc++]="";
2501   z[lc++]="/*************************************************************************/";
2502   z[lc++]="PaError PaHost_Term( void )";
2503   z[lc++]="{";
2504   z[lc++]="/* Free all of the linked devices. */";
2505   z[lc++]="	internalPortAudioDevice *pad, *nextPad;";
2506   z[lc++]="	pad = sDeviceList;";
2507   z[lc++]="	while( pad != NULL )";
2508   z[lc++]="	{";
2509   z[lc++]="		nextPad = pad->pad_Next;";
2510   z[lc++]="		DBUG((\"PaHost_Term: freeing %s\\n\", pad->pad_DeviceName ));";
2511   z[lc++]="		PaHost_FreeFastMemory( pad, sizeof(internalPortAudioDevice) );";
2512   z[lc++]="		pad = nextPad;";
2513   z[lc++]="	}";
2514   z[lc++]="	sDeviceList = NULL;";
2515   z[lc++]="	return 0;";
2516   z[lc++]="}";
2517   z[lc++]="";
2518   z[lc++]="/*************************************************************************";
2519   z[lc++]=" * Sleep for the requested number of milliseconds.";
2520   z[lc++]=" */";
2521   z[lc++]="void Pa_Sleep( long msec )";
2522   z[lc++]="{";
2523   z[lc++]="#if 0";
2524   z[lc++]="	struct timeval timeout;";
2525   z[lc++]="	timeout.tv_sec = msec / 1000;";
2526   z[lc++]="	timeout.tv_usec = (msec % 1000) * 1000;";
2527   z[lc++]="	select( 0, NULL, NULL, NULL, &timeout );";
2528   z[lc++]="#else";
2529   z[lc++]="	long usecs = msec * 1000;";
2530   z[lc++]="	usleep( usecs );";
2531   z[lc++]="#endif";
2532   z[lc++]="}";
2533   z[lc++]="";
2534   z[lc++]="/*************************************************************************";
2535   z[lc++]=" * Allocate memory that can be accessed in real-time.";
2536   z[lc++]=" * This may need to be held in physical memory so that it is not";
2537   z[lc++]=" * paged to virtual memory.";
2538   z[lc++]=" * This call MUST be balanced with a call to PaHost_FreeFastMemory().";
2539   z[lc++]=" */";
2540   z[lc++]="void *PaHost_AllocateFastMemory( long numBytes )";
2541   z[lc++]="{";
2542   z[lc++]="	void *addr = malloc( numBytes ); /* FIXME - do we need physical memory? */";
2543   z[lc++]="	if( addr != NULL ) memset( addr, 0, numBytes );";
2544   z[lc++]="	return addr;";
2545   z[lc++]="}";
2546   z[lc++]="";
2547   z[lc++]="/*************************************************************************";
2548   z[lc++]=" * Free memory that could be accessed in real-time.";
2549   z[lc++]=" * This call MUST be balanced with a call to PaHost_AllocateFastMemory().";
2550   z[lc++]=" */";
2551   z[lc++]="void PaHost_FreeFastMemory( void *addr, long numBytes )";
2552   z[lc++]="{";
2553   z[lc++]="	if( addr != NULL ) free( addr );";
2554   z[lc++]="}";
2555   z[lc++]="";
2556   z[lc++]="";
2557   z[lc++]="/***********************************************************************/";
2558   z[lc++]="PaError PaHost_StreamActive( internalPortAudioStream   *past )";
2559   z[lc++]="{";
2560   z[lc++]="	PaHostSoundControl *pahsc;";
2561   z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
2562   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
2563   z[lc++]="	if( pahsc == NULL ) return paInternalError;";
2564   z[lc++]="	return (PaError) (past->past_IsActive != 0);";
2565   z[lc++]="}";
2566   z[lc++]="";
2567   z[lc++]="/***********************************************************************/";
2568   z[lc++]="PaTimestamp Pa_StreamTime( PortAudioStream *stream )";
2569   z[lc++]="{";
2570   z[lc++]="	internalPortAudioStream *past = (internalPortAudioStream *) stream; ";
2571   z[lc++]="/* FIXME - return actual frames played, not frames generated.";
2572   z[lc++]="** Need to query the output device somehow.";
2573   z[lc++]="*/";
2574   z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
2575   z[lc++]="	return past->past_FrameCount;";
2576   z[lc++]="}";
2577   z[lc++]="";
2578   z[lc++]="/***********************************************************************/";
2579   z[lc++]="long Pa_GetHostError( void )";
2580   z[lc++]="{";
2581   z[lc++]="	return (long) sPaHostError;";
2582   z[lc++]="}";
2583   printlib(lc);
2584 }
2585 
2586 
2587 void makepa_win_wmme(void)
2588 {
2589   int lc = 0;
2590 
2591   z[lc++]="/*";
2592   z[lc++]=" * pa_win_wmme.c";
2593   z[lc++]=" * Implementation of PortAudio for Windows MultiMedia Extensions (WMME)";
2594   z[lc++]=" *";
2595   z[lc++]=" * PortAudio Portable Real-Time Audio Library";
2596   z[lc++]=" * Latest Version at: http://www.portaudio.com";
2597   z[lc++]=" *";
2598   z[lc++]=" * Authors: Ross Bencina and Phil Burk";
2599   z[lc++]=" * Copyright (c) 1999-2000 Ross Bencina and Phil Burk";
2600   z[lc++]=" *";
2601   z[lc++]=" * Permission is hereby granted, free of charge, to any person obtainingF";
2602   z[lc++]=" * a copy of this software and associated documentation files";
2603   z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
2604   z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
2605   z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
2606   z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
2607   z[lc++]=" * subject to the following conditions:";
2608   z[lc++]=" *";
2609   z[lc++]=" * The above copyright notice and this permission notice shall be";
2610   z[lc++]=" * included in all copies or substantial portions of the Software.";
2611   z[lc++]=" *";
2612   z[lc++]=" * Any person wishing to distribute modifications to the Software is";
2613   z[lc++]=" * requested to send the modifications to the original developer so that";
2614   z[lc++]=" * they can be incorporated into the canonical version.";
2615   z[lc++]=" *";
2616   z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
2617   z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
2618   z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
2619   z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
2620   z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
2621   z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
2622   z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
2623   z[lc++]=" *";
2624   z[lc++]=" */";
2625   z[lc++]="/*";
2626   z[lc++]="  All memory allocations and frees are marked with MEM for quick review.";
2627   z[lc++]="*/";
2628   z[lc++]="/* Modification History:";
2629   z[lc++]=" PLB = Phil Burk";
2630   z[lc++]=" PLB20010402 - sDevicePtrs now allocates based on sizeof(pointer)";
2631   z[lc++]=" PLB20010413 - check for excessive numbers of channels";
2632   z[lc++]=" PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC";
2633   z[lc++]="               including condition including of memory.h,";
2634   z[lc++]="			   and explicit typecasting on memory allocation";
2635   z[lc++]=" PLB20010802 - use GlobalAlloc for sDevicesPtr instead of PaHost_AllocFastMemory";
2636   z[lc++]=" PLB20010816 - pass process instead of thread to SetPriorityClass()";
2637   z[lc++]=" PLB20010927 - use number of frames instead of real-time for CPULoad calculation.";
2638   z[lc++]="*/";
2639   z[lc++]="#include <stdio.h>";
2640   z[lc++]="#include <stdlib.h>";
2641   z[lc++]="#include <math.h>";
2642   z[lc++]="#include <windows.h>";
2643   z[lc++]="#include <mmsystem.h>";
2644   z[lc++]="#include <process.h>";
2645   z[lc++]="/* PLB20010422 - \"memory.h\" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */";
2646   z[lc++]="#ifndef __MWERKS__";
2647   z[lc++]="#include <malloc.h>";
2648   z[lc++]="#include <memory.h>";
2649   z[lc++]="#endif /* __MWERKS__ */";
2650   z[lc++]="";
2651   z[lc++]="#if 0";
2652   z[lc++]="#include \"portaudio.h\"";
2653   z[lc++]="#include \"pa_host.h\"";
2654   z[lc++]="#include \"pa_trace.h\"";
2655   z[lc++]="#endif";
2656   z[lc++]="";
2657   z[lc++]="/************************************************* Constants ********/";
2658   z[lc++]="#define PA_USE_TIMER_CALLBACK    (0)  /* Select between two options for background task. 0=thread, 1=timer */";
2659   z[lc++]="#define PA_USE_HIGH_LATENCY      (0)  /* For debugging glitches. */";
2660   z[lc++]="/* Switches for debugging. */";
2661   z[lc++]="#define PA_SIMULATE_UNDERFLOW    (0)  /* Set to one to force an underflow of the output buffer. */";
2662   z[lc++]="/* To trace program, enable TRACE_REALTIME_EVENTS in pa_trace.h */";
2663   z[lc++]="#define PA_TRACE_RUN             (0)";
2664   z[lc++]="#define PA_TRACE_START_STOP      (1)";
2665   z[lc++]="#if PA_USE_HIGH_LATENCY";
2666   z[lc++]="	#define PA_MIN_MSEC_PER_HOST_BUFFER  (100)";
2667   z[lc++]="	#define PA_MAX_MSEC_PER_HOST_BUFFER  (300) /* Do not exceed unless user buffer exceeds */";
2668   z[lc++]="	#define PA_MIN_NUM_HOST_BUFFERS      (4)";
2669   z[lc++]="	#define PA_MAX_NUM_HOST_BUFFERS      (16)  /* OK to exceed if necessary */";
2670   z[lc++]="	#define PA_WIN_9X_LATENCY            (400)";
2671   z[lc++]="#else";
2672   z[lc++]="	#define PA_MIN_MSEC_PER_HOST_BUFFER  (10)";
2673   z[lc++]="	#define PA_MAX_MSEC_PER_HOST_BUFFER  (100) /* Do not exceed unless user buffer exceeds */";
2674   z[lc++]="	#define PA_MIN_NUM_HOST_BUFFERS      (3)";
2675   z[lc++]="	#define PA_MAX_NUM_HOST_BUFFERS      (16)  /* OK to exceed if necessary */";
2676   z[lc++]="	#define PA_WIN_9X_LATENCY            (200)";
2677   z[lc++]="#endif";
2678   z[lc++]="#define MIN_TIMEOUT_MSEC                 (1000)";
2679   z[lc++]="/*";
2680   z[lc++]="** Use higher latency for NT because it is even worse at real-time";
2681   z[lc++]="** operation than Win9x.";
2682   z[lc++]="*/";
2683   z[lc++]="#define PA_WIN_NT_LATENCY        (PA_WIN_9X_LATENCY * 2)";
2684   z[lc++]="#if PA_SIMULATE_UNDERFLOW";
2685   z[lc++]="static  gUnderCallbackCounter = 0;";
2686   z[lc++]="#define UNDER_SLEEP_AT       (40)";
2687   z[lc++]="#define UNDER_SLEEP_FOR      (500)";
2688   z[lc++]="#endif";
2689   z[lc++]="#define PRINT(x) { printf x; fflush(stdout); }";
2690   z[lc++]="#define ERR_RPT(x) PRINT(x)";
2691   z[lc++]="#define DBUG(x)  /* PRINT(x) */";
2692   z[lc++]="#define DBUGX(x) /* PRINT(x) */";
2693   z[lc++]="/************************************************* Definitions ********/";
2694   z[lc++]="/**************************************************************";
2695   z[lc++]=" * Structure for internal host specific stream data.";
2696   z[lc++]=" * This is allocated on a per stream basis.";
2697   z[lc++]=" */";
2698   z[lc++]="typedef struct PaHostSoundControl";
2699   z[lc++]="{";
2700   z[lc++]="/* Input -------------- */";
2701   z[lc++]="    HWAVEIN            pahsc_HWaveIn;";
2702   z[lc++]="    WAVEHDR           *pahsc_InputBuffers;";
2703   z[lc++]="    int                pahsc_CurrentInputBuffer;";
2704   z[lc++]="	int                pahsc_BytesPerHostInputBuffer;";
2705   z[lc++]="	int                pahsc_BytesPerUserInputBuffer;    /* native buffer size in bytes */";
2706   z[lc++]="/* Output -------------- */    ";
2707   z[lc++]="    HWAVEOUT           pahsc_HWaveOut;";
2708   z[lc++]="    WAVEHDR           *pahsc_OutputBuffers;";
2709   z[lc++]="    int                pahsc_CurrentOutputBuffer;";
2710   z[lc++]="	int                pahsc_BytesPerHostOutputBuffer;";
2711   z[lc++]="	int                pahsc_BytesPerUserOutputBuffer;    /* native buffer size in bytes */";
2712   z[lc++]="/* Run Time -------------- */    ";
2713   z[lc++]="	PaTimestamp        pahsc_FramesPlayed;";
2714   z[lc++]="	long               pahsc_LastPosition;                /* used to track frames played. */";
2715   z[lc++]="/* For measuring CPU utilization. */";
2716   z[lc++]="	LARGE_INTEGER      pahsc_EntryCount;";
2717   z[lc++]="	double             pahsc_InverseTicksPerHostBuffer;";
2718   z[lc++]="/* Init Time -------------- */    ";
2719   z[lc++]="	int                pahsc_NumHostBuffers;";
2720   z[lc++]="	int                pahsc_FramesPerHostBuffer;";
2721   z[lc++]="	int                pahsc_UserBuffersPerHostBuffer;";
2722   z[lc++]="    CRITICAL_SECTION   pahsc_StreamLock;                  /* Mutext to prevent threads from colliding. */";
2723   z[lc++]="	INT                pahsc_StreamLockInited;";
2724   z[lc++]="#if PA_USE_TIMER_CALLBACK";
2725   z[lc++]="	BOOL               pahsc_IfInsideCallback;            /* Test for reentrancy. */";
2726   z[lc++]="	MMRESULT           pahsc_TimerID;";
2727   z[lc++]="#else";
2728   z[lc++]="    HANDLE             pahsc_AbortEvent;";
2729   z[lc++]="    int                pahsc_AbortEventInited;";
2730   z[lc++]="    HANDLE             pahsc_BufferEvent;";
2731   z[lc++]="    int                pahsc_BufferEventInited;";
2732   z[lc++]="    HANDLE             pahsc_EngineThread;";
2733   z[lc++]="    DWORD              pahsc_EngineThreadID;";
2734   z[lc++]="#endif";
2735   z[lc++]="} PaHostSoundControl;";
2736   z[lc++]="/************************************************* Shared Data ********/";
2737   z[lc++]="/* FIXME - put Mutex around this shared data. */";
2738   z[lc++]="static int sNumInputDevices = 0;";
2739   z[lc++]="static int sNumOutputDevices = 0;";
2740   z[lc++]="static int sNumDevices = 0;";
2741   z[lc++]="static PaDeviceInfo **sDevicePtrs = NULL;";
2742   z[lc++]="static int sDefaultInputDeviceID = paNoDevice;";
2743   z[lc++]="static int sDefaultOutputDeviceID = paNoDevice;";
2744   z[lc++]="static int sPaHostError = 0;";
2745   z[lc++]="static const char sMapperSuffixInput[] = \" - Input\";";
2746   z[lc++]="static const char sMapperSuffixOutput[] = \" - Output\";";
2747   z[lc++]="/************************************************* Macros ********/";
2748   z[lc++]="/* Convert external PA ID to an internal ID that includes WAVE_MAPPER */";
2749   z[lc++]="#define PaDeviceIdToWinId(id) (((id) < sNumInputDevices) ? (id - 1) : (id - sNumInputDevices - 1))";
2750   z[lc++]="/************************************************* Prototypes **********/";
2751   z[lc++]="static Pa_QueryDevices( void );";
2752   z[lc++]="static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg,";
2753   z[lc++]="									  DWORD dwUser, DWORD dw1, DWORD dw2);";
2754   z[lc++]="PaError PaHost_GetTotalBufferFrames( internalPortAudioStream   *past );";
2755   z[lc++]="static PaError PaHost_UpdateStreamTime( PaHostSoundControl *pahsc );";
2756   z[lc++]="static PaError PaHost_BackgroundManager( internalPortAudioStream   *past );";
2757   z[lc++]="/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/";
2758   z[lc++]="static void Pa_StartUsageCalculation( internalPortAudioStream   *past )";
2759   z[lc++]="{";
2760   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
2761   z[lc++]="	if( pahsc == NULL ) return;";
2762   z[lc++]="/* Query system timer for usage analysis and to prevent overuse of CPU. */";
2763   z[lc++]="	QueryPerformanceCounter( &pahsc->pahsc_EntryCount );";
2764   z[lc++]="}";
2765   z[lc++]="static void Pa_EndUsageCalculation( internalPortAudioStream   *past )";
2766   z[lc++]="{";
2767   z[lc++]="	LARGE_INTEGER CurrentCount = { 0, 0 };";
2768   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
2769   z[lc++]="	if( pahsc == NULL ) return;";
2770   z[lc++]="/*";
2771   z[lc++]="** Measure CPU utilization during this callback. Note that this calculation";
2772   z[lc++]="** assumes that we had the processor the whole time.";
2773   z[lc++]="*/";
2774   z[lc++]="#define LOWPASS_COEFFICIENT_0   (0.9)";
2775   z[lc++]="#define LOWPASS_COEFFICIENT_1   (0.99999 - LOWPASS_COEFFICIENT_0)";
2776   z[lc++]="	if( QueryPerformanceCounter( &CurrentCount ) )";
2777   z[lc++]="	{";
2778   z[lc++]="		LONGLONG InsideCount = CurrentCount.QuadPart - pahsc->pahsc_EntryCount.QuadPart;	";
2779   z[lc++]="		double newUsage = InsideCount * pahsc->pahsc_InverseTicksPerHostBuffer;";
2780   z[lc++]="		past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +";
2781   z[lc++]="			(LOWPASS_COEFFICIENT_1 * newUsage);";
2782   z[lc++]="	}";
2783   z[lc++]="}";
2784   z[lc++]="/****************************************** END CPU UTILIZATION *******/";
2785   z[lc++]="static PaError Pa_QueryDevices( void )";
2786   z[lc++]="{";
2787   z[lc++]="	int numBytes;";
2788   z[lc++]="/* Count the devices and add one extra for the WAVE_MAPPER */";
2789   z[lc++]="    sNumInputDevices = waveInGetNumDevs() + 1;";
2790   z[lc++]="	sDefaultInputDeviceID = 0;";
2791   z[lc++]="    sNumOutputDevices = waveOutGetNumDevs() + 1;";
2792   z[lc++]="	sDefaultOutputDeviceID = sNumInputDevices;";
2793   z[lc++]="    sNumDevices = sNumInputDevices + sNumOutputDevices;";
2794   z[lc++]="/* Allocate structures to hold device info. */";
2795   z[lc++]="/* PLB20010402 - was allocating too much memory. */";
2796   z[lc++]="/*	numBytes = sNumDevices * sizeof(PaDeviceInfo);  // PLB20010402 */";
2797   z[lc++]="	numBytes = sNumDevices * sizeof(PaDeviceInfo *); /* PLB20010402 */";
2798   z[lc++]="	sDevicePtrs = (PaDeviceInfo **) GlobalAlloc( GPTR, numBytes ); /* MEM */";
2799   z[lc++]="	if( sDevicePtrs == NULL ) return paInsufficientMemory;";
2800   z[lc++]="	return paNoError;";
2801   z[lc++]="}";
2802   z[lc++]="/************************************************************************************/";
2803   z[lc++]="long Pa_GetHostError()";
2804   z[lc++]="{";
2805   z[lc++]="	return sPaHostError;";
2806   z[lc++]="}";
2807   z[lc++]="/*************************************************************************/";
2808   z[lc++]="int Pa_CountDevices()";
2809   z[lc++]="{";
2810   z[lc++]="	if( sNumDevices <= 0 ) Pa_Initialize();";
2811   z[lc++]="	return sNumDevices;";
2812   z[lc++]="}";
2813   z[lc++]="/*************************************************************************";
2814   z[lc++]="** If a PaDeviceInfo structure has not already been created,";
2815   z[lc++]="** then allocate one and fill it in for the selected device.";
2816   z[lc++]="**";
2817   z[lc++]="** We create one extra input and one extra output device for the WAVE_MAPPER.";
2818   z[lc++]="** [Does anyone know how to query the default device and get its name?]";
2819   z[lc++]="*/";
2820   z[lc++]="const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )";
2821   z[lc++]="{	";
2822   z[lc++]="#define NUM_STANDARDSAMPLINGRATES   3   /* 11.025, 22.05, 44.1 */";
2823   z[lc++]="#define NUM_CUSTOMSAMPLINGRATES     5   /* must be the same number of elements as in the array below */";
2824   z[lc++]="#define MAX_NUMSAMPLINGRATES        (NUM_STANDARDSAMPLINGRATES+NUM_CUSTOMSAMPLINGRATES)";
2825   z[lc++]="    static DWORD customSamplingRates[] = { 32000, 48000, 64000, 88200, 96000 };";
2826   z[lc++]="    PaDeviceInfo *deviceInfo;";
2827   z[lc++]="    double *sampleRates; /* non-const ptr */";
2828   z[lc++]="    int i;";
2829   z[lc++]="    char *s;";
2830   z[lc++]="    ";
2831   z[lc++]="    if( id < 0 || id >= sNumDevices )";
2832   z[lc++]="        return NULL;";
2833   z[lc++]="    if( sDevicePtrs[ id ] != NULL )";
2834   z[lc++]="	{";
2835   z[lc++]="        return sDevicePtrs[ id ];";
2836   z[lc++]="    }";
2837   z[lc++]="    deviceInfo = (PaDeviceInfo *)GlobalAlloc( GPTR, sizeof(PaDeviceInfo) ); /* MEM */";
2838   z[lc++]="	if( deviceInfo == NULL ) return NULL;";
2839   z[lc++]="    deviceInfo->structVersion = 1;";
2840   z[lc++]="    deviceInfo->maxInputChannels = 0;";
2841   z[lc++]="    deviceInfo->maxOutputChannels = 0;";
2842   z[lc++]="    deviceInfo->numSampleRates = 0;";
2843   z[lc++]="    sampleRates = (double*)GlobalAlloc( GPTR, MAX_NUMSAMPLINGRATES * sizeof(double) ); /* MEM */";
2844   z[lc++]="    deviceInfo->sampleRates = sampleRates;";
2845   z[lc++]="    deviceInfo->nativeSampleFormats = paInt16;       /* should query for higher bit depths below */";
2846   z[lc++]="    if( id < sNumInputDevices )";
2847   z[lc++]="	{";
2848   z[lc++]="        /* input device */";
2849   z[lc++]="        int inputMmID = id - 1; /* WAVE_MAPPER is -1 so we start with WAVE_MAPPER */";
2850   z[lc++]="        WAVEINCAPS wic;";
2851   z[lc++]="        if( waveInGetDevCaps( inputMmID, &wic, sizeof( WAVEINCAPS ) ) != MMSYSERR_NOERROR )";
2852   z[lc++]="            goto error;";
2853   z[lc++]="        ";
2854   z[lc++]="	/* Append I/O suffix to WAVE_MAPPER device. */";
2855   z[lc++]="		if( inputMmID == WAVE_MAPPER )";
2856   z[lc++]="		{";
2857   z[lc++]="			s = (char *) GlobalAlloc( GMEM_FIXED, strlen( wic.szPname ) + 1 + sizeof(sMapperSuffixInput) ); /* MEM */";
2858   z[lc++]="			strcpy( s, wic.szPname );";
2859   z[lc++]="			strcat( s, sMapperSuffixInput );";
2860   z[lc++]="		}";
2861   z[lc++]="		else";
2862   z[lc++]="		{";
2863   z[lc++]="			s = (char *) GlobalAlloc( GMEM_FIXED, strlen( wic.szPname ) + 1 ); /* MEM */";
2864   z[lc++]="			strcpy( s, wic.szPname );";
2865   z[lc++]="		}";
2866   z[lc++]="        deviceInfo->name = s;";
2867   z[lc++]="        deviceInfo->maxInputChannels = wic.wChannels;";
2868   z[lc++]="	/* Sometimes a device can return a rediculously large number of channels.";
2869   z[lc++]="	** This happened with an SBLive card on a Windows ME box.";
2870   z[lc++]="	** If that happens, then force it to 2 channels.  PLB20010413";
2871   z[lc++]="	*/";
2872   z[lc++]="		if( (deviceInfo->maxInputChannels < 1) || (deviceInfo->maxInputChannels > 256) )";
2873   z[lc++]="		{";
2874   z[lc++]="			ERR_RPT((\"Pa_GetDeviceInfo: Num input channels reported as %d! Changed to 2.\\n\", deviceInfo->maxOutputChannels ));";
2875   z[lc++]="			deviceInfo->maxInputChannels = 2;";
2876   z[lc++]="		}";
2877   z[lc++]="	/* Add a sample rate to the list if we can do stereo 16 bit at that rate";
2878   z[lc++]="	 * based on the format flags. */";
2879   z[lc++]="        if( wic.dwFormats & WAVE_FORMAT_1M16 ||wic.dwFormats & WAVE_FORMAT_1S16 )";
2880   z[lc++]="            sampleRates[ deviceInfo->numSampleRates++ ] = 11025.;";
2881   z[lc++]="        if( wic.dwFormats & WAVE_FORMAT_2M16 ||wic.dwFormats & WAVE_FORMAT_2S16 )";
2882   z[lc++]="            sampleRates[ deviceInfo->numSampleRates++ ] = 22050.;";
2883   z[lc++]="        if( wic.dwFormats & WAVE_FORMAT_4M16 ||wic.dwFormats & WAVE_FORMAT_4S16 )";
2884   z[lc++]="            sampleRates[ deviceInfo->numSampleRates++ ] = 44100.;";
2885   z[lc++]="	/* Add a sample rate to the list if we can do stereo 16 bit at that rate";
2886   z[lc++]="	 * based on opening the device successfully. */";
2887   z[lc++]="        for( i=0; i < NUM_CUSTOMSAMPLINGRATES; i++ ){";
2888   z[lc++]="            WAVEFORMATEX wfx;";
2889   z[lc++]="            wfx.wFormatTag = WAVE_FORMAT_PCM;";
2890   z[lc++]="            wfx.nSamplesPerSec = customSamplingRates[i];";
2891   z[lc++]="            wfx.wBitsPerSample = 16;";
2892   z[lc++]="            wfx.cbSize = 0; /* ignored */";
2893   z[lc++]="            wfx.nChannels = (WORD)deviceInfo->maxInputChannels;";
2894   z[lc++]="            wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);";
2895   z[lc++]="            wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));";
2896   z[lc++]="            if( waveInOpen( NULL, inputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR )";
2897   z[lc++]="			{";
2898   z[lc++]="                sampleRates[ deviceInfo->numSampleRates++ ] = customSamplingRates[i];";
2899   z[lc++]="            }";
2900   z[lc++]="        }";
2901   z[lc++]="        ";
2902   z[lc++]="    }";
2903   z[lc++]="	else if( id - sNumInputDevices < sNumOutputDevices )";
2904   z[lc++]="	{";
2905   z[lc++]="        /* output device */";
2906   z[lc++]="        int outputMmID = id - sNumInputDevices - 1;";
2907   z[lc++]="        WAVEOUTCAPS woc;";
2908   z[lc++]="        if( waveOutGetDevCaps( outputMmID, &woc, sizeof( WAVEOUTCAPS ) ) != MMSYSERR_NOERROR )";
2909   z[lc++]="            goto error;";
2910   z[lc++]="	/* Append I/O suffix to WAVE_MAPPER device. */";
2911   z[lc++]="		if( outputMmID == WAVE_MAPPER )";
2912   z[lc++]="		{";
2913   z[lc++]="			s = (char *) GlobalAlloc( GMEM_FIXED, strlen( woc.szPname ) + 1 + sizeof(sMapperSuffixOutput) );  /* MEM */";
2914   z[lc++]="			strcpy( s, woc.szPname );";
2915   z[lc++]="			strcat( s, sMapperSuffixOutput );";
2916   z[lc++]="		}";
2917   z[lc++]="		else";
2918   z[lc++]="		{";
2919   z[lc++]="			s = (char *) GlobalAlloc( GMEM_FIXED, strlen( woc.szPname ) + 1 );  /* MEM */";
2920   z[lc++]="			strcpy( s, woc.szPname );";
2921   z[lc++]="		}";
2922   z[lc++]="        deviceInfo->name = s;";
2923   z[lc++]="        deviceInfo->maxOutputChannels = woc.wChannels;";
2924   z[lc++]="	/* Sometimes a device can return a rediculously large number of channels.";
2925   z[lc++]="	** This happened with an SBLive card on a Windows ME box.";
2926   z[lc++]="	** If that happens, then force it to 2 channels. PLB20010413";
2927   z[lc++]="	*/";
2928   z[lc++]="		if( (deviceInfo->maxOutputChannels < 1) || (deviceInfo->maxOutputChannels > 256) )";
2929   z[lc++]="		{";
2930   z[lc++]="			ERR_RPT((\"Pa_GetDeviceInfo: Num output channels reported as %d! Changed to 2.\\n\", deviceInfo->maxOutputChannels ));";
2931   z[lc++]="			deviceInfo->maxOutputChannels = 2;";
2932   z[lc++]="		}";
2933   z[lc++]="	/* Add a sample rate to the list if we can do stereo 16 bit at that rate";
2934   z[lc++]="	 * based on the format flags. */";
2935   z[lc++]="        if( woc.dwFormats & WAVE_FORMAT_1M16 ||woc.dwFormats & WAVE_FORMAT_1S16 )";
2936   z[lc++]="            sampleRates[ deviceInfo->numSampleRates++ ] = 11025.;";
2937   z[lc++]="        if( woc.dwFormats & WAVE_FORMAT_2M16 ||woc.dwFormats & WAVE_FORMAT_2S16 )";
2938   z[lc++]="            sampleRates[ deviceInfo->numSampleRates++ ] = 22050.;";
2939   z[lc++]="        if( woc.dwFormats & WAVE_FORMAT_4M16 ||woc.dwFormats & WAVE_FORMAT_4S16 )";
2940   z[lc++]="            sampleRates[ deviceInfo->numSampleRates++ ] = 44100.;";
2941   z[lc++]="	/* Add a sample rate to the list if we can do stereo 16 bit at that rate";
2942   z[lc++]="	 * based on opening the device successfully. */";
2943   z[lc++]="        for( i=0; i < NUM_CUSTOMSAMPLINGRATES; i++ )";
2944   z[lc++]="		{";
2945   z[lc++]="            WAVEFORMATEX wfx;";
2946   z[lc++]="            wfx.wFormatTag = WAVE_FORMAT_PCM;";
2947   z[lc++]="            wfx.nSamplesPerSec = customSamplingRates[i];";
2948   z[lc++]="            wfx.wBitsPerSample = 16;";
2949   z[lc++]="            wfx.cbSize = 0; /* ignored */";
2950   z[lc++]="            wfx.nChannels = (WORD)deviceInfo->maxOutputChannels;";
2951   z[lc++]="            wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);";
2952   z[lc++]="            wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));";
2953   z[lc++]="            if( waveOutOpen( NULL, outputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR ){";
2954   z[lc++]="                sampleRates[ deviceInfo->numSampleRates++ ] = customSamplingRates[i];";
2955   z[lc++]="            }";
2956   z[lc++]="        }";
2957   z[lc++]="    }";
2958   z[lc++]="    sDevicePtrs[ id ] = deviceInfo;";
2959   z[lc++]="    return deviceInfo;";
2960   z[lc++]="error:";
2961   z[lc++]="    GlobalFree( sampleRates ); /* MEM */";
2962   z[lc++]="    GlobalFree( deviceInfo ); /* MEM */";
2963   z[lc++]="    ";
2964   z[lc++]="    return NULL;";
2965   z[lc++]="}";
2966   z[lc++]="/*************************************************************************";
2967   z[lc++]="** Returns recommended device ID.";
2968   z[lc++]="** On the PC, the recommended device can be specified by the user by";
2969   z[lc++]="** setting an environment variable. For example, to use device #1.";
2970   z[lc++]="**";
2971   z[lc++]="**    set PA_RECOMMENDED_OUTPUT_DEVICE=1";
2972   z[lc++]="**";
2973   z[lc++]="** The user should first determine the available device ID by using";
2974   z[lc++]="** the supplied application \"pa_devs\".";
2975   z[lc++]="*/";
2976   z[lc++]="#define PA_ENV_BUF_SIZE  (32)";
2977   z[lc++]="#define PA_REC_IN_DEV_ENV_NAME  (\"PA_RECOMMENDED_INPUT_DEVICE\")";
2978   z[lc++]="#define PA_REC_OUT_DEV_ENV_NAME  (\"PA_RECOMMENDED_OUTPUT_DEVICE\")";
2979   z[lc++]="static PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName )";
2980   z[lc++]="{";
2981   z[lc++]="	DWORD   hresult;";
2982   z[lc++]="	char    envbuf[PA_ENV_BUF_SIZE];";
2983   z[lc++]="	PaDeviceID recommendedID = paNoDevice;";
2984   z[lc++]="/* Let user determine default device by setting environment variable. */";
2985   z[lc++]="	hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE );";
2986   z[lc++]="	if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )";
2987   z[lc++]="	{";
2988   z[lc++]="		recommendedID = atoi( envbuf );";
2989   z[lc++]="	}";
2990   z[lc++]="	return recommendedID;";
2991   z[lc++]="}";
2992   z[lc++]="static PaError Pa_MaybeQueryDevices( void )";
2993   z[lc++]="{";
2994   z[lc++]="	if( sNumDevices == 0 )";
2995   z[lc++]="	{";
2996   z[lc++]="		return Pa_QueryDevices();";
2997   z[lc++]="	}";
2998   z[lc++]="	return 0;";
2999   z[lc++]="}";
3000   z[lc++]="/**********************************************************************";
3001   z[lc++]="** Check for environment variable, else query devices and use result.";
3002   z[lc++]="*/";
3003   z[lc++]="PaDeviceID Pa_GetDefaultInputDeviceID( void )";
3004   z[lc++]="{";
3005   z[lc++]="	PaError result;";
3006   z[lc++]="	result = PaHost_GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME );";
3007   z[lc++]="	if( result < 0 )";
3008   z[lc++]="	{";
3009   z[lc++]="		result = Pa_MaybeQueryDevices();";
3010   z[lc++]="		if( result < 0 ) return result;";
3011   z[lc++]="		result = sDefaultInputDeviceID;";
3012   z[lc++]="	}";
3013   z[lc++]="	return result;";
3014   z[lc++]="}";
3015   z[lc++]="PaDeviceID Pa_GetDefaultOutputDeviceID( void )";
3016   z[lc++]="{";
3017   z[lc++]="	PaError result;";
3018   z[lc++]="	result = PaHost_GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME );";
3019   z[lc++]="	if( result < 0 )";
3020   z[lc++]="	{";
3021   z[lc++]="		result = Pa_MaybeQueryDevices();";
3022   z[lc++]="		if( result < 0 ) return result;";
3023   z[lc++]="		result = sDefaultOutputDeviceID;";
3024   z[lc++]="	}";
3025   z[lc++]="	return result;";
3026   z[lc++]="}";
3027   z[lc++]="/**********************************************************************";
3028   z[lc++]="** Initialize Host dependant part of API.";
3029   z[lc++]="*/";
3030   z[lc++]="PaError PaHost_Init( void )";
3031   z[lc++]="{";
3032   z[lc++]="#if PA_SIMULATE_UNDERFLOW";
3033   z[lc++]="	PRINT((\"WARNING - Underflow Simulation Enabled - Expect a Big Glitch!!!\\n\"));";
3034   z[lc++]="#endif";
3035   z[lc++]="	return Pa_MaybeQueryDevices();";
3036   z[lc++]="}";
3037   z[lc++]="/**********************************************************************";
3038   z[lc++]="** Check WAVE buffers to see if they are done.";
3039   z[lc++]="** Fill any available output buffers and use any available";
3040   z[lc++]="** input buffers by calling user callback.";
3041   z[lc++]="*/";
3042   z[lc++]="static PaError Pa_TimeSlice( internalPortAudioStream   *past )";
3043   z[lc++]="{";
3044   z[lc++]="	PaError           result = 0;";
3045   z[lc++]="	long              bytesEmpty = 0;";
3046   z[lc++]="	long              bytesFilled = 0;";
3047   z[lc++]="	long              buffersEmpty = 0;";
3048   z[lc++]="	MMRESULT          mresult;";
3049   z[lc++]="	char             *inBufPtr;";
3050   z[lc++]="	char             *outBufPtr;";
3051   z[lc++]="	int               gotInput = 0;";
3052   z[lc++]="	int               gotOutput = 0;";
3053   z[lc++]="	int               i;";
3054   z[lc++]="	int               buffersProcessed = 0;";
3055   z[lc++]="	int               done = 0;";
3056   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3057   z[lc++]="	if( pahsc == NULL ) return paInternalError;";
3058   z[lc++]="	past->past_NumCallbacks += 1;";
3059   z[lc++]="#if PA_SIMULATE_UNDERFLOW";
3060   z[lc++]="	if(gUnderCallbackCounter++ == UNDER_SLEEP_AT)";
3061   z[lc++]="	{";
3062   z[lc++]="		Sleep(UNDER_SLEEP_FOR);";
3063   z[lc++]="	}";
3064   z[lc++]="#endif";
3065   z[lc++]="#if PA_TRACE_RUN";
3066   z[lc++]="	AddTraceMessage(\"Pa_TimeSlice: past_NumCallbacks \", past->past_NumCallbacks );";
3067   z[lc++]="#endif";
3068   z[lc++]="	while(!done)";
3069   z[lc++]="	{";
3070   z[lc++]="/* If we are using output, then we need an empty output buffer. */";
3071   z[lc++]="		gotOutput = 0;";
3072   z[lc++]="		outBufPtr = NULL;";
3073   z[lc++]="		if( past->past_NumOutputChannels > 0 )";
3074   z[lc++]="		{";
3075   z[lc++]="			if((pahsc->pahsc_OutputBuffers[ pahsc->pahsc_CurrentOutputBuffer ].dwFlags & WHDR_DONE) == 0)";
3076   z[lc++]="			{	";
3077   z[lc++]="				break;  /* If none empty then bail and try again later. */";
3078   z[lc++]="			}";
3079   z[lc++]="			else";
3080   z[lc++]="			{";
3081   z[lc++]="				outBufPtr = pahsc->pahsc_OutputBuffers[ pahsc->pahsc_CurrentOutputBuffer ].lpData;";
3082   z[lc++]="				gotOutput = 1;";
3083   z[lc++]="			}";
3084   z[lc++]="		}";
3085   z[lc++]="/* Use an input buffer if one is available. */";
3086   z[lc++]="		gotInput = 0;";
3087   z[lc++]="		inBufPtr = NULL;";
3088   z[lc++]="		if( ( past->past_NumInputChannels > 0 ) &&";
3089   z[lc++]="			(pahsc->pahsc_InputBuffers[ pahsc->pahsc_CurrentInputBuffer ].dwFlags & WHDR_DONE) )";
3090   z[lc++]="		{";
3091   z[lc++]="			inBufPtr = pahsc->pahsc_InputBuffers[ pahsc->pahsc_CurrentInputBuffer ].lpData;";
3092   z[lc++]="			gotInput = 1;";
3093   z[lc++]="#if PA_TRACE_RUN";
3094   z[lc++]="			AddTraceMessage(\"Pa_TimeSlice: got input buffer at \", (int)inBufPtr );";
3095   z[lc++]="			AddTraceMessage(\"Pa_TimeSlice: got input buffer # \", pahsc->pahsc_CurrentInputBuffer );";
3096   z[lc++]="#endif";
3097   z[lc++]="		}";
3098   z[lc++]="/* If we can't do anything then bail out. */";
3099   z[lc++]="		if( !gotInput && !gotOutput ) break;";
3100   z[lc++]="		buffersProcessed += 1;";
3101   z[lc++]="/* Each Wave buffer contains multiple user buffers so do them all now. */";
3102   z[lc++]="/* Base Usage on time it took to process one host buffer. */";
3103   z[lc++]="		Pa_StartUsageCalculation( past );";
3104   z[lc++]="		for( i=0; i<pahsc->pahsc_UserBuffersPerHostBuffer; i++ )";
3105   z[lc++]="		{";
3106   z[lc++]="			if( done )";
3107   z[lc++]="			{";
3108   z[lc++]="				if( gotOutput )";
3109   z[lc++]="				{";
3110   z[lc++]="		/* Clear remainder of wave buffer if we are waiting for stop. */";
3111   z[lc++]="					AddTraceMessage(\"Pa_TimeSlice: zero rest of wave buffer \", i );";
3112   z[lc++]="					memset( outBufPtr, 0, pahsc->pahsc_BytesPerUserOutputBuffer );";
3113   z[lc++]="				}";
3114   z[lc++]="			}";
3115   z[lc++]="			else";
3116   z[lc++]="			{";
3117   z[lc++]="	/* Convert 16 bit native data to user data and call user routine. */";
3118   z[lc++]="				result = Pa_CallConvertInt16( past, (short *) inBufPtr, (short *) outBufPtr );";
3119   z[lc++]="				if( result != 0) done = 1;";
3120   z[lc++]="			}";
3121   z[lc++]="			if( gotInput ) inBufPtr += pahsc->pahsc_BytesPerUserInputBuffer;";
3122   z[lc++]="			if( gotOutput) outBufPtr += pahsc->pahsc_BytesPerUserOutputBuffer;";
3123   z[lc++]="		}";
3124   z[lc++]="		Pa_EndUsageCalculation( past );";
3125   z[lc++]="/* Send WAVE buffer to Wave Device to be refilled. */";
3126   z[lc++]="		if( gotInput )";
3127   z[lc++]="		{";
3128   z[lc++]="			mresult = waveInAddBuffer( pahsc->pahsc_HWaveIn,";
3129   z[lc++]="				&pahsc->pahsc_InputBuffers[ pahsc->pahsc_CurrentInputBuffer ],";
3130   z[lc++]="				sizeof(WAVEHDR) );";
3131   z[lc++]="			if( mresult != MMSYSERR_NOERROR )";
3132   z[lc++]="			{";
3133   z[lc++]="				sPaHostError = mresult;";
3134   z[lc++]="				result = paHostError;";
3135   z[lc++]="				break;";
3136   z[lc++]="			}";
3137   z[lc++]="			pahsc->pahsc_CurrentInputBuffer = (pahsc->pahsc_CurrentInputBuffer+1 >= pahsc->pahsc_NumHostBuffers) ?";
3138   z[lc++]="				0 : pahsc->pahsc_CurrentInputBuffer+1;";
3139   z[lc++]="		}";
3140   z[lc++]="/* Write WAVE buffer to Wave Device. */";
3141   z[lc++]="		if( gotOutput )";
3142   z[lc++]="		{";
3143   z[lc++]="#if PA_TRACE_START_STOP";
3144   z[lc++]="    AddTraceMessage( \"Pa_TimeSlice: writing buffer \", pahsc->pahsc_CurrentOutputBuffer );";
3145   z[lc++]="#endif";
3146   z[lc++]="			mresult = waveOutWrite( pahsc->pahsc_HWaveOut,";
3147   z[lc++]="				&pahsc->pahsc_OutputBuffers[ pahsc->pahsc_CurrentOutputBuffer ],";
3148   z[lc++]="				sizeof(WAVEHDR) );";
3149   z[lc++]="			if( mresult != MMSYSERR_NOERROR )";
3150   z[lc++]="			{";
3151   z[lc++]="				sPaHostError = mresult;";
3152   z[lc++]="				result = paHostError;";
3153   z[lc++]="				break;";
3154   z[lc++]="			}";
3155   z[lc++]="			pahsc->pahsc_CurrentOutputBuffer = (pahsc->pahsc_CurrentOutputBuffer+1 >= pahsc->pahsc_NumHostBuffers) ?";
3156   z[lc++]="				0 : pahsc->pahsc_CurrentOutputBuffer+1;";
3157   z[lc++]="		}";
3158   z[lc++]="	}";
3159   z[lc++]="			";
3160   z[lc++]="#if PA_TRACE_RUN";
3161   z[lc++]="	AddTraceMessage(\"Pa_TimeSlice: buffersProcessed \", buffersProcessed );";
3162   z[lc++]="#endif";
3163   z[lc++]="	return (result != 0) ? result : done;";
3164   z[lc++]="}";
3165   z[lc++]="/*******************************************************************/";
3166   z[lc++]="static PaError PaHost_BackgroundManager( internalPortAudioStream   *past )";
3167   z[lc++]="{";
3168   z[lc++]="	PaError      result = 0;";
3169   z[lc++]="    int          i;";
3170   z[lc++]="	int          numQueuedOutputBuffers = 0;";
3171   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3172   z[lc++]="/* Has someone asked us to abort by calling Pa_AbortStream()? */";
3173   z[lc++]="	if( past->past_StopNow )";
3174   z[lc++]="	{";
3175   z[lc++]="        past->past_IsActive = 0; /* Will cause thread to return. */";
3176   z[lc++]="    }";
3177   z[lc++]="/* Has someone asked us to stop by calling Pa_StopStream()";
3178   z[lc++]=" * OR has a user callback returned '1' to indicate finished.";
3179   z[lc++]=" */";
3180   z[lc++]="	else if( past->past_StopSoon )";
3181   z[lc++]="	{";
3182   z[lc++]="/* Poll buffer and when all have played then exit thread. */";
3183   z[lc++]="/* Count how many output buffers are queued. */";
3184   z[lc++]="        numQueuedOutputBuffers = 0;";
3185   z[lc++]="        if( past->past_NumOutputChannels > 0 )";
3186   z[lc++]="		{";
3187   z[lc++]="			for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
3188   z[lc++]="			{";
3189   z[lc++]="				if( !( pahsc->pahsc_OutputBuffers[ i ].dwFlags & WHDR_DONE) )";
3190   z[lc++]="				{";
3191   z[lc++]="#if PA_TRACE_START_STOP";
3192   z[lc++]="AddTraceMessage( \"WinMMPa_OutputThreadProc: waiting for buffer \", i );";
3193   z[lc++]="#endif";
3194   z[lc++]="					numQueuedOutputBuffers++;";
3195   z[lc++]="				}";
3196   z[lc++]="			}";
3197   z[lc++]="		}";
3198   z[lc++]="#if PA_TRACE_START_STOP";
3199   z[lc++]="AddTraceMessage( \"WinMMPa_OutputThreadProc: numQueuedOutputBuffers \", numQueuedOutputBuffers );";
3200   z[lc++]="#endif";
3201   z[lc++]="        if( numQueuedOutputBuffers == 0 )";
3202   z[lc++]="		{";
3203   z[lc++]="            past->past_IsActive = 0; /* Will cause thread to return. */";
3204   z[lc++]="		}";
3205   z[lc++]="    }";
3206   z[lc++]="	else";
3207   z[lc++]="	{";
3208   z[lc++]="/* Process full input buffer and fill up empty output buffers. */";
3209   z[lc++]="		if( (result = Pa_TimeSlice( past )) != 0) ";
3210   z[lc++]="		{";
3211   z[lc++]="	/* User callback has asked us to stop. */";
3212   z[lc++]="#if PA_TRACE_START_STOP";
3213   z[lc++]="AddTraceMessage( \"WinMMPa_OutputThreadProc: TimeSlice() returned \", result );";
3214   z[lc++]="#endif";
3215   z[lc++]="            past->past_StopSoon = 1; /* Request that audio play out then stop. */";
3216   z[lc++]="			result = paNoError;";
3217   z[lc++]="		}";
3218   z[lc++]="	}";
3219   z[lc++]="	";
3220   z[lc++]="	PaHost_UpdateStreamTime( pahsc );";
3221   z[lc++]="	return result;";
3222   z[lc++]="}";
3223   z[lc++]="#if PA_USE_TIMER_CALLBACK";
3224   z[lc++]="/*******************************************************************/";
3225   z[lc++]="static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)";
3226   z[lc++]="{";
3227   z[lc++]="	internalPortAudioStream   *past;";
3228   z[lc++]="	PaHostSoundControl        *pahsc;";
3229   z[lc++]="	PaError                    result;";
3230   z[lc++]="	past = (internalPortAudioStream *) dwUser;";
3231   z[lc++]="	if( past == NULL ) return;";
3232   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3233   z[lc++]="	if( pahsc == NULL ) return;";
3234   z[lc++]="	if( pahsc->pahsc_IfInsideCallback )";
3235   z[lc++]="	{";
3236   z[lc++]="		if( pahsc->pahsc_TimerID != 0 )";
3237   z[lc++]="		{";
3238   z[lc++]="			timeKillEvent(pahsc->pahsc_TimerID);  /* Stop callback timer. */";
3239   z[lc++]="			pahsc->pahsc_TimerID = 0;";
3240   z[lc++]="		}";
3241   z[lc++]="		return;";
3242   z[lc++]="	}";
3243   z[lc++]="	pahsc->pahsc_IfInsideCallback = 1;";
3244   z[lc++]="/* Manage flags and audio processing. */";
3245   z[lc++]=" 	result = PaHost_BackgroundManager( past );";
3246   z[lc++]="	if( result != paNoError )";
3247   z[lc++]="	{";
3248   z[lc++]="		past->past_IsActive = 0;";
3249   z[lc++]="	}";
3250   z[lc++]="	pahsc->pahsc_IfInsideCallback = 0;";
3251   z[lc++]="}";
3252   z[lc++]="#else /* PA_USE_TIMER_CALLBACK */";
3253   z[lc++]="/*******************************************************************/";
3254   z[lc++]="static DWORD WINAPI WinMMPa_OutputThreadProc( void *pArg )";
3255   z[lc++]="{";
3256   z[lc++]="	internalPortAudioStream *past;";
3257   z[lc++]=" 	PaHostSoundControl      *pahsc;";
3258   z[lc++]="    void        *inputBuffer=NULL;";
3259   z[lc++]="    HANDLE       events[2];";
3260   z[lc++]="	int          numEvents = 0;";
3261   z[lc++]="	DWORD        result = 0;";
3262   z[lc++]="	DWORD        waitResult;";
3263   z[lc++]="	DWORD        numTimeouts = 0;";
3264   z[lc++]="	DWORD        timeOut;";
3265   z[lc++]="	past = (internalPortAudioStream *) pArg;";
3266   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3267   z[lc++]="#if PA_TRACE_START_STOP";
3268   z[lc++]="    AddTraceMessage( \"WinMMPa_OutputThreadProc: timeoutPeriod\", timeoutPeriod );";
3269   z[lc++]="    AddTraceMessage( \"WinMMPa_OutputThreadProc: past_NumUserBuffers\", past->past_NumUserBuffers );";
3270   z[lc++]="#endif";
3271   z[lc++]="/* Calculate timeOut as half the time it would take to play all buffers. */";
3272   z[lc++]="	timeOut = (DWORD) (500.0 * PaHost_GetTotalBufferFrames( past ) / past->past_SampleRate);";
3273   z[lc++]="/* Get event(s) ready for wait. */";
3274   z[lc++]="    events[numEvents++] = pahsc->pahsc_BufferEvent;";
3275   z[lc++]="    if( pahsc->pahsc_AbortEventInited ) events[numEvents++] = pahsc->pahsc_AbortEvent;";
3276   z[lc++]="/* Stay in this thread as long as we are \"active\". */";
3277   z[lc++]="    while( past->past_IsActive )";
3278   z[lc++]="	{";
3279   z[lc++]="/*******************************************************************/";
3280   z[lc++]="/******** WAIT here for an event from WMME or PA *******************/";
3281   z[lc++]="/*******************************************************************/";
3282   z[lc++]="        waitResult = WaitForMultipleObjects( numEvents, events, FALSE, timeOut );";
3283   z[lc++]="	/* Error? */";
3284   z[lc++]="		if( waitResult == WAIT_FAILED )";
3285   z[lc++]="		{";
3286   z[lc++]="			sPaHostError = GetLastError();";
3287   z[lc++]="			result = paHostError;";
3288   z[lc++]="			past->past_IsActive = 0;";
3289   z[lc++]="		}";
3290   z[lc++]="	/* Timeout? Don't stop. Just keep polling for DONE.*/";
3291   z[lc++]="		else if( waitResult == WAIT_TIMEOUT )";
3292   z[lc++]="		{";
3293   z[lc++]="#if PA_TRACE_START_STOP";
3294   z[lc++]="	AddTraceMessage( \"WinMMPa_OutputThreadProc: timed out \", numQueuedOutputBuffers );";
3295   z[lc++]="#endif";
3296   z[lc++]="			numTimeouts += 1;";
3297   z[lc++]="		}";
3298   z[lc++]="		/* Manage flags and audio processing. */";
3299   z[lc++]=" 		result = PaHost_BackgroundManager( past );";
3300   z[lc++]="		if( result != paNoError )";
3301   z[lc++]="		{";
3302   z[lc++]="			past->past_IsActive = 0;";
3303   z[lc++]="		}";
3304   z[lc++]="	}";
3305   z[lc++]="	return result;";
3306   z[lc++]="}";
3307   z[lc++]="#endif";
3308   z[lc++]="/*******************************************************************/";
3309   z[lc++]="PaError PaHost_OpenInputStream( internalPortAudioStream   *past )";
3310   z[lc++]="{";
3311   z[lc++]="	MMRESULT         mr;";
3312   z[lc++]="	PaError          result = paNoError;";
3313   z[lc++]="	PaHostSoundControl *pahsc;";
3314   z[lc++]="	int              i;";
3315   z[lc++]="	int              inputMmId;";
3316   z[lc++]="	int              bytesPerInputFrame;";
3317   z[lc++]="	WAVEFORMATEX     wfx;";
3318   z[lc++]="	const PaDeviceInfo  *pad;";
3319   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3320   z[lc++]="	DBUG((\"PaHost_OpenStream: deviceID = 0x%x\\n\", past->past_InputDeviceID));";
3321   z[lc++]="	pad = Pa_GetDeviceInfo( past->past_InputDeviceID );";
3322   z[lc++]="	if( pad == NULL ) return paInternalError;";
3323   z[lc++]="	switch( pad->nativeSampleFormats  )";
3324   z[lc++]="	{";
3325   z[lc++]="		case paInt32:";
3326   z[lc++]="		case paFloat32:";
3327   z[lc++]="			bytesPerInputFrame = sizeof(float) * past->past_NumInputChannels;";
3328   z[lc++]="			break;";
3329   z[lc++]="		default:";
3330   z[lc++]="			bytesPerInputFrame = sizeof(short) * past->past_NumInputChannels;";
3331   z[lc++]="			break;";
3332   z[lc++]="	}";
3333   z[lc++]="	wfx.wFormatTag = WAVE_FORMAT_PCM;";
3334   z[lc++]="	wfx.nChannels = (WORD) past->past_NumInputChannels;";
3335   z[lc++]="	wfx.nSamplesPerSec = (DWORD) past->past_SampleRate;";
3336   z[lc++]="	wfx.nAvgBytesPerSec = (DWORD)(bytesPerInputFrame * past->past_SampleRate);";
3337   z[lc++]="	wfx.nBlockAlign = (WORD)bytesPerInputFrame;";
3338   z[lc++]="	wfx.wBitsPerSample = (WORD)((bytesPerInputFrame/past->past_NumInputChannels) * 8);";
3339   z[lc++]="	wfx.cbSize = 0;";
3340   z[lc++]="	inputMmId = PaDeviceIdToWinId( past->past_InputDeviceID );";
3341   z[lc++]="#if PA_USE_TIMER_CALLBACK";
3342   z[lc++]="	mr = waveInOpen( &pahsc->pahsc_HWaveIn, inputMmId, &wfx,";
3343   z[lc++]="	                  0, 0, CALLBACK_NULL );";
3344   z[lc++]="#else";
3345   z[lc++]="	mr = waveInOpen( &pahsc->pahsc_HWaveIn, inputMmId, &wfx,";
3346   z[lc++]="	                  (DWORD)pahsc->pahsc_BufferEvent, (DWORD) past, CALLBACK_EVENT );";
3347   z[lc++]="#endif";
3348   z[lc++]="	if( mr != MMSYSERR_NOERROR )";
3349   z[lc++]="	{";
3350   z[lc++]="		ERR_RPT((\"PortAudio: PaHost_OpenInputStream() failed!\\n\"));";
3351   z[lc++]="		result = paHostError;";
3352   z[lc++]="		sPaHostError = mr;";
3353   z[lc++]="		goto error;";
3354   z[lc++]="	}";
3355   z[lc++]="/* Allocate an array to hold the buffer pointers. */";
3356   z[lc++]="	pahsc->pahsc_InputBuffers = (WAVEHDR *) GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(WAVEHDR)*pahsc->pahsc_NumHostBuffers ); /* MEM */";
3357   z[lc++]="	if( pahsc->pahsc_InputBuffers == NULL )";
3358   z[lc++]="	{";
3359   z[lc++]="		result = paInsufficientMemory;";
3360   z[lc++]="		goto error;";
3361   z[lc++]="	}";
3362   z[lc++]="/* Allocate each buffer. */";
3363   z[lc++]="	for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
3364   z[lc++]="	{";
3365   z[lc++]="		pahsc->pahsc_InputBuffers[i].lpData = (char *)GlobalAlloc( GMEM_FIXED, pahsc->pahsc_BytesPerHostInputBuffer ); /* MEM */";
3366   z[lc++]="		if( pahsc->pahsc_InputBuffers[i].lpData == NULL )";
3367   z[lc++]="		{";
3368   z[lc++]="			result = paInsufficientMemory;";
3369   z[lc++]="			goto error;";
3370   z[lc++]="		}";
3371   z[lc++]="		pahsc->pahsc_InputBuffers[i].dwBufferLength = pahsc->pahsc_BytesPerHostInputBuffer;";
3372   z[lc++]="		pahsc->pahsc_InputBuffers[i].dwUser = i;";
3373   z[lc++]="		if( ( mr = waveInPrepareHeader( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )";
3374   z[lc++]="		{";
3375   z[lc++]="			result = paHostError;";
3376   z[lc++]="			sPaHostError = mr;";
3377   z[lc++]="			goto error;";
3378   z[lc++]="		}";
3379   z[lc++]="	}";
3380   z[lc++]="	return result;";
3381   z[lc++]="error:";
3382   z[lc++]="	return result;";
3383   z[lc++]="}";
3384   z[lc++]="/*******************************************************************/";
3385   z[lc++]="PaError PaHost_OpenOutputStream( internalPortAudioStream   *past )";
3386   z[lc++]="{";
3387   z[lc++]="	MMRESULT         mr;";
3388   z[lc++]="	PaError          result = paNoError;";
3389   z[lc++]="	PaHostSoundControl *pahsc;";
3390   z[lc++]="	int              i;";
3391   z[lc++]="	int              outputMmID;";
3392   z[lc++]="	int              bytesPerOutputFrame;";
3393   z[lc++]="	WAVEFORMATEX     wfx;";
3394   z[lc++]="	const PaDeviceInfo *pad;";
3395   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3396   z[lc++]="	DBUG((\"PaHost_OpenStream: deviceID = 0x%x\\n\", past->past_OutputDeviceID));";
3397   z[lc++]="	pad = Pa_GetDeviceInfo( past->past_OutputDeviceID );";
3398   z[lc++]="	if( pad == NULL ) return paInternalError;";
3399   z[lc++]="	switch( pad->nativeSampleFormats  )";
3400   z[lc++]="	{";
3401   z[lc++]="		case paInt32:";
3402   z[lc++]="		case paFloat32:";
3403   z[lc++]="			bytesPerOutputFrame = sizeof(float) * past->past_NumOutputChannels;";
3404   z[lc++]="			break;";
3405   z[lc++]="		default:";
3406   z[lc++]="			bytesPerOutputFrame = sizeof(short) * past->past_NumOutputChannels;";
3407   z[lc++]="			break;";
3408   z[lc++]="	}";
3409   z[lc++]="	wfx.wFormatTag = WAVE_FORMAT_PCM;";
3410   z[lc++]="	wfx.nChannels = (WORD) past->past_NumOutputChannels;";
3411   z[lc++]="	wfx.nSamplesPerSec = (DWORD) past->past_SampleRate;";
3412   z[lc++]="	wfx.nAvgBytesPerSec = (DWORD)(bytesPerOutputFrame * past->past_SampleRate);";
3413   z[lc++]="	wfx.nBlockAlign = (WORD)bytesPerOutputFrame;";
3414   z[lc++]="	wfx.wBitsPerSample = (WORD)((bytesPerOutputFrame/past->past_NumOutputChannels) * 8);";
3415   z[lc++]="	wfx.cbSize = 0;";
3416   z[lc++]="	outputMmID = PaDeviceIdToWinId( past->past_OutputDeviceID );";
3417   z[lc++]="#if PA_USE_TIMER_CALLBACK";
3418   z[lc++]="	mr = waveOutOpen( &pahsc->pahsc_HWaveOut, outputMmID, &wfx,";
3419   z[lc++]="	                  0, 0, CALLBACK_NULL );";
3420   z[lc++]="#else";
3421   z[lc++]="	        ";
3422   z[lc++]="	pahsc->pahsc_AbortEvent = CreateEvent( NULL, TRUE, FALSE, NULL );";
3423   z[lc++]="	if( pahsc->pahsc_AbortEvent == NULL )";
3424   z[lc++]="	{";
3425   z[lc++]="		result = paHostError;";
3426   z[lc++]="		sPaHostError = GetLastError();";
3427   z[lc++]="		goto error;";
3428   z[lc++]="	}";
3429   z[lc++]="	pahsc->pahsc_AbortEventInited = 1;";
3430   z[lc++]="	mr = waveOutOpen( &pahsc->pahsc_HWaveOut, outputMmID, &wfx,";
3431   z[lc++]="	                  (DWORD)pahsc->pahsc_BufferEvent, (DWORD) past, CALLBACK_EVENT );";
3432   z[lc++]="#endif";
3433   z[lc++]="	if( mr != MMSYSERR_NOERROR )";
3434   z[lc++]="	{";
3435   z[lc++]="		ERR_RPT((\"PortAudio: PaHost_OpenOutputStream() failed!\\n\"));";
3436   z[lc++]="		result = paHostError;";
3437   z[lc++]="		sPaHostError = mr;";
3438   z[lc++]="		goto error;";
3439   z[lc++]="	}";
3440   z[lc++]="/* Allocate an array to hold the buffer pointers. */";
3441   z[lc++]="	pahsc->pahsc_OutputBuffers = (WAVEHDR *) GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(WAVEHDR)*pahsc->pahsc_NumHostBuffers ); /* MEM */";
3442   z[lc++]="	if( pahsc->pahsc_OutputBuffers == NULL )";
3443   z[lc++]="	{";
3444   z[lc++]="		result = paInsufficientMemory;";
3445   z[lc++]="		goto error;";
3446   z[lc++]="	}";
3447   z[lc++]="/* Allocate each buffer. */";
3448   z[lc++]="	for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
3449   z[lc++]="	{";
3450   z[lc++]="		pahsc->pahsc_OutputBuffers[i].lpData = (char *) GlobalAlloc( GMEM_FIXED, pahsc->pahsc_BytesPerHostOutputBuffer ); /* MEM */";
3451   z[lc++]="		if( pahsc->pahsc_OutputBuffers[i].lpData == NULL )";
3452   z[lc++]="		{";
3453   z[lc++]="			result = paInsufficientMemory;";
3454   z[lc++]="			goto error;";
3455   z[lc++]="		}";
3456   z[lc++]="		pahsc->pahsc_OutputBuffers[i].dwBufferLength = pahsc->pahsc_BytesPerHostOutputBuffer;";
3457   z[lc++]="		pahsc->pahsc_OutputBuffers[i].dwUser = i;";
3458   z[lc++]="		if( (mr = waveOutPrepareHeader( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )";
3459   z[lc++]="		{";
3460   z[lc++]="			result = paHostError;";
3461   z[lc++]="			sPaHostError = mr;";
3462   z[lc++]="			goto error;";
3463   z[lc++]="		}";
3464   z[lc++]="	}";
3465   z[lc++]="	return result;";
3466   z[lc++]="error:";
3467   z[lc++]="	return result;";
3468   z[lc++]="}";
3469   z[lc++]="/*******************************************************************/";
3470   z[lc++]="PaError PaHost_GetTotalBufferFrames( internalPortAudioStream   *past )";
3471   z[lc++]="{";
3472   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3473   z[lc++]="	return pahsc->pahsc_NumHostBuffers * pahsc->pahsc_FramesPerHostBuffer;";
3474   z[lc++]="}";
3475   z[lc++]="/*******************************************************************";
3476   z[lc++]="* Determine number of WAVE Buffers";
3477   z[lc++]="* and how many User Buffers we can put into each WAVE buffer.";
3478   z[lc++]="*/";
3479   z[lc++]="static void PaHost_CalcNumHostBuffers( internalPortAudioStream *past )";
3480   z[lc++]="{";
3481   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3482   z[lc++]="	unsigned int  minNumBuffers;";
3483   z[lc++]="	int           minFramesPerHostBuffer;";
3484   z[lc++]="	int           maxFramesPerHostBuffer;";
3485   z[lc++]="	int           minTotalFrames;";
3486   z[lc++]="	int           userBuffersPerHostBuffer;";
3487   z[lc++]="	int           framesPerHostBuffer;";
3488   z[lc++]="	int           numHostBuffers;";
3489   z[lc++]="/* Calculate minimum and maximum sizes based on timing and sample rate. */";
3490   z[lc++]="	minFramesPerHostBuffer = (int) (PA_MIN_MSEC_PER_HOST_BUFFER * past->past_SampleRate / 1000.0);";
3491   z[lc++]="	minFramesPerHostBuffer = (minFramesPerHostBuffer + 7) & ~7;";
3492   z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: minFramesPerHostBuffer = %d\\n\", minFramesPerHostBuffer ));";
3493   z[lc++]="	maxFramesPerHostBuffer = (int) (PA_MAX_MSEC_PER_HOST_BUFFER * past->past_SampleRate / 1000.0);";
3494   z[lc++]="	maxFramesPerHostBuffer = (maxFramesPerHostBuffer + 7) & ~7;";
3495   z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: maxFramesPerHostBuffer = %d\\n\", maxFramesPerHostBuffer ));";
3496   z[lc++]="/* Determine number of user buffers based on minimum latency. */";
3497   z[lc++]="	minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );";
3498   z[lc++]="	past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;";
3499   z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: min past_NumUserBuffers = %d\\n\", past->past_NumUserBuffers ));";
3500   z[lc++]="	minTotalFrames = past->past_NumUserBuffers * past->past_FramesPerUserBuffer;";
3501   z[lc++]="/* We cannot make the WAVE buffers too small because they may not get serviced quickly enough. */";
3502   z[lc++]="	if( (int) past->past_FramesPerUserBuffer < minFramesPerHostBuffer )";
3503   z[lc++]="	{";
3504   z[lc++]="		userBuffersPerHostBuffer =";
3505   z[lc++]="			(minFramesPerHostBuffer + past->past_FramesPerUserBuffer - 1) /";
3506   z[lc++]="			past->past_FramesPerUserBuffer;";
3507   z[lc++]="	}";
3508   z[lc++]="	else";
3509   z[lc++]="	{";
3510   z[lc++]="		userBuffersPerHostBuffer = 1;";
3511   z[lc++]="	}";
3512   z[lc++]="	framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;";
3513   z[lc++]="/* Calculate number of WAVE buffers needed. Round up to cover minTotalFrames. */";
3514   z[lc++]="	numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;";
3515   z[lc++]="/* Make sure we have anough WAVE buffers. */";
3516   z[lc++]="	if( numHostBuffers < PA_MIN_NUM_HOST_BUFFERS)";
3517   z[lc++]="	{";
3518   z[lc++]="		numHostBuffers = PA_MIN_NUM_HOST_BUFFERS;";
3519   z[lc++]="	}";
3520   z[lc++]="	else if( (numHostBuffers > PA_MAX_NUM_HOST_BUFFERS) && ";
3521   z[lc++]="	         ((int) past->past_FramesPerUserBuffer < (maxFramesPerHostBuffer/2) ) )";
3522   z[lc++]="	{";
3523   z[lc++]="/* If we have too many WAVE buffers, try to put more user buffers in a wave buffer. */";
3524   z[lc++]="		while(numHostBuffers > PA_MAX_NUM_HOST_BUFFERS)";
3525   z[lc++]="		{";
3526   z[lc++]="			userBuffersPerHostBuffer += 1;";
3527   z[lc++]="			framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;";
3528   z[lc++]="			numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;";
3529   z[lc++]="	/* If we have gone too far, back up one. */";
3530   z[lc++]="			if( (framesPerHostBuffer > maxFramesPerHostBuffer) ||";
3531   z[lc++]="				(numHostBuffers < PA_MAX_NUM_HOST_BUFFERS) )";
3532   z[lc++]="			{";
3533   z[lc++]="				userBuffersPerHostBuffer -= 1;";
3534   z[lc++]="				framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;";
3535   z[lc++]="				numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;";
3536   z[lc++]="				break;";
3537   z[lc++]="			}";
3538   z[lc++]="		}";
3539   z[lc++]="	}";
3540   z[lc++]="	";
3541   z[lc++]="	pahsc->pahsc_UserBuffersPerHostBuffer = userBuffersPerHostBuffer;";
3542   z[lc++]="	pahsc->pahsc_FramesPerHostBuffer = framesPerHostBuffer;";
3543   z[lc++]="	pahsc->pahsc_NumHostBuffers = numHostBuffers;";
3544   z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: pahsc_UserBuffersPerHostBuffer = %d\\n\", pahsc->pahsc_UserBuffersPerHostBuffer ));";
3545   z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: pahsc_NumHostBuffers = %d\\n\", pahsc->pahsc_NumHostBuffers ));";
3546   z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: pahsc_FramesPerHostBuffer = %d\\n\", pahsc->pahsc_FramesPerHostBuffer ));";
3547   z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: past_NumUserBuffers = %d\\n\", past->past_NumUserBuffers ));";
3548   z[lc++]="}";
3549   z[lc++]="/*******************************************************************/";
3550   z[lc++]="PaError PaHost_OpenStream( internalPortAudioStream   *past )";
3551   z[lc++]="{";
3552   z[lc++]="	PaError             result = paNoError;";
3553   z[lc++]="	PaHostSoundControl *pahsc;";
3554   z[lc++]="/* Allocate and initialize host data. */";
3555   z[lc++]="	pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); /* MEM */";
3556   z[lc++]="	if( pahsc == NULL )";
3557   z[lc++]="	{";
3558   z[lc++]="		result = paInsufficientMemory;";
3559   z[lc++]="		goto error;";
3560   z[lc++]="	}";
3561   z[lc++]="	memset( pahsc, 0, sizeof(PaHostSoundControl) );";
3562   z[lc++]="	past->past_DeviceData = (void *) pahsc;";
3563   z[lc++]="/* Figure out how user buffers fit into WAVE buffers. */";
3564   z[lc++]="	PaHost_CalcNumHostBuffers( past );";
3565   z[lc++]="	{";
3566   z[lc++]="		int msecLatency = (int) ((PaHost_GetTotalBufferFrames(past) * 1000) / past->past_SampleRate);";
3567   z[lc++]="		DBUG((\"PortAudio on WMME - Latency = %d frames, %d msec\\n\", PaHost_GetTotalBufferFrames(past), msecLatency ));";
3568   z[lc++]="	}";
3569   z[lc++]="    InitializeCriticalSection( &pahsc->pahsc_StreamLock );";
3570   z[lc++]="    pahsc->pahsc_StreamLockInited = 1;";
3571   z[lc++]="	";
3572   z[lc++]="#if (PA_USE_TIMER_CALLBACK == 0)";
3573   z[lc++]="    pahsc->pahsc_BufferEventInited = 0;";
3574   z[lc++]="    pahsc->pahsc_BufferEvent = CreateEvent( NULL, FALSE, FALSE, NULL );";
3575   z[lc++]="    if( pahsc->pahsc_BufferEvent == NULL ){";
3576   z[lc++]="        result = paHostError;";
3577   z[lc++]="        sPaHostError = GetLastError();";
3578   z[lc++]="        goto error;";
3579   z[lc++]="    }";
3580   z[lc++]="    pahsc->pahsc_BufferEventInited = 1;";
3581   z[lc++]="#endif /* (PA_USE_TIMER_CALLBACK == 0) */";
3582   z[lc++]="/* ------------------ OUTPUT */";
3583   z[lc++]="	pahsc->pahsc_BytesPerUserOutputBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels * sizeof(short);";
3584   z[lc++]="	pahsc->pahsc_BytesPerHostOutputBuffer = pahsc->pahsc_UserBuffersPerHostBuffer * pahsc->pahsc_BytesPerUserOutputBuffer;";
3585   z[lc++]="	if( (past->past_OutputDeviceID != paNoDevice) && (past->past_NumOutputChannels > 0) )";
3586   z[lc++]="	{";
3587   z[lc++]="		result = PaHost_OpenOutputStream( past );";
3588   z[lc++]="		if( result < 0 ) goto error;";
3589   z[lc++]="	}";
3590   z[lc++]="/* ------------------ INPUT */";
3591   z[lc++]="	pahsc->pahsc_BytesPerUserInputBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels * sizeof(short);";
3592   z[lc++]="	pahsc->pahsc_BytesPerHostInputBuffer = pahsc->pahsc_UserBuffersPerHostBuffer * pahsc->pahsc_BytesPerUserInputBuffer;";
3593   z[lc++]="	if( (past->past_InputDeviceID != paNoDevice) && (past->past_NumInputChannels > 0) )";
3594   z[lc++]="	{";
3595   z[lc++]="		result = PaHost_OpenInputStream( past );";
3596   z[lc++]="		if( result < 0 ) goto error;";
3597   z[lc++]="	}";
3598   z[lc++]="/* Calculate scalar used in CPULoad calculation. */ ";
3599   z[lc++]="	{";
3600   z[lc++]="		LARGE_INTEGER frequency;";
3601   z[lc++]="		if( QueryPerformanceFrequency( &frequency ) == 0 )";
3602   z[lc++]="		{";
3603   z[lc++]="			pahsc->pahsc_InverseTicksPerHostBuffer = 0.0;";
3604   z[lc++]="		}";
3605   z[lc++]="		else";
3606   z[lc++]="		{";
3607   z[lc++]="			pahsc->pahsc_InverseTicksPerHostBuffer = past->past_SampleRate /";
3608   z[lc++]="				( (double)frequency.QuadPart * past->past_FramesPerUserBuffer * pahsc->pahsc_UserBuffersPerHostBuffer );";
3609   z[lc++]="			DBUG((\"pahsc_InverseTicksPerHostBuffer = %g\\n\", pahsc->pahsc_InverseTicksPerHostBuffer ));";
3610   z[lc++]="		}";
3611   z[lc++]="	}";
3612   z[lc++]="	return result;";
3613   z[lc++]="error:";
3614   z[lc++]="	PaHost_CloseStream( past );";
3615   z[lc++]="	return result;";
3616   z[lc++]="}";
3617   z[lc++]="/*************************************************************************/";
3618   z[lc++]="PaError PaHost_StartOutput( internalPortAudioStream *past )";
3619   z[lc++]="{";
3620   z[lc++]="	MMRESULT         mr;";
3621   z[lc++]="	PaHostSoundControl *pahsc;";
3622   z[lc++]="	PaError          result = paNoError;";
3623   z[lc++]="	int              i;";
3624   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3625   z[lc++]="    if( past->past_OutputDeviceID != paNoDevice )";
3626   z[lc++]="	{";
3627   z[lc++]="        if( (mr = waveOutPause( pahsc->pahsc_HWaveOut )) != MMSYSERR_NOERROR )";
3628   z[lc++]="		{";
3629   z[lc++]="			result = paHostError;";
3630   z[lc++]="			sPaHostError = mr;";
3631   z[lc++]="			goto error;";
3632   z[lc++]="		}";
3633   z[lc++]="        for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
3634   z[lc++]="		{";
3635   z[lc++]="            ZeroMemory( pahsc->pahsc_OutputBuffers[i].lpData, pahsc->pahsc_OutputBuffers[i].dwBufferLength );";
3636   z[lc++]="            mr = waveOutWrite( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) );";
3637   z[lc++]="			if( mr != MMSYSERR_NOERROR )";
3638   z[lc++]="			{";
3639   z[lc++]="				result = paHostError;";
3640   z[lc++]="				sPaHostError = mr;";
3641   z[lc++]="				goto error;";
3642   z[lc++]="			}";
3643   z[lc++]="			past->past_FrameCount += pahsc->pahsc_FramesPerHostBuffer;";
3644   z[lc++]="        }";
3645   z[lc++]="        pahsc->pahsc_CurrentOutputBuffer = 0;";
3646   z[lc++]="		if( (mr = waveOutRestart( pahsc->pahsc_HWaveOut )) != MMSYSERR_NOERROR )";
3647   z[lc++]="		{";
3648   z[lc++]="			result = paHostError;";
3649   z[lc++]="			sPaHostError = mr;";
3650   z[lc++]="			goto error;";
3651   z[lc++]="		}";
3652   z[lc++]="	}";
3653   z[lc++]="	DBUG((\"PaHost_StartOutput: DSW_StartOutput returned = 0x%X.\\n\", hr));";
3654   z[lc++]="error:";
3655   z[lc++]="	return result;";
3656   z[lc++]="}";
3657   z[lc++]="/*************************************************************************/";
3658   z[lc++]="PaError PaHost_StartInput( internalPortAudioStream *past )";
3659   z[lc++]="{";
3660   z[lc++]="	PaError          result = paNoError;";
3661   z[lc++]="	MMRESULT         mr;";
3662   z[lc++]="	int              i;";
3663   z[lc++]="	PaHostSoundControl *pahsc;";
3664   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3665   z[lc++]="    if( past->past_InputDeviceID != paNoDevice )";
3666   z[lc++]="    {";
3667   z[lc++]="        for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
3668   z[lc++]="		{";
3669   z[lc++]="            mr = waveInAddBuffer( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) );";
3670   z[lc++]="			if( mr != MMSYSERR_NOERROR )";
3671   z[lc++]="			{";
3672   z[lc++]="				result = paHostError;";
3673   z[lc++]="				sPaHostError = mr;";
3674   z[lc++]="				goto error;";
3675   z[lc++]="			}";
3676   z[lc++]="        }";
3677   z[lc++]="        pahsc->pahsc_CurrentInputBuffer = 0;";
3678   z[lc++]="		mr = waveInStart( pahsc->pahsc_HWaveIn );";
3679   z[lc++]="		DBUG((\"Pa_StartStream: waveInStart returned = 0x%X.\\n\", hr));";
3680   z[lc++]="		if( mr != MMSYSERR_NOERROR )";
3681   z[lc++]="		{";
3682   z[lc++]="			result = paHostError;";
3683   z[lc++]="			sPaHostError = mr;";
3684   z[lc++]="			goto error;";
3685   z[lc++]="		}";
3686   z[lc++]="	}";
3687   z[lc++]="error:";
3688   z[lc++]="	return result;";
3689   z[lc++]="}";
3690   z[lc++]="/*************************************************************************/";
3691   z[lc++]="PaError PaHost_StartEngine( internalPortAudioStream *past )";
3692   z[lc++]="{";
3693   z[lc++]="	PaError             result = paNoError;";
3694   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3695   z[lc++]="#if PA_USE_TIMER_CALLBACK";
3696   z[lc++]="	int                 resolution;";
3697   z[lc++]="	int                 bufsPerTimerCallback;";
3698   z[lc++]="	int                 msecPerBuffer;";
3699   z[lc++]="#endif /* PA_USE_TIMER_CALLBACK */";
3700   z[lc++]="	";
3701   z[lc++]="    past->past_StopSoon = 0;";
3702   z[lc++]="    past->past_StopNow = 0;";
3703   z[lc++]="	past->past_IsActive = 1;";
3704   z[lc++]="	pahsc->pahsc_FramesPlayed = 0.0;";
3705   z[lc++]="	pahsc->pahsc_LastPosition = 0;";
3706   z[lc++]="#if PA_TRACE_START_STOP";
3707   z[lc++]="    AddTraceMessage( \"PaHost_StartEngine: TimeSlice() returned \", result );";
3708   z[lc++]="#endif";
3709   z[lc++]="#if PA_USE_TIMER_CALLBACK";
3710   z[lc++]="/* Create timer that will wake us up so we can fill the DSound buffer. */";
3711   z[lc++]="	bufsPerTimerCallback = pahsc->pahsc_NumHostBuffers/4;";
3712   z[lc++]="	if( bufsPerTimerCallback < 1 ) bufsPerTimerCallback = 1;";
3713   z[lc++]="	if( bufsPerTimerCallback < 1 ) bufsPerTimerCallback = 1;";
3714   z[lc++]="	msecPerBuffer = (1000 * bufsPerTimerCallback *";
3715   z[lc++]="		pahsc->pahsc_UserBuffersPerHostBuffer *";
3716   z[lc++]="		past->past_FramesPerUserBuffer ) / (int) past->past_SampleRate;";
3717   z[lc++]="	if( msecPerBuffer < 10 ) msecPerBuffer = 10;";
3718   z[lc++]="	else if( msecPerBuffer > 100 ) msecPerBuffer = 100;";
3719   z[lc++]="	resolution = msecPerBuffer/4;";
3720   z[lc++]="	pahsc->pahsc_TimerID = timeSetEvent( msecPerBuffer, resolution,";
3721   z[lc++]="	                                     (LPTIMECALLBACK) Pa_TimerCallback,";
3722   z[lc++]="	                                     (DWORD) past, TIME_PERIODIC );";
3723   z[lc++]="	if( pahsc->pahsc_TimerID == 0 )";
3724   z[lc++]="	{";
3725   z[lc++]="		result = paHostError;";
3726   z[lc++]="		sPaHostError = GetLastError();;";
3727   z[lc++]="		goto error;";
3728   z[lc++]="	}";
3729   z[lc++]="#else /* PA_USE_TIMER_CALLBACK */";
3730   z[lc++]="	ResetEvent( pahsc->pahsc_AbortEvent );";
3731   z[lc++]="/* Create thread that waits for audio buffers to be ready for processing. */";
3732   z[lc++]="	pahsc->pahsc_EngineThread = CreateThread( 0, 0, WinMMPa_OutputThreadProc, past, 0, &pahsc->pahsc_EngineThreadID );";
3733   z[lc++]="	if( pahsc->pahsc_EngineThread == NULL )";
3734   z[lc++]="	{";
3735   z[lc++]="		result = paHostError;";
3736   z[lc++]="		sPaHostError = GetLastError();;";
3737   z[lc++]="		goto error;";
3738   z[lc++]="	}";
3739   z[lc++]="#if PA_TRACE_START_STOP";
3740   z[lc++]="    AddTraceMessage( \"PaHost_StartEngine: thread \", (int) pahsc->pahsc_EngineThread );";
3741   z[lc++]="#endif";
3742   z[lc++]="/* I used to pass the thread which was failing. I now pass GetCurrentProcess().";
3743   z[lc++]="** This fix could improve latency for some applications. It could also result in CPU";
3744   z[lc++]="** starvation if the callback did too much processing.";
3745   z[lc++]="** I also added result checks, so we might see more failures at initialization.";
3746   z[lc++]="** Thanks to Alberto di Bene for spotting this.";
3747   z[lc++]="*/";
3748   z[lc++]="    if( !SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) ) /* PLB20010816 */";
3749   z[lc++]="	{";
3750   z[lc++]="		result = paHostError;";
3751   z[lc++]="		sPaHostError = GetLastError();;";
3752   z[lc++]="		goto error;";
3753   z[lc++]="	}";
3754   z[lc++]="    if( !SetThreadPriority( pahsc->pahsc_EngineThread, THREAD_PRIORITY_HIGHEST ) )";
3755   z[lc++]="	{";
3756   z[lc++]="		result = paHostError;";
3757   z[lc++]="		sPaHostError = GetLastError();;";
3758   z[lc++]="		goto error;";
3759   z[lc++]="	}";
3760   z[lc++]="#endif";
3761   z[lc++]="error:";
3762   z[lc++]="	return result;";
3763   z[lc++]="}";
3764   z[lc++]="/*************************************************************************/";
3765   z[lc++]="PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )";
3766   z[lc++]="{";
3767   z[lc++]="	int timeOut;";
3768   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3769   z[lc++]="	if( pahsc == NULL ) return paNoError;";
3770   z[lc++]="/* Tell background thread to stop generating more data and to let current data play out. */";
3771   z[lc++]="	past->past_StopSoon = 1;";
3772   z[lc++]="/* If aborting, tell background thread to stop NOW! */";
3773   z[lc++]="	if( abort ) past->past_StopNow = 1;";
3774   z[lc++]="/* Calculate timeOut longer than longest time it could take to play all buffers. */";
3775   z[lc++]="	timeOut = (DWORD) (1500.0 * PaHost_GetTotalBufferFrames( past ) / past->past_SampleRate);";
3776   z[lc++]="	if( timeOut < MIN_TIMEOUT_MSEC ) timeOut = MIN_TIMEOUT_MSEC;";
3777   z[lc++]="#if PA_USE_TIMER_CALLBACK";
3778   z[lc++]="	if( (past->past_OutputDeviceID != paNoDevice) &&";
3779   z[lc++]="		past->past_IsActive &&";
3780   z[lc++]="		(pahsc->pahsc_TimerID != 0) )";
3781   z[lc++]="	{";
3782   z[lc++]="	/* Wait for IsActive to drop. */";
3783   z[lc++]="		while( (past->past_IsActive) &&	(timeOut > 0) )";
3784   z[lc++]="		{";
3785   z[lc++]="			Sleep(10);";
3786   z[lc++]="			timeOut -= 10;";
3787   z[lc++]="		}";
3788   z[lc++]="		timeKillEvent(pahsc->pahsc_TimerID);  /* Stop callback timer. */";
3789   z[lc++]="		pahsc->pahsc_TimerID = 0;";
3790   z[lc++]="	}";
3791   z[lc++]="#else /* PA_USE_TIMER_CALLBACK */";
3792   z[lc++]="#if PA_TRACE_START_STOP";
3793   z[lc++]="    AddTraceMessage( \"PaHost_StopEngine: thread \", (int) pahsc->pahsc_EngineThread );";
3794   z[lc++]="#endif";
3795   z[lc++]="    if( (past->past_OutputDeviceID != paNoDevice) &&";
3796   z[lc++]="		(past->past_IsActive) &&";
3797   z[lc++]="		(pahsc->pahsc_EngineThread != NULL) )";
3798   z[lc++]="	{";
3799   z[lc++]="		DWORD got;";
3800   z[lc++]="/* Tell background thread to stop generating more data and to let current data play out. */";
3801   z[lc++]="		DBUG((\"PaHost_StopEngine: waiting for background thread.\\n\"));";
3802   z[lc++]="        got = WaitForSingleObject( pahsc->pahsc_EngineThread, timeOut );";
3803   z[lc++]="		if( got == WAIT_TIMEOUT )";
3804   z[lc++]="		{";
3805   z[lc++]="			ERR_RPT((\"PaHost_StopEngine: timed out while waiting for background thread.\\n\"));";
3806   z[lc++]="			return paTimedOut;";
3807   z[lc++]="		}";
3808   z[lc++]="		CloseHandle( pahsc->pahsc_EngineThread );";
3809   z[lc++]="		pahsc->pahsc_EngineThread = NULL;";
3810   z[lc++]="    }";
3811   z[lc++]="#endif /* PA_USE_TIMER_CALLBACK */";
3812   z[lc++]="	past->past_IsActive = 0;";
3813   z[lc++]="	return paNoError;";
3814   z[lc++]="}";
3815   z[lc++]="/*************************************************************************/";
3816   z[lc++]="PaError PaHost_StopInput( internalPortAudioStream *past, int abort )";
3817   z[lc++]="{";
3818   z[lc++]="	MMRESULT mr;";
3819   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3820   z[lc++]="	if( pahsc == NULL ) return paNoError;";
3821   z[lc++]="	(void) abort;";
3822   z[lc++]="    if( pahsc->pahsc_HWaveIn != NULL )";
3823   z[lc++]="	{";
3824   z[lc++]="		mr = waveInReset( pahsc->pahsc_HWaveIn );";
3825   z[lc++]="		if( mr != MMSYSERR_NOERROR )";
3826   z[lc++]="		{";
3827   z[lc++]="			sPaHostError = mr;";
3828   z[lc++]="			return paHostError;";
3829   z[lc++]="		}";
3830   z[lc++]="	}";
3831   z[lc++]="	return paNoError;";
3832   z[lc++]="}";
3833   z[lc++]="/*************************************************************************/";
3834   z[lc++]="PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )";
3835   z[lc++]="{";
3836   z[lc++]="	MMRESULT mr;";
3837   z[lc++]="	PaHostSoundControl *pahsc;";
3838   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3839   z[lc++]="	if( pahsc == NULL ) return paNoError;";
3840   z[lc++]="	(void) abort;";
3841   z[lc++]="#if PA_TRACE_START_STOP";
3842   z[lc++]="    AddTraceMessage( \"PaHost_StopOutput: pahsc_HWaveOut \", (int) pahsc->pahsc_HWaveOut );";
3843   z[lc++]="#endif";
3844   z[lc++]="   if( pahsc->pahsc_HWaveOut != NULL )";
3845   z[lc++]="	{";
3846   z[lc++]="		mr = waveOutReset( pahsc->pahsc_HWaveOut );";
3847   z[lc++]="		if( mr != MMSYSERR_NOERROR )";
3848   z[lc++]="		{";
3849   z[lc++]="			sPaHostError = mr;";
3850   z[lc++]="			return paHostError;";
3851   z[lc++]="		}";
3852   z[lc++]="	}";
3853   z[lc++]="	return paNoError;";
3854   z[lc++]="}";
3855   z[lc++]="/*******************************************************************/";
3856   z[lc++]="PaError PaHost_CloseStream( internalPortAudioStream   *past )";
3857   z[lc++]="{";
3858   z[lc++]="	int                 i;";
3859   z[lc++]="	PaHostSoundControl *pahsc;";
3860   z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
3861   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
3862   z[lc++]="	if( pahsc == NULL ) return paNoError;";
3863   z[lc++]="#if PA_TRACE_START_STOP";
3864   z[lc++]="    AddTraceMessage( \"PaHost_CloseStream: pahsc_HWaveOut \", (int) pahsc->pahsc_HWaveOut );";
3865   z[lc++]="#endif";
3866   z[lc++]="/* Free data and device for output. */";
3867   z[lc++]="    if( pahsc->pahsc_HWaveOut )";
3868   z[lc++]="	{";
3869   z[lc++]="        if( pahsc->pahsc_OutputBuffers )";
3870   z[lc++]="		{";
3871   z[lc++]="            for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
3872   z[lc++]="			{";
3873   z[lc++]="                waveOutUnprepareHeader( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) );";
3874   z[lc++]="                GlobalFree( pahsc->pahsc_OutputBuffers[i].lpData ); /* MEM */";
3875   z[lc++]="            }";
3876   z[lc++]="            GlobalFree( pahsc->pahsc_OutputBuffers ); /* MEM */";
3877   z[lc++]="        }";
3878   z[lc++]="        waveOutClose( pahsc->pahsc_HWaveOut );";
3879   z[lc++]="    }";
3880   z[lc++]=" /* Free data and device for input. */";
3881   z[lc++]="   if( pahsc->pahsc_HWaveIn )";
3882   z[lc++]="	{";
3883   z[lc++]="        if( pahsc->pahsc_InputBuffers )";
3884   z[lc++]="		{";
3885   z[lc++]="            for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
3886   z[lc++]="			{";
3887   z[lc++]="                waveInUnprepareHeader( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) );";
3888   z[lc++]="                GlobalFree( pahsc->pahsc_InputBuffers[i].lpData ); /* MEM */";
3889   z[lc++]="            }";
3890   z[lc++]="            GlobalFree( pahsc->pahsc_InputBuffers ); /* MEM */";
3891   z[lc++]="        }";
3892   z[lc++]="        waveInClose( pahsc->pahsc_HWaveIn );";
3893   z[lc++]="    }";
3894   z[lc++]="#if (PA_USE_TIMER_CALLBACK == 0)";
3895   z[lc++]="    if( pahsc->pahsc_AbortEventInited ) CloseHandle( pahsc->pahsc_AbortEvent );";
3896   z[lc++]="    if( pahsc->pahsc_BufferEventInited ) CloseHandle( pahsc->pahsc_BufferEvent );";
3897   z[lc++]="#endif";
3898   z[lc++]="	if( pahsc->pahsc_StreamLockInited )";
3899   z[lc++]="	DeleteCriticalSection( &pahsc->pahsc_StreamLock );";
3900   z[lc++]="	PaHost_FreeFastMemory( pahsc, sizeof(PaHostSoundControl) ); /* MEM */";
3901   z[lc++]="	past->past_DeviceData = NULL;";
3902   z[lc++]="	return paNoError;";
3903   z[lc++]="}";
3904   z[lc++]="/*************************************************************************";
3905   z[lc++]="** Determine minimum number of buffers required for this host based";
3906   z[lc++]="** on minimum latency. Latency can be optionally set by user by setting";
3907   z[lc++]="** an environment variable. For example, to set latency to 200 msec, put:";
3908   z[lc++]="**";
3909   z[lc++]="**    set PA_MIN_LATENCY_MSEC=200";
3910   z[lc++]="**";
3911   z[lc++]="** in the AUTOEXEC.BAT file and reboot.";
3912   z[lc++]="** If the environment variable is not set, then the latency will be determined";
3913   z[lc++]="** based on the OS. Windows NT has higher latency than Win95.";
3914   z[lc++]="*/";
3915   z[lc++]="#define PA_LATENCY_ENV_NAME  (\"PA_MIN_LATENCY_MSEC\")";
3916   z[lc++]="int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )";
3917   z[lc++]="{";
3918   z[lc++]="	char      envbuf[PA_ENV_BUF_SIZE];";
3919   z[lc++]="	DWORD     hostVersion;";
3920   z[lc++]="	DWORD     hresult;";
3921   z[lc++]="	int       minLatencyMsec = 0;";
3922   z[lc++]="	double    msecPerBuffer = (1000.0 * framesPerBuffer) / sampleRate;";
3923   z[lc++]="	int       minBuffers;";
3924   z[lc++]="/* Let user determine minimal latency by setting environment variable. */";
3925   z[lc++]="	hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );";
3926   z[lc++]="	if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )";
3927   z[lc++]="	{";
3928   z[lc++]="		minLatencyMsec = atoi( envbuf );";
3929   z[lc++]="	}";
3930   z[lc++]="	else";
3931   z[lc++]="	{";
3932   z[lc++]="/* Set minimal latency based on whether NT or Win95.";
3933   z[lc++]=" * NT has higher latency.";
3934   z[lc++]=" */";
3935   z[lc++]="		hostVersion = GetVersion();";
3936   z[lc++]="/* High bit clear if NT */";
3937   z[lc++]="		minLatencyMsec = ( (hostVersion & 0x80000000) == 0 ) ? PA_WIN_NT_LATENCY : PA_WIN_9X_LATENCY  ;";
3938   z[lc++]="#if PA_USE_HIGH_LATENCY";
3939   z[lc++]="		PRINT((\"PA - Minimum Latency set to %d msec!\\n\", minLatencyMsec ));";
3940   z[lc++]="#endif";
3941   z[lc++]="	}";
3942   z[lc++]="	DBUG((\"PA - Minimum Latency set to %d msec!\\n\", minLatencyMsec ));";
3943   z[lc++]="	minBuffers = (int) (1.0 + ((double)minLatencyMsec / msecPerBuffer));";
3944   z[lc++]="	if( minBuffers < 2 ) minBuffers = 2;";
3945   z[lc++]="	return minBuffers;";
3946   z[lc++]="}";
3947   z[lc++]="/*************************************************************************";
3948   z[lc++]="** Cleanup device info.";
3949   z[lc++]="*/";
3950   z[lc++]="PaError PaHost_Term( void )";
3951   z[lc++]="{";
3952   z[lc++]="    int i;";
3953   z[lc++]="    if( sNumDevices > 0 ){";
3954   z[lc++]="        if( sDevicePtrs != NULL ){";
3955   z[lc++]="            for( i=0; i<sNumDevices; i++ )";
3956   z[lc++]="			{";
3957   z[lc++]="                if( sDevicePtrs[i] != NULL )";
3958   z[lc++]="				{";
3959   z[lc++]="                    GlobalFree( (char*)sDevicePtrs[i]->name ); /* MEM */";
3960   z[lc++]="                    GlobalFree( (void*)sDevicePtrs[i]->sampleRates ); /* MEM */";
3961   z[lc++]="                    GlobalFree( sDevicePtrs[i] ); /* MEM */";
3962   z[lc++]="                }";
3963   z[lc++]="            }";
3964   z[lc++]="            GlobalFree( sDevicePtrs ); /* MEM */";
3965   z[lc++]="            sDevicePtrs = NULL;";
3966   z[lc++]="        }";
3967   z[lc++]="        sNumDevices = 0;";
3968   z[lc++]="    }";
3969   z[lc++]="    return paNoError;";
3970   z[lc++]="}";
3971   z[lc++]="/*************************************************************************/";
3972   z[lc++]="void Pa_Sleep( long msec )";
3973   z[lc++]="{";
3974   z[lc++]="	Sleep( msec );";
3975   z[lc++]="}";
3976   z[lc++]="/*************************************************************************";
3977   z[lc++]=" * Allocate memory that can be accessed in real-time.";
3978   z[lc++]=" * This may need to be held in physical memory so that it is not";
3979   z[lc++]=" * paged to virtual memory.";
3980   z[lc++]=" * This call MUST be balanced with a call to PaHost_FreeFastMemory().";
3981   z[lc++]=" * Memory will be set to zero.";
3982   z[lc++]=" */";
3983   z[lc++]="void *PaHost_AllocateFastMemory( long numBytes )";
3984   z[lc++]="{";
3985   z[lc++]="	void *addr = GlobalAlloc( GPTR, numBytes ); /* FIXME - do we need physical memory? Use VirtualLock() */ /* MEM */";
3986   z[lc++]="	return addr;";
3987   z[lc++]="}";
3988   z[lc++]="/*************************************************************************";
3989   z[lc++]=" * Free memory that could be accessed in real-time.";
3990   z[lc++]=" * This call MUST be balanced with a call to PaHost_AllocateFastMemory().";
3991   z[lc++]=" */";
3992   z[lc++]="void PaHost_FreeFastMemory( void *addr, long numBytes )";
3993   z[lc++]="{";
3994   z[lc++]="	if( addr != NULL ) GlobalFree( addr ); /* MEM */";
3995   z[lc++]="}";
3996   z[lc++]="/***********************************************************************/";
3997   z[lc++]="PaError PaHost_StreamActive( internalPortAudioStream   *past )";
3998   z[lc++]="{";
3999   z[lc++]="	PaHostSoundControl *pahsc;";
4000   z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
4001   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
4002   z[lc++]="	if( pahsc == NULL ) return paInternalError;";
4003   z[lc++]="	return (PaError) past->past_IsActive;";
4004   z[lc++]="}";
4005   z[lc++]="/*************************************************************************";
4006   z[lc++]=" * This must be called periodically because mmtime.u.sample";
4007   z[lc++]=" * is a DWORD and can wrap and lose sync after a few hours.";
4008   z[lc++]=" */";
4009   z[lc++]="static PaError PaHost_UpdateStreamTime( PaHostSoundControl *pahsc )";
4010   z[lc++]="{";
4011   z[lc++]="	MMRESULT  mr;";
4012   z[lc++]="	MMTIME    mmtime;";
4013   z[lc++]="	mmtime.wType = TIME_SAMPLES;";
4014   z[lc++]="	if( pahsc->pahsc_HWaveOut != NULL )";
4015   z[lc++]="	{";
4016   z[lc++]="		mr = waveOutGetPosition( pahsc->pahsc_HWaveOut, &mmtime, sizeof(mmtime) );";
4017   z[lc++]="	}";
4018   z[lc++]="	else";
4019   z[lc++]="	{";
4020   z[lc++]="		mr = waveInGetPosition( pahsc->pahsc_HWaveIn, &mmtime, sizeof(mmtime) );";
4021   z[lc++]="	}";
4022   z[lc++]="	if( mr != MMSYSERR_NOERROR )";
4023   z[lc++]="	{";
4024   z[lc++]="		sPaHostError = mr;";
4025   z[lc++]="		return paHostError;";
4026   z[lc++]="	}";
4027   z[lc++]="/* This data has two variables and is shared by foreground and background. */";
4028   z[lc++]="/* So we need to make it thread safe. */";
4029   z[lc++]="	EnterCriticalSection( &pahsc->pahsc_StreamLock );";
4030   z[lc++]="		pahsc->pahsc_FramesPlayed += ((long)mmtime.u.sample) - pahsc->pahsc_LastPosition;";
4031   z[lc++]="		pahsc->pahsc_LastPosition = (long)mmtime.u.sample;";
4032   z[lc++]="    LeaveCriticalSection( &pahsc->pahsc_StreamLock );";
4033   z[lc++]="	return paNoError;";
4034   z[lc++]="}";
4035   z[lc++]="/*************************************************************************/";
4036   z[lc++]="PaTimestamp Pa_StreamTime( PortAudioStream *stream )";
4037   z[lc++]="{";
4038   z[lc++]="	PaHostSoundControl *pahsc;";
4039   z[lc++]="	internalPortAudioStream   *past = (internalPortAudioStream *) stream;";
4040   z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
4041   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
4042   z[lc++]="	PaHost_UpdateStreamTime( pahsc );";
4043   z[lc++]="	return pahsc->pahsc_FramesPlayed;";
4044   z[lc++]="}";
4045   printlib(lc);
4046 }
4047 
4048 
4049 void makepa_dshdr(void)
4050 {
4051   int lc = 0;
4052 
4053   z[lc++]="#ifndef __DSOUND_WRAPPER_H";
4054   z[lc++]="#define __DSOUND_WRAPPER_H";
4055   z[lc++]="/*";
4056   z[lc++]=" * Simplified DirectSound interface.";
4057   z[lc++]=" *";
4058   z[lc++]=" * Author: Phil Burk & Robert Marsanyi";
4059   z[lc++]=" *";
4060   z[lc++]=" * For PortAudio Portable Real-Time Audio Library";
4061   z[lc++]=" * For more information see: http://www.softsynth.com/portaudio/";
4062   z[lc++]=" * DirectSound Implementation";
4063   z[lc++]=" * Copyright (c) 1999-2000 Phil Burk & Robert Marsanyi";
4064   z[lc++]=" *";
4065   z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
4066   z[lc++]=" * a copy of this software and associated documentation files";
4067   z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
4068   z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
4069   z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
4070   z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
4071   z[lc++]=" * subject to the following conditions:";
4072   z[lc++]=" *";
4073   z[lc++]=" * The above copyright notice and this permission notice shall be";
4074   z[lc++]=" * included in all copies or substantial portions of the Software.";
4075   z[lc++]=" *";
4076   z[lc++]=" * Any person wishing to distribute modifications to the Software is";
4077   z[lc++]=" * requested to send the modifications to the original developer so that";
4078   z[lc++]=" * they can be incorporated into the canonical version.";
4079   z[lc++]=" *";
4080   z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
4081   z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
4082   z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
4083   z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
4084   z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
4085   z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
4086   z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
4087   z[lc++]=" *";
4088   z[lc++]=" */";
4089   z[lc++]="#include <DSound.h>";
4090   z[lc++]="#if !defined(BOOL)";
4091   z[lc++]="#define BOOL short";
4092   z[lc++]="#endif";
4093   z[lc++]="#ifndef SUPPORT_AUDIO_CAPTURE";
4094   z[lc++]="#define SUPPORT_AUDIO_CAPTURE  (1)";
4095   z[lc++]="#endif";
4096   z[lc++]="#ifdef __cplusplus";
4097   z[lc++]="extern \"C\" {";
4098   z[lc++]="#endif /* __cplusplus */	";
4099   z[lc++]="#define DSW_NUM_POSITIONS     (4)";
4100   z[lc++]="#define DSW_NUM_EVENTS        (5)";
4101   z[lc++]="#define DSW_TERMINATION_EVENT     (DSW_NUM_POSITIONS)";
4102   z[lc++]="typedef struct";
4103   z[lc++]="{";
4104   z[lc++]="/* Output */";
4105   z[lc++]="	LPDIRECTSOUND        dsw_pDirectSound;";
4106   z[lc++]="	LPDIRECTSOUNDBUFFER  dsw_OutputBuffer;";
4107   z[lc++]="	DWORD                dsw_WriteOffset;     /* last write position */";
4108   z[lc++]="	INT                  dsw_OutputSize;";
4109   z[lc++]="	INT                  dsw_BytesPerFrame;";
4110   z[lc++]="/* Try to detect play buffer underflows. */";
4111   z[lc++]="	LARGE_INTEGER        dsw_CounterTicksPerBuffer; /* counter ticks it should take to play a full buffer */";
4112   z[lc++]="	LARGE_INTEGER        dsw_LastPlayTime;";
4113   z[lc++]="	UINT                 dsw_LastPlayCursor;";
4114   z[lc++]="	UINT                 dsw_OutputUnderflows;";
4115   z[lc++]="	BOOL                 dsw_OutputRunning;";
4116   z[lc++]="/* use double which lets us can play for several thousand years with enough precision */";
4117   z[lc++]="	double               dsw_FramesWritten;";
4118   z[lc++]="	double               dsw_FramesPlayed;";
4119   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
4120   z[lc++]="	/* Input */";
4121   z[lc++]="	LPDIRECTSOUNDCAPTURE dsw_pDirectSoundCapture;";
4122   z[lc++]="	LPDIRECTSOUNDCAPTUREBUFFER   dsw_InputBuffer;";
4123   z[lc++]="	UINT                 dsw_ReadOffset;      /* last read position */";
4124   z[lc++]="	UINT                 dsw_InputSize;";
4125   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
4126   z[lc++]="} DSoundWrapper;";
4127   z[lc++]="HRESULT DSW_Init( DSoundWrapper *dsw );";
4128   z[lc++]="void DSW_Term( DSoundWrapper *dsw );";
4129   z[lc++]="HRESULT DSW_InitOutputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate,";
4130   z[lc++]="							 int nChannels, int bufSize );";
4131   z[lc++]="HRESULT DSW_StartOutput( DSoundWrapper *dsw );";
4132   z[lc++]="HRESULT DSW_StopOutput( DSoundWrapper *dsw );";
4133   z[lc++]="DWORD   DSW_GetOutputStatus( DSoundWrapper *dsw );";
4134   z[lc++]="HRESULT DSW_WriteBlock( DSoundWrapper *dsw, char *buf, long numBytes );";
4135   z[lc++]="HRESULT DSW_ZeroEmptySpace( DSoundWrapper *dsw );";
4136   z[lc++]="HRESULT DSW_QueryOutputSpace( DSoundWrapper *dsw, long *bytesEmpty );";
4137   z[lc++]="HRESULT DSW_Enumerate( DSoundWrapper *dsw );";
4138   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
4139   z[lc++]="HRESULT DSW_InitInputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate,";
4140   z[lc++]="							 int nChannels, int bufSize );";
4141   z[lc++]="HRESULT DSW_StartInput( DSoundWrapper *dsw );";
4142   z[lc++]="HRESULT DSW_StopInput( DSoundWrapper *dsw );";
4143   z[lc++]="HRESULT DSW_ReadBlock( DSoundWrapper *dsw, char *buf, long numBytes );";
4144   z[lc++]="HRESULT DSW_QueryInputFilled( DSoundWrapper *dsw, long *bytesFilled );";
4145   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
4146   z[lc++]="#ifdef __cplusplus";
4147   z[lc++]="}";
4148   z[lc++]="#endif /* __cplusplus */";
4149   z[lc++]="#endif  /* __DSOUND_WRAPPER_H */";
4150   printlib(lc);
4151 }
4152 
4153 
4154 void makepa_dswrap(void)
4155 {
4156   int lc = 0;
4157 
4158   z[lc++]="/*";
4159   z[lc++]=" * Simplified DirectSound interface.";
4160   z[lc++]=" *";
4161   z[lc++]=" * Author: Phil Burk & Robert Marsanyi";
4162   z[lc++]=" *";
4163   z[lc++]=" * PortAudio Portable Real-Time Audio Library";
4164   z[lc++]=" * For more information see: http://www.softsynth.com/portaudio/";
4165   z[lc++]=" * DirectSound Implementation";
4166   z[lc++]=" * Copyright (c) 1999-2000 Phil Burk & Robert Marsanyi";
4167   z[lc++]=" *";
4168   z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
4169   z[lc++]=" * a copy of this software and associated documentation files";
4170   z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
4171   z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
4172   z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
4173   z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
4174   z[lc++]=" * subject to the following conditions:";
4175   z[lc++]=" *";
4176   z[lc++]=" * The above copyright notice and this permission notice shall be";
4177   z[lc++]=" * included in all copies or substantial portions of the Software.";
4178   z[lc++]=" *";
4179   z[lc++]=" * Any person wishing to distribute modifications to the Software is";
4180   z[lc++]=" * requested to send the modifications to the original developer so that";
4181   z[lc++]=" * they can be incorporated into the canonical version.";
4182   z[lc++]=" *";
4183   z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
4184   z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
4185   z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
4186   z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
4187   z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
4188   z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
4189   z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
4190   z[lc++]=" *";
4191   z[lc++]=" */";
4192   z[lc++]="#include <stdio.h>";
4193   z[lc++]="#include <stdlib.h>";
4194   z[lc++]="#include <math.h>";
4195   z[lc++]="#define INITGUID     // Needed to build IID_IDirectSoundNotify. See objbase.h for info.";
4196   z[lc++]="#include <objbase.h>";
4197   z[lc++]="#include <unknwn.h>";
4198   z[lc++]="#if 0";
4199   z[lc++]="#include \"dsound_wrapper.h\"";
4200   z[lc++]="#include \"pa_trace.h\"";
4201   z[lc++]="#endif";
4202   z[lc++]="/************************************************************************************/";
4203   z[lc++]="void DSW_Term( DSoundWrapper *dsw )";
4204   z[lc++]="{";
4205   z[lc++]="// Cleanup the sound buffers";
4206   z[lc++]="	if (dsw->dsw_OutputBuffer)";
4207   z[lc++]="	{";
4208   z[lc++]="		IDirectSoundBuffer_Stop( dsw->dsw_OutputBuffer );";
4209   z[lc++]="		IDirectSoundBuffer_Release( dsw->dsw_OutputBuffer );";
4210   z[lc++]="		dsw->dsw_OutputBuffer = NULL;";
4211   z[lc++]="	}";
4212   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
4213   z[lc++]="	if (dsw->dsw_InputBuffer)";
4214   z[lc++]="	{";
4215   z[lc++]="		IDirectSoundCaptureBuffer_Stop( dsw->dsw_InputBuffer );";
4216   z[lc++]="		IDirectSoundCaptureBuffer_Release( dsw->dsw_InputBuffer );";
4217   z[lc++]="		dsw->dsw_InputBuffer = NULL;";
4218   z[lc++]="	}";
4219   z[lc++]="	if (dsw->dsw_pDirectSoundCapture)";
4220   z[lc++]="	{";
4221   z[lc++]="		IDirectSoundCapture_Release( dsw->dsw_pDirectSoundCapture );";
4222   z[lc++]="		dsw->dsw_pDirectSoundCapture = NULL;";
4223   z[lc++]="	}";
4224   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
4225   z[lc++]="	if (dsw->dsw_pDirectSound)";
4226   z[lc++]="	{";
4227   z[lc++]="		IDirectSound_Release( dsw->dsw_pDirectSound );";
4228   z[lc++]="		dsw->dsw_pDirectSound = NULL;";
4229   z[lc++]="	}";
4230   z[lc++]="}";
4231   z[lc++]="/************************************************************************************/";
4232   z[lc++]="HRESULT DSW_Init( DSoundWrapper *dsw )";
4233   z[lc++]="{";
4234   z[lc++]="	memset( dsw, 0, sizeof(DSoundWrapper) );";
4235   z[lc++]="	return 0;";
4236   z[lc++]="}";
4237   z[lc++]="/************************************************************************************/";
4238   z[lc++]="HRESULT DSW_InitOutputDevice( DSoundWrapper *dsw, LPGUID lpGUID )";
4239   z[lc++]="{";
4240   z[lc++]="// Create the DS object";
4241   z[lc++]="	HRESULT hr = DirectSoundCreate( lpGUID, &dsw->dsw_pDirectSound, NULL );";
4242   z[lc++]="	if( hr != DS_OK ) return hr;";
4243   z[lc++]="	return hr;";
4244   z[lc++]="}";
4245   z[lc++]="/************************************************************************************/";
4246   z[lc++]="HRESULT DSW_InitOutputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate, int nChannels, int bytesPerBuffer )";
4247   z[lc++]="{";
4248   z[lc++]="	DWORD          dwDataLen;";
4249   z[lc++]="	DWORD          playCursor;";
4250   z[lc++]="	HRESULT        result;";
4251   z[lc++]="	LPDIRECTSOUNDBUFFER pPrimaryBuffer;";
4252   z[lc++]="	HWND           hWnd;";
4253   z[lc++]="	HRESULT        hr;";
4254   z[lc++]="	WAVEFORMATEX   wfFormat;";
4255   z[lc++]="	DSBUFFERDESC   primaryDesc;";
4256   z[lc++]="	DSBUFFERDESC   secondaryDesc;";
4257   z[lc++]="	unsigned char* pDSBuffData;";
4258   z[lc++]="	LARGE_INTEGER  counterFrequency;";
4259   z[lc++]="	dsw->dsw_OutputSize = bytesPerBuffer;";
4260   z[lc++]="	dsw->dsw_OutputRunning = FALSE;";
4261   z[lc++]="	dsw->dsw_OutputUnderflows = 0;";
4262   z[lc++]="	dsw->dsw_FramesWritten = 0;";
4263   z[lc++]="	dsw->dsw_BytesPerFrame = nChannels * sizeof(short);";
4264   z[lc++]="// We were using getForegroundWindow() but sometimes the ForegroundWindow may not be the";
4265   z[lc++]="// applications's window. Also if that window is closed before the Buffer is closed";
4266   z[lc++]="// then DirectSound can crash. (Thanks for Scott Patterson for reporting this.)";
4267   z[lc++]="// So we will use GetDesktopWindow() which was suggested by Miller Puckette.";
4268   z[lc++]="//	hWnd = GetForegroundWindow();";
4269   z[lc++]="	hWnd = GetDesktopWindow();";
4270   z[lc++]="// Set cooperative level to DSSCL_EXCLUSIVE so that we can get 16 bit output, 44.1 KHz.";
4271   z[lc++]="// Exclusize also prevents unexpected sounds from other apps during a performance.";
4272   z[lc++]="	if ((hr = IDirectSound_SetCooperativeLevel( dsw->dsw_pDirectSound,";
4273   z[lc++]="			hWnd, DSSCL_EXCLUSIVE)) != DS_OK)";
4274   z[lc++]="	{";
4275   z[lc++]="		return hr;";
4276   z[lc++]="	}";
4277   z[lc++]="// -----------------------------------------------------------------------";
4278   z[lc++]="// Create primary buffer and set format just so we can specify our custom format.";
4279   z[lc++]="// Otherwise we would be stuck with the default which might be 8 bit or 22050 Hz.";
4280   z[lc++]="// Setup the primary buffer description";
4281   z[lc++]="	ZeroMemory(&primaryDesc, sizeof(DSBUFFERDESC));";
4282   z[lc++]="	primaryDesc.dwSize        = sizeof(DSBUFFERDESC);";
4283   z[lc++]="	primaryDesc.dwFlags       = DSBCAPS_PRIMARYBUFFER; // all panning, mixing, etc done by synth";
4284   z[lc++]="	primaryDesc.dwBufferBytes = 0;";
4285   z[lc++]="	primaryDesc.lpwfxFormat   = NULL;";
4286   z[lc++]="// Create the buffer";
4287   z[lc++]="	if ((result = IDirectSound_CreateSoundBuffer( dsw->dsw_pDirectSound,";
4288   z[lc++]="			&primaryDesc, &pPrimaryBuffer, NULL)) != DS_OK) return result;";
4289   z[lc++]="// Define the buffer format";
4290   z[lc++]="	wfFormat.wFormatTag = WAVE_FORMAT_PCM;";
4291   z[lc++]="	wfFormat.nChannels = nChannels;";
4292   z[lc++]="	wfFormat.nSamplesPerSec = nFrameRate;";
4293   z[lc++]="	wfFormat.wBitsPerSample = 8 * sizeof(short);";
4294   z[lc++]="	wfFormat.nBlockAlign = wfFormat.nChannels * wfFormat.wBitsPerSample / 8;";
4295   z[lc++]="	wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;";
4296   z[lc++]="	wfFormat.cbSize = 0;  /* No extended format info. */";
4297   z[lc++]="// Set the primary buffer's format";
4298   z[lc++]="	if((result = IDirectSoundBuffer_SetFormat( pPrimaryBuffer, &wfFormat)) != DS_OK) return result;";
4299   z[lc++]="// ----------------------------------------------------------------------";
4300   z[lc++]="// Setup the secondary buffer description";
4301   z[lc++]="	ZeroMemory(&secondaryDesc, sizeof(DSBUFFERDESC));";
4302   z[lc++]="	secondaryDesc.dwSize = sizeof(DSBUFFERDESC);";
4303   z[lc++]="	secondaryDesc.dwFlags =  DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;";
4304   z[lc++]="	secondaryDesc.dwBufferBytes = bytesPerBuffer;";
4305   z[lc++]="	secondaryDesc.lpwfxFormat = &wfFormat;";
4306   z[lc++]="// Create the secondary buffer";
4307   z[lc++]="	if ((result = IDirectSound_CreateSoundBuffer( dsw->dsw_pDirectSound,";
4308   z[lc++]="			&secondaryDesc, &dsw->dsw_OutputBuffer, NULL)) != DS_OK) return result;";
4309   z[lc++]="// Lock the DS buffer";
4310   z[lc++]="	if ((result = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, 0, dsw->dsw_OutputSize, (LPVOID*)&pDSBuffData,";
4311   z[lc++]="	  &dwDataLen, NULL, 0, 0)) != DS_OK) return result;";
4312   z[lc++]="// Zero the DS buffer";
4313   z[lc++]="	ZeroMemory(pDSBuffData, dwDataLen);";
4314   z[lc++]="// Unlock the DS buffer";
4315   z[lc++]="	if ((result = IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) return result;";
4316   z[lc++]="	if( QueryPerformanceFrequency( &counterFrequency ) )";
4317   z[lc++]="	{";
4318   z[lc++]="		int framesInBuffer = bytesPerBuffer / (nChannels * sizeof(short));";
4319   z[lc++]="		dsw->dsw_CounterTicksPerBuffer.QuadPart = (counterFrequency.QuadPart * framesInBuffer) / nFrameRate;";
4320   z[lc++]="		AddTraceMessage(\"dsw_CounterTicksPerBuffer = %d\\n\", dsw->dsw_CounterTicksPerBuffer.LowPart );";
4321   z[lc++]="	}";
4322   z[lc++]="	else";
4323   z[lc++]="	{";
4324   z[lc++]="		dsw->dsw_CounterTicksPerBuffer.QuadPart = 0;";
4325   z[lc++]="	}";
4326   z[lc++]="// Let DSound set the starting write position because if we set it to zero, it looks like the";
4327   z[lc++]="// buffer is full to begin with. This causes a long pause before sound starts when using large buffers.";
4328   z[lc++]="	hr = IDirectSoundBuffer_GetCurrentPosition( dsw->dsw_OutputBuffer, &playCursor, &dsw->dsw_WriteOffset );";
4329   z[lc++]="	if( hr != DS_OK )";
4330   z[lc++]="	{";
4331   z[lc++]="		return hr;";
4332   z[lc++]="	}";
4333   z[lc++]="	dsw->dsw_FramesWritten = dsw->dsw_WriteOffset / dsw->dsw_BytesPerFrame;";
4334   z[lc++]="	/* printf(\"DSW_InitOutputBuffer: playCursor = %d, writeCursor = %d\\n\", playCursor, dsw->dsw_WriteOffset ); */";
4335   z[lc++]="	return DS_OK;";
4336   z[lc++]="}";
4337   z[lc++]="/************************************************************************************/";
4338   z[lc++]="HRESULT DSW_StartOutput( DSoundWrapper *dsw )";
4339   z[lc++]="{";
4340   z[lc++]="	HRESULT        hr;";
4341   z[lc++]="	QueryPerformanceCounter( &dsw->dsw_LastPlayTime );";
4342   z[lc++]="	dsw->dsw_LastPlayCursor = 0;";
4343   z[lc++]="	dsw->dsw_FramesPlayed = 0;";
4344   z[lc++]="	hr = IDirectSoundBuffer_SetCurrentPosition( dsw->dsw_OutputBuffer, 0 );";
4345   z[lc++]="	if( hr != DS_OK )";
4346   z[lc++]="	{";
4347   z[lc++]="		return hr;";
4348   z[lc++]="	}";
4349   z[lc++]="// Start the buffer playback in a loop.";
4350   z[lc++]="	if( dsw->dsw_OutputBuffer != NULL )";
4351   z[lc++]="	{";
4352   z[lc++]="		hr = IDirectSoundBuffer_Play( dsw->dsw_OutputBuffer, 0, 0, DSBPLAY_LOOPING );";
4353   z[lc++]="		if( hr != DS_OK )";
4354   z[lc++]="		{";
4355   z[lc++]="			return hr;";
4356   z[lc++]="		}";
4357   z[lc++]="		dsw->dsw_OutputRunning = TRUE;";
4358   z[lc++]="	}";
4359   z[lc++]="	";
4360   z[lc++]="	return 0;";
4361   z[lc++]="}";
4362   z[lc++]="/************************************************************************************/";
4363   z[lc++]="HRESULT DSW_StopOutput( DSoundWrapper *dsw )";
4364   z[lc++]="{";
4365   z[lc++]="// Stop the buffer playback";
4366   z[lc++]="	if( dsw->dsw_OutputBuffer != NULL )";
4367   z[lc++]="	{";
4368   z[lc++]="		dsw->dsw_OutputRunning = FALSE;";
4369   z[lc++]="		return IDirectSoundBuffer_Stop( dsw->dsw_OutputBuffer );";
4370   z[lc++]="	}";
4371   z[lc++]="	else return 0;";
4372   z[lc++]="}";
4373   z[lc++]="/************************************************************************************/";
4374   z[lc++]="HRESULT DSW_QueryOutputSpace( DSoundWrapper *dsw, long *bytesEmpty )";
4375   z[lc++]="{";
4376   z[lc++]="	HRESULT hr;";
4377   z[lc++]="	DWORD   playCursor;";
4378   z[lc++]="	DWORD   writeCursor;";
4379   z[lc++]="	long    numBytesEmpty;";
4380   z[lc++]="	long    playWriteGap;";
4381   z[lc++]="// Query to see how much room is in buffer.";
4382   z[lc++]="// Note: Even though writeCursor is not used, it must be passed to prevent DirectSound from dieing";
4383   z[lc++]="// under WinNT. The Microsoft documentation says we can pass NULL but apparently not.";
4384   z[lc++]="// Thanks to Max Rheiner for the fix.";
4385   z[lc++]="	hr = IDirectSoundBuffer_GetCurrentPosition( dsw->dsw_OutputBuffer, &playCursor, &writeCursor );";
4386   z[lc++]="	if( hr != DS_OK )";
4387   z[lc++]="	{";
4388   z[lc++]="		return hr;";
4389   z[lc++]="	}";
4390   z[lc++]="	AddTraceMessage(\"playCursor\", playCursor);";
4391   z[lc++]="	AddTraceMessage(\"dsw_WriteOffset\", dsw->dsw_WriteOffset);";
4392   z[lc++]="// Determine size of gap between playIndex and WriteIndex that we cannot write into.";
4393   z[lc++]="	playWriteGap = writeCursor - playCursor;";
4394   z[lc++]="	if( playWriteGap < 0 ) playWriteGap += dsw->dsw_OutputSize; // unwrap";
4395   z[lc++]="/* DirectSound doesn't have a large enough playCursor so we cannot detect wrap-around. */";
4396   z[lc++]="/* Attempt to detect playCursor wrap-around and correct it. */";
4397   z[lc++]="	if( dsw->dsw_OutputRunning && (dsw->dsw_CounterTicksPerBuffer.QuadPart != 0) )";
4398   z[lc++]="	{";
4399   z[lc++]="/* How much time has elapsed since last check. */";
4400   z[lc++]="		LARGE_INTEGER   currentTime;";
4401   z[lc++]="		LARGE_INTEGER   elapsedTime;";
4402   z[lc++]="		long            bytesPlayed;";
4403   z[lc++]="		long            bytesExpected;";
4404   z[lc++]="		long            buffersWrapped;";
4405   z[lc++]="		QueryPerformanceCounter( &currentTime );";
4406   z[lc++]="		elapsedTime.QuadPart = currentTime.QuadPart - dsw->dsw_LastPlayTime.QuadPart;";
4407   z[lc++]="		dsw->dsw_LastPlayTime = currentTime;";
4408   z[lc++]="/* How many bytes does DirectSound say have been played. */";
4409   z[lc++]="		bytesPlayed = playCursor - dsw->dsw_LastPlayCursor;";
4410   z[lc++]="		if( bytesPlayed < 0 ) bytesPlayed += dsw->dsw_OutputSize; // unwrap";
4411   z[lc++]="		dsw->dsw_LastPlayCursor = playCursor;";
4412   z[lc++]="/* Calculate how many bytes we would have expected to been played by now. */";
4413   z[lc++]="		bytesExpected = (long) ((elapsedTime.QuadPart * dsw->dsw_OutputSize) / dsw->dsw_CounterTicksPerBuffer.QuadPart);";
4414   z[lc++]="		buffersWrapped = (bytesExpected - bytesPlayed) / dsw->dsw_OutputSize;";
4415   z[lc++]="		if( buffersWrapped > 0 )";
4416   z[lc++]="		{";
4417   z[lc++]="			AddTraceMessage(\"playCursor wrapped! bytesPlayed\", bytesPlayed );";
4418   z[lc++]="			AddTraceMessage(\"playCursor wrapped! bytesExpected\", bytesExpected );";
4419   z[lc++]="			playCursor += (buffersWrapped * dsw->dsw_OutputSize);";
4420   z[lc++]="			bytesPlayed += (buffersWrapped * dsw->dsw_OutputSize);";
4421   z[lc++]="		}";
4422   z[lc++]="	/* Maintain frame output cursor. */";
4423   z[lc++]="		dsw->dsw_FramesPlayed += (bytesPlayed / dsw->dsw_BytesPerFrame);";
4424   z[lc++]="	}";
4425   z[lc++]="	numBytesEmpty = playCursor - dsw->dsw_WriteOffset;";
4426   z[lc++]="	if( numBytesEmpty < 0 ) numBytesEmpty += dsw->dsw_OutputSize; // unwrap offset";
4427   z[lc++]="/* Have we underflowed? */";
4428   z[lc++]="	if( numBytesEmpty > (dsw->dsw_OutputSize - playWriteGap) )";
4429   z[lc++]="	{";
4430   z[lc++]="		if( dsw->dsw_OutputRunning )";
4431   z[lc++]="		{";
4432   z[lc++]="			dsw->dsw_OutputUnderflows += 1;";
4433   z[lc++]="			AddTraceMessage(\"underflow detected! numBytesEmpty\", numBytesEmpty );";
4434   z[lc++]="		}";
4435   z[lc++]="		dsw->dsw_WriteOffset = writeCursor;";
4436   z[lc++]="		numBytesEmpty = dsw->dsw_OutputSize - playWriteGap;";
4437   z[lc++]="	}";
4438   z[lc++]="	*bytesEmpty = numBytesEmpty;";
4439   z[lc++]="	return hr;";
4440   z[lc++]="}";
4441   z[lc++]="/************************************************************************************/";
4442   z[lc++]="HRESULT DSW_ZeroEmptySpace( DSoundWrapper *dsw )";
4443   z[lc++]="{";
4444   z[lc++]="	HRESULT hr;";
4445   z[lc++]="	LPBYTE lpbuf1 = NULL;";
4446   z[lc++]="	LPBYTE lpbuf2 = NULL;";
4447   z[lc++]="	DWORD dwsize1 = 0;";
4448   z[lc++]="	DWORD dwsize2 = 0;";
4449   z[lc++]="	long  bytesEmpty;";
4450   z[lc++]="	hr = DSW_QueryOutputSpace( dsw, &bytesEmpty ); // updates dsw_FramesPlayed";
4451   z[lc++]="	if (hr != DS_OK) return hr;";
4452   z[lc++]="	if( bytesEmpty == 0 ) return DS_OK;";
4453   z[lc++]="	// Lock free space in the DS";
4454   z[lc++]="	hr = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, dsw->dsw_WriteOffset, bytesEmpty, (void **) &lpbuf1, &dwsize1,";
4455   z[lc++]="		(void **) &lpbuf2, &dwsize2, 0);";
4456   z[lc++]="	if (hr == DS_OK)";
4457   z[lc++]="	{";
4458   z[lc++]="		// Copy the buffer into the DS";
4459   z[lc++]="		ZeroMemory(lpbuf1, dwsize1);";
4460   z[lc++]="		if(lpbuf2 != NULL)";
4461   z[lc++]="		{";
4462   z[lc++]="			ZeroMemory(lpbuf2, dwsize2);";
4463   z[lc++]="		}";
4464   z[lc++]="		// Update our buffer offset and unlock sound buffer";
4465   z[lc++]=" 		dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + dwsize1 + dwsize2) % dsw->dsw_OutputSize;";
4466   z[lc++]="		IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);";
4467   z[lc++]="		dsw->dsw_FramesWritten += bytesEmpty / dsw->dsw_BytesPerFrame;";
4468   z[lc++]="	}";
4469   z[lc++]="	return hr;";
4470   z[lc++]="}";
4471   z[lc++]="/************************************************************************************/";
4472   z[lc++]="HRESULT DSW_WriteBlock( DSoundWrapper *dsw, char *buf, long numBytes )";
4473   z[lc++]="{";
4474   z[lc++]="	HRESULT hr;";
4475   z[lc++]="	LPBYTE lpbuf1 = NULL;";
4476   z[lc++]="	LPBYTE lpbuf2 = NULL;";
4477   z[lc++]="	DWORD dwsize1 = 0;";
4478   z[lc++]="	DWORD dwsize2 = 0;";
4479   z[lc++]="	// Lock free space in the DS";
4480   z[lc++]="	hr = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, dsw->dsw_WriteOffset, numBytes, (void **) &lpbuf1, &dwsize1,";
4481   z[lc++]="		(void **) &lpbuf2, &dwsize2, 0);";
4482   z[lc++]="	if (hr == DS_OK)";
4483   z[lc++]="	{";
4484   z[lc++]="		// Copy the buffer into the DS";
4485   z[lc++]="		CopyMemory(lpbuf1, buf, dwsize1);";
4486   z[lc++]="		if(lpbuf2 != NULL)";
4487   z[lc++]="		{";
4488   z[lc++]="			CopyMemory(lpbuf2, buf+dwsize1, dwsize2);";
4489   z[lc++]="		}";
4490   z[lc++]="		// Update our buffer offset and unlock sound buffer";
4491   z[lc++]=" 		dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + dwsize1 + dwsize2) % dsw->dsw_OutputSize;";
4492   z[lc++]="		IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);";
4493   z[lc++]="		dsw->dsw_FramesWritten += numBytes / dsw->dsw_BytesPerFrame;";
4494   z[lc++]="	}";
4495   z[lc++]="	return hr;";
4496   z[lc++]="}";
4497   z[lc++]="/************************************************************************************/";
4498   z[lc++]="DWORD DSW_GetOutputStatus( DSoundWrapper *dsw )";
4499   z[lc++]="{";
4500   z[lc++]="	DWORD status;";
4501   z[lc++]="	if (IDirectSoundBuffer_GetStatus( dsw->dsw_OutputBuffer, &status ) != DS_OK)";
4502   z[lc++]="		return( DSERR_INVALIDPARAM );";
4503   z[lc++]="	else";
4504   z[lc++]="		return( status );";
4505   z[lc++]="}";
4506   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
4507   z[lc++]="/* These routines are used to support audio input.";
4508   z[lc++]=" * Do NOT compile these calls when using NT4 because it does";
4509   z[lc++]=" * not support the entry points.";
4510   z[lc++]=" */";
4511   z[lc++]="/************************************************************************************/";
4512   z[lc++]="HRESULT DSW_InitInputDevice( DSoundWrapper *dsw, LPGUID lpGUID )";
4513   z[lc++]="{";
4514   z[lc++]="	HRESULT hr = DirectSoundCaptureCreate(  lpGUID, &dsw->dsw_pDirectSoundCapture,   NULL );";
4515   z[lc++]="	if( hr != DS_OK ) return hr;";
4516   z[lc++]="	return hr;";
4517   z[lc++]="}";
4518   z[lc++]="/************************************************************************************/";
4519   z[lc++]="HRESULT DSW_InitInputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate, int nChannels, int bytesPerBuffer )";
4520   z[lc++]="{";
4521   z[lc++]="	DSCBUFFERDESC  captureDesc;";
4522   z[lc++]="	WAVEFORMATEX   wfFormat;";
4523   z[lc++]="	HRESULT        result;";
4524   z[lc++]="// Define the buffer format";
4525   z[lc++]="	wfFormat.wFormatTag      = WAVE_FORMAT_PCM;";
4526   z[lc++]="	wfFormat.nChannels       = nChannels;";
4527   z[lc++]="	wfFormat.nSamplesPerSec  = nFrameRate;";
4528   z[lc++]="	wfFormat.wBitsPerSample  = 8 * sizeof(short);";
4529   z[lc++]="	wfFormat.nBlockAlign     = wfFormat.nChannels * (wfFormat.wBitsPerSample / 8);";
4530   z[lc++]="	wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;";
4531   z[lc++]="	wfFormat.cbSize          = 0;   /* No extended format info. */";
4532   z[lc++]="	dsw->dsw_InputSize = bytesPerBuffer;";
4533   z[lc++]="// ----------------------------------------------------------------------";
4534   z[lc++]="// Setup the secondary buffer description";
4535   z[lc++]="	ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC));";
4536   z[lc++]="	captureDesc.dwSize = sizeof(DSCBUFFERDESC);";
4537   z[lc++]="	captureDesc.dwFlags =  0;";
4538   z[lc++]="	captureDesc.dwBufferBytes = bytesPerBuffer;";
4539   z[lc++]="	captureDesc.lpwfxFormat = &wfFormat;";
4540   z[lc++]="	// Create the capture buffer";
4541   z[lc++]="	if ((result = IDirectSoundCapture_CreateCaptureBuffer( dsw->dsw_pDirectSoundCapture,";
4542   z[lc++]="		&captureDesc, &dsw->dsw_InputBuffer, NULL)) != DS_OK) return result;";
4543   z[lc++]="	dsw->dsw_ReadOffset = 0;  // reset last read position to start of buffer";
4544   z[lc++]="	return DS_OK;";
4545   z[lc++]="}";
4546   z[lc++]="/************************************************************************************/";
4547   z[lc++]="HRESULT DSW_StartInput( DSoundWrapper *dsw )";
4548   z[lc++]="{";
4549   z[lc++]="// Start the buffer playback";
4550   z[lc++]="	if( dsw->dsw_InputBuffer != NULL )";
4551   z[lc++]="	{";
4552   z[lc++]="		return IDirectSoundCaptureBuffer_Start( dsw->dsw_InputBuffer, DSCBSTART_LOOPING );";
4553   z[lc++]="	}";
4554   z[lc++]="	else return 0;";
4555   z[lc++]="}";
4556   z[lc++]="/************************************************************************************/";
4557   z[lc++]="HRESULT DSW_StopInput( DSoundWrapper *dsw )";
4558   z[lc++]="{";
4559   z[lc++]="// Stop the buffer playback";
4560   z[lc++]="	if( dsw->dsw_InputBuffer != NULL )";
4561   z[lc++]="	{";
4562   z[lc++]="		return IDirectSoundCaptureBuffer_Stop( dsw->dsw_InputBuffer );";
4563   z[lc++]="	}";
4564   z[lc++]="	else return 0;";
4565   z[lc++]="}";
4566   z[lc++]="/************************************************************************************/";
4567   z[lc++]="HRESULT DSW_QueryInputFilled( DSoundWrapper *dsw, long *bytesFilled )";
4568   z[lc++]="{";
4569   z[lc++]="	HRESULT hr;";
4570   z[lc++]="	DWORD capturePos;";
4571   z[lc++]="	DWORD readPos;";
4572   z[lc++]="	long  filled;";
4573   z[lc++]="// Query to see how much data is in buffer.";
4574   z[lc++]="// We don't need the capture position but sometimes DirectSound doesn't handle NULLS correctly";
4575   z[lc++]="// so let's pass a pointer just to be safe.";
4576   z[lc++]="	hr = IDirectSoundCaptureBuffer_GetCurrentPosition( dsw->dsw_InputBuffer, &capturePos, &readPos );";
4577   z[lc++]="	if( hr != DS_OK )";
4578   z[lc++]="	{";
4579   z[lc++]="		return hr;";
4580   z[lc++]="	}";
4581   z[lc++]="	filled = readPos - dsw->dsw_ReadOffset;";
4582   z[lc++]="	if( filled < 0 ) filled += dsw->dsw_InputSize; // unwrap offset";
4583   z[lc++]="	*bytesFilled = filled;";
4584   z[lc++]="	return hr;";
4585   z[lc++]="}";
4586   z[lc++]="/************************************************************************************/";
4587   z[lc++]="HRESULT DSW_ReadBlock( DSoundWrapper *dsw, char *buf, long numBytes )";
4588   z[lc++]="{";
4589   z[lc++]="	HRESULT hr;";
4590   z[lc++]="	LPBYTE lpbuf1 = NULL;";
4591   z[lc++]="	LPBYTE lpbuf2 = NULL;";
4592   z[lc++]="	DWORD dwsize1 = 0;";
4593   z[lc++]="	DWORD dwsize2 = 0;";
4594   z[lc++]="	// Lock free space in the DS";
4595   z[lc++]="	hr = IDirectSoundCaptureBuffer_Lock ( dsw->dsw_InputBuffer, dsw->dsw_ReadOffset, numBytes, (void **) &lpbuf1, &dwsize1,";
4596   z[lc++]="		(void **) &lpbuf2, &dwsize2, 0);";
4597   z[lc++]="	if (hr == DS_OK)";
4598   z[lc++]="	{";
4599   z[lc++]="		// Copy from DS to the buffer";
4600   z[lc++]="		CopyMemory( buf, lpbuf1, dwsize1);";
4601   z[lc++]="		if(lpbuf2 != NULL)";
4602   z[lc++]="		{";
4603   z[lc++]="			CopyMemory( buf+dwsize1, lpbuf2, dwsize2);";
4604   z[lc++]="		}";
4605   z[lc++]="		// Update our buffer offset and unlock sound buffer";
4606   z[lc++]=" 		dsw->dsw_ReadOffset = (dsw->dsw_ReadOffset + dwsize1 + dwsize2) % dsw->dsw_InputSize;";
4607   z[lc++]="		IDirectSoundCaptureBuffer_Unlock ( dsw->dsw_InputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);";
4608   z[lc++]="	}";
4609   z[lc++]="	return hr;";
4610   z[lc++]="}";
4611   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
4612   printlib(lc);
4613 }
4614 
4615 
4616 void makepa_dsound(void)
4617 {
4618   int lc = 0;
4619 
4620   z[lc++]="/*";
4621   z[lc++]=" * PortAudio Portable Real-Time Audio Library";
4622   z[lc++]=" * Latest Version at: http://www.softsynth.com/portaudio/";
4623   z[lc++]=" * DirectSound Implementation";
4624   z[lc++]=" *";
4625   z[lc++]=" * Copyright (c) 1999-2000 Phil Burk";
4626   z[lc++]=" *";
4627   z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
4628   z[lc++]=" * a copy of this software and associated documentation files";
4629   z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
4630   z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
4631   z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
4632   z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
4633   z[lc++]=" * subject to the following conditions:";
4634   z[lc++]=" *";
4635   z[lc++]=" * The above copyright notice and this permission notice shall be";
4636   z[lc++]=" * included in all copies or substantial portions of the Software.";
4637   z[lc++]=" *";
4638   z[lc++]=" * Any person wishing to distribute modifications to the Software is";
4639   z[lc++]=" * requested to send the modifications to the original developer so that";
4640   z[lc++]=" * they can be incorporated into the canonical version.";
4641   z[lc++]=" *";
4642   z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
4643   z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
4644   z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
4645   z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
4646   z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
4647   z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
4648   z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
4649   z[lc++]=" *";
4650   z[lc++]=" */";
4651   z[lc++]="/* Modifications";
4652   z[lc++]=" *    7/19/01 Mike Berry - casts for compiling with __MWERKS__ CodeWarrior";
4653   z[lc++]=" *    9/27/01 Phil Burk - use number of frames instead of real-time for CPULoad calculation.";
4654   z[lc++]=" */";
4655   z[lc++]="/* Compiler flags:";
4656   z[lc++]="	SUPPORT_AUDIO_CAPTURE - define this flag if you want to SUPPORT_AUDIO_CAPTURE";
4657   z[lc++]=" */";
4658   z[lc++]="#include <stdio.h>";
4659   z[lc++]="#include <stdlib.h>";
4660   z[lc++]="#ifndef __MWERKS__";
4661   z[lc++]="#include <malloc.h>";
4662   z[lc++]="#include <memory.h>";
4663   z[lc++]="#endif //__MWERKS__";
4664   z[lc++]="#include <math.h>";
4665   z[lc++]="#if 0";
4666   z[lc++]="#include \"portaudio.h\"";
4667   z[lc++]="#include \"pa_host.h\"";
4668   z[lc++]="#include \"pa_trace.h\"";
4669   z[lc++]="#include \"dsound_wrapper.h\"";
4670   z[lc++]="#endif";
4671   z[lc++]="#define PRINT(x) { printf x; fflush(stdout); }";
4672   z[lc++]="#define ERR_RPT(x) PRINT(x)";
4673   z[lc++]="#define DBUG(x)  /* PRINT(x) */";
4674   z[lc++]="#define DBUGX(x) /* PRINT(x) */";
4675   z[lc++]="#define PA_USE_HIGH_LATENCY   (0)";
4676   z[lc++]="#if PA_USE_HIGH_LATENCY";
4677   z[lc++]="#define PA_WIN_9X_LATENCY     (500)";
4678   z[lc++]="#define PA_WIN_NT_LATENCY     (600)";
4679   z[lc++]="#else";
4680   z[lc++]="#define PA_WIN_9X_LATENCY     (140)";
4681   z[lc++]="#define PA_WIN_NT_LATENCY     (280)";
4682   z[lc++]="#endif";
4683   z[lc++]="/* Trigger an underflow for testing purposes. Should normally be (0). */";
4684   z[lc++]="#define PA_SIMULATE_UNDERFLOW (0)";
4685   z[lc++]="#if PA_SIMULATE_UNDERFLOW";
4686   z[lc++]="static  gUnderCallbackCounter = 0;";
4687   z[lc++]="#define UNDER_START_GAP       (10)";
4688   z[lc++]="#define UNDER_STOP_GAP        (UNDER_START_GAP + 4)";
4689   z[lc++]="#endif";
4690   z[lc++]="/************************************************* Definitions ********/";
4691   z[lc++]="typedef struct internalPortAudioStream internalPortAudioStream;";
4692   z[lc++]="typedef struct internalPortAudioDevice";
4693   z[lc++]="{";
4694   z[lc++]="	GUID                             pad_GUID;";
4695   z[lc++]="	GUID                            *pad_lpGUID;";
4696   z[lc++]="	double                           pad_SampleRates[10]; /* for pointing to from pad_Info FIXME?!*/";
4697   z[lc++]="	PaDeviceInfo                     pad_Info;";
4698   z[lc++]="} internalPortAudioDevice;";
4699   z[lc++]="/* Define structure to contain all DirectSound and Windows specific data. */";
4700   z[lc++]="typedef struct PaHostSoundControl";
4701   z[lc++]="{";
4702   z[lc++]="	DSoundWrapper    pahsc_DSoundWrapper;";
4703   z[lc++]="	MMRESULT         pahsc_TimerID;";
4704   z[lc++]="	BOOL             pahsc_IfInsideCallback;  /* Test for reentrancy. */";
4705   z[lc++]="	short           *pahsc_NativeBuffer;";
4706   z[lc++]="	unsigned int     pahsc_BytesPerBuffer;    /* native buffer size in bytes */";
4707   z[lc++]="	double           pahsc_ValidFramesWritten;";
4708   z[lc++]="	int              pahsc_FramesPerDSBuffer;";
4709   z[lc++]="/* For measuring CPU utilization. */";
4710   z[lc++]="	LARGE_INTEGER    pahsc_EntryCount;";
4711   z[lc++]="	double           pahsc_InverseTicksPerUserBuffer;";
4712   z[lc++]="} PaHostSoundControl;";
4713   z[lc++]="/************************************************* Shared Data ********/";
4714   z[lc++]="/* FIXME - put Mutex around this shared data. */";
4715   z[lc++]="static int sNumDevices = 0;";
4716   z[lc++]="static int sDeviceIndex = 0;";
4717   z[lc++]="static internalPortAudioDevice *sDevices = NULL;";
4718   z[lc++]="static int sDefaultInputDeviceID = paNoDevice;";
4719   z[lc++]="static int sDefaultOutputDeviceID = paNoDevice;";
4720   z[lc++]="static int sEnumerationError;";
4721   z[lc++]="static int sPaHostError = 0;";
4722   z[lc++]="/************************************************* Prototypes **********/";
4723   z[lc++]="static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id );";
4724   z[lc++]="static BOOL CALLBACK Pa_EnumProc(LPGUID lpGUID, ";
4725   z[lc++]="				         LPCTSTR lpszDesc,";
4726   z[lc++]="				         LPCTSTR lpszDrvName, ";
4727   z[lc++]="				         LPVOID lpContext );";
4728   z[lc++]="static BOOL CALLBACK Pa_CountDevProc(LPGUID lpGUID, ";
4729   z[lc++]="				         LPCTSTR lpszDesc,";
4730   z[lc++]="				         LPCTSTR lpszDrvName, ";
4731   z[lc++]="				         LPVOID lpContext );";
4732   z[lc++]="static Pa_QueryDevices( void );";
4733   z[lc++]="static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg,";
4734   z[lc++]="									  DWORD dwUser, DWORD dw1, DWORD dw2);";
4735   z[lc++]="/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/";
4736   z[lc++]="static void Pa_StartUsageCalculation( internalPortAudioStream   *past )";
4737   z[lc++]="{";
4738   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
4739   z[lc++]="	if( pahsc == NULL ) return;";
4740   z[lc++]="/* Query system timer for usage analysis and to prevent overuse of CPU. */";
4741   z[lc++]="	QueryPerformanceCounter( &pahsc->pahsc_EntryCount );";
4742   z[lc++]="}";
4743   z[lc++]="static void Pa_EndUsageCalculation( internalPortAudioStream   *past )";
4744   z[lc++]="{";
4745   z[lc++]="	LARGE_INTEGER CurrentCount = { 0, 0 };";
4746   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
4747   z[lc++]="	if( pahsc == NULL ) return;";
4748   z[lc++]="/*";
4749   z[lc++]="** Measure CPU utilization during this callback. Note that this calculation";
4750   z[lc++]="** assumes that we had the processor the whole time.";
4751   z[lc++]="*/";
4752   z[lc++]="#define LOWPASS_COEFFICIENT_0   (0.9)";
4753   z[lc++]="#define LOWPASS_COEFFICIENT_1   (0.99999 - LOWPASS_COEFFICIENT_0)";
4754   z[lc++]="	if( QueryPerformanceCounter( &CurrentCount ) )";
4755   z[lc++]="	{";
4756   z[lc++]="		LONGLONG InsideCount = CurrentCount.QuadPart - pahsc->pahsc_EntryCount.QuadPart;	";
4757   z[lc++]="		double newUsage = InsideCount * pahsc->pahsc_InverseTicksPerUserBuffer;";
4758   z[lc++]="		past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +";
4759   z[lc++]="			(LOWPASS_COEFFICIENT_1 * newUsage);";
4760   z[lc++]="	}";
4761   z[lc++]="}";
4762   z[lc++]="/****************************************** END CPU UTILIZATION *******/";
4763   z[lc++]="static PaError Pa_QueryDevices( void )";
4764   z[lc++]="{";
4765   z[lc++]="	int numBytes;";
4766   z[lc++]="	sDefaultInputDeviceID = paNoDevice;";
4767   z[lc++]="	sDefaultOutputDeviceID = paNoDevice;";
4768   z[lc++]="/* Enumerate once just to count devices. */";
4769   z[lc++]="	sNumDevices = 0; // for default device";
4770   z[lc++]="	DirectSoundEnumerate( (LPDSENUMCALLBACK)Pa_CountDevProc, NULL );";
4771   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
4772   z[lc++]="	DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)Pa_CountDevProc, NULL );";
4773   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
4774   z[lc++]="/* Allocate structures to hold device info. */";
4775   z[lc++]="	numBytes = sNumDevices * sizeof(internalPortAudioDevice);";
4776   z[lc++]="	sDevices = (internalPortAudioDevice *)PaHost_AllocateFastMemory( numBytes ); /* MEM */";
4777   z[lc++]="	if( sDevices == NULL ) return paInsufficientMemory;";
4778   z[lc++]="/* Enumerate again to fill in structures. */";
4779   z[lc++]="	sDeviceIndex = 0;";
4780   z[lc++]="	sEnumerationError = 0;";
4781   z[lc++]="	DirectSoundEnumerate( (LPDSENUMCALLBACK)Pa_EnumProc, (void *)0 );";
4782   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
4783   z[lc++]="	if( sEnumerationError != paNoError ) return sEnumerationError;";
4784   z[lc++]="	sEnumerationError = 0;";
4785   z[lc++]="	DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)Pa_EnumProc, (void *)1 );";
4786   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
4787   z[lc++]="	return sEnumerationError;";
4788   z[lc++]="}";
4789   z[lc++]="/************************************************************************************/";
4790   z[lc++]="long Pa_GetHostError()";
4791   z[lc++]="{";
4792   z[lc++]="	return sPaHostError;";
4793   z[lc++]="}";
4794   z[lc++]="/************************************************************************************";
4795   z[lc++]="** Just count devices so we know how much memory to allocate.";
4796   z[lc++]="*/";
4797   z[lc++]="static BOOL CALLBACK Pa_CountDevProc(LPGUID lpGUID, ";
4798   z[lc++]="				         LPCTSTR lpszDesc,";
4799   z[lc++]="				         LPCTSTR lpszDrvName, ";
4800   z[lc++]="				         LPVOID lpContext )";
4801   z[lc++]="{";
4802   z[lc++]="	sNumDevices++;";
4803   z[lc++]="	return TRUE;";
4804   z[lc++]="}";
4805   z[lc++]="/************************************************************************************";
4806   z[lc++]="** Extract capabilities info from each device.";
4807   z[lc++]="*/";
4808   z[lc++]="static BOOL CALLBACK Pa_EnumProc(LPGUID lpGUID, ";
4809   z[lc++]="				         LPCTSTR lpszDesc,";
4810   z[lc++]="				         LPCTSTR lpszDrvName, ";
4811   z[lc++]="				         LPVOID lpContext )";
4812   z[lc++]="{";
4813   z[lc++]="	HRESULT    hr;";
4814   z[lc++]="	LPDIRECTSOUND          lpDirectSound;";
4815   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
4816   z[lc++]="	LPDIRECTSOUNDCAPTURE   lpDirectSoundCapture;";
4817   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
4818   z[lc++]="	int        isInput  = (int) lpContext;  /* Passed from Pa_CountDevices() */";
4819   z[lc++]="	internalPortAudioDevice *pad;";
4820   z[lc++]="		";
4821   z[lc++]="	if( sDeviceIndex >= sNumDevices )";
4822   z[lc++]="	{";
4823   z[lc++]="		sEnumerationError = paInternalError;";
4824   z[lc++]="		return FALSE;";
4825   z[lc++]="	}";
4826   z[lc++]="	pad = &sDevices[sDeviceIndex];";
4827   z[lc++]="/* Copy GUID to static array. Set pointer. */";
4828   z[lc++]="	if( lpGUID == NULL )";
4829   z[lc++]="	{";
4830   z[lc++]="		pad->pad_lpGUID = NULL;";
4831   z[lc++]="	}";
4832   z[lc++]="	else";
4833   z[lc++]="	{";
4834   z[lc++]="		memcpy( &pad->pad_GUID, lpGUID, sizeof(GUID) );";
4835   z[lc++]="		pad->pad_lpGUID = &pad->pad_GUID;";
4836   z[lc++]="	}";
4837   z[lc++]="	pad->pad_Info.sampleRates = pad->pad_SampleRates;  /* Point to array. */";
4838   z[lc++]="/* Allocate room for descriptive name. */";
4839   z[lc++]="	if( lpszDesc != NULL )";
4840   z[lc++]="	{";
4841   z[lc++]="		int len = strlen(lpszDesc);";
4842   z[lc++]="		pad->pad_Info.name = (char *)malloc( len+1 );";
4843   z[lc++]="		if( pad->pad_Info.name == NULL )";
4844   z[lc++]="		{";
4845   z[lc++]="			sEnumerationError = paInsufficientMemory;";
4846   z[lc++]="			return FALSE;";
4847   z[lc++]="		}";
4848   z[lc++]="		memcpy( (void *) pad->pad_Info.name, lpszDesc, len+1 );";
4849   z[lc++]="	}";
4850   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
4851   z[lc++]="	if( isInput )";
4852   z[lc++]="	{";
4853   z[lc++]="	/********** Input ******************************/";
4854   z[lc++]="		DSCCAPS     caps;";
4855   z[lc++]="		if( lpGUID == NULL ) sDefaultInputDeviceID = sDeviceIndex;";
4856   z[lc++]="		hr = DirectSoundCaptureCreate(  lpGUID, &lpDirectSoundCapture,   NULL );";
4857   z[lc++]="		if( hr != DS_OK )";
4858   z[lc++]="		{";
4859   z[lc++]="			pad->pad_Info.maxInputChannels = 0;";
4860   z[lc++]="			DBUG((\"Cannot create Capture for %s. Result = 0x%x\\n\", lpszDesc, hr ));";
4861   z[lc++]="		}";
4862   z[lc++]="		else";
4863   z[lc++]="		{";
4864   z[lc++]="	/* Query device characteristics. */";
4865   z[lc++]="			caps.dwSize = sizeof(caps);";
4866   z[lc++]="			IDirectSoundCapture_GetCaps( lpDirectSoundCapture, &caps );";
4867   z[lc++]="			/* printf(\"caps.dwFormats = 0x%x\\n\", caps.dwFormats ); */";
4868   z[lc++]="			pad->pad_Info.maxInputChannels = caps.dwChannels;";
4869   z[lc++]="	/* Determine sample rates from flags. */";
4870   z[lc++]="			if( caps.dwChannels == 2 )";
4871   z[lc++]="			{";
4872   z[lc++]="				int index = 0;";
4873   z[lc++]="				if( caps.dwFormats & WAVE_FORMAT_1S16) pad->pad_SampleRates[index++] = 11025.0;";
4874   z[lc++]="				if( caps.dwFormats & WAVE_FORMAT_2S16) pad->pad_SampleRates[index++] = 22050.0;";
4875   z[lc++]="				if( caps.dwFormats & WAVE_FORMAT_4S16) pad->pad_SampleRates[index++] = 44100.0;";
4876   z[lc++]="				pad->pad_Info.numSampleRates = index;";
4877   z[lc++]="			}";
4878   z[lc++]="			else if( caps.dwChannels == 1 )";
4879   z[lc++]="			{";
4880   z[lc++]="				int index = 0;";
4881   z[lc++]="				if( caps.dwFormats & WAVE_FORMAT_1M16) pad->pad_SampleRates[index++] = 11025.0;";
4882   z[lc++]="				if( caps.dwFormats & WAVE_FORMAT_2M16) pad->pad_SampleRates[index++] = 22050.0;";
4883   z[lc++]="				if( caps.dwFormats & WAVE_FORMAT_4M16) pad->pad_SampleRates[index++] = 44100.0;";
4884   z[lc++]="				pad->pad_Info.numSampleRates = index;";
4885   z[lc++]="			}";
4886   z[lc++]="			else pad->pad_Info.numSampleRates = 0;";
4887   z[lc++]="			IDirectSoundCapture_Release( lpDirectSoundCapture );";
4888   z[lc++]="		}";
4889   z[lc++]="	}";
4890   z[lc++]="	else";
4891   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
4892   z[lc++]="	{";
4893   z[lc++]="	/********** Output ******************************/";
4894   z[lc++]="		DSCAPS     caps;";
4895   z[lc++]="		if( lpGUID == NULL ) sDefaultOutputDeviceID = sDeviceIndex;";
4896   z[lc++]="	/* Create interfaces for each object. */";
4897   z[lc++]="		hr = DirectSoundCreate(  lpGUID, &lpDirectSound,   NULL );";
4898   z[lc++]="		if( hr != DS_OK )";
4899   z[lc++]="		{";
4900   z[lc++]="			pad->pad_Info.maxOutputChannels = 0;";
4901   z[lc++]="			DBUG((\"Cannot create dsound for %s. Result = 0x%x\\n\", lpszDesc, hr ));";
4902   z[lc++]="		}";
4903   z[lc++]="		else";
4904   z[lc++]="		{";
4905   z[lc++]="		/* Query device characteristics. */";
4906   z[lc++]="			caps.dwSize = sizeof(caps);";
4907   z[lc++]="			IDirectSound_GetCaps( lpDirectSound, &caps );";
4908   z[lc++]="			pad->pad_Info.maxOutputChannels = ( caps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1;";
4909   z[lc++]="		/* Get sample rates. */";
4910   z[lc++]="			pad->pad_SampleRates[0] = (double) caps.dwMinSecondarySampleRate;";
4911   z[lc++]="			pad->pad_SampleRates[1] = (double) caps.dwMaxSecondarySampleRate;";
4912   z[lc++]="			if( caps.dwFlags & DSCAPS_CONTINUOUSRATE ) pad->pad_Info.numSampleRates = -1;";
4913   z[lc++]="			else if( caps.dwMinSecondarySampleRate == caps.dwMaxSecondarySampleRate )";
4914   z[lc++]="			{";
4915   z[lc++]="				if( caps.dwMinSecondarySampleRate == 0 )";
4916   z[lc++]="				{";
4917   z[lc++]="			/*";
4918   z[lc++]="			** On my Thinkpad 380Z, DirectSoundV6 returns min-max=0 !!";
4919   z[lc++]="			** But it supports continuous sampling.";
4920   z[lc++]="			** So fake range of rates, and hope it really supports it.";
4921   z[lc++]="			*/";
4922   z[lc++]="					pad->pad_SampleRates[0] = 11025.0f;";
4923   z[lc++]="					pad->pad_SampleRates[1] = 48000.0f;";
4924   z[lc++]="					pad->pad_Info.numSampleRates = -1; /* continuous range */";
4925   z[lc++]="					";
4926   z[lc++]="					DBUG((\"PA - Reported rates both zero. Setting to fake values for device #%d\\n\", sDeviceIndex ));";
4927   z[lc++]="				}";
4928   z[lc++]="				else";
4929   z[lc++]="				{";
4930   z[lc++]="					pad->pad_Info.numSampleRates = 1;";
4931   z[lc++]="				}";
4932   z[lc++]="			}";
4933   z[lc++]="			else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) )";
4934   z[lc++]="			{";
4935   z[lc++]="			/* The EWS88MT drivers lie, lie, lie. The say they only support two rates, 100 & 100000.";
4936   z[lc++]="			** But we know that they really support a range of rates!";
4937   z[lc++]="			** So when we see a ridiculous set of rates, assume it is a range.";
4938   z[lc++]="			*/";
4939   z[lc++]="				pad->pad_Info.numSampleRates = -1;";
4940   z[lc++]="				DBUG((\"PA - Sample rate range used instead of two odd values for device #%d\\n\", sDeviceIndex ));";
4941   z[lc++]="			}";
4942   z[lc++]="			else pad->pad_Info.numSampleRates = 2;";
4943   z[lc++]="			IDirectSound_Release( lpDirectSound );";
4944   z[lc++]="		}";
4945   z[lc++]="	}";
4946   z[lc++]="	pad->pad_Info.nativeSampleFormats = paInt16;";
4947   z[lc++]="	sDeviceIndex++;";
4948   z[lc++]="	return( TRUE );";
4949   z[lc++]="}";
4950   z[lc++]="/*************************************************************************/";
4951   z[lc++]="int Pa_CountDevices()";
4952   z[lc++]="{";
4953   z[lc++]="	if( sNumDevices <= 0 ) Pa_Initialize();";
4954   z[lc++]="	return sNumDevices;";
4955   z[lc++]="}";
4956   z[lc++]="static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id )";
4957   z[lc++]="{";
4958   z[lc++]="	if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;";
4959   z[lc++]="	return &sDevices[id];";
4960   z[lc++]="}";
4961   z[lc++]="/*************************************************************************/";
4962   z[lc++]="const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )";
4963   z[lc++]="{";
4964   z[lc++]="	internalPortAudioDevice *pad;";
4965   z[lc++]="	if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;";
4966   z[lc++]="	pad = Pa_GetInternalDevice( id );";
4967   z[lc++]="	return  &pad->pad_Info ;";
4968   z[lc++]="}";
4969   z[lc++]="static PaError Pa_MaybeQueryDevices( void )";
4970   z[lc++]="{";
4971   z[lc++]="	if( sNumDevices == 0 )";
4972   z[lc++]="	{";
4973   z[lc++]="		return Pa_QueryDevices();";
4974   z[lc++]="	}";
4975   z[lc++]="	return 0;";
4976   z[lc++]="}";
4977   z[lc++]="/*************************************************************************";
4978   z[lc++]="** Returns recommended device ID.";
4979   z[lc++]="** On the PC, the recommended device can be specified by the user by";
4980   z[lc++]="** setting an environment variable. For example, to use device #1.";
4981   z[lc++]="**";
4982   z[lc++]="**    set PA_RECOMMENDED_OUTPUT_DEVICE=1";
4983   z[lc++]="**";
4984   z[lc++]="** The user should first determine the available device ID by using";
4985   z[lc++]="** the supplied application \"pa_devs\".";
4986   z[lc++]="*/";
4987   z[lc++]="#define PA_ENV_BUF_SIZE  (32)";
4988   z[lc++]="#define PA_REC_IN_DEV_ENV_NAME  (\"PA_RECOMMENDED_INPUT_DEVICE\")";
4989   z[lc++]="#define PA_REC_OUT_DEV_ENV_NAME  (\"PA_RECOMMENDED_OUTPUT_DEVICE\")";
4990   z[lc++]="static PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName )";
4991   z[lc++]="{";
4992   z[lc++]="	DWORD   hresult;";
4993   z[lc++]="	char    envbuf[PA_ENV_BUF_SIZE];";
4994   z[lc++]="	PaDeviceID recommendedID = paNoDevice;";
4995   z[lc++]="/* Let user determine default device by setting environment variable. */";
4996   z[lc++]="	hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE );";
4997   z[lc++]="	if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )";
4998   z[lc++]="	{";
4999   z[lc++]="		recommendedID = atoi( envbuf );";
5000   z[lc++]="	}";
5001   z[lc++]="	return recommendedID;";
5002   z[lc++]="}";
5003   z[lc++]="PaDeviceID Pa_GetDefaultInputDeviceID( void )";
5004   z[lc++]="{";
5005   z[lc++]="	PaError result;";
5006   z[lc++]="	result = PaHost_GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME );";
5007   z[lc++]="	if( result < 0 )";
5008   z[lc++]="	{";
5009   z[lc++]="		result = Pa_MaybeQueryDevices();";
5010   z[lc++]="		if( result < 0 ) return result;";
5011   z[lc++]="		result = sDefaultInputDeviceID;";
5012   z[lc++]="	}";
5013   z[lc++]="	return result;";
5014   z[lc++]="}";
5015   z[lc++]="PaDeviceID Pa_GetDefaultOutputDeviceID( void )";
5016   z[lc++]="{";
5017   z[lc++]="	PaError result;";
5018   z[lc++]="	result = PaHost_GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME );";
5019   z[lc++]="	if( result < 0 )";
5020   z[lc++]="	{";
5021   z[lc++]="		result = Pa_MaybeQueryDevices();";
5022   z[lc++]="		if( result < 0 ) return result;";
5023   z[lc++]="		result = sDefaultOutputDeviceID;";
5024   z[lc++]="	}";
5025   z[lc++]="	return result;";
5026   z[lc++]="}";
5027   z[lc++]="/**********************************************************************";
5028   z[lc++]="** Make sure that we have queried the device capabilities.";
5029   z[lc++]="*/";
5030   z[lc++]="PaError PaHost_Init( void )";
5031   z[lc++]="{";
5032   z[lc++]="#if PA_SIMULATE_UNDERFLOW";
5033   z[lc++]="	PRINT((\"WARNING - Underflow Simulation Enabled - Expect a Big Glitch!!!\\n\"));";
5034   z[lc++]="#endif";
5035   z[lc++]="	return Pa_MaybeQueryDevices();";
5036   z[lc++]="}";
5037   z[lc++]="static PaError Pa_TimeSlice( internalPortAudioStream   *past )";
5038   z[lc++]="{";
5039   z[lc++]="	PaError           result = 0;";
5040   z[lc++]="	long              bytesEmpty = 0;";
5041   z[lc++]="	long              bytesFilled = 0;";
5042   z[lc++]="	long              bytesToXfer = 0;";
5043   z[lc++]="	long              numChunks;";
5044   z[lc++]="	HRESULT           hresult;";
5045   z[lc++]="	PaHostSoundControl  *pahsc;";
5046   z[lc++]="	short            *nativeBufPtr;";
5047   z[lc++]="	past->past_NumCallbacks += 1;";
5048   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
5049   z[lc++]="	if( pahsc == NULL ) return paInternalError;";
5050   z[lc++]="/* How much input data is available? */";
5051   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
5052   z[lc++]="	if( past->past_NumInputChannels > 0 )";
5053   z[lc++]="	{";
5054   z[lc++]="		DSW_QueryInputFilled( &pahsc->pahsc_DSoundWrapper, &bytesFilled );";
5055   z[lc++]="		bytesToXfer = bytesFilled;";
5056   z[lc++]="	}";
5057   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
5058   z[lc++]="/* How much output room is available? */";
5059   z[lc++]="	if( past->past_NumOutputChannels > 0 )";
5060   z[lc++]="	{";
5061   z[lc++]="		DSW_QueryOutputSpace( &pahsc->pahsc_DSoundWrapper, &bytesEmpty );";
5062   z[lc++]="		bytesToXfer = bytesEmpty;";
5063   z[lc++]="	}";
5064   z[lc++]="	AddTraceMessage( \"bytesEmpty \", bytesEmpty );";
5065   z[lc++]="/* Choose smallest value if both are active. */";
5066   z[lc++]="	if( (past->past_NumInputChannels > 0) && (past->past_NumOutputChannels > 0) )";
5067   z[lc++]="	{";
5068   z[lc++]="		bytesToXfer = ( bytesFilled < bytesEmpty ) ? bytesFilled : bytesEmpty;";
5069   z[lc++]="	}";
5070   z[lc++]="/*	printf(\"bytesFilled = %d, bytesEmpty = %d, bytesToXfer = %d\\n\",";
5071   z[lc++]="		bytesFilled, bytesEmpty, bytesToXfer);";
5072   z[lc++]="*/";
5073   z[lc++]="/* Quantize to multiples of a buffer. */";
5074   z[lc++]="	numChunks = bytesToXfer / pahsc->pahsc_BytesPerBuffer;";
5075   z[lc++]="	if( numChunks > (long)(past->past_NumUserBuffers/2) )";
5076   z[lc++]="	{";
5077   z[lc++]="		numChunks = (long)past->past_NumUserBuffers/2;";
5078   z[lc++]="	}";
5079   z[lc++]="	else if( numChunks < 0 )";
5080   z[lc++]="	{";
5081   z[lc++]="		numChunks = 0;";
5082   z[lc++]="	}";
5083   z[lc++]="	AddTraceMessage( \"numChunks \", numChunks );";
5084   z[lc++]="	nativeBufPtr = pahsc->pahsc_NativeBuffer;";
5085   z[lc++]="	if( numChunks > 0 )";
5086   z[lc++]="	{";
5087   z[lc++]="		while( numChunks-- > 0 )";
5088   z[lc++]="		{";
5089   z[lc++]="		/* Measure usage based on time to process one user buffer. */";
5090   z[lc++]="			Pa_StartUsageCalculation( past );";
5091   z[lc++]="	#if SUPPORT_AUDIO_CAPTURE";
5092   z[lc++]="	/* Get native data from DirectSound. */";
5093   z[lc++]="			if( past->past_NumInputChannels > 0 )";
5094   z[lc++]="			{";
5095   z[lc++]="				hresult = DSW_ReadBlock( &pahsc->pahsc_DSoundWrapper, (char *) nativeBufPtr, pahsc->pahsc_BytesPerBuffer );";
5096   z[lc++]="				if( hresult < 0 )";
5097   z[lc++]="				{";
5098   z[lc++]="					ERR_RPT((\"DirectSound ReadBlock failed, hresult = 0x%x\\n\",hresult));";
5099   z[lc++]="					sPaHostError = hresult;";
5100   z[lc++]="					break;";
5101   z[lc++]="				}";
5102   z[lc++]="			}";
5103   z[lc++]="	#endif /* SUPPORT_AUDIO_CAPTURE */";
5104   z[lc++]="	/* Convert 16 bit native data to user data and call user routine. */";
5105   z[lc++]="			result = Pa_CallConvertInt16( past, nativeBufPtr, nativeBufPtr );";
5106   z[lc++]="			if( result != 0) break;";
5107   z[lc++]="	/* Pass native data to DirectSound. */";
5108   z[lc++]="			if( past->past_NumOutputChannels > 0 )";
5109   z[lc++]="			{";
5110   z[lc++]="			/*	static short DEBUGHACK = 0;";
5111   z[lc++]="				DEBUGHACK += 0x0049;";
5112   z[lc++]="				nativeBufPtr[0] = DEBUGHACK; /* Make buzz to see if DirectSound still running. */";
5113   z[lc++]="				hresult = DSW_WriteBlock( &pahsc->pahsc_DSoundWrapper, (char *) nativeBufPtr, pahsc->pahsc_BytesPerBuffer );";
5114   z[lc++]="				if( hresult < 0 )";
5115   z[lc++]="				{";
5116   z[lc++]="					ERR_RPT((\"DirectSound WriteBlock failed, result = 0x%x\\n\",hresult));";
5117   z[lc++]="					sPaHostError = hresult;";
5118   z[lc++]="					break;";
5119   z[lc++]="				}";
5120   z[lc++]="			}";
5121   z[lc++]="			Pa_EndUsageCalculation( past );";
5122   z[lc++]="		}";
5123   z[lc++]="	}";
5124   z[lc++]="	return result;";
5125   z[lc++]="}";
5126   z[lc++]="/*******************************************************************/";
5127   z[lc++]="static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)";
5128   z[lc++]="{";
5129   z[lc++]="	internalPortAudioStream   *past;";
5130   z[lc++]="	PaHostSoundControl  *pahsc;";
5131   z[lc++]="#if PA_SIMULATE_UNDERFLOW";
5132   z[lc++]="	gUnderCallbackCounter++;";
5133   z[lc++]="	if( (gUnderCallbackCounter >= UNDER_START_GAP) &&";
5134   z[lc++]="		(gUnderCallbackCounter <= UNDER_STOP_GAP) )";
5135   z[lc++]="	{";
5136   z[lc++]="		if( gUnderCallbackCounter == UNDER_START_GAP)";
5137   z[lc++]="		{";
5138   z[lc++]="			AddTraceMessage(\"Begin stall: gUnderCallbackCounter =======\", gUnderCallbackCounter );";
5139   z[lc++]="		}";
5140   z[lc++]="		if( gUnderCallbackCounter == UNDER_STOP_GAP)";
5141   z[lc++]="		{";
5142   z[lc++]="			AddTraceMessage(\"End stall: gUnderCallbackCounter =======\", gUnderCallbackCounter );";
5143   z[lc++]="		}";
5144   z[lc++]="		return;";
5145   z[lc++]="	}";
5146   z[lc++]="#endif";
5147   z[lc++]="	past = (internalPortAudioStream *) dwUser;";
5148   z[lc++]="	if( past == NULL ) return;";
5149   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
5150   z[lc++]="	if( pahsc == NULL ) return;";
5151   z[lc++]="	if( !pahsc->pahsc_IfInsideCallback && past->past_IsActive )";
5152   z[lc++]="	{";
5153   z[lc++]="		if( past->past_StopNow )";
5154   z[lc++]="		{";
5155   z[lc++]="			past->past_IsActive = 0;";
5156   z[lc++]="		}";
5157   z[lc++]="		else if( past->past_StopSoon )";
5158   z[lc++]="		{";
5159   z[lc++]="			DSoundWrapper   *dsw = &pahsc->pahsc_DSoundWrapper;";
5160   z[lc++]="			if( past->past_NumOutputChannels > 0 )";
5161   z[lc++]="			{";
5162   z[lc++]="				DSW_ZeroEmptySpace( dsw ); ";
5163   z[lc++]="				AddTraceMessage(\"Pa_TimerCallback: waiting - written \", (int) dsw->dsw_FramesWritten );";
5164   z[lc++]="				AddTraceMessage(\"Pa_TimerCallback: waiting - played \", (int) dsw->dsw_FramesPlayed );";
5165   z[lc++]="		/* clear past_IsActive when all sound played */";
5166   z[lc++]="				if( dsw->dsw_FramesPlayed >= past->past_FrameCount )";
5167   z[lc++]="				{";
5168   z[lc++]="					past->past_IsActive = 0;";
5169   z[lc++]="				}";
5170   z[lc++]="			}";
5171   z[lc++]="			else";
5172   z[lc++]="			{";
5173   z[lc++]="				past->past_IsActive = 0;";
5174   z[lc++]="			}";
5175   z[lc++]="		}";
5176   z[lc++]="		else";
5177   z[lc++]="		{";
5178   z[lc++]="			pahsc->pahsc_IfInsideCallback = 1;";
5179   z[lc++]="			if( Pa_TimeSlice( past ) != 0)  /* Call time slice independant of timing method. */";
5180   z[lc++]="			{";
5181   z[lc++]="				past->past_StopSoon = 1;";
5182   z[lc++]="			}";
5183   z[lc++]="			pahsc->pahsc_IfInsideCallback = 0;";
5184   z[lc++]="		}";
5185   z[lc++]="	}";
5186   z[lc++]="}";
5187   z[lc++]="/*******************************************************************/";
5188   z[lc++]="PaError PaHost_OpenStream( internalPortAudioStream   *past )";
5189   z[lc++]="{";
5190   z[lc++]="	HRESULT          hr;";
5191   z[lc++]="	PaError          result = paNoError;";
5192   z[lc++]="	PaHostSoundControl *pahsc;";
5193   z[lc++]="	int              numBytes, maxChannels;";
5194   z[lc++]="	unsigned int     minNumBuffers;";
5195   z[lc++]="	internalPortAudioDevice *pad;";
5196   z[lc++]="	DSoundWrapper   *dsw;";
5197   z[lc++]="/* Allocate and initialize host data. */";
5198   z[lc++]="	pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); /* MEM */";
5199   z[lc++]="	if( pahsc == NULL )";
5200   z[lc++]="	{";
5201   z[lc++]="		result = paInsufficientMemory;";
5202   z[lc++]="		goto error;";
5203   z[lc++]="	}";
5204   z[lc++]="	memset( pahsc, 0, sizeof(PaHostSoundControl) );";
5205   z[lc++]="	past->past_DeviceData = (void *) pahsc;";
5206   z[lc++]="	pahsc->pahsc_TimerID = 0;";
5207   z[lc++]="	dsw = &pahsc->pahsc_DSoundWrapper;";
5208   z[lc++]="	DSW_Init( dsw );";
5209   z[lc++]="/* Allocate native buffer. */";
5210   z[lc++]="	maxChannels = ( past->past_NumOutputChannels > past->past_NumInputChannels ) ?";
5211   z[lc++]="		past->past_NumOutputChannels : past->past_NumInputChannels;";
5212   z[lc++]="	pahsc->pahsc_BytesPerBuffer = past->past_FramesPerUserBuffer * maxChannels * sizeof(short);";
5213   z[lc++]="	if( maxChannels > 0 )";
5214   z[lc++]="	{";
5215   z[lc++]="		pahsc->pahsc_NativeBuffer = (short *) PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerBuffer); /* MEM */";
5216   z[lc++]="		if( pahsc->pahsc_NativeBuffer == NULL )";
5217   z[lc++]="		{";
5218   z[lc++]="			result = paInsufficientMemory;";
5219   z[lc++]="			goto error;";
5220   z[lc++]="		}";
5221   z[lc++]="	}";
5222   z[lc++]="	else";
5223   z[lc++]="	{";
5224   z[lc++]="		result = paInvalidChannelCount;";
5225   z[lc++]="		goto error;";
5226   z[lc++]="	}";
5227   z[lc++]="	";
5228   z[lc++]="	DBUG((\"PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\\n\", pahsc->pahsc_MinFramesPerHostBuffer ));";
5229   z[lc++]="	minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );";
5230   z[lc++]="	past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;";
5231   z[lc++]="	numBytes = pahsc->pahsc_BytesPerBuffer * past->past_NumUserBuffers;";
5232   z[lc++]="	if( numBytes < DSBSIZE_MIN )";
5233   z[lc++]="	{";
5234   z[lc++]="		result = paBufferTooSmall;";
5235   z[lc++]="		goto error;";
5236   z[lc++]="	}";
5237   z[lc++]="	if( numBytes > DSBSIZE_MAX )";
5238   z[lc++]="	{";
5239   z[lc++]="		result = paBufferTooBig;";
5240   z[lc++]="		goto error;";
5241   z[lc++]="	}";
5242   z[lc++]="	pahsc->pahsc_FramesPerDSBuffer = past->past_FramesPerUserBuffer * past->past_NumUserBuffers;";
5243   z[lc++]="	{";
5244   z[lc++]="		int msecLatency = (int) ((pahsc->pahsc_FramesPerDSBuffer * 1000) / past->past_SampleRate);";
5245   z[lc++]="		PRINT((\"PortAudio on DirectSound - Latency = %d frames, %d msec\\n\", pahsc->pahsc_FramesPerDSBuffer, msecLatency ));";
5246   z[lc++]="	}";
5247   z[lc++]="/* ------------------ OUTPUT */";
5248   z[lc++]="	if( (past->past_OutputDeviceID >= 0) && (past->past_NumOutputChannels > 0) )";
5249   z[lc++]="	{";
5250   z[lc++]="		DBUG((\"PaHost_OpenStream: deviceID = 0x%x\\n\", past->past_OutputDeviceID));";
5251   z[lc++]="		pad = Pa_GetInternalDevice( past->past_OutputDeviceID );";
5252   z[lc++]="		hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound,   NULL );";
5253   z[lc++]="/* If this fails, then try each output device until we find one that works. */";
5254   z[lc++]="		if( hr != DS_OK )";
5255   z[lc++]="		{";
5256   z[lc++]="			int i;";
5257   z[lc++]="			ERR_RPT((\"Creation of requested Audio Output device '%s' failed.\\n\",";
5258   z[lc++]="				((pad->pad_lpGUID == NULL) ? \"Default\" : pad->pad_Info.name) ));";
5259   z[lc++]="			for( i=0; i<Pa_CountDevices(); i++ )";
5260   z[lc++]="			{";
5261   z[lc++]="				pad = Pa_GetInternalDevice( i );";
5262   z[lc++]="				if( pad->pad_Info.maxOutputChannels >= past->past_NumOutputChannels )";
5263   z[lc++]="				{";
5264   z[lc++]="					DBUG((\"Try device '%s' instead.\\n\", pad->pad_Info.name ));";
5265   z[lc++]="					hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound,   NULL );";
5266   z[lc++]="					if( hr == DS_OK )";
5267   z[lc++]="					{";
5268   z[lc++]="						ERR_RPT((\"Using device '%s' instead.\\n\", pad->pad_Info.name ));";
5269   z[lc++]="						break;";
5270   z[lc++]="					}";
5271   z[lc++]="				}";
5272   z[lc++]="			}";
5273   z[lc++]="		}";
5274   z[lc++]="		if( hr != DS_OK )";
5275   z[lc++]="		{";
5276   z[lc++]="			ERR_RPT((\"PortAudio: DirectSoundCreate() failed!\\n\"));";
5277   z[lc++]="			result = paHostError;";
5278   z[lc++]="			sPaHostError = hr;";
5279   z[lc++]="			goto error;";
5280   z[lc++]="		}";
5281   z[lc++]="		hr = DSW_InitOutputBuffer( dsw,";
5282   z[lc++]="			(unsigned long) (past->past_SampleRate + 0.5),";
5283   z[lc++]="			past->past_NumOutputChannels, numBytes );";
5284   z[lc++]="		DBUG((\"DSW_InitOutputBuffer() returns %x\\n\", hr));";
5285   z[lc++]="		if( hr != DS_OK )";
5286   z[lc++]="		{";
5287   z[lc++]="			result = paHostError;";
5288   z[lc++]="			sPaHostError = hr;";
5289   z[lc++]="			goto error;";
5290   z[lc++]="		}";
5291   z[lc++]="		past->past_FrameCount = pahsc->pahsc_DSoundWrapper.dsw_FramesWritten;";
5292   z[lc++]="	}";
5293   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
5294   z[lc++]="/* ------------------ INPUT */";
5295   z[lc++]="	if( (past->past_InputDeviceID >= 0) && (past->past_NumInputChannels > 0) )";
5296   z[lc++]="	{";
5297   z[lc++]="		pad = Pa_GetInternalDevice( past->past_InputDeviceID );";
5298   z[lc++]="		hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture,   NULL );";
5299   z[lc++]="/* If this fails, then try each input device until we find one that works. */";
5300   z[lc++]="		if( hr != DS_OK )";
5301   z[lc++]="		{";
5302   z[lc++]="			int i;";
5303   z[lc++]="			ERR_RPT((\"Creation of requested Audio Capture device '%s' failed.\\n\",";
5304   z[lc++]="				((pad->pad_lpGUID == NULL) ? \"Default\" : pad->pad_Info.name) ));";
5305   z[lc++]="			for( i=0; i<Pa_CountDevices(); i++ )";
5306   z[lc++]="			{";
5307   z[lc++]="				pad = Pa_GetInternalDevice( i );";
5308   z[lc++]="				if( pad->pad_Info.maxInputChannels >= past->past_NumInputChannels )";
5309   z[lc++]="				{";
5310   z[lc++]="					PRINT((\"Try device '%s' instead.\\n\", pad->pad_Info.name ));";
5311   z[lc++]="					hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture,   NULL );";
5312   z[lc++]="					if( hr == DS_OK ) break;";
5313   z[lc++]="				}";
5314   z[lc++]="			}";
5315   z[lc++]="		}";
5316   z[lc++]="		if( hr != DS_OK )";
5317   z[lc++]="		{";
5318   z[lc++]="			ERR_RPT((\"PortAudio: DirectSoundCaptureCreate() failed!\\n\"));";
5319   z[lc++]="			result = paHostError;";
5320   z[lc++]="			sPaHostError = hr;";
5321   z[lc++]="			goto error;";
5322   z[lc++]="		}";
5323   z[lc++]="		hr = DSW_InitInputBuffer( dsw,";
5324   z[lc++]="			(unsigned long) (past->past_SampleRate + 0.5),";
5325   z[lc++]="			past->past_NumInputChannels, numBytes );";
5326   z[lc++]="		DBUG((\"DSW_InitInputBuffer() returns %x\\n\", hr));";
5327   z[lc++]="		if( hr != DS_OK )";
5328   z[lc++]="		{";
5329   z[lc++]="			ERR_RPT((\"PortAudio: DSW_InitInputBuffer() returns %x\\n\", hr));";
5330   z[lc++]="			result = paHostError;";
5331   z[lc++]="			sPaHostError = hr;";
5332   z[lc++]="			goto error;";
5333   z[lc++]="		}";
5334   z[lc++]="	}";
5335   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
5336   z[lc++]="	/* Calculate scalar used in CPULoad calculation. */ ";
5337   z[lc++]="	{";
5338   z[lc++]="		LARGE_INTEGER frequency;";
5339   z[lc++]="		if( QueryPerformanceFrequency( &frequency ) == 0 )";
5340   z[lc++]="		{";
5341   z[lc++]="			pahsc->pahsc_InverseTicksPerUserBuffer = 0.0;";
5342   z[lc++]="		}";
5343   z[lc++]="		else";
5344   z[lc++]="		{";
5345   z[lc++]="			pahsc->pahsc_InverseTicksPerUserBuffer = past->past_SampleRate /";
5346   z[lc++]="				( (double)frequency.QuadPart * past->past_FramesPerUserBuffer );";
5347   z[lc++]="			DBUG((\"pahsc_InverseTicksPerUserBuffer = %g\\n\", pahsc->pahsc_InverseTicksPerUserBuffer ));";
5348   z[lc++]="		}";
5349   z[lc++]="	}";
5350   z[lc++]="	return result;";
5351   z[lc++]="error:";
5352   z[lc++]="	PaHost_CloseStream( past );";
5353   z[lc++]="	return result;";
5354   z[lc++]="}";
5355   z[lc++]="/*************************************************************************/";
5356   z[lc++]="PaError PaHost_StartOutput( internalPortAudioStream *past )";
5357   z[lc++]="{";
5358   z[lc++]="	HRESULT          hr;";
5359   z[lc++]="	PaHostSoundControl *pahsc;";
5360   z[lc++]="	PaError          result = paNoError;";
5361   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
5362   z[lc++]="/* Give user callback a chance to pre-fill buffer. */";
5363   z[lc++]="	result = Pa_TimeSlice( past );";
5364   z[lc++]="	if( result != paNoError ) return result; // FIXME - what if finished?";
5365   z[lc++]="	hr = DSW_StartOutput( &pahsc->pahsc_DSoundWrapper );";
5366   z[lc++]="	DBUG((\"PaHost_StartOutput: DSW_StartOutput returned = 0x%X.\\n\", hr));";
5367   z[lc++]="	if( hr != DS_OK )";
5368   z[lc++]="	{";
5369   z[lc++]="		result = paHostError;";
5370   z[lc++]="		sPaHostError = hr;";
5371   z[lc++]="		goto error;";
5372   z[lc++]="	}";
5373   z[lc++]="error:";
5374   z[lc++]="	return result;";
5375   z[lc++]="}";
5376   z[lc++]="/*************************************************************************/";
5377   z[lc++]="PaError PaHost_StartInput( internalPortAudioStream *past )";
5378   z[lc++]="{";
5379   z[lc++]="	PaError          result = paNoError;";
5380   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
5381   z[lc++]="	HRESULT          hr;";
5382   z[lc++]="	PaHostSoundControl *pahsc;";
5383   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
5384   z[lc++]="	hr = DSW_StartInput( &pahsc->pahsc_DSoundWrapper );";
5385   z[lc++]="	DBUG((\"Pa_StartStream: DSW_StartInput returned = 0x%X.\\n\", hr));";
5386   z[lc++]="	if( hr != DS_OK )";
5387   z[lc++]="	{";
5388   z[lc++]="		result = paHostError;";
5389   z[lc++]="		sPaHostError = hr;";
5390   z[lc++]="		goto error;";
5391   z[lc++]="	}";
5392   z[lc++]="error:";
5393   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
5394   z[lc++]="	return result;";
5395   z[lc++]="}";
5396   z[lc++]="/*************************************************************************/";
5397   z[lc++]="PaError PaHost_StartEngine( internalPortAudioStream *past )";
5398   z[lc++]="{";
5399   z[lc++]="	PaHostSoundControl *pahsc;";
5400   z[lc++]="	PaError          result = paNoError;";
5401   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
5402   z[lc++]="	past->past_StopNow = 0;";
5403   z[lc++]="	past->past_StopSoon = 0;";
5404   z[lc++]="	past->past_IsActive = 1;";
5405   z[lc++]="/* Create timer that will wake us up so we can fill the DSound buffer. */";
5406   z[lc++]="	{";
5407   z[lc++]="		int msecPerBuffer;";
5408   z[lc++]="		int resolution;";
5409   z[lc++]="		int bufsPerInterrupt = past->past_NumUserBuffers/4;";
5410   z[lc++]="		if( bufsPerInterrupt < 1 ) bufsPerInterrupt = 1;";
5411   z[lc++]="		msecPerBuffer = 1000 * (bufsPerInterrupt * past->past_FramesPerUserBuffer) / (int) past->past_SampleRate;";
5412   z[lc++]="		if( msecPerBuffer < 10 ) msecPerBuffer = 10;";
5413   z[lc++]="		else if( msecPerBuffer > 100 ) msecPerBuffer = 100;";
5414   z[lc++]="		resolution = msecPerBuffer/4;";
5415   z[lc++]="		pahsc->pahsc_TimerID = timeSetEvent( msecPerBuffer, resolution, (LPTIMECALLBACK) Pa_TimerCallback,";
5416   z[lc++]="		(DWORD) past, TIME_PERIODIC );";
5417   z[lc++]="	}";
5418   z[lc++]="	if( pahsc->pahsc_TimerID == 0 )";
5419   z[lc++]="	{";
5420   z[lc++]="		past->past_IsActive = 0;";
5421   z[lc++]="		result = paHostError;";
5422   z[lc++]="		sPaHostError = 0;";
5423   z[lc++]="		goto error;";
5424   z[lc++]="	}";
5425   z[lc++]="error:";
5426   z[lc++]="	return result;";
5427   z[lc++]="}";
5428   z[lc++]="/*************************************************************************/";
5429   z[lc++]="PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )";
5430   z[lc++]="{";
5431   z[lc++]="	int timeoutMsec;";
5432   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
5433   z[lc++]="	if( pahsc == NULL ) return paNoError;";
5434   z[lc++]="	if( abort ) past->past_StopNow = 1;";
5435   z[lc++]="	past->past_StopSoon = 1;";
5436   z[lc++]="/* Set timeout at 20% beyond maximum time we might wait. */";
5437   z[lc++]="	timeoutMsec = (int) (1200.0 * pahsc->pahsc_FramesPerDSBuffer / past->past_SampleRate);";
5438   z[lc++]="	while( past->past_IsActive && (timeoutMsec > 0)  )";
5439   z[lc++]="	{";
5440   z[lc++]="		Sleep(10);";
5441   z[lc++]="		timeoutMsec -= 10;";
5442   z[lc++]="	}";
5443   z[lc++]="	if( pahsc->pahsc_TimerID != 0 )";
5444   z[lc++]="	{";
5445   z[lc++]="		timeKillEvent(pahsc->pahsc_TimerID);  /* Stop callback timer. */";
5446   z[lc++]="		pahsc->pahsc_TimerID = 0;";
5447   z[lc++]="	}";
5448   z[lc++]="	return paNoError;";
5449   z[lc++]="}";
5450   z[lc++]="/*************************************************************************/";
5451   z[lc++]="PaError PaHost_StopInput( internalPortAudioStream *past, int abort )";
5452   z[lc++]="{";
5453   z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
5454   z[lc++]="	HRESULT hr;";
5455   z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
5456   z[lc++]="	if( pahsc == NULL ) return paNoError;";
5457   z[lc++]="	(void) abort;";
5458   z[lc++]="	hr = DSW_StopInput( &pahsc->pahsc_DSoundWrapper );";
5459   z[lc++]="	DBUG((\"DSW_StopInput() result is %x\\n\", hr));";
5460   z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
5461   z[lc++]="	return paNoError;";
5462   z[lc++]="}";
5463   z[lc++]="/*************************************************************************/";
5464   z[lc++]="PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )";
5465   z[lc++]="{";
5466   z[lc++]="	HRESULT hr;";
5467   z[lc++]="	PaHostSoundControl *pahsc;";
5468   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
5469   z[lc++]="	if( pahsc == NULL ) return paNoError;";
5470   z[lc++]="	(void) abort;";
5471   z[lc++]="	hr = DSW_StopOutput( &pahsc->pahsc_DSoundWrapper );";
5472   z[lc++]="	DBUG((\"DSW_StopOutput() result is %x\\n\", hr));";
5473   z[lc++]="	return paNoError;";
5474   z[lc++]="}";
5475   z[lc++]="/*******************************************************************/";
5476   z[lc++]="PaError PaHost_CloseStream( internalPortAudioStream   *past )";
5477   z[lc++]="{";
5478   z[lc++]="	PaHostSoundControl *pahsc;";
5479   z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
5480   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
5481   z[lc++]="	if( pahsc == NULL ) return paNoError;";
5482   z[lc++]="	DSW_Term( &pahsc->pahsc_DSoundWrapper );";
5483   z[lc++]="	if( pahsc->pahsc_NativeBuffer )";
5484   z[lc++]="	{";
5485   z[lc++]="		PaHost_FreeFastMemory( pahsc->pahsc_NativeBuffer, pahsc->pahsc_BytesPerBuffer ); /* MEM */";
5486   z[lc++]="		pahsc->pahsc_NativeBuffer = NULL;";
5487   z[lc++]="	}";
5488   z[lc++]="	PaHost_FreeFastMemory( pahsc, sizeof(PaHostSoundControl) ); /* MEM */";
5489   z[lc++]="	past->past_DeviceData = NULL;";
5490   z[lc++]="	return paNoError;";
5491   z[lc++]="}";
5492   z[lc++]="/*************************************************************************";
5493   z[lc++]="** Determine minimum number of buffers required for this host based";
5494   z[lc++]="** on minimum latency. Latency can be optionally set by user by setting";
5495   z[lc++]="** an environment variable. For example, to set latency to 200 msec, put:";
5496   z[lc++]="**";
5497   z[lc++]="**    set PA_MIN_LATENCY_MSEC=200";
5498   z[lc++]="**";
5499   z[lc++]="** in the AUTOEXEC.BAT file and reboot.";
5500   z[lc++]="** If the environment variable is not set, then the latency will be determined";
5501   z[lc++]="** based on the OS. Windows NT has higher latency than Win95.";
5502   z[lc++]="*/";
5503   z[lc++]="#define PA_LATENCY_ENV_NAME  (\"PA_MIN_LATENCY_MSEC\")";
5504   z[lc++]="int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )";
5505   z[lc++]="{";
5506   z[lc++]="	char      envbuf[PA_ENV_BUF_SIZE];";
5507   z[lc++]="	DWORD     hostVersion;";
5508   z[lc++]="	DWORD     hresult;";
5509   z[lc++]="	int       minLatencyMsec = 0;";
5510   z[lc++]="	double    msecPerBuffer = (1000.0 * framesPerBuffer) / sampleRate;";
5511   z[lc++]="	int       minBuffers;";
5512   z[lc++]="/* Let user determine minimal latency by setting environment variable. */";
5513   z[lc++]="	hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );";
5514   z[lc++]="	if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )";
5515   z[lc++]="	{";
5516   z[lc++]="		minLatencyMsec = atoi( envbuf );";
5517   z[lc++]="	}";
5518   z[lc++]="	else";
5519   z[lc++]="	{";
5520   z[lc++]="/* Set minimal latency based on whether NT or Win95.";
5521   z[lc++]=" * NT has higher latency.";
5522   z[lc++]=" */";
5523   z[lc++]="		hostVersion = GetVersion();";
5524   z[lc++]="/* High bit clear if NT */";
5525   z[lc++]="		minLatencyMsec = ( (hostVersion & 0x80000000) == 0 ) ? PA_WIN_NT_LATENCY : PA_WIN_9X_LATENCY  ;";
5526   z[lc++]="#if PA_USE_HIGH_LATENCY";
5527   z[lc++]="		PRINT((\"PA - Minimum Latency set to %d msec!\\n\", minLatencyMsec ));";
5528   z[lc++]="#endif";
5529   z[lc++]="	}";
5530   z[lc++]="	minBuffers = (int) (1.0 + ((double)minLatencyMsec / msecPerBuffer));";
5531   z[lc++]="	if( minBuffers < 2 ) minBuffers = 2;";
5532   z[lc++]="	return minBuffers;";
5533   z[lc++]="}";
5534   z[lc++]="/*************************************************************************/";
5535   z[lc++]="PaError PaHost_Term( void )";
5536   z[lc++]="{";
5537   z[lc++]="	int i;";
5538   z[lc++]="/* Free names allocated during enumeration. */";
5539   z[lc++]="	for( i=0; i<sNumDevices; i++ )";
5540   z[lc++]="	{";
5541   z[lc++]="		if( sDevices[i].pad_Info.name != NULL )";
5542   z[lc++]="		{";
5543   z[lc++]="			free( (void *) sDevices[i].pad_Info.name );";
5544   z[lc++]="			sDevices[i].pad_Info.name = NULL;";
5545   z[lc++]="		}";
5546   z[lc++]="	}";
5547   z[lc++]="	if( sDevices != NULL )";
5548   z[lc++]="	{";
5549   z[lc++]="		PaHost_FreeFastMemory( sDevices, sNumDevices * sizeof(internalPortAudioDevice) ); /* MEM */";
5550   z[lc++]="		sDevices = NULL;";
5551   z[lc++]="		sNumDevices = 0;";
5552   z[lc++]="	}";
5553   z[lc++]="	return 0;";
5554   z[lc++]="}";
5555   z[lc++]="void Pa_Sleep( long msec )";
5556   z[lc++]="{";
5557   z[lc++]="	Sleep( msec );";
5558   z[lc++]="}";
5559   z[lc++]="/*************************************************************************";
5560   z[lc++]=" * Allocate memory that can be accessed in real-time.";
5561   z[lc++]=" * This may need to be held in physical memory so that it is not";
5562   z[lc++]=" * paged to virtual memory.";
5563   z[lc++]=" * This call MUST be balanced with a call to PaHost_FreeFastMemory().";
5564   z[lc++]=" * Memory will be set to zero.";
5565   z[lc++]=" */";
5566   z[lc++]="void *PaHost_AllocateFastMemory( long numBytes )";
5567   z[lc++]="{";
5568   z[lc++]="	void *addr = GlobalAlloc( GPTR, numBytes ); /* FIXME - do we need physical memory? Use VirtualLock() */ /* MEM */";
5569   z[lc++]="	return addr;";
5570   z[lc++]="}";
5571   z[lc++]="/*************************************************************************";
5572   z[lc++]=" * Free memory that could be accessed in real-time.";
5573   z[lc++]=" * This call MUST be balanced with a call to PaHost_AllocateFastMemory().";
5574   z[lc++]=" */";
5575   z[lc++]="void PaHost_FreeFastMemory( void *addr, long numBytes )";
5576   z[lc++]="{";
5577   z[lc++]="	if( addr != NULL ) GlobalFree( addr ); /* MEM */";
5578   z[lc++]="}";
5579   z[lc++]="/***********************************************************************/";
5580   z[lc++]="PaError PaHost_StreamActive( internalPortAudioStream   *past )";
5581   z[lc++]="{";
5582   z[lc++]="	PaHostSoundControl *pahsc;";
5583   z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
5584   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
5585   z[lc++]="	if( pahsc == NULL ) return paInternalError;";
5586   z[lc++]="	return (PaError) (past->past_IsActive);";
5587   z[lc++]="}";
5588   z[lc++]="/*************************************************************************/";
5589   z[lc++]="PaTimestamp Pa_StreamTime( PortAudioStream *stream )";
5590   z[lc++]="{";
5591   z[lc++]="	DSoundWrapper   *dsw;";
5592   z[lc++]="	internalPortAudioStream   *past = (internalPortAudioStream *) stream;";
5593   z[lc++]="	PaHostSoundControl *pahsc;";
5594   z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
5595   z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
5596   z[lc++]="	dsw = &pahsc->pahsc_DSoundWrapper;";
5597   z[lc++]="	return dsw->dsw_FramesPlayed;";
5598   z[lc++]="}";
5599   printlib(lc);
5600 }
5601 
5602 
5603