
/*
 * Copyright (c) 1999-2006, Regents of the University of California
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 *  Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 * 
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 * 
 *  Neither the name of the University of California, Berkeley nor the
 *  names of its contributors may be used to endorse or promote products
 *  derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * Automatically generated library file psys

 * The drivers embedded in this file may be covered by a different
 * license.  Scroll down to see the license appearing before each
 * driver, or see sfront/src/lib/ directories for driver source file.

 */

#include "tree.h"



void makepa_hosthdr(void)
{
  int lc = 0;

  z[lc++]="#ifndef PA_HOST_H";
  z[lc++]="#define PA_HOST_H";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]=" * Host dependant internal API for PortAudio";
  z[lc++]=" *";
  z[lc++]=" * Author: Phil Burk  <philburk@softsynth.com>";
  z[lc++]=" *";
  z[lc++]=" * PortAudio Portable Real-Time Audio Library";
  z[lc++]=" * Latest Version at: http://www.softsynth.com/portaudio/";
  z[lc++]=" * DirectSound and Macintosh Implementation";
  z[lc++]=" * Copyright (c) 1999-2000 Phil Burk";
  z[lc++]=" *";
  z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
  z[lc++]=" * a copy of this software and associated documentation files";
  z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
  z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
  z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
  z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
  z[lc++]=" * subject to the following conditions:";
  z[lc++]=" *";
  z[lc++]=" * The above copyright notice and this permission notice shall be";
  z[lc++]=" * included in all copies or substantial portions of the Software.";
  z[lc++]=" *";
  z[lc++]=" * Any person wishing to distribute modifications to the Software is";
  z[lc++]=" * requested to send the modifications to the original developer so that";
  z[lc++]=" * they can be incorporated into the canonical version.";
  z[lc++]=" *";
  z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
  z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
  z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
  z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
  z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
  z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
  z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
  z[lc++]=" *";
  z[lc++]=" */";
  z[lc++]="";
  z[lc++]="#ifdef __cplusplus";
  z[lc++]="extern \"C\" {";
  z[lc++]="#endif /* __cplusplus */";
  z[lc++]="";
  z[lc++]="#ifndef SUPPORT_AUDIO_CAPTURE";
  z[lc++]="#define SUPPORT_AUDIO_CAPTURE  (1)";
  z[lc++]="#endif";
  z[lc++]="";
  z[lc++]="#ifndef int32";
  z[lc++]="typedef long int32;";
  z[lc++]="#endif";
  z[lc++]="#ifndef uint32";
  z[lc++]="typedef unsigned long uint32;";
  z[lc++]="#endif";
  z[lc++]="#ifndef int16";
  z[lc++]="typedef short int16;";
  z[lc++]="#endif";
  z[lc++]="#ifndef uint16";
  z[lc++]="typedef unsigned short uint16;";
  z[lc++]="#endif";
  z[lc++]="";
  z[lc++]="#define PA_MAGIC    (0x18273645)";
  z[lc++]="";
  z[lc++]="/************************************************************************************/";
  z[lc++]="/****************** Structures ******************************************************/";
  z[lc++]="/************************************************************************************/";
  z[lc++]=" ";
  z[lc++]="typedef struct internalPortAudioStream";
  z[lc++]="{";
  z[lc++]="	uint32                    past_Magic;  /* ID for struct to catch bugs. */";
  z[lc++]="/* User specified information. */";
  z[lc++]="	uint32                    past_FramesPerUserBuffer;";
  z[lc++]="	uint32                    past_NumUserBuffers;";
  z[lc++]="	double                    past_SampleRate;     /* Closest supported sample rate. */";
  z[lc++]="	int                       past_NumInputChannels;";
  z[lc++]="	int                       past_NumOutputChannels;";
  z[lc++]="	PaDeviceID                past_InputDeviceID;";
  z[lc++]="	PaDeviceID                past_OutputDeviceID;";
  z[lc++]="	PaSampleFormat            past_InputSampleFormat;";
  z[lc++]="	PaSampleFormat            past_OutputSampleFormat;";
  z[lc++]="	void                     *past_DeviceData;";
  z[lc++]="	PortAudioCallback        *past_Callback;";
  z[lc++]="	void                     *past_UserData;";
  z[lc++]="	uint32                    past_Flags;";
  z[lc++]="/* Flags for communicating between foreground and background. */";
  z[lc++]="	volatile int              past_IsActive;      /* Background is still playing. */";
  z[lc++]="	volatile int              past_StopSoon;      /* Background should keep playing when buffers empty. */";
  z[lc++]="	volatile int              past_StopNow;       /* Background should stop playing now. */";
  z[lc++]="/* These buffers are used when the native format does not match the user format. */";
  z[lc++]="	void                     *past_InputBuffer;";
  z[lc++]="	uint32                    past_InputBufferSize;";
  z[lc++]="	void                     *past_OutputBuffer;";
  z[lc++]="	uint32                    past_OutputBufferSize;";
  z[lc++]="/* Measurements */";
  z[lc++]="	uint32                    past_NumCallbacks;";
  z[lc++]="	PaTimestamp               past_FrameCount;    /* Frames output to buffer. */";
  z[lc++]="/* For measuring CPU utilization. */";
  z[lc++]="	double                    past_AverageInsideCount;";
  z[lc++]="	double                    past_AverageTotalCount;";
  z[lc++]="	double                    past_Usage;";
  z[lc++]="	int                       past_IfLastExitValid;";
  z[lc++]="} internalPortAudioStream;";
  z[lc++]="";
  z[lc++]="/************************************************************************************/";
  z[lc++]="/****************** Prototypes ******************************************************/";
  z[lc++]="/************************************************************************************/";
  z[lc++]="";
  z[lc++]="PaError PaHost_Init( void );";
  z[lc++]="PaError PaHost_Term( void );";
  z[lc++]="";
  z[lc++]="PaError PaHost_OpenStream( internalPortAudioStream   *past );";
  z[lc++]="PaError PaHost_CloseStream( internalPortAudioStream   *past );";
  z[lc++]="";
  z[lc++]="PaError PaHost_StartOutput( internalPortAudioStream   *past );";
  z[lc++]="PaError PaHost_StopOutput( internalPortAudioStream   *past, int abort );";
  z[lc++]="PaError PaHost_StartInput( internalPortAudioStream   *past );";
  z[lc++]="PaError PaHost_StopInput( internalPortAudioStream   *past, int abort );";
  z[lc++]="PaError PaHost_StartEngine( internalPortAudioStream   *past );";
  z[lc++]="PaError PaHost_StopEngine( internalPortAudioStream *past, int abort );";
  z[lc++]="PaError PaHost_StreamActive( internalPortAudioStream   *past );";
  z[lc++]="";
  z[lc++]="long Pa_CallConvertInt16( internalPortAudioStream   *past, ";
  z[lc++]="            short *nativeInputBuffer,";
  z[lc++]="            short *nativeOutputBuffer );";
  z[lc++]="";
  z[lc++]="long Pa_CallConvertFloat32( internalPortAudioStream   *past, ";
  z[lc++]="            float *nativeInputBuffer,";
  z[lc++]="            float *nativeOutputBuffer );";
  z[lc++]="";
  z[lc++]="void   *PaHost_AllocateFastMemory( long numBytes );";
  z[lc++]="void    PaHost_FreeFastMemory( void *addr, long numBytes );";
  z[lc++]="";
  z[lc++]="PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate,";
  z[lc++]="            double *closestFrameRatePtr );";
  z[lc++]="int PaHost_FindClosestTableEntry( double allowableError,  const double *rateTable,";
  z[lc++]="            int numRates, double frameRate );";
  z[lc++]="";
  z[lc++]="#ifdef __cplusplus";
  z[lc++]="}";
  z[lc++]="#endif /* __cplusplus */";
  z[lc++]="#endif /* PA_HOST_H */";
  printlib(lc);
}


void makepa_porthdr(void)
{
  int lc = 0;

  z[lc++]="#ifndef PORT_AUDIO_H";
  z[lc++]="#define PORT_AUDIO_H";
  z[lc++]="";
  z[lc++]="#ifdef __cplusplus";
  z[lc++]="extern \"C\" {";
  z[lc++]="#endif /* __cplusplus */";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]=" * PortAudio Portable Real-Time Audio Library";
  z[lc++]=" * PortAudio API Header File";
  z[lc++]=" * Latest version available at: http://www.audiomulch.com/portaudio/";
  z[lc++]=" *";
  z[lc++]=" * Copyright (c) 1999-2000 Ross Bencina and Phil Burk";
  z[lc++]=" *";
  z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
  z[lc++]=" * a copy of this software and associated documentation files";
  z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
  z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
  z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
  z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
  z[lc++]=" * subject to the following conditions:";
  z[lc++]=" *";
  z[lc++]=" * The above copyright notice and this permission notice shall be";
  z[lc++]=" * included in all copies or substantial portions of the Software.";
  z[lc++]=" *";
  z[lc++]=" * Any person wishing to distribute modifications to the Software is";
  z[lc++]=" * requested to send the modifications to the original developer so that";
  z[lc++]=" * they can be incorporated into the canonical version.";
  z[lc++]=" *";
  z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
  z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
  z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
  z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
  z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
  z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
  z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
  z[lc++]=" *";
  z[lc++]=" */";
  z[lc++]="";
  z[lc++]="typedef int PaError;";
  z[lc++]="typedef enum {";
  z[lc++]="	paNoError = 0,";
  z[lc++]="";
  z[lc++]="	paHostError = -10000,";
  z[lc++]="	paInvalidChannelCount,";
  z[lc++]="	paInvalidSampleRate,";
  z[lc++]="	paInvalidDeviceId,";
  z[lc++]="	paInvalidFlag,";
  z[lc++]="	paSampleFormatNotSupported,";
  z[lc++]="	paBadIODeviceCombination,";
  z[lc++]="	paInsufficientMemory,";
  z[lc++]="	paBufferTooBig,";
  z[lc++]="	paBufferTooSmall,";
  z[lc++]="	paNullCallback,";
  z[lc++]="	paBadStreamPtr,";
  z[lc++]="	paTimedOut,";
  z[lc++]="	paInternalError";
  z[lc++]="} PaErrorNum;";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Pa_Initialize() is the library initialisation function - call this before";
  z[lc++]="	using the library.";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="PaError Pa_Initialize( void );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Pa_Terminate() is the library termination function - call this after";
  z[lc++]="	using the library.";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="PaError Pa_Terminate( void );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Return host specific error.";
  z[lc++]="	This can be called after receiving a paHostError.";
  z[lc++]="*/";
  z[lc++]="long Pa_GetHostError( void );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Translate the error number into a human readable message.";
  z[lc++]="*/";
  z[lc++]="const char *Pa_GetErrorText( PaError errnum );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Sample formats";
  z[lc++]="";
  z[lc++]="	These are formats used to pass sound data between the callback and the";
  z[lc++]="	stream. Each device has a \"native\" format which may be used when optimum";
  z[lc++]="	efficiency or control over conversion is required.";
  z[lc++]="";
  z[lc++]="	Formats marked \"always available\" are supported (emulated) by all devices.";
  z[lc++]="";
  z[lc++]="	The floating point representation uses +1.0 and -1.0 as the respective";
  z[lc++]="	maximum and minimum.";
  z[lc++]="	";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="typedef unsigned long PaSampleFormat;";
  z[lc++]="#define paFloat32      ((PaSampleFormat) (1<<0))	/*always available*/";
  z[lc++]="#define paInt16        ((PaSampleFormat) (1<<1))	/*always available*/";
  z[lc++]="#define paInt32        ((PaSampleFormat) (1<<2))	/*always available*/";
  z[lc++]="#define paInt24        ((PaSampleFormat) (1<<3))";
  z[lc++]="#define paPackedInt24  ((PaSampleFormat) (1<<4))";
  z[lc++]="#define paInt8         ((PaSampleFormat) (1<<5))";
  z[lc++]="#define paUInt8        ((PaSampleFormat) (1<<6))    /* unsigned 8 bit, 128 is \"ground\" */";
  z[lc++]="#define paCustomFormat ((PaSampleFormat) (1<<16))";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Device enumeration mechanism.";
  z[lc++]="";
  z[lc++]="   	Device ids range from 0 to Pa_CountDevices()-1.";
  z[lc++]="";
  z[lc++]="	Devices may support input, output or both. Device 0 is always the \"default\"";
  z[lc++]="	device and should support at least stereo in and out if that is available";
  z[lc++]="	on the taget platform _even_ if this involves kludging an input/output";
  z[lc++]="	device on platforms that usually separate input from output. Other platform";
  z[lc++]="	specific devices are specified by positive device ids.";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="typedef int PaDeviceID;";
  z[lc++]="#define paNoDevice -1";
  z[lc++]="";
  z[lc++]="typedef struct{";
  z[lc++]="	int structVersion; ";
  z[lc++]="	const char *name;";
  z[lc++]="	int maxInputChannels;";
  z[lc++]="	int maxOutputChannels;";
  z[lc++]="/* Number of discrete rates, or -1 if range supported. */";
  z[lc++]="	int numSampleRates;";
  z[lc++]="/* Array of supported sample rates, or {min,max} if range supported. */";
  z[lc++]="	const double *sampleRates;";
  z[lc++]="	PaSampleFormat nativeSampleFormats;";
  z[lc++]="} PaDeviceInfo;";
  z[lc++]="";
  z[lc++]="";
  z[lc++]="int Pa_CountDevices();";
  z[lc++]="/*";
  z[lc++]="	Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID()";
  z[lc++]="";
  z[lc++]="	Return the default device ID or paNoDevice if there is no devices.";
  z[lc++]="	The result can be passed to Pa_OpenStream().";
  z[lc++]="	";
  z[lc++]="	On the PC, the user can specify a default device by";
  z[lc++]="	setting an environment variable. For example, to use device #1.";
  z[lc++]="";
  z[lc++]="		set PA_RECOMMENDED_OUTPUT_DEVICE=1";
  z[lc++]="	";
  z[lc++]="	The user should first determine the available device ID by using";
  z[lc++]="	the supplied application \"pa_devs\".";
  z[lc++]="*/";
  z[lc++]="PaDeviceID Pa_GetDefaultInputDeviceID( void );";
  z[lc++]="PaDeviceID Pa_GetDefaultOutputDeviceID( void );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	PaTimestamp is used to represent a continuous sample clock with arbitrary";
  z[lc++]="	start time useful for syncronisation. The type is used in the outTime";
  z[lc++]="	argument to the callback function and the result of Pa_StreamTime()";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="typedef double PaTimestamp;";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure";
  z[lc++]="	referring to the device specified by id.";
  z[lc++]="	If id is out of range the function returns NULL.";
  z[lc++]="";
  z[lc++]="	The returned structure is owned by the PortAudio implementation and must";
  z[lc++]="	not be manipulated or freed. The pointer is guaranteed to be valid until";
  z[lc++]="	between calls to Pa_Initialize() and Pa_Terminate().";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID devID );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	PortAudioCallback is implemented by clients of the portable audio api.";
  z[lc++]="";
  z[lc++]="	inputBuffer and outputBuffer are arrays of interleaved samples,";
  z[lc++]="	the format, packing and number of channels used by the buffers are";
  z[lc++]="	determined by parameters to Pa_OpenStream() (see below).";
  z[lc++]="";
  z[lc++]="	framesPerBuffer is the number of sample frames to be processed by the callback.";
  z[lc++]="";
  z[lc++]="	outTime is the time in samples when the buffer(s) processed by";
  z[lc++]="	this callback will begin being played at the audio output.";
  z[lc++]="	See also Pa_StreamTime()";
  z[lc++]="";
  z[lc++]="	userData is the value of a user supplied pointer passed to Pa_OpenStream()";
  z[lc++]="	intended for storing synthesis data etc.";
  z[lc++]="";
  z[lc++]="	return value:";
  z[lc++]="	The callback can return a nonzero value to stop the stream. This may be";
  z[lc++]="	useful in applications such as soundfile players where a specific duration";
  z[lc++]="	of output is required. However, it is not necessary to utilise this mechanism";
  z[lc++]="	as StopStream() will also terminate the stream. A callback returning a";
  z[lc++]="	nonzero value must fill the entire outputBuffer.";
  z[lc++]="";
  z[lc++]="	NOTE: None of the other stream functions may be called from within the";
  z[lc++]="	callback function except for Pa_GetCPULoad().";
  z[lc++]="";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="typedef int (PortAudioCallback)(";
  z[lc++]="		void *inputBuffer, void *outputBuffer,";
  z[lc++]="		unsigned long framesPerBuffer,";
  z[lc++]="		PaTimestamp outTime, void *userData );";
  z[lc++]="";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Stream flags";
  z[lc++]="";
  z[lc++]="	These flags may be supplied (ored together) in the streamFlags argument to";
  z[lc++]="	the Pa_OpenStream() function.";
  z[lc++]="";
  z[lc++]="	[ suggestions? ]";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="#define   paNoFlag      (0)";
  z[lc++]="#define   paClipOff     (1<<0)   /* disable defult clipping of out of range samples */";
  z[lc++]="#define   paDitherOff   (1<<1)   /* disable default dithering */";
  z[lc++]="#define   paPlatformSpecificFlags (0x00010000)";
  z[lc++]="typedef   unsigned long PaStreamFlags;";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	A single PortAudioStream provides multiple channels of real-time";
  z[lc++]="	input and output audio streaming to a client application.";
  z[lc++]="	Pointers to PortAudioStream objects are passed between PortAudio functions.";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="typedef void PortAudioStream;";
  z[lc++]="#define PaStream PortAudioStream";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Pa_OpenStream() opens a stream for either input, output or both.";
  z[lc++]="";
  z[lc++]="	stream is the address of a PortAudioStream pointer which will receive";
  z[lc++]="	a pointer to the newly opened stream.";
  z[lc++]="";
  z[lc++]="	inputDevice is the id of the device used for input (see PaDeviceID above.)";
  z[lc++]="	inputDevice may be paNoDevice to indicate that an input device is not required.";
  z[lc++]="";
  z[lc++]="	numInputChannels is the number of channels of sound to be delivered to the";
  z[lc++]="	callback. It can range from 1 to the value of maxInputChannels in the";
  z[lc++]="	device input record for the device specified in the inputDevice parameter.";
  z[lc++]="	If inputDevice is paNoDevice numInputChannels is ignored.";
  z[lc++]="";
  z[lc++]="	inputSampleFormat is the format of inputBuffer provided to the callback";
  z[lc++]="	function. inputSampleFormat may be any of the formats described by the";
  z[lc++]="	PaSampleFormat enumeration (see above). PortAudio guarantees support for";
  z[lc++]="	the sound devices native formats (nativeSampleFormats in the device info";
  z[lc++]="	record) and additionally 16 and 32 bit integer and 32 bit floating point";
  z[lc++]="	formats. Support for other formats is implementation defined.";
  z[lc++]="";
  z[lc++]="	inputDriverInfo is a pointer to an optional driver specific data structure";
  z[lc++]="	containing additional information for device setup or stream processing.";
  z[lc++]="	inputDriverInfo is never required for correct operation. If not used";
  z[lc++]="	inputDriverInfo should be NULL.";
  z[lc++]="";
  z[lc++]="	outputDevice is the id of the device used for output (see PaDeviceID above.)";
  z[lc++]="	outputDevice may be paNoDevice to indicate that an output device is not required.";
  z[lc++]="";
  z[lc++]="	numOutputChannels is the number of channels of sound to be supplied by the";
  z[lc++]="	callback. See the definition of numInputChannels above for more details.";
  z[lc++]="";
  z[lc++]="	outputSampleFormat is the sample format of the outputBuffer filled by the";
  z[lc++]="	callback function. See the definition of inputSampleFormat above for more";
  z[lc++]="	details.";
  z[lc++]="";
  z[lc++]="	outputDriverInfo is a pointer to an optional driver specific data structure";
  z[lc++]="	containing additional information for device setup or stream processing.";
  z[lc++]="	outputDriverInfo is never required for correct operation. If not used";
  z[lc++]="	outputDriverInfo should be NULL.";
  z[lc++]="";
  z[lc++]="	sampleRate is the desired sampleRate for input and output";
  z[lc++]="";
  z[lc++]="	framesPerBuffer is the length in sample frames of all internal sample buffers";
  z[lc++]="	used for communication with platform specific audio routines. Wherever";
  z[lc++]="	possible this corresponds to the framesPerBuffer parameter passed to the";
  z[lc++]="	callback function.";
  z[lc++]="";
  z[lc++]="	numberOfBuffers is the number of buffers used for multibuffered";
  z[lc++]="	communication with the platform specific audio routines. This parameter is";
  z[lc++]="	provided only as a guide - and does not imply that an implementation must";
  z[lc++]="	use multibuffered i/o when reliable double buffering is available (such as";
  z[lc++]="	SndPlayDoubleBuffer() on the Macintosh.)";
  z[lc++]="";
  z[lc++]="	streamFlags may contain a combination of flags ORed together.";
  z[lc++]="	These flags modify the behavior of the";
  z[lc++]="	streaming process. Some flags may only be relevant to certain buffer formats.";
  z[lc++]="";
  z[lc++]="	callback is a pointer to a client supplied function that is responsible";
  z[lc++]="	for processing and filling input and output buffers (see above for details.)";
  z[lc++]="";
  z[lc++]="	userData is a client supplied pointer which is passed to the callback";
  z[lc++]="	function. It could for example, contain a pointer to instance data necessary";
  z[lc++]="	for processing the audio buffers.";
  z[lc++]="";
  z[lc++]="	return value:";
  z[lc++]="	Apon success Pa_OpenStream() returns PaNoError and places a pointer to a";
  z[lc++]="	valid PortAudioStream in the stream argument. The stream is inactive (stopped).";
  z[lc++]="	If a call to Pa_OpenStream() fails a nonzero error code is returned (see";
  z[lc++]="	PAError above) and the value of stream is invalid.";
  z[lc++]="";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="PaError Pa_OpenStream( PortAudioStream** stream,";
  z[lc++]="				PaDeviceID inputDevice,";
  z[lc++]="				int numInputChannels,";
  z[lc++]="				PaSampleFormat inputSampleFormat,";
  z[lc++]="				void *inputDriverInfo,";
  z[lc++]="				PaDeviceID outputDevice,";
  z[lc++]="				int numOutputChannels,";
  z[lc++]="				PaSampleFormat outputSampleFormat,";
  z[lc++]="				void *outputDriverInfo,";
  z[lc++]="				double sampleRate,";
  z[lc++]="				unsigned long framesPerBuffer,";
  z[lc++]="				unsigned long numberOfBuffers,";
  z[lc++]="				PaStreamFlags streamFlags,";
  z[lc++]="				PortAudioCallback *callback,";
  z[lc++]="				void *userData );";
  z[lc++]="";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that";
  z[lc++]="	opens the default input and/or ouput devices. Most parameters have";
  z[lc++]="	identical meaning to their Pa_OpenStream() counterparts, with the following";
  z[lc++]="	exceptions:";
  z[lc++]="";
  z[lc++]="	If either numInputChannels or numOutputChannels is 0 the respective device";
  z[lc++]="	is not opened (same as passing paNoDevice in the device arguments to Pa_OpenStream() )";
  z[lc++]="";
  z[lc++]="	sampleFormat applies to both the input and output buffers.";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="PaError Pa_OpenDefaultStream( PortAudioStream** stream,";
  z[lc++]="				int numInputChannels,";
  z[lc++]="				int numOutputChannels,";
  z[lc++]="				PaSampleFormat sampleFormat,";
  z[lc++]="				double sampleRate,";
  z[lc++]="				unsigned long framesPerBuffer,";
  z[lc++]="				unsigned long numberOfBuffers,";
  z[lc++]="				PortAudioCallback *callback,";
  z[lc++]="				void *userData );";
  z[lc++]="	   ";
  z[lc++]="/*";
  z[lc++]="	Pa_CloseStream() closes an audio stream, flushing any pending buffers.";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="PaError Pa_CloseStream( PortAudioStream* );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]=" 	Pa_StartStream() and Pa_StopStream() begin and terminate audio processing.";
  z[lc++]="	Pa_StopStream() waits until all pending audio buffers have been played.";
  z[lc++]="    Pa_AbortStream() stops playing immediately without waiting for pending";
  z[lc++]="    buffers to complete.";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="PaError Pa_StartStream( PortAudioStream *stream );";
  z[lc++]="";
  z[lc++]="PaError Pa_StopStream( PortAudioStream *stream );";
  z[lc++]="";
  z[lc++]="PaError Pa_AbortStream( PortAudioStream *stream );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Pa_StreamActive() returns one when the stream is playing audio,";
  z[lc++]="	zero when not playing, or a negative error number if the";
  z[lc++]="	stream is invalid.";
  z[lc++]="	The stream is active between calls to Pa_StartStream() and Pa_StopStream(),";
  z[lc++]="	but may also become inactive if the callback returns a non-zero value.";
  z[lc++]="	In the latter case, the stream is considered inactive after the last";
  z[lc++]="	buffer has finished playing.";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="PaError Pa_StreamActive( PortAudioStream *stream );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Pa_StreamTime() returns the current output time for the stream in samples.";
  z[lc++]="	This time may be used as a time reference (for example syncronising audio to";
  z[lc++]="	MIDI).";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="PaTimestamp Pa_StreamTime( PortAudioStream *stream );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	The \"CPU Load\" is a fraction of total CPU time consumed by the";
  z[lc++]="	stream's audio processing.";
  z[lc++]="	A value of 0.5 would imply that PortAudio and the sound generating";
  z[lc++]="	callback was consuming roughly 50% of the available CPU time.";
  z[lc++]="	This function may be called from the callback function or the application.";
  z[lc++]="*/";
  z[lc++]="double Pa_GetCPULoad( PortAudioStream* stream );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Use Pa_GetMinNumBuffers() to determine minimum number of buffers required for";
  z[lc++]="	the current host based on minimum latency. ";
  z[lc++]="	On the PC, for the DirectSound implementation, latency can be optionally set";
  z[lc++]="	by user by setting an environment variable.";
  z[lc++]="	For example, to set latency to 200 msec, put:";
  z[lc++]="	";
  z[lc++]="	   set PA_MIN_LATENCY_MSEC=200";
  z[lc++]="	";
  z[lc++]="	in the AUTOEXEC.BAT file and reboot.";
  z[lc++]="	If the environment variable is not set, then the latency will be determined";
  z[lc++]="	based on the OS. Windows NT has higher latency than Win95.";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Sleep for at least 'msec' milliseconds.";
  z[lc++]="	You may sleep longer than the requested time so don't rely";
  z[lc++]="	on this for accurate musical timing.";
  z[lc++]="*/";
  z[lc++]="void Pa_Sleep( long msec );";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Return size in bytes of a single sample in a given PaSampleFormat";
  z[lc++]="	or paSampleFormatNotSupported. ";
  z[lc++]="*/";
  z[lc++]="PaError Pa_GetSampleSize( PaSampleFormat format );";
  z[lc++]="";
  z[lc++]="#ifdef __cplusplus";
  z[lc++]="}";
  z[lc++]="#endif /* __cplusplus */";
  z[lc++]="#endif /* PORT_AUDIO_H */";
  printlib(lc);
}


void makepa_tracehdr(void)
{
  int lc = 0;

  z[lc++]="#ifndef PA_TRACE_H";
  z[lc++]="#define PA_TRACE_H";
  z[lc++]="/*";
  z[lc++]=" * Portable Audio I/O Library Trace Facility";
  z[lc++]=" * Store trace information in real-time for later printing.";
  z[lc++]=" *";
  z[lc++]=" * Based on the Open Source API proposed by Ross Bencina";
  z[lc++]=" * Copyright (c) 1999-2000 Phil Burk";
  z[lc++]=" *";
  z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
  z[lc++]=" * a copy of this software and associated documentation files";
  z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
  z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
  z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
  z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
  z[lc++]=" * subject to the following conditions:";
  z[lc++]=" *";
  z[lc++]=" * The above copyright notice and this permission notice shall be";
  z[lc++]=" * included in all copies or substantial portions of the Software.";
  z[lc++]=" *";
  z[lc++]=" * Any person wishing to distribute modifications to the Software is";
  z[lc++]=" * requested to send the modifications to the original developer so that";
  z[lc++]=" * they can be incorporated into the canonical version.";
  z[lc++]=" *";
  z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
  z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
  z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
  z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
  z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
  z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
  z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
  z[lc++]=" */";
  z[lc++]="";
  z[lc++]="";
  z[lc++]="#define TRACE_REALTIME_EVENTS     (0)   /* Keep log of various real-time events. */";
  z[lc++]="#define MAX_TRACE_RECORDS      (2048)";
  z[lc++]="";
  z[lc++]="#ifdef __cplusplus";
  z[lc++]="extern \"C\" {";
  z[lc++]="#endif /* __cplusplus */";
  z[lc++]="";
  z[lc++]="";
  z[lc++]="/************************************************************************************/";
  z[lc++]="/****************** Prototypes ******************************************************/";
  z[lc++]="/************************************************************************************/";
  z[lc++]="";
  z[lc++]="#if TRACE_REALTIME_EVENTS";
  z[lc++]="";
  z[lc++]="void DumpTraceMessages();";
  z[lc++]="void ResetTraceMessages();";
  z[lc++]="void AddTraceMessage( char *msg, int data );";
  z[lc++]="";
  z[lc++]="#else";
  z[lc++]="";
  z[lc++]="#define AddTraceMessage(msg,data) /* noop */";
  z[lc++]="#define ResetTraceMessages() /* noop */";
  z[lc++]="#define DumpTraceMessages() /* noop */";
  z[lc++]="";
  z[lc++]="#endif";
  z[lc++]="";
  z[lc++]="#ifdef __cplusplus";
  z[lc++]="}";
  z[lc++]="#endif /* __cplusplus */";
  z[lc++]="";
  z[lc++]="#endif /* PA_TRACE_H */";
  printlib(lc);
}


void makepa_lib(void)
{
  int lc = 0;

  z[lc++]="/*";
  z[lc++]=" * Portable Audio I/O Library";
  z[lc++]=" * Host Independant Layer";
  z[lc++]=" *";
  z[lc++]=" * Based on the Open Source API proposed by Ross Bencina";
  z[lc++]=" * Copyright (c) 1999-2000 Phil Burk";
  z[lc++]=" *";
  z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
  z[lc++]=" * a copy of this software and associated documentation files";
  z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
  z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
  z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
  z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
  z[lc++]=" * subject to the following conditions:";
  z[lc++]=" *";
  z[lc++]=" * The above copyright notice and this permission notice shall be";
  z[lc++]=" * included in all copies or substantial portions of the Software.";
  z[lc++]=" *";
  z[lc++]=" * Any person wishing to distribute modifications to the Software is";
  z[lc++]=" * requested to send the modifications to the original developer so that";
  z[lc++]=" * they can be incorporated into the canonical version.";
  z[lc++]=" *";
  z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
  z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
  z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
  z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
  z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
  z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
  z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
  z[lc++]=" *";
  z[lc++]=" */";
  z[lc++]="";
  z[lc++]="/* Modification History:";
  z[lc++]=" PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC";
  z[lc++]=" PLB20010820 - fix dither and shift for recording PaUInt8 format ";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="#include <stdio.h>";
  z[lc++]="#include <stdlib.h>";
  z[lc++]="#include <string.h>";
  z[lc++]="#include <math.h>";
  z[lc++]="";
  z[lc++]="/* PLB20010422 - \"memory.h\" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */";
  z[lc++]="#ifdef _WIN32";
  z[lc++]="#ifndef __MWERKS__";
  z[lc++]="#include <memory.h>";
  z[lc++]="#endif  /* __MWERKS__ */";
  z[lc++]="#else   /* !_WIN32 */";
  z[lc++]="#include <memory.h>";
  z[lc++]="#endif  /* _WIN32 */";
  z[lc++]="";
  z[lc++]="#if 0";
  z[lc++]="#include \"portaudio.h\"";
  z[lc++]="#include \"pa_host.h\"";
  z[lc++]="#include \"pa_trace.h\"";
  z[lc++]="#endif";
  z[lc++]="";
  z[lc++]="/* The reason we might NOT want to validate the rate before opening the stream";
  z[lc++]=" * is because many DirectSound drivers lie about the rates they actually support.";
  z[lc++]=" */";
  z[lc++]="#define PA_VALIDATE_RATE    (0)   /* If true validate sample rate against driver info. */";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="O- maybe not allocate past_InputBuffer and past_OutputBuffer if not needed for conversion";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="#ifndef FALSE";
  z[lc++]="	#define FALSE  (0)";
  z[lc++]="	#define TRUE   (!FALSE)";
  z[lc++]="#endif";
  z[lc++]="";
  z[lc++]="#define PRINT(x) { printf x; fflush(stdout); }";
  z[lc++]="#define ERR_RPT(x) PRINT(x)";
  z[lc++]="#define DBUG(x)  /* PRINT(x) */";
  z[lc++]="#define DBUGX(x) /* PRINT(x) */";
  z[lc++]="";
  z[lc++]="static int gInitCount = 0; /* Count number of times Pa_Initialize() called to allow nesting and overlapping. */";
  z[lc++]="";
  z[lc++]="static PaError Pa_KillStream(  PortAudioStream *stream, int abort );";
  z[lc++]="";
  z[lc++]="/***********************************************************************/";
  z[lc++]="int PaHost_FindClosestTableEntry( double allowableError,  const double *rateTable, int numRates, double frameRate )";
  z[lc++]="{";
  z[lc++]="	double err, minErr = allowableError;";
  z[lc++]="	int i, bestFit = -1;";
  z[lc++]="	";
  z[lc++]="	for( i=0; i<numRates; i++ )";
  z[lc++]="	{";
  z[lc++]="		err = fabs( frameRate - rateTable[i] );";
  z[lc++]="		if( err < minErr )";
  z[lc++]="		{";
  z[lc++]="			minErr = err;";
  z[lc++]="			bestFit = i;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	return bestFit;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/**************************************************************************";
  z[lc++]="** Make sure sample rate is legal and also convert to enumeration for driver.";
  z[lc++]="*/";
  z[lc++]="PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate,";
  z[lc++]="	double *closestFrameRatePtr )";
  z[lc++]="{";
  z[lc++]="	long bestRateIndex;";
  z[lc++]="	const PaDeviceInfo *pdi;";
  z[lc++]="	pdi = Pa_GetDeviceInfo( id );";
  z[lc++]="	if( pdi == NULL )";
  z[lc++]="	{";
  z[lc++]="		return paInvalidDeviceId;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="	if( pdi->numSampleRates == -1 )";
  z[lc++]="	{";
  z[lc++]="	/* Is it out of range? */";
  z[lc++]="		if( (requestedFrameRate < pdi->sampleRates[0]) ||";
  z[lc++]="			(requestedFrameRate > pdi->sampleRates[1]) )";
  z[lc++]="		{";
  z[lc++]="			return paInvalidSampleRate;";
  z[lc++]="		}";
  z[lc++]="		";
  z[lc++]="		*closestFrameRatePtr = requestedFrameRate;";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="		bestRateIndex = PaHost_FindClosestTableEntry( 1.0, pdi->sampleRates, pdi->numSampleRates, requestedFrameRate );";
  z[lc++]="		if( bestRateIndex < 0 ) return paInvalidSampleRate;";
  z[lc++]="		*closestFrameRatePtr = pdi->sampleRates[bestRateIndex];";
  z[lc++]="	}";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError Pa_OpenStream(";
  z[lc++]="		PortAudioStream** streamPtrPtr,";
  z[lc++]="		PaDeviceID inputDeviceID,";
  z[lc++]="		int numInputChannels,";
  z[lc++]="		PaSampleFormat inputSampleFormat,";
  z[lc++]="		void *inputDriverInfo,";
  z[lc++]="		PaDeviceID outputDeviceID,";
  z[lc++]="		int numOutputChannels,";
  z[lc++]="		PaSampleFormat outputSampleFormat,";
  z[lc++]="		void *outputDriverInfo,";
  z[lc++]="		double sampleRate,";
  z[lc++]="		unsigned long framesPerBuffer,";
  z[lc++]="		unsigned long numberOfBuffers,";
  z[lc++]="		unsigned long streamFlags,";
  z[lc++]="		PortAudioCallback *callback,";
  z[lc++]="		void *userData )";
  z[lc++]="{";
  z[lc++]="	internalPortAudioStream   *past = NULL;";
  z[lc++]="	PaError                    result = paNoError;";
  z[lc++]="	int                        bitsPerInputSample;";
  z[lc++]="	int                        bitsPerOutputSample;";
  z[lc++]="/* Print passed parameters. */";
  z[lc++]="	DBUG((\"Pa_OpenStream( %p, %d, %d, %d, %p, /* input */ \\n\",";
  z[lc++]="			streamPtrPtr, inputDeviceID, numInputChannels,";
  z[lc++]="			inputSampleFormat, inputDriverInfo ));";
  z[lc++]="	DBUG((\"               %d, %d, %d, %p, /* output */\\n\",";
  z[lc++]="			outputDeviceID, numOutputChannels,";
  z[lc++]="			outputSampleFormat, outputDriverInfo ));";
  z[lc++]="	DBUG((\"               %g, %d, %d, 0x%x, , %p )\\n\",";
  z[lc++]="			sampleRate, framesPerBuffer, numberOfBuffers,";
  z[lc++]="			streamFlags, userData ));";
  z[lc++]="";
  z[lc++]="/* Check for parameter errors. */";
  z[lc++]="	if( (streamFlags & ~(paClipOff | paDitherOff)) != 0 ) return paInvalidFlag;";
  z[lc++]="	if( streamPtrPtr == NULL ) return paBadStreamPtr;";
  z[lc++]="	if( inputDriverInfo != NULL ) return paHostError; /* REVIEW */";
  z[lc++]="	if( outputDriverInfo != NULL ) return paHostError; /* REVIEW */";
  z[lc++]="	if( (inputDeviceID < 0) && ( outputDeviceID < 0) ) return paInvalidDeviceId;";
  z[lc++]="	if( (outputDeviceID >= Pa_CountDevices()) || (inputDeviceID >= Pa_CountDevices()) )";
  z[lc++]="	{";
  z[lc++]="		return paInvalidDeviceId;";
  z[lc++]="	}";
  z[lc++]="	if( (numInputChannels <= 0) && ( numOutputChannels <= 0) ) return paInvalidChannelCount;";
  z[lc++]="";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="	if( inputDeviceID >= 0 )";
  z[lc++]="	{";
  z[lc++]="		PaError size = Pa_GetSampleSize( inputSampleFormat );";
  z[lc++]="		if( size < 0 ) return size;";
  z[lc++]="		bitsPerInputSample = 8 * size;";
  z[lc++]="		if( (numInputChannels <= 0) ) return paInvalidChannelCount;";
  z[lc++]="	}";
  z[lc++]="#else";
  z[lc++]="	if( inputDeviceID >= 0 )";
  z[lc++]="	{";
  z[lc++]="		return paInvalidChannelCount;";
  z[lc++]="	}";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="		if( numInputChannels > 0 ) return paInvalidChannelCount;";
  z[lc++]="		bitsPerInputSample = 0;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="	if( outputDeviceID >= 0 )";
  z[lc++]="	{";
  z[lc++]="		PaError size = Pa_GetSampleSize( outputSampleFormat );";
  z[lc++]="		if( size < 0 ) return size;";
  z[lc++]="		bitsPerOutputSample = 8 * size;";
  z[lc++]="		if( (numOutputChannels <= 0) ) return paInvalidChannelCount;";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="		if( numOutputChannels > 0 ) return paInvalidChannelCount;";
  z[lc++]="		bitsPerOutputSample = 0;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="	if( callback == NULL ) return paNullCallback;";
  z[lc++]="";
  z[lc++]="/* Allocate and clear stream structure. */";
  z[lc++]="	past = (internalPortAudioStream *) PaHost_AllocateFastMemory( sizeof(internalPortAudioStream) );";
  z[lc++]="	if( past == NULL ) return paInsufficientMemory;";
  z[lc++]="	memset( past, 0, sizeof(internalPortAudioStream) );";
  z[lc++]="	AddTraceMessage(\"Pa_OpenStream: past\", (long) past );";
  z[lc++]="	";
  z[lc++]="	past->past_Magic = PA_MAGIC;  /* Set ID to catch bugs. */";
  z[lc++]="	past->past_FramesPerUserBuffer = framesPerBuffer;";
  z[lc++]="	past->past_NumUserBuffers = numberOfBuffers; /* NOTE - PaHost_OpenStream() NMUST CHECK FOR ZERO! */";
  z[lc++]="	past->past_Callback = callback;";
  z[lc++]="	past->past_UserData = userData;";
  z[lc++]="	past->past_OutputSampleFormat = outputSampleFormat;";
  z[lc++]="	past->past_InputSampleFormat = inputSampleFormat;";
  z[lc++]="	past->past_OutputDeviceID = outputDeviceID;";
  z[lc++]="	past->past_InputDeviceID = inputDeviceID;";
  z[lc++]="	past->past_NumInputChannels = numInputChannels;";
  z[lc++]="	past->past_NumOutputChannels = numOutputChannels;";
  z[lc++]="	past->past_Flags = streamFlags;";
  z[lc++]="";
  z[lc++]="/* Check for absurd sample rates. */";
  z[lc++]="	if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )";
  z[lc++]="	{";
  z[lc++]="		result = paInvalidSampleRate;";
  z[lc++]="		goto cleanup;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="/* Allocate buffers that may be used for format conversion from user to native buffers. */";
  z[lc++]="	if( numInputChannels > 0 )";
  z[lc++]="	{";
  z[lc++]="	";
  z[lc++]="#if PA_VALIDATE_RATE";
  z[lc++]="		result = PaHost_ValidateSampleRate( inputDeviceID, sampleRate, &past->past_SampleRate );";
  z[lc++]="		if( result < 0 )";
  z[lc++]="		{";
  z[lc++]="			goto cleanup;";
  z[lc++]="		}";
  z[lc++]="#else";
  z[lc++]="		past->past_SampleRate = sampleRate;";
  z[lc++]="#endif";
  z[lc++]="/* Allocate single Input buffer. */";
  z[lc++]="		past->past_InputBufferSize = framesPerBuffer * numInputChannels * ((bitsPerInputSample+7) / 8);";
  z[lc++]="		past->past_InputBuffer = PaHost_AllocateFastMemory(past->past_InputBufferSize);";
  z[lc++]="		if( past->past_InputBuffer == NULL )";
  z[lc++]="		{";
  z[lc++]="			result = paInsufficientMemory;";
  z[lc++]="			goto cleanup;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="		past->past_InputBuffer = NULL;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="/* Allocate single Output buffer. */";
  z[lc++]="	if( numOutputChannels > 0 )";
  z[lc++]="	{";
  z[lc++]="#if PA_VALIDATE_RATE";
  z[lc++]="		result = PaHost_ValidateSampleRate( outputDeviceID, sampleRate, &past->past_SampleRate );";
  z[lc++]="		if( result < 0 )";
  z[lc++]="		{";
  z[lc++]="			goto cleanup;";
  z[lc++]="		}";
  z[lc++]="#else";
  z[lc++]="		past->past_SampleRate = sampleRate;";
  z[lc++]="#endif";
  z[lc++]="		past->past_OutputBufferSize = framesPerBuffer * numOutputChannels * ((bitsPerOutputSample+7) / 8);";
  z[lc++]="		past->past_OutputBuffer = PaHost_AllocateFastMemory(past->past_OutputBufferSize);";
  z[lc++]="		if( past->past_OutputBuffer == NULL )";
  z[lc++]="		{";
  z[lc++]="			result = paInsufficientMemory;";
  z[lc++]="			goto cleanup;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="		past->past_OutputBuffer = NULL;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="	result = PaHost_OpenStream( past );";
  z[lc++]="	if( result < 0 ) goto cleanup;";
  z[lc++]="";
  z[lc++]="	*streamPtrPtr = (void *) past;";
  z[lc++]="";
  z[lc++]="	return result;";
  z[lc++]="";
  z[lc++]="cleanup:";
  z[lc++]="	if( past != NULL ) Pa_CloseStream( past );";
  z[lc++]="	*streamPtrPtr = NULL;";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError Pa_OpenDefaultStream( PortAudioStream** stream,";
  z[lc++]="		int numInputChannels,";
  z[lc++]="		int numOutputChannels,";
  z[lc++]="		PaSampleFormat sampleFormat,";
  z[lc++]="		double sampleRate,";
  z[lc++]="		unsigned long framesPerBuffer,";
  z[lc++]="		unsigned long numberOfBuffers,";
  z[lc++]="		PortAudioCallback *callback,";
  z[lc++]="		void *userData )";
  z[lc++]="{";
  z[lc++]="	return Pa_OpenStream(";
  z[lc++]="		stream,";
  z[lc++]="		((numInputChannels > 0) ? Pa_GetDefaultInputDeviceID() : paNoDevice),";
  z[lc++]="		numInputChannels, sampleFormat, NULL,";
  z[lc++]="		((numOutputChannels > 0) ? Pa_GetDefaultOutputDeviceID() : paNoDevice),";
  z[lc++]="		numOutputChannels, sampleFormat, NULL,";
  z[lc++]="		sampleRate, framesPerBuffer, numberOfBuffers, paNoFlag, callback, userData );";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError Pa_CloseStream( PortAudioStream* stream)";
  z[lc++]="{";
  z[lc++]="	PaError   result;";
  z[lc++]="	internalPortAudioStream   *past;";
  z[lc++]="	";
  z[lc++]="	DBUG((\"Pa_CloseStream()\\n\"));";
  z[lc++]="	if( stream == NULL ) return paBadStreamPtr;";
  z[lc++]="	past = (internalPortAudioStream *) stream;";
  z[lc++]="";
  z[lc++]="	Pa_AbortStream( past );";
  z[lc++]="	result = PaHost_CloseStream( past );";
  z[lc++]="	";
  z[lc++]="	if( past->past_InputBuffer ) PaHost_FreeFastMemory( past->past_InputBuffer, past->past_InputBufferSize );";
  z[lc++]="	if( past->past_OutputBuffer ) PaHost_FreeFastMemory( past->past_OutputBuffer, past->past_OutputBufferSize );";
  z[lc++]="	PaHost_FreeFastMemory( past, sizeof(internalPortAudioStream) );";
  z[lc++]="";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError Pa_StartStream( PortAudioStream *stream )";
  z[lc++]="{";
  z[lc++]="	PaError result = paHostError;";
  z[lc++]="	internalPortAudioStream   *past;";
  z[lc++]="";
  z[lc++]="	if( stream == NULL ) return paBadStreamPtr;";
  z[lc++]="	past = (internalPortAudioStream *) stream;";
  z[lc++]="";
  z[lc++]="	past->past_FrameCount = 0.0;";
  z[lc++]="";
  z[lc++]="	if( past->past_NumInputChannels > 0 )";
  z[lc++]="	{";
  z[lc++]="		result = PaHost_StartInput( past );";
  z[lc++]="		DBUG((\"Pa_StartStream: PaHost_StartInput returned = 0x%X.\\n\", result));";
  z[lc++]="		if( result < 0 ) goto error;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="	if( past->past_NumOutputChannels > 0 )";
  z[lc++]="	{";
  z[lc++]="		result = PaHost_StartOutput( past );";
  z[lc++]="		DBUG((\"Pa_StartStream: PaHost_StartOutput returned = 0x%X.\\n\", result));";
  z[lc++]="		if( result < 0 ) goto error;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="	result = PaHost_StartEngine( past );";
  z[lc++]="	DBUG((\"Pa_StartStream: PaHost_StartEngine returned = 0x%X.\\n\", result));";
  z[lc++]="	if( result < 0 ) goto error;";
  z[lc++]="";
  z[lc++]="	return paNoError;";
  z[lc++]="";
  z[lc++]="error:";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError Pa_StopStream(  PortAudioStream *stream )";
  z[lc++]="{";
  z[lc++]="	return Pa_KillStream( stream, 0 );";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError Pa_AbortStream(  PortAudioStream *stream )";
  z[lc++]="{";
  z[lc++]="	return Pa_KillStream( stream, 1 );";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="static PaError Pa_KillStream(  PortAudioStream *stream, int abort )";
  z[lc++]="{";
  z[lc++]="	PaError result = paNoError;";
  z[lc++]="	internalPortAudioStream   *past;";
  z[lc++]="";
  z[lc++]="	DBUG((\"Pa_StopStream().\\n\"));";
  z[lc++]="	if( stream == NULL ) return paBadStreamPtr;";
  z[lc++]="	past = (internalPortAudioStream *) stream;";
  z[lc++]="";
  z[lc++]="	if( (past->past_NumInputChannels > 0) || (past->past_NumOutputChannels > 0) )";
  z[lc++]="	{";
  z[lc++]="		result = PaHost_StopEngine( past, abort );";
  z[lc++]="		DBUG((\"Pa_StopStream: PaHost_StopEngine returned = 0x%X.\\n\", result));";
  z[lc++]="		if( result < 0 ) goto error;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="	if( past->past_NumInputChannels > 0 )";
  z[lc++]="	{";
  z[lc++]="		result = PaHost_StopInput( past, abort );";
  z[lc++]="		DBUG((\"Pa_StopStream: PaHost_StopInput returned = 0x%X.\\n\", result));";
  z[lc++]="		if( result != paNoError ) goto error;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="	if( past->past_NumOutputChannels > 0 )";
  z[lc++]="	{";
  z[lc++]="		result = PaHost_StopOutput( past, abort );";
  z[lc++]="		DBUG((\"Pa_StopStream: PaHost_StopOutput returned = 0x%X.\\n\", result));";
  z[lc++]="		if( result != paNoError ) goto error;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="error:";
  z[lc++]="	past->past_Usage = 0;";
  z[lc++]="	past->past_IfLastExitValid = 0;";
  z[lc++]="	";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError Pa_StreamActive( PortAudioStream *stream )";
  z[lc++]="{";
  z[lc++]="	internalPortAudioStream   *past;";
  z[lc++]="	if( stream == NULL ) return paBadStreamPtr;";
  z[lc++]="	past = (internalPortAudioStream *) stream;";
  z[lc++]="	return PaHost_StreamActive( past );";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="const char *Pa_GetErrorText( PaError errnum )";
  z[lc++]="{";
  z[lc++]="	const char *msg;";
  z[lc++]="";
  z[lc++]="	switch(errnum)";
  z[lc++]="	{";
  z[lc++]="	case paNoError:                  msg = \"Success\"; break;";
  z[lc++]="	case paHostError:                msg = \"Host error.\"; break;";
  z[lc++]="	case paInvalidChannelCount:      msg = \"Invalid number of channels.\"; break;";
  z[lc++]="	case paInvalidSampleRate:        msg = \"Invalid sample rate.\"; break;";
  z[lc++]="	case paInvalidDeviceId:          msg = \"Invalid device ID.\"; break;";
  z[lc++]="	case paInvalidFlag:              msg = \"Invalid flag.\"; break;";
  z[lc++]="	case paSampleFormatNotSupported: msg = \"Sample format not supported\"; break;";
  z[lc++]="	case paBadIODeviceCombination:   msg = \"Illegal combination of I/O devices.\"; break;";
  z[lc++]="	case paInsufficientMemory:       msg = \"Insufficient memory.\"; break;";
  z[lc++]="	case paBufferTooBig:             msg = \"Buffer too big.\"; break;";
  z[lc++]="	case paBufferTooSmall:           msg = \"Buffer too small.\"; break;";
  z[lc++]="	case paNullCallback:             msg = \"No callback routine specified.\"; break;";
  z[lc++]="	case paBadStreamPtr:             msg = \"Invalid stream pointer.\"; break;";
  z[lc++]="	case paTimedOut    :             msg = \"Wait Timed Out.\"; break;";
  z[lc++]="	case paInternalError:            msg = \"Internal PortAudio Error.\"; break;";
  z[lc++]="	default:                         msg = \"Illegal error number.\"; break;";
  z[lc++]="	}";
  z[lc++]="	return msg;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*";
  z[lc++]="	Get CPU Load as a fraction of total CPU time.";
  z[lc++]="	A value of 0.5 would imply that PortAudio and the sound generating";
  z[lc++]="	callback was consuming roughly 50% of the available CPU time.";
  z[lc++]="	The amount may vary depending on CPU load.";
  z[lc++]="	This function may be called from the callback function.";
  z[lc++]="*/";
  z[lc++]="double Pa_GetCPULoad(  PortAudioStream* stream)";
  z[lc++]="{";
  z[lc++]="	internalPortAudioStream   *past;";
  z[lc++]="	if( stream == NULL ) return (double) paBadStreamPtr;";
  z[lc++]="	past = (internalPortAudioStream *) stream;";
  z[lc++]="	return past->past_Usage;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************";
  z[lc++]="** Calculate 2 LSB dither signal with a triangular distribution.";
  z[lc++]="** Ranged properly for adding to a 32 bit integer prior to >>15.";
  z[lc++]="*/";
  z[lc++]="#define DITHER_BITS   (15)";
  z[lc++]="#define DITHER_SCALE  (1.0f / ((1<<DITHER_BITS)-1))";
  z[lc++]="static long Pa_TriangularDither( void )";
  z[lc++]="{";
  z[lc++]="	static unsigned long previous = 0;";
  z[lc++]="	static unsigned long randSeed1 = 22222;";
  z[lc++]="	static unsigned long randSeed2 = 5555555;";
  z[lc++]="	long current, highPass;";
  z[lc++]="/* Generate two random numbers. */";
  z[lc++]="	randSeed1 = (randSeed1 * 196314165) + 907633515;";
  z[lc++]="	randSeed2 = (randSeed2 * 196314165) + 907633515;";
  z[lc++]="/* Generate triangular distribution about 0. */";
  z[lc++]="	current = (((long)randSeed1)>>(32-DITHER_BITS)) + (((long)randSeed2)>>(32-DITHER_BITS));";
  z[lc++]=" /* High pass filter to reduce audibility. */";
  z[lc++]="	highPass = current - previous;";
  z[lc++]="	previous = current;";
  z[lc++]="	return highPass;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************";
  z[lc++]="** Called by host code.";
  z[lc++]="** Convert input from Int16, call user code, then convert output";
  z[lc++]="** to Int16 format for native use.";
  z[lc++]="** Assumes host native format is paInt16.";
  z[lc++]="** Returns result from user callback.";
  z[lc++]="*/";
  z[lc++]="long Pa_CallConvertInt16( internalPortAudioStream   *past, ";
  z[lc++]="	short *nativeInputBuffer,";
  z[lc++]="	short *nativeOutputBuffer )";
  z[lc++]="{";
  z[lc++]="	long              temp;";
  z[lc++]="	long              bytesEmpty = 0;";
  z[lc++]="	long              bytesFilled = 0;";
  z[lc++]="	int               userResult;";
  z[lc++]="	unsigned int      i;";
  z[lc++]="	void             *inputBuffer = NULL;";
  z[lc++]="	void             *outputBuffer = NULL;";
  z[lc++]="	";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="/* Get native data from DirectSound. */";
  z[lc++]="	if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )";
  z[lc++]="	{";
  z[lc++]="/* Convert from native format to PA format. */";
  z[lc++]="		unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels;";
  z[lc++]="		switch(past->past_InputSampleFormat)";
  z[lc++]="		{";
  z[lc++]="		";
  z[lc++]="		case paFloat32:";
  z[lc++]="			{";
  z[lc++]="				float *inBufPtr = (float *) past->past_InputBuffer;";
  z[lc++]="				inputBuffer = past->past_InputBuffer;";
  z[lc++]="				for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="				{";
  z[lc++]="					inBufPtr[i] = nativeInputBuffer[i] * (1.0f / 32767.0f);";
  z[lc++]="				}";
  z[lc++]="				break;";
  z[lc++]="			}";
  z[lc++]="			";
  z[lc++]="		case paInt32:";
  z[lc++]="			{";
  z[lc++]="			/* Convert 16 bit data to 32 bit integers */";
  z[lc++]="				int *inBufPtr = (int *) past->past_InputBuffer;";
  z[lc++]="				inputBuffer = past->past_InputBuffer;";
  z[lc++]="				for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="				{";
  z[lc++]="					inBufPtr[i] = nativeInputBuffer[i] << 16;";
  z[lc++]="				}";
  z[lc++]="				break;";
  z[lc++]="			}";
  z[lc++]="			";
  z[lc++]="		case paInt16:";
  z[lc++]="			{";
  z[lc++]="			/* Already in correct format so don't copy. */";
  z[lc++]="				inputBuffer = nativeInputBuffer;";
  z[lc++]="				break;";
  z[lc++]="			}";
  z[lc++]="";
  z[lc++]="		case paInt8:";
  z[lc++]="			{";
  z[lc++]="			/* Convert 16 bit data to 8 bit chars */";
  z[lc++]="				char *inBufPtr = (char *) past->past_InputBuffer;";
  z[lc++]="				inputBuffer = past->past_InputBuffer;";
  z[lc++]="				if( past->past_Flags & paDitherOff )";
  z[lc++]="				{";
  z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="					{";
  z[lc++]="						inBufPtr[i] = (char)(nativeInputBuffer[i] >> 8);";
  z[lc++]="					}";
  z[lc++]="				}";
  z[lc++]="				else";
  z[lc++]="				{";
  z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="					{";
  z[lc++]="						temp = nativeInputBuffer[i];";
  z[lc++]="						temp += Pa_TriangularDither() >> 8; /* PLB20010820 */";
  z[lc++]="						temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));";
  z[lc++]="						inBufPtr[i] = (char)(temp >> 8);";
  z[lc++]="					}";
  z[lc++]="				}";
  z[lc++]="				break;";
  z[lc++]="			}";
  z[lc++]="";
  z[lc++]="		case paUInt8:";
  z[lc++]="			{";
  z[lc++]="			/* Convert 16 bit data to 8 bit unsigned chars */";
  z[lc++]="				unsigned char *inBufPtr = (unsigned char *) past->past_InputBuffer;";
  z[lc++]="				inputBuffer = past->past_InputBuffer;";
  z[lc++]="				if( past->past_Flags & paDitherOff )";
  z[lc++]="				{";
  z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="					{";
  z[lc++]="						inBufPtr[i] = ((unsigned char)(nativeInputBuffer[i] >> 8)) + 0x80;";
  z[lc++]="					}";
  z[lc++]="				}";
  z[lc++]="				else";
  z[lc++]="				{";
  z[lc++]="			/* If you dither then you have to clip because dithering could push the signal out of range! */";
  z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="					{";
  z[lc++]="						temp = nativeInputBuffer[i];";
  z[lc++]="						temp += Pa_TriangularDither() >> 8; /* PLB20010820 */";
  z[lc++]="						temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));";
  z[lc++]="						inBufPtr[i] = (unsigned char)((temp>>8) + 0x80); /* PLB20010820 */";
  z[lc++]="					}";
  z[lc++]="				}";
  z[lc++]="				break;";
  z[lc++]="			}";
  z[lc++]="			";
  z[lc++]="		default:";
  z[lc++]="			break;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="";
  z[lc++]="/* Are we doing output time? */";
  z[lc++]="	if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )";
  z[lc++]="	{";
  z[lc++]="	/* May already be in native format so just write directly to native buffer. */";
  z[lc++]="		outputBuffer = (past->past_OutputSampleFormat == paInt16) ?";
  z[lc++]="			nativeOutputBuffer : past->past_OutputBuffer;";
  z[lc++]="	}";
  z[lc++]="/*	";
  z[lc++]="	AddTraceMessage(\"Pa_CallConvertInt16: inputBuffer = \", (int) inputBuffer );";
  z[lc++]="	AddTraceMessage(\"Pa_CallConvertInt16: outputBuffer = \", (int) outputBuffer );";
  z[lc++]="*/	";
  z[lc++]="/* Call user callback routine. */";
  z[lc++]="	userResult = past->past_Callback(";
  z[lc++]="			inputBuffer,";
  z[lc++]="			outputBuffer,";
  z[lc++]="			past->past_FramesPerUserBuffer,";
  z[lc++]="			past->past_FrameCount,";
  z[lc++]="			past->past_UserData );";
  z[lc++]="";
  z[lc++]="	past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;";
  z[lc++]="";
  z[lc++]="/* Convert to native format if necessary. */";
  z[lc++]="	if( outputBuffer != NULL )";
  z[lc++]="	{";
  z[lc++]="		unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels;";
  z[lc++]="		switch(past->past_OutputSampleFormat)";
  z[lc++]="		{";
  z[lc++]="		case paFloat32:";
  z[lc++]="			{";
  z[lc++]="				float *outBufPtr = (float *) past->past_OutputBuffer;";
  z[lc++]="				if( past->past_Flags & paDitherOff )";
  z[lc++]="				{";
  z[lc++]="					if( past->past_Flags & paClipOff ) /* NOTHING */";
  z[lc++]="					{";
  z[lc++]="						for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="						{";
  z[lc++]="							*nativeOutputBuffer++ = (short) (outBufPtr[i] * (32767.0f));";
  z[lc++]="						}";
  z[lc++]="					}";
  z[lc++]="					else /* CLIP */";
  z[lc++]="					{";
  z[lc++]="						for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="						{";
  z[lc++]="							temp = (long)(outBufPtr[i] * 32767.0f);";
  z[lc++]="							*nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));";
  z[lc++]="						}";
  z[lc++]="					}";
  z[lc++]="				}";
  z[lc++]="				else";
  z[lc++]="				{";
  z[lc++]="			/* If you dither then you have to clip because dithering could push the signal out of range! */";
  z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="					{";
  z[lc++]="						float dither  = Pa_TriangularDither()*DITHER_SCALE;";
  z[lc++]="						float dithered = (outBufPtr[i] * (32767.0f)) + dither;";
  z[lc++]="						temp = (long) (dithered);";
  z[lc++]="						*nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));";
  z[lc++]="					}";
  z[lc++]="				}";
  z[lc++]="				break;";
  z[lc++]="			}";
  z[lc++]="			";
  z[lc++]="		case paInt32:";
  z[lc++]="			{";
  z[lc++]="				int *outBufPtr = (int *) past->past_OutputBuffer;";
  z[lc++]="				if( past->past_Flags & paDitherOff )";
  z[lc++]="				{";
  z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="					{";
  z[lc++]="						*nativeOutputBuffer++ = (short) (outBufPtr[i] >> 16 );";
  z[lc++]="					}";
  z[lc++]="				}";
  z[lc++]="				else";
  z[lc++]="				{";
  z[lc++]="					for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="					{";
  z[lc++]="				/* Shift one bit down before dithering so that we have room for overflow from add. */";
  z[lc++]="						temp = (outBufPtr[i] >> 1) + Pa_TriangularDither();";
  z[lc++]="						temp = temp >> 15;";
  z[lc++]="						*nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));";
  z[lc++]="					}";
  z[lc++]="				}";
  z[lc++]="				break;";
  z[lc++]="			}";
  z[lc++]="";
  z[lc++]="		case paInt8:";
  z[lc++]="			{";
  z[lc++]="				char *outBufPtr = (char *) past->past_OutputBuffer;";
  z[lc++]="				for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="				{";
  z[lc++]="					*nativeOutputBuffer++ = ((short)outBufPtr[i]) << 8;";
  z[lc++]="				}";
  z[lc++]="				break;";
  z[lc++]="			}";
  z[lc++]="";
  z[lc++]="		case paUInt8:";
  z[lc++]="			{";
  z[lc++]="				unsigned char *outBufPtr = (unsigned char *) past->past_OutputBuffer;";
  z[lc++]="				for( i=0; i<samplesPerBuffer; i++ )";
  z[lc++]="				{";
  z[lc++]="					*nativeOutputBuffer++ = ((short)(outBufPtr[i] - 0x80)) << 8;";
  z[lc++]="				}";
  z[lc++]="				break;";
  z[lc++]="			}";
  z[lc++]="";
  z[lc++]="		default:";
  z[lc++]="			break;";
  z[lc++]="		}";
  z[lc++]="";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="	return userResult;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************";
  z[lc++]="** Called by host code.";
  z[lc++]="** Convert input from Float32, call user code, then convert output";
  z[lc++]="** to Float32 format for native use.";
  z[lc++]="** Assumes host native format is Float32.";
  z[lc++]="** Returns result from user callback.";
  z[lc++]="** FIXME - Unimplemented for formats other than paFloat32!!!!";
  z[lc++]="*/";
  z[lc++]="long Pa_CallConvertFloat32( internalPortAudioStream   *past, ";
  z[lc++]="	float *nativeInputBuffer,";
  z[lc++]="	float *nativeOutputBuffer )";
  z[lc++]="{";
  z[lc++]="	long              bytesEmpty = 0;";
  z[lc++]="	long              bytesFilled = 0;";
  z[lc++]="	int               userResult;";
  z[lc++]="	void             *inputBuffer = NULL;";
  z[lc++]="	void             *outputBuffer = NULL;";
  z[lc++]="	";
  z[lc++]="/* Get native data from DirectSound. */";
  z[lc++]="	if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )";
  z[lc++]="	{";
  z[lc++]="		inputBuffer = nativeInputBuffer;  /* FIXME */";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="/* Are we doing output time? */";
  z[lc++]="	if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )";
  z[lc++]="	{";
  z[lc++]="	/* May already be in native format so just write directly to native buffer. */";
  z[lc++]="		outputBuffer = (past->past_OutputSampleFormat == paFloat32) ?";
  z[lc++]="			nativeOutputBuffer : past->past_OutputBuffer;";
  z[lc++]="	}";
  z[lc++]="/*	";
  z[lc++]="	AddTraceMessage(\"Pa_CallConvertInt16: inputBuffer = \", (int) inputBuffer );";
  z[lc++]="	AddTraceMessage(\"Pa_CallConvertInt16: outputBuffer = \", (int) outputBuffer );";
  z[lc++]="*/	";
  z[lc++]="/* Call user callback routine. */";
  z[lc++]="	userResult = past->past_Callback(";
  z[lc++]="			inputBuffer,";
  z[lc++]="			outputBuffer,";
  z[lc++]="			past->past_FramesPerUserBuffer,";
  z[lc++]="			past->past_FrameCount,";
  z[lc++]="			past->past_UserData );";
  z[lc++]="";
  z[lc++]="	past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;";
  z[lc++]="";
  z[lc++]="/* Convert to native format if necessary. */  /* FIXME */	";
  z[lc++]="	return userResult;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError Pa_Initialize( void )";
  z[lc++]="{";
  z[lc++]="	if( gInitCount++ > 0 ) return paNoError;";
  z[lc++]="	ResetTraceMessages();";
  z[lc++]="	return PaHost_Init();";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="PaError Pa_Terminate( void )";
  z[lc++]="{";
  z[lc++]="	PaError result = paNoError;";
  z[lc++]="";
  z[lc++]="	if( gInitCount == 0 ) return paNoError;";
  z[lc++]="	else if( --gInitCount == 0 )";
  z[lc++]="	{";
  z[lc++]="		result = PaHost_Term();";
  z[lc++]="		DumpTraceMessages();";
  z[lc++]="	}";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError Pa_GetSampleSize( PaSampleFormat format )";
  z[lc++]="{";
  z[lc++]="	int size;";
  z[lc++]="	switch(format )";
  z[lc++]="	{";
  z[lc++]="";
  z[lc++]="	case paUInt8:";
  z[lc++]="	case paInt8:";
  z[lc++]="		size = 1;";
  z[lc++]="		break;";
  z[lc++]="";
  z[lc++]="	case paInt16:";
  z[lc++]="		size = 2;";
  z[lc++]="		break;";
  z[lc++]="";
  z[lc++]="	case paPackedInt24:";
  z[lc++]="		size = 3;";
  z[lc++]="		break;";
  z[lc++]="";
  z[lc++]="	case paFloat32:";
  z[lc++]="	case paInt32:";
  z[lc++]="	case paInt24:";
  z[lc++]="		size = 4;";
  z[lc++]="		break;";
  z[lc++]="";
  z[lc++]="	default:";
  z[lc++]="		size = paSampleFormatNotSupported;";
  z[lc++]="		break;";
  z[lc++]="	}";
  z[lc++]="	return (PaError) size;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="";
  printlib(lc);
}


void makepa_unix_oss(void)
{
  int lc = 0;

  z[lc++]="/*";
  z[lc++]=" * PortAudio Portable Real-Time Audio Library";
  z[lc++]=" * Latest Version at: http://www.portaudio.com";
  z[lc++]=" * Linux OSS Implementation by douglas repetto and Phil Burk";
  z[lc++]=" *";
  z[lc++]=" * Copyright (c) 1999-2000 Phil Burk";
  z[lc++]=" *";
  z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
  z[lc++]=" * a copy of this software and associated documentation files";
  z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
  z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
  z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
  z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
  z[lc++]=" * subject to the following conditions:";
  z[lc++]=" *";
  z[lc++]=" * The above copyright notice and this permission notice shall be";
  z[lc++]=" * included in all copies or substantial portions of the Software.";
  z[lc++]=" *";
  z[lc++]=" * Any person wishing to distribute modifications to the Software is";
  z[lc++]=" * requested to send the modifications to the original developer so that";
  z[lc++]=" * they can be incorporated into the canonical version.";
  z[lc++]=" *";
  z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
  z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
  z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
  z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
  z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
  z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
  z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
  z[lc++]=" *";
  z[lc++]=" */";
  z[lc++]="/*";
  z[lc++]="Modfication History";
  z[lc++]="  1/2001 - Phil Burk - initial hack for Linux";
  z[lc++]="  2/2001 - Douglas Repetto - many improvements, initial query support";
  z[lc++]="  4/2/2001 - Phil - stop/abort thread control, separate in/out native buffers";
  z[lc++]="  5/28/2001 - Phil - use pthread_create() instead of clone(). Thanks Stephen Brandon!";
  z[lc++]="		     use pthread_join() after thread shutdown.";
  z[lc++]="  5/29/2001 - Phil - query for multiple devices, multiple formats,";
  z[lc++]="                     input mode and input+output mode working,";
  z[lc++]="		     Pa_GetCPULoad() implemented.";
  z[lc++]="  PLB20010817 - Phil & Janos Haber - don't halt if test of sample rate fails.";
  z[lc++]="  SB20010904 - Stephen Brandon - mods needed for GNUSTEP and SndKit";
  z[lc++]="  JH20010905 - Janos Haber - FreeBSD mods";
  z[lc++]="  2001-09-22 - Heiko - (i.e. Heiko Purnhagen <purnhage@tnt.uni-hannover.de> ;-)";
  z[lc++]="                       added 24k and 16k to ratesToTry[]";
  z[lc++]="		       fixed Pa_GetInternalDevice()";
  z[lc++]="		       changed DEVICE_NAME_BASE from /dev/audio to /dev/dsp";
  z[lc++]="		       handled SNDCTL_DSP_SPEED in Pq_QueryDevice() more graceful";
  z[lc++]="		       fixed Pa_StreamTime() for paqa_errs.c";
  z[lc++]="		       fixed numCannel=2 oddity and error handling in Pa_SetupDeviceFormat()";
  z[lc++]="		       grep also for HP20010922 ...";
  z[lc++]="  PLB20010924 - Phil - merged Heiko's changes";
  z[lc++]="                       removed sNumDevices and potential related bugs,";
  z[lc++]="		       use getenv(\"PA_MIN_LATENCY_MSEC\") to set desired latency,";
  z[lc++]="		       simplify CPU Load calculation by comparing real-time to framesPerBuffer,";
  z[lc++]="		       always close device when querying even if error occurs,";
  z[lc++]="  PLB20010927 - Phil - Improved negotiation for numChannels.";
  z[lc++]="		       ";
  z[lc++]="  ";
  z[lc++]="TODO";
  z[lc++]="O- change Pa_StreamTime() to query device (patest_sync.c)";
  z[lc++]="O- put semaphore lock around shared data?";
  z[lc++]="O- handle native formats better";
  z[lc++]="O- handle stereo-only device better ???";
  z[lc++]="O- what if input and output of a device capabilities differ (e.g. es1371) ???";
  z[lc++]="*/";
  z[lc++]="/*";
  z[lc++]="	PROPOSED - should we add this to \"portaudio.h\". Problem with ";
  z[lc++]="	Pa_QueryDevice() not having same driver name os Pa_OpenStream().";
  z[lc++]="";
  z[lc++]="	A PaDriverInfo structure can be passed to the underlying device";
  z[lc++]="	on the Pa_OpenStream() call. The contents and interpretation of";
  z[lc++]="	the structure is determined by the PA implementation.";
  z[lc++]="*/";
  z[lc++]="typedef struct PaDriverInfo /* PROPOSED */";
  z[lc++]="{";
  z[lc++]="/* Size of structure. Allows driver to extend the structure without breaking existing applications. */";
  z[lc++]="	int           size;";
  z[lc++]="/* Can be used to request a specific device name. */";
  z[lc++]="	const char   *name;";
  z[lc++]="	unsigned long data;";
  z[lc++]="} PaDriverInfo;";
  z[lc++]="";
  z[lc++]="";
  z[lc++]="";
  z[lc++]="#include <stdio.h>";
  z[lc++]="#include <stdlib.h>";
  z[lc++]="#include <malloc.h>";
  z[lc++]="#include <memory.h>";
  z[lc++]="#include <math.h>";
  z[lc++]="#if 0";
  z[lc++]="#include \"portaudio.h\"";
  z[lc++]="#include \"pa_host.h\"";
  z[lc++]="#include \"pa_trace.h\"";
  z[lc++]="#endif";
  z[lc++]="#include <sys/ioctl.h>";
  z[lc++]="#include <sys/time.h>";
  z[lc++]="#include <fcntl.h> ";
  z[lc++]="#include <unistd.h> ";
  z[lc++]="#include <signal.h> ";
  z[lc++]="#include <stdio.h> ";
  z[lc++]="#include <stdlib.h>";
  z[lc++]="";
  z[lc++]="#ifdef __linux__";
  z[lc++]="#include <linux/soundcard.h>";
  z[lc++]="#else";
  z[lc++]="#include <machine/soundcard.h> /* JH20010905 */";
  z[lc++]="#endif";
  z[lc++]="";
  z[lc++]="#include <sched.h> ";
  z[lc++]="#include <pthread.h> ";
  z[lc++]="                     ";
  z[lc++]="/* Some versions of OSS do not define AFMT_S16_NE. Assume little endian. FIXME - check CPU*/     ";
  z[lc++]="#ifndef AFMT_S16_NE";
  z[lc++]="	#define AFMT_S16_NE AFMT_S16_LE";
  z[lc++]="#endif";
  z[lc++]="";
  z[lc++]="#define PRINT(x)   { printf x; fflush(stdout); }";
  z[lc++]="#define ERR_RPT(x) PRINT(x)";
  z[lc++]="#define DBUG(x)    /* PRINT(x) */";
  z[lc++]="#define DBUGX(x)   /* PRINT(x) */";
  z[lc++]="";
  z[lc++]="#define BAD_DEVICE_ID (-1)";
  z[lc++]="";
  z[lc++]="#define MIN_LATENCY_MSEC   (2)";
  z[lc++]="#define MIN_TIMEOUT_MSEC   (100)";
  z[lc++]="#define MAX_TIMEOUT_MSEC   (1000)";
  z[lc++]="";
  z[lc++]="/************************************************* Definitions ********/";
  z[lc++]="#ifdef __linux__";
  z[lc++]="	#define DEVICE_NAME_BASE            \"/dev/dsp\"";
  z[lc++]="#else";
  z[lc++]="	#define DEVICE_NAME_BASE            \"/dev/audio\"";
  z[lc++]="#endif";
  z[lc++]="";
  z[lc++]="#define MAX_CHARS_DEVNAME           (32)";
  z[lc++]="#define MAX_SAMPLE_RATES            (10)";
  z[lc++]="typedef struct internalPortAudioDevice";
  z[lc++]="{";
  z[lc++]="	struct internalPortAudioDevice *pad_Next; /* Singly linked list. */";
  z[lc++]="	double          pad_SampleRates[MAX_SAMPLE_RATES]; /* for pointing to from pad_Info */";
  z[lc++]="	char            pad_DeviceName[MAX_CHARS_DEVNAME];";
  z[lc++]="	PaDeviceInfo    pad_Info;";
  z[lc++]="} internalPortAudioDevice;";
  z[lc++]="";
  z[lc++]="/* Define structure to contain all OSS and Linux specific data. */";
  z[lc++]="typedef struct PaHostSoundControl";
  z[lc++]="{";
  z[lc++]="	int              pahsc_OutputHandle;";
  z[lc++]="	int              pahsc_InputHandle;";
  z[lc++]="	pthread_t        pahsc_ThreadPID;";
  z[lc++]="	short           *pahsc_NativeInputBuffer;";
  z[lc++]="	short           *pahsc_NativeOutputBuffer;";
  z[lc++]="	unsigned int     pahsc_BytesPerInputBuffer;    /* native buffer size in bytes */";
  z[lc++]="	unsigned int     pahsc_BytesPerOutputBuffer;   /* native buffer size in bytes */";
  z[lc++]="/* For measuring CPU utilization. */";
  z[lc++]="	struct timeval   pahsc_EntryTime;";
  z[lc++]="	double           pahsc_InverseMicrosPerBuffer; /* 1/Microseconds of real-time audio per user buffer. */";
  z[lc++]="} PaHostSoundControl;";
  z[lc++]="";
  z[lc++]="/************************************************* Shared Data ********/";
  z[lc++]="/* FIXME - put Mutex around this shared data. */";
  z[lc++]="static int sDeviceIndex = 0;";
  z[lc++]="static internalPortAudioDevice *sDeviceList = NULL;";
  z[lc++]="static int sDefaultInputDeviceID = paNoDevice;";
  z[lc++]="static int sDefaultOutputDeviceID = paNoDevice;";
  z[lc++]="static int sEnumerationError;";
  z[lc++]="static int sPaHostError = 0;";
  z[lc++]="";
  z[lc++]="/************************************************* Prototypes **********/";
  z[lc++]="";
  z[lc++]="static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id );";
  z[lc++]="static Pa_QueryDevices( void );";
  z[lc++]="static PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *pad );";
  z[lc++]="static PaError Pa_SetupDeviceFormat( int devHandle, int numChannels, int sampleRate );";
  z[lc++]="";
  z[lc++]="/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/";
  z[lc++]="static void Pa_StartUsageCalculation( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	struct itimerval itimer;";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return;";
  z[lc++]="/* Query system timer for usage analysis and to prevent overuse of CPU. */";
  z[lc++]="	gettimeofday( &pahsc->pahsc_EntryTime, NULL );";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="static long SubtractTime_AminusB( struct timeval *timeA, struct timeval *timeB )";
  z[lc++]="{";
  z[lc++]="	long secs = timeA->tv_sec - timeB->tv_sec;";
  z[lc++]="	long usecs = secs * 1000000;";
  z[lc++]="	usecs += (timeA->tv_usec - timeB->tv_usec);";
  z[lc++]="	return usecs;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/******************************************************************************";
  z[lc++]="** Measure fractional CPU load based on real-time it took to calculate";
  z[lc++]="** buffers worth of output.";
  z[lc++]="*/";
  z[lc++]="static void Pa_EndUsageCalculation( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	struct timeval currentTime;";
  z[lc++]="	long  usecsElapsed;";
  z[lc++]="	double newUsage;";
  z[lc++]="";
  z[lc++]="#define LOWPASS_COEFFICIENT_0   (0.95)";
  z[lc++]="#define LOWPASS_COEFFICIENT_1   (0.99999 - LOWPASS_COEFFICIENT_0)";
  z[lc++]="";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return;";
  z[lc++]="";
  z[lc++]="	if( gettimeofday( &currentTime, NULL ) == 0 )";
  z[lc++]="	{";
  z[lc++]="		usecsElapsed = SubtractTime_AminusB( &currentTime, &pahsc->pahsc_EntryTime );";
  z[lc++]="	/* Use inverse because it is faster than the divide. */";
  z[lc++]="		newUsage =  usecsElapsed * pahsc->pahsc_InverseMicrosPerBuffer;";
  z[lc++]="		";
  z[lc++]="		past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +";
  z[lc++]="			(LOWPASS_COEFFICIENT_1 * newUsage);";
  z[lc++]="	}";
  z[lc++]="}";
  z[lc++]="/****************************************** END CPU UTILIZATION *******/";
  z[lc++]="";
  z[lc++]="/*********************************************************************";
  z[lc++]=" * Try to open the named device.";
  z[lc++]=" * If it opens, try to set various rates and formats and fill in ";
  z[lc++]=" * the device info structure.";
  z[lc++]=" */";
  z[lc++]="static PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *pad )";
  z[lc++]="{";
  z[lc++]="	int result = paHostError;";
  z[lc++]="	int numBytes;";
  z[lc++]="	int tempDevHandle;";
  z[lc++]="	int numChannels, maxNumChannels;";
  z[lc++]="	int format;";
  z[lc++]="	int numSampleRates;";
  z[lc++]="	int sampleRate;";
  z[lc++]="	int numRatesToTry;";
  z[lc++]="	int ratesToTry[9] = {96000, 48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000};";
  z[lc++]="	int i;";
  z[lc++]="";
  z[lc++]="/* douglas: ";
  z[lc++]="	we have to do this querying in a slightly different order. apparently";
  z[lc++]="	some sound cards will give you different info based on their settins. ";
  z[lc++]="	e.g. a card might give you stereo at 22kHz but only mono at 44kHz.";
  z[lc++]="	the correct order for OSS is: format, channels, sample rate";
  z[lc++]="";
  z[lc++]="*/";
  z[lc++]="	if ( (tempDevHandle = open(deviceName,O_WRONLY))  == -1 )";
  z[lc++]="	{";
  z[lc++]="		DBUG((\"Pa_QueryDevice: could not open %s\\n\", deviceName ));";
  z[lc++]="		return paHostError;";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="/*  Ask OSS what formats are supported by the hardware. */";
  z[lc++]="	pad->pad_Info.nativeSampleFormats = 0;";
  z[lc++]="	if (ioctl(tempDevHandle, SNDCTL_DSP_GETFMTS, &format) == -1)";
  z[lc++]="	{";
  z[lc++]="		ERR_RPT((\"Pa_QueryDevice: could not get format info\\n\" ));";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="	if( format & AFMT_U8 )     pad->pad_Info.nativeSampleFormats |= paUInt8;";
  z[lc++]="	if( format & AFMT_S16_NE ) pad->pad_Info.nativeSampleFormats |= paInt16;";
  z[lc++]="";
  z[lc++]="/* Negotiate for the maximum number of channels for this device. PLB20010927";
  z[lc++]=" * Start with 16 as a hard coded upper number of channels.";
  z[lc++]=" * Variable numChannels should contain the actual upper limit after the call.";
  z[lc++]=" * Thanks to John Lazzaro and Heiko Purnhagen for suggestions.";
  z[lc++]=" */";
  z[lc++]="	maxNumChannels = 0;";
  z[lc++]="	for( numChannels = 1; numChannels <= 16; numChannels++ )";
  z[lc++]="	{";
  z[lc++]="		int temp = numChannels;";
  z[lc++]="		DBUG((\"Pa_QueryDevice: use SNDCTL_DSP_CHANNELS, numChannels = %d\\n\", numChannels ))";
  z[lc++]="		if(ioctl(tempDevHandle, SNDCTL_DSP_CHANNELS, &temp) < 0 )";
  z[lc++]="		{";
  z[lc++]="		/* ioctl() failed so bail out if we already have stereo */";
  z[lc++]="			if( numChannels > 2 ) break;";
  z[lc++]="		}";
  z[lc++]="		else";
  z[lc++]="		{";
  z[lc++]="		/* ioctl() worked but bail out if it does not support numChannels.";
  z[lc++]="		 * We don't want to leave gaps in the numChannels supported.";
  z[lc++]="		 */";
  z[lc++]="			if( (numChannels > 2) && (temp != numChannels) ) break;";
  z[lc++]="			DBUG((\"Pa_QueryDevice: temp = %d\\n\", temp ))";
  z[lc++]="			if( temp > maxNumChannels ) maxNumChannels = temp; /* Save maximum. */";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="/* The above negotiation may fail for an old driver so try this older technique. */";
  z[lc++]="	if( maxNumChannels < 1 )";
  z[lc++]="	{";
  z[lc++]="		int stereo = 1;";
  z[lc++]="		if(ioctl(tempDevHandle, SNDCTL_DSP_STEREO, &stereo) < 0)";
  z[lc++]="		{";
  z[lc++]="			maxNumChannels = 1;";
  z[lc++]="		}";
  z[lc++]="		else";
  z[lc++]="		{";
  z[lc++]="			maxNumChannels = (stereo) ? 2 : 1;";
  z[lc++]="		}";
  z[lc++]="		DBUG((\"Pa_QueryDevice: use SNDCTL_DSP_STEREO, maxNumChannels = %d\\n\", maxNumChannels ))";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="	pad->pad_Info.maxOutputChannels = maxNumChannels;";
  z[lc++]="	DBUG((\"Pa_QueryDevice: maxNumChannels = %d\\n\", maxNumChannels))";
  z[lc++]="		";
  z[lc++]="/* FIXME - for now, assume maxInputChannels = maxOutputChannels.";
  z[lc++]=" *    Eventually do separate queries for O_WRONLY and O_RDONLY";
  z[lc++]="*/";
  z[lc++]="	pad->pad_Info.maxInputChannels = pad->pad_Info.maxOutputChannels;";
  z[lc++]="	";
  z[lc++]="	DBUG((\"Pa_QueryDevice: maxInputChannels = %d\\n\", ";
  z[lc++]="		pad->pad_Info.maxInputChannels))";
  z[lc++]="";
  z[lc++]="";
  z[lc++]="/* Determine available sample rates by trying each one and seeing result.";
  z[lc++]=" */";
  z[lc++]="	numSampleRates = 0;";
  z[lc++]="	numRatesToTry = sizeof(ratesToTry)/sizeof(int);";
  z[lc++]="	for (i = 0; i < numRatesToTry; i++)";
  z[lc++]="	{";
  z[lc++]="		sampleRate = ratesToTry[i];";
  z[lc++]="		";
  z[lc++]="		if (ioctl(tempDevHandle, SNDCTL_DSP_SPEED, &sampleRate) >= 0 ) // PLB20010817";
  z[lc++]="		{";
  z[lc++]="			if (sampleRate == ratesToTry[i])";
  z[lc++]="			{";
  z[lc++]="				DBUG((\"Pa_QueryDevice: got sample rate: %d\\n\", sampleRate))";
  z[lc++]="				pad->pad_SampleRates[numSampleRates] = (float)ratesToTry[i];";
  z[lc++]="				numSampleRates++;";
  z[lc++]="			}";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="	DBUG((\"Pa_QueryDevice: final numSampleRates = %d\\n\", numSampleRates))";
  z[lc++]="	if (numSampleRates==0)   /* HP20010922 */";
  z[lc++]="	{";
  z[lc++]="		ERR_RPT((\"Pa_QueryDevice: no supported sample rate (or SNDCTL_DSP_SPEED ioctl call failed).\\n\" ));";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="	pad->pad_Info.numSampleRates = numSampleRates;";
  z[lc++]="	pad->pad_Info.sampleRates = pad->pad_SampleRates;";
  z[lc++]="	";
  z[lc++]="	pad->pad_Info.name = deviceName;";
  z[lc++]="";
  z[lc++]="	result = paNoError;";
  z[lc++]="	";
  z[lc++]="error:";
  z[lc++]="/* We MUST close the handle here or we won't be able to reopen it later!!!  */";
  z[lc++]="	close(tempDevHandle);";
  z[lc++]="";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*********************************************************************";
  z[lc++]=" * Determines the number of available devices by trying to open";
  z[lc++]=" * each \"/dev/dsp#\" or \"/dsp/audio#\" in order until it fails.";
  z[lc++]=" * Add each working device to a singly linked list of devices.";
  z[lc++]=" */";
  z[lc++]="static PaError Pa_QueryDevices( void )";
  z[lc++]="{";
  z[lc++]="	internalPortAudioDevice *pad, *lastPad;";
  z[lc++]="	int      numBytes;";
  z[lc++]="	int      go = 1;";
  z[lc++]="	int      numDevices = 0;";
  z[lc++]="	PaError  testResult;";
  z[lc++]="	PaError  result = paNoError;";
  z[lc++]="	";
  z[lc++]="	sDefaultInputDeviceID = paNoDevice;";
  z[lc++]="	sDefaultOutputDeviceID = paNoDevice;";
  z[lc++]="";
  z[lc++]="	lastPad = NULL;";
  z[lc++]="	";
  z[lc++]="	while( go )";
  z[lc++]="	{";
  z[lc++]="/* Allocate structure to hold device info. */";
  z[lc++]="		pad = PaHost_AllocateFastMemory( sizeof(internalPortAudioDevice) );";
  z[lc++]="		if( pad == NULL ) return paInsufficientMemory;";
  z[lc++]="		memset( pad, 0, sizeof(internalPortAudioDevice) );";
  z[lc++]="		";
  z[lc++]="/* Build name for device. */";
  z[lc++]="		if( numDevices == 0 )";
  z[lc++]="		{";
  z[lc++]="			sprintf( pad->pad_DeviceName, DEVICE_NAME_BASE);";
  z[lc++]="		}";
  z[lc++]="		else";
  z[lc++]="		{";
  z[lc++]="			sprintf( pad->pad_DeviceName, DEVICE_NAME_BASE \"%d\", numDevices );";
  z[lc++]="		}";
  z[lc++]="		";
  z[lc++]="		DBUG((\"Try device %s\\n\", pad->pad_DeviceName ));";
  z[lc++]="		testResult = Pa_QueryDevice( pad->pad_DeviceName, pad );";
  z[lc++]="		DBUG((\"Pa_QueryDevice returned %d\\n\", testResult ));";
  z[lc++]="		if( testResult != paNoError )";
  z[lc++]="		{";
  z[lc++]="			if( lastPad == NULL )";
  z[lc++]="			{";
  z[lc++]="				result = testResult; /* No good devices! */";
  z[lc++]="			}";
  z[lc++]="			go = 0;";
  z[lc++]="			PaHost_FreeFastMemory( pad, sizeof(internalPortAudioDevice) );";
  z[lc++]="		}";
  z[lc++]="		else";
  z[lc++]="		{";
  z[lc++]="			numDevices += 1;";
  z[lc++]="		/* Add to linked list of devices. */";
  z[lc++]="			if( lastPad )";
  z[lc++]="			{";
  z[lc++]="				lastPad->pad_Next = pad;";
  z[lc++]="			}";
  z[lc++]="			else";
  z[lc++]="			{";
  z[lc++]="				sDeviceList = pad; /* First element in linked list. */";
  z[lc++]="			}";
  z[lc++]="			lastPad = pad;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="	return result;";
  z[lc++]="	";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="int Pa_CountDevices()";
  z[lc++]="{";
  z[lc++]="	int numDevices = 0;";
  z[lc++]="	internalPortAudioDevice *pad;";
  z[lc++]="	";
  z[lc++]="	if( sDeviceList == NULL ) Pa_Initialize();";
  z[lc++]="/* Count devices in list. */";
  z[lc++]="	pad = sDeviceList;";
  z[lc++]="	while( pad != NULL )";
  z[lc++]="	{";
  z[lc++]="		pad = pad->pad_Next;";
  z[lc++]="		numDevices++;";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="	return numDevices;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id )";
  z[lc++]="{";
  z[lc++]="	internalPortAudioDevice *pad;";
  z[lc++]="	if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;";
  z[lc++]="	pad = sDeviceList;";
  z[lc++]="	while( id > 0 )";
  z[lc++]="	{";
  z[lc++]="		pad = pad->pad_Next;";
  z[lc++]="		id--;";
  z[lc++]="	}";
  z[lc++]="	return pad;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )";
  z[lc++]="{";
  z[lc++]="	internalPortAudioDevice *pad;";
  z[lc++]="	if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;";
  z[lc++]="	pad = Pa_GetInternalDevice( id );";
  z[lc++]="	return  &pad->pad_Info ;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="static PaError Pa_MaybeQueryDevices( void )";
  z[lc++]="{";
  z[lc++]="	if( sDeviceList == NULL )";
  z[lc++]="	{";
  z[lc++]="		return Pa_QueryDevices();";
  z[lc++]="	}";
  z[lc++]="	return 0;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="PaDeviceID Pa_GetDefaultInputDeviceID( void )";
  z[lc++]="{";
  z[lc++]="	/* return paNoDevice; */";
  z[lc++]="	return 0;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="PaDeviceID Pa_GetDefaultOutputDeviceID( void )";
  z[lc++]="{";
  z[lc++]="	return 0;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/**********************************************************************";
  z[lc++]="** Make sure that we have queried the device capabilities.";
  z[lc++]="*/";
  z[lc++]="";
  z[lc++]="PaError PaHost_Init( void )";
  z[lc++]="{";
  z[lc++]="	return Pa_MaybeQueryDevices();";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*******************************************************************************************/";
  z[lc++]="static PaError Pa_AudioThreadProc( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaError				result = 0;";
  z[lc++]="	PaHostSoundControl             *pahsc;";
  z[lc++]=" 	short				bytes_read = 0;";
  z[lc++]=" ";
  z[lc++]="#ifdef GNUSTEP";
  z[lc++]="	GSRegisterCurrentThread(); /* SB20010904 */";
  z[lc++]="#endif";
  z[lc++]="	";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paInternalError;";
  z[lc++]="";
  z[lc++]="	past->past_IsActive = 1;";
  z[lc++]="	DBUG((\"entering thread.\\n\"));";
  z[lc++]="	";
  z[lc++]="	while( (past->past_StopNow == 0) && (past->past_StopSoon == 0) )";
  z[lc++]="	{";
  z[lc++]="";
  z[lc++]="		DBUG((\"go!\\n\"));";
  z[lc++]="	/* Read data from device */";
  z[lc++]="		if(pahsc->pahsc_NativeInputBuffer)";
  z[lc++]="		{";
  z[lc++]="	           	bytes_read = read(pahsc->pahsc_InputHandle,";
  z[lc++]="				(void *)pahsc->pahsc_NativeInputBuffer,";
  z[lc++]="				pahsc->pahsc_BytesPerInputBuffer);  ";
  z[lc++]="            	";
  z[lc++]="			DBUG((\"bytes_read: %d\\n\", bytes_read));";
  z[lc++]="		}";
  z[lc++]="	";
  z[lc++]="	/* Convert 16 bit native data to user data and call user routine. */";
  z[lc++]="		DBUG((\"converting...\\n\"));";
  z[lc++]="		Pa_StartUsageCalculation( past );";
  z[lc++]="		result = Pa_CallConvertInt16( past,";
  z[lc++]="				pahsc->pahsc_NativeInputBuffer,";
  z[lc++]="				pahsc->pahsc_NativeOutputBuffer );";
  z[lc++]="		Pa_EndUsageCalculation( past );";
  z[lc++]="		if( result != 0) ";
  z[lc++]="		{";
  z[lc++]="			DBUG((\"hmm, Pa_CallConvertInt16() says: %d. i'm bailing.\\n\",";
  z[lc++]="				result));";
  z[lc++]="			break;";
  z[lc++]="		}";
  z[lc++]="";
  z[lc++]="	/* Write data to device. */";
  z[lc++]="		if( pahsc->pahsc_NativeOutputBuffer )";
  z[lc++]="		{";
  z[lc++]="";
  z[lc++]="            		write(pahsc->pahsc_OutputHandle,";
  z[lc++]="				(void *)pahsc->pahsc_NativeOutputBuffer,";
  z[lc++]="            			pahsc->pahsc_BytesPerOutputBuffer);  	";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="	past->past_IsActive = 0;";
  z[lc++]="	DBUG((\"leaving thread.\\n\"));";
  z[lc++]="	";
  z[lc++]="#ifdef GNUSTEP";
  z[lc++]="	GSUnregisterCurrentThread();  /* SB20010904 */";
  z[lc++]="#endif";
  z[lc++]="	return 0;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*******************************************************************************************/";
  z[lc++]="static PaError Pa_SetupDeviceFormat( int devHandle, int numChannels, int sampleRate )";
  z[lc++]="{";
  z[lc++]="	PaError result = paNoError;";
  z[lc++]="	int     tmp;";
  z[lc++]="";
  z[lc++]="/* Set format, channels, and rate in this order to keep OSS happy. */";
  z[lc++]="/* Set data format. FIXME - handle more native formats. */";
  z[lc++]="	tmp = AFMT_S16_NE;		";
  z[lc++]="	if( ioctl(devHandle,SNDCTL_DSP_SETFMT,&tmp) == -1)";
  z[lc++]="	{";
  z[lc++]="		ERR_RPT((\"Pa_SetupDeviceFormat: could not SNDCTL_DSP_SETFMT\\n\" ));";
  z[lc++]="		return paHostError;";
  z[lc++]="	}";
  z[lc++]="	if( tmp != AFMT_S16_NE)";
  z[lc++]="	{";
  z[lc++]="		ERR_RPT((\"Pa_SetupDeviceFormat: HW does not support AFMT_S16_NE\\n\" ));";
  z[lc++]="		return paHostError;";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="";
  z[lc++]="/* Set number of channels. */";
  z[lc++]="	tmp = numChannels;";
  z[lc++]="	if (ioctl(devHandle, SNDCTL_DSP_CHANNELS, &numChannels) == -1)";
  z[lc++]="	{";
  z[lc++]="		ERR_RPT((\"Pa_SetupDeviceFormat: could not SNDCTL_DSP_CHANNELS\\n\" ));";
  z[lc++]="		return paHostError;";
  z[lc++]="	}";
  z[lc++]="	if( tmp != numChannels)";
  z[lc++]="	{";
  z[lc++]="		ERR_RPT((\"Pa_SetupDeviceFormat: HW does not support %d channels\\n\", numChannels ));";
  z[lc++]="		return paHostError;";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="/* Set playing frequency. 44100, 22050 and 11025 are safe bets. */";
  z[lc++]="	tmp = sampleRate;";
  z[lc++]=" 	if( ioctl(devHandle,SNDCTL_DSP_SPEED,&tmp) == -1)";
  z[lc++]=" 	{";
  z[lc++]="		ERR_RPT((\"Pa_SetupDeviceFormat: could not SNDCTL_DSP_SPEED\\n\" ));";
  z[lc++]="		return paHostError;";
  z[lc++]="	}";
  z[lc++]="	if( tmp != sampleRate)";
  z[lc++]="	{";
  z[lc++]="		ERR_RPT((\"Pa_SetupDeviceFormat: HW does not support %d Hz sample rate\\n\",sampleRate ));";
  z[lc++]="		return paHostError;";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="	return result;";
  z[lc++]="}		";
  z[lc++]="";
  z[lc++]="static int CalcHigherLogTwo( int n )";
  z[lc++]="{";
  z[lc++]="	int log2 = 0;";
  z[lc++]="	while( (1<<log2) < n ) log2++;";
  z[lc++]="	return log2;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*******************************************************************************************";
  z[lc++]="** Set number of fragments and size of fragments to achieve desired latency.";
  z[lc++]="*/";
  z[lc++]="static void Pa_SetLatency( int devHandle, int numBuffers, int framesPerBuffer, int channelsPerFrame  )";
  z[lc++]="{";
  z[lc++]="	int     tmp;";
  z[lc++]="	int     numFrames , bufferSize, powerOfTwo;";
  z[lc++]="";
  z[lc++]="/* Increase size of buffers and reduce number of buffers to reduce latency inside driver. */";
  z[lc++]="	while( numBuffers > 8 )";
  z[lc++]="	{";
  z[lc++]="		numBuffers = (numBuffers + 1) >> 1;";
  z[lc++]="		framesPerBuffer = framesPerBuffer << 1;";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="/* calculate size of buffers in bytes */";
  z[lc++]="	bufferSize = framesPerBuffer * channelsPerFrame * sizeof(short); /* FIXME */";
  z[lc++]="	";
  z[lc++]="/* Calculate next largest power of two */";
  z[lc++]="	powerOfTwo = CalcHigherLogTwo( bufferSize );";
  z[lc++]="	DBUG((\"Pa_SetLatency: numBuffers = %d, framesPerBuffer = %d, powerOfTwo = %d\\n\",";
  z[lc++]="		numBuffers, framesPerBuffer, powerOfTwo ));";
  z[lc++]="";
  z[lc++]="/* Encode info into a single int */";
  z[lc++]="	tmp=(numBuffers<<16) + powerOfTwo;";
  z[lc++]="	";
  z[lc++]="	if(ioctl(devHandle,SNDCTL_DSP_SETFRAGMENT,&tmp) == -1)";
  z[lc++]="	{";
  z[lc++]="		ERR_RPT((\"Pa_SetLatency: could not SNDCTL_DSP_SETFRAGMENT\\n\" ));";
  z[lc++]="		/* Don't return an error. Best to just continue and hope for the best. */";
  z[lc++]="		ERR_RPT((\"Pa_SetLatency: numBuffers = %d, framesPerBuffer = %d, powerOfTwo = %d\\n\",";
  z[lc++]="			numBuffers, framesPerBuffer, powerOfTwo ));";
  z[lc++]="	}";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************";
  z[lc++]="** Determine minimum number of buffers required for this host based";
  z[lc++]="** on minimum latency. Latency can be optionally set by user by setting";
  z[lc++]="** an environment variable. For example, to set latency to 200 msec, put:";
  z[lc++]="**";
  z[lc++]="**    set PA_MIN_LATENCY_MSEC=200";
  z[lc++]="**";
  z[lc++]="** in the cshrc file.";
  z[lc++]="*/";
  z[lc++]="#define PA_LATENCY_ENV_NAME  (\"PA_MIN_LATENCY_MSEC\")";
  z[lc++]="";
  z[lc++]="int Pa_GetMinNumBuffers( int framesPerBuffer, double framesPerSecond )";
  z[lc++]="{";
  z[lc++]="	int minBuffers;";
  z[lc++]="	int minLatencyMsec = MIN_LATENCY_MSEC;";
  z[lc++]="	char *minLatencyText = getenv(PA_LATENCY_ENV_NAME);";
  z[lc++]="	if( minLatencyText != NULL )";
  z[lc++]="	{";
  z[lc++]="		PRINT((\"PA_MIN_LATENCY_MSEC = %s\\n\", minLatencyText ));";
  z[lc++]="		minLatencyMsec = atoi( minLatencyText );";
  z[lc++]="		if( minLatencyMsec < 1 ) minLatencyMsec = 1;";
  z[lc++]="		else if( minLatencyMsec > 5000 ) minLatencyMsec = 5000;";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="	minBuffers = (int) ((minLatencyMsec * framesPerSecond) / ( 1000.0 * framesPerBuffer ));";
  z[lc++]="	if( minBuffers < 2 ) minBuffers = 2;";
  z[lc++]="	return minBuffers;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*******************************************************************/";
  z[lc++]="PaError PaHost_OpenStream( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaError          result = paNoError;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	int tmp;";
  z[lc++]="	int flags;";
  z[lc++]="	int              numBytes, maxChannels;";
  z[lc++]="	unsigned int     minNumBuffers;";
  z[lc++]="	internalPortAudioDevice *pad;";
  z[lc++]="	DBUG((\"PaHost_OpenStream() called.\\n\" ));";
  z[lc++]="";
  z[lc++]="/* Allocate and initialize host data. */";
  z[lc++]="	pahsc = (PaHostSoundControl *) malloc(sizeof(PaHostSoundControl));";
  z[lc++]="	if( pahsc == NULL )";
  z[lc++]="	{";
  z[lc++]="		result = paInsufficientMemory;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="	memset( pahsc, 0, sizeof(PaHostSoundControl) );";
  z[lc++]="	past->past_DeviceData = (void *) pahsc;";
  z[lc++]="";
  z[lc++]="	pahsc->pahsc_OutputHandle = BAD_DEVICE_ID; /* No device currently opened. */";
  z[lc++]="	pahsc->pahsc_InputHandle = BAD_DEVICE_ID;";
  z[lc++]="	";
  z[lc++]="/* Allocate native buffers. */";
  z[lc++]="	pahsc->pahsc_BytesPerInputBuffer = past->past_FramesPerUserBuffer *";
  z[lc++]="		past->past_NumInputChannels * sizeof(short);";
  z[lc++]="	if( past->past_NumInputChannels > 0)";
  z[lc++]="	{";
  z[lc++]="		pahsc->pahsc_NativeInputBuffer = (short *) malloc(pahsc->pahsc_BytesPerInputBuffer);";
  z[lc++]="		if( pahsc->pahsc_NativeInputBuffer == NULL )";
  z[lc++]="		{";
  z[lc++]="			result = paInsufficientMemory;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	pahsc->pahsc_BytesPerOutputBuffer = past->past_FramesPerUserBuffer *";
  z[lc++]="		past->past_NumOutputChannels * sizeof(short);";
  z[lc++]="	if( past->past_NumOutputChannels > 0)";
  z[lc++]="	{";
  z[lc++]="		pahsc->pahsc_NativeOutputBuffer = (short *) malloc(pahsc->pahsc_BytesPerOutputBuffer);";
  z[lc++]="		if( pahsc->pahsc_NativeOutputBuffer == NULL )";
  z[lc++]="		{";
  z[lc++]="			result = paInsufficientMemory;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="	/* DBUG((\"PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\\n\", pahsc->pahsc_MinFramesPerHostBuffer )); */";
  z[lc++]="	minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );";
  z[lc++]="	past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;";
  z[lc++]="";
  z[lc++]="	pahsc->pahsc_InverseMicrosPerBuffer = past->past_SampleRate / (1000000.0 * past->past_FramesPerUserBuffer);";
  z[lc++]="	DBUG((\"pahsc_InverseMicrosPerBuffer = %g\\n\", pahsc->pahsc_InverseMicrosPerBuffer ));";
  z[lc++]="	";
  z[lc++]="/* ------------------------- OPEN DEVICE -----------------------*/";
  z[lc++]="	    ";
  z[lc++]="	/* just output */";
  z[lc++]="	if (past->past_OutputDeviceID == past->past_InputDeviceID)";
  z[lc++]="	{";
  z[lc++]="	";
  z[lc++]="		if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0) )";
  z[lc++]="		{";
  z[lc++]="			pad = Pa_GetInternalDevice( past->past_OutputDeviceID );";
  z[lc++]="			DBUG((\"PaHost_OpenStream: attempt to open %s for O_RDWR\\n\", pad->pad_DeviceName ));";
  z[lc++]="			pahsc->pahsc_OutputHandle = pahsc->pahsc_InputHandle =";
  z[lc++]="				open(pad->pad_DeviceName,O_RDWR); ";
  z[lc++]="			if(pahsc->pahsc_InputHandle==-1)";
  z[lc++]="			{";
  z[lc++]="				ERR_RPT((\"PaHost_OpenStream: could not open %s for O_RDWR\\n\", pad->pad_DeviceName ));";
  z[lc++]="				result = paHostError;";
  z[lc++]="				goto error;";
  z[lc++]="			} ";
  z[lc++]="			Pa_SetLatency( pahsc->pahsc_OutputHandle,";
  z[lc++]="				past->past_NumUserBuffers, past->past_FramesPerUserBuffer,";
  z[lc++]="				past->past_NumOutputChannels );";
  z[lc++]="			result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle,";
  z[lc++]="				past->past_NumOutputChannels, (int)past->past_SampleRate );";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="		if (past->past_NumOutputChannels > 0)";
  z[lc++]="		{	    ";
  z[lc++]="			pad = Pa_GetInternalDevice( past->past_OutputDeviceID );";
  z[lc++]="			DBUG((\"PaHost_OpenStream: attempt to open %s for O_WRONLY\\n\", pad->pad_DeviceName ));";
  z[lc++]="			pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY); ";
  z[lc++]="			if(pahsc->pahsc_OutputHandle==-1)";
  z[lc++]="			{";
  z[lc++]="				ERR_RPT((\"PaHost_OpenStream: could not open %s for O_WRONLY\\n\", pad->pad_DeviceName ));";
  z[lc++]="				result = paHostError;";
  z[lc++]="				goto error;";
  z[lc++]="			} ";
  z[lc++]="			Pa_SetLatency( pahsc->pahsc_OutputHandle,";
  z[lc++]="				past->past_NumUserBuffers, past->past_FramesPerUserBuffer,";
  z[lc++]="				past->past_NumOutputChannels );";
  z[lc++]="			result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle,";
  z[lc++]="				past->past_NumOutputChannels, (int)past->past_SampleRate );";
  z[lc++]="		}";
  z[lc++]="";
  z[lc++]="		if (past->past_NumInputChannels > 0)";
  z[lc++]="		{	    ";
  z[lc++]="			pad = Pa_GetInternalDevice( past->past_InputDeviceID );";
  z[lc++]="			DBUG((\"PaHost_OpenStream: attempt to open %s for O_RDONLY\\n\", pad->pad_DeviceName ));";
  z[lc++]="			pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY); ";
  z[lc++]="			if(pahsc->pahsc_InputHandle==-1)";
  z[lc++]="			{";
  z[lc++]="				ERR_RPT((\"PaHost_OpenStream: could not open %s for O_RDONLY\\n\", pad->pad_DeviceName ));";
  z[lc++]="				result = paHostError;";
  z[lc++]="				goto error;";
  z[lc++]="			} ";
  z[lc++]="			Pa_SetLatency( pahsc->pahsc_OutputHandle,";
  z[lc++]="				past->past_NumUserBuffers, past->past_FramesPerUserBuffer,";
  z[lc++]="				past->past_NumInputChannels );";
  z[lc++]="			result = Pa_SetupDeviceFormat( pahsc->pahsc_InputHandle,";
  z[lc++]="				past->past_NumInputChannels, (int)past->past_SampleRate );";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]=" 		";
  z[lc++]=" ";
  z[lc++]="	DBUG((\"PaHost_OpenStream: SUCCESS - result = %d\\n\", result ));";
  z[lc++]="	return result;";
  z[lc++]="	";
  z[lc++]="error:";
  z[lc++]="	ERR_RPT((\"PaHost_OpenStream: ERROR - result = %d\\n\", result ));";
  z[lc++]="	PaHost_CloseStream( past );";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StartOutput( internalPortAudioStream *past )";
  z[lc++]="{";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StartInput( internalPortAudioStream *past )";
  z[lc++]="{";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StartEngine( internalPortAudioStream *past )";
  z[lc++]="{";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	PaError             result = paNoError;";
  z[lc++]="	int                 hres;";
  z[lc++]="	";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="";
  z[lc++]="	past->past_StopSoon = 0;";
  z[lc++]="	past->past_StopNow = 0;";
  z[lc++]="        past->past_IsActive = 1; ";
  z[lc++]="";
  z[lc++]="/* Use pthread_create() instead of __clone() because:";
  z[lc++]=" *   - pthread_create also works for other UNIX systems like Solaris,";
  z[lc++]=" *   - the Java HotSpot VM crashes in pthread_setcanceltype() when using __clone()";
  z[lc++]=" */";
  z[lc++]="	hres = pthread_create(&(pahsc->pahsc_ThreadPID),";
  z[lc++]="		NULL /*pthread_attr_t * attr*/,";
  z[lc++]="		(void*)Pa_AudioThreadProc, past);";
  z[lc++]="	if( hres != 0 )";
  z[lc++]="	{";
  z[lc++]="		result = paHostError;";
  z[lc++]="		sPaHostError = hres;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="error:";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )";
  z[lc++]="{";
  z[lc++]="	int                 hres;";
  z[lc++]="	long                timeOut;";
  z[lc++]="	PaError             result = paNoError;";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	";
  z[lc++]="	if( pahsc == NULL ) return paNoError;";
  z[lc++]=" ";
  z[lc++]="/* Tell background thread to stop generating more data and to let current data play out. */";
  z[lc++]="        past->past_StopSoon = 1;";
  z[lc++]="/* If aborting, tell background thread to stop NOW! */";
  z[lc++]="        if( abort ) past->past_StopNow = 1;";
  z[lc++]="";
  z[lc++]="/* Join thread to recover memory resources. */";
  z[lc++]="	if( pahsc->pahsc_ThreadPID != -1 )";
  z[lc++]="	{";
  z[lc++]="	/* This check is needed for GNUSTEP - SB20010904 */";
  z[lc++]="		if ( !pthread_equal( pahsc->pahsc_ThreadPID, pthread_self() ) )";
  z[lc++]="		{";
  z[lc++]="			hres = pthread_join( pahsc->pahsc_ThreadPID, NULL );";
  z[lc++]="		}";
  z[lc++]="		else {";
  z[lc++]="			DBUG((\"Play thread was stopped from itself - can't do pthread_join()\\n\"));";
  z[lc++]="			hres = 0;";
  z[lc++]="		}";
  z[lc++]="";
  z[lc++]="		if( hres != 0 )";
  z[lc++]="		{";
  z[lc++]="			result = paHostError;";
  z[lc++]="			sPaHostError = hres;";
  z[lc++]="		}";
  z[lc++]="		pahsc->pahsc_ThreadPID = -1;";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="        past->past_IsActive = 0;      ";
  z[lc++]="";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StopInput( internalPortAudioStream *past, int abort )";
  z[lc++]="{";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )";
  z[lc++]="{";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*******************************************************************/";
  z[lc++]="PaError PaHost_CloseStream( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paNoError;";
  z[lc++]="";
  z[lc++]="	if( pahsc->pahsc_OutputHandle != BAD_DEVICE_ID )";
  z[lc++]="	{";
  z[lc++]="		int err;";
  z[lc++]="		DBUG((\"PaHost_CloseStream: attempt to close output device handle = %d\\n\",";
  z[lc++]="			pahsc->pahsc_OutputHandle ));";
  z[lc++]="		err = close(pahsc->pahsc_OutputHandle);";
  z[lc++]="		if( err < 0 )";
  z[lc++]="		{";
  z[lc++]="			ERR_RPT((\"PaHost_CloseStream: warning, closing output device failed.\\n\"));";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="	if( (pahsc->pahsc_InputHandle != BAD_DEVICE_ID) &&";
  z[lc++]="	    (pahsc->pahsc_InputHandle != pahsc->pahsc_OutputHandle) )";
  z[lc++]="	{";
  z[lc++]="		int err;";
  z[lc++]="		DBUG((\"PaHost_CloseStream: attempt to close input device handle = %d\\n\",";
  z[lc++]="			pahsc->pahsc_InputHandle ));";
  z[lc++]="		err = close(pahsc->pahsc_InputHandle);";
  z[lc++]="		if( err < 0 )";
  z[lc++]="		{";
  z[lc++]="			ERR_RPT((\"PaHost_CloseStream: warning, closing input device failed.\\n\"));";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	pahsc->pahsc_OutputHandle = BAD_DEVICE_ID;";
  z[lc++]="	pahsc->pahsc_InputHandle = BAD_DEVICE_ID;";
  z[lc++]="	";
  z[lc++]="	if( pahsc->pahsc_NativeInputBuffer )";
  z[lc++]="	{";
  z[lc++]="		free( pahsc->pahsc_NativeInputBuffer );";
  z[lc++]="		pahsc->pahsc_NativeInputBuffer = NULL;";
  z[lc++]="	}";
  z[lc++]="	if( pahsc->pahsc_NativeOutputBuffer )";
  z[lc++]="	{";
  z[lc++]="		free( pahsc->pahsc_NativeOutputBuffer );";
  z[lc++]="		pahsc->pahsc_NativeOutputBuffer = NULL;";
  z[lc++]="	}";
  z[lc++]="";
  z[lc++]="	free( pahsc );";
  z[lc++]="	past->past_DeviceData = NULL;";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_Term( void )";
  z[lc++]="{";
  z[lc++]="/* Free all of the linked devices. */";
  z[lc++]="	internalPortAudioDevice *pad, *nextPad;";
  z[lc++]="	pad = sDeviceList;";
  z[lc++]="	while( pad != NULL )";
  z[lc++]="	{";
  z[lc++]="		nextPad = pad->pad_Next;";
  z[lc++]="		DBUG((\"PaHost_Term: freeing %s\\n\", pad->pad_DeviceName ));";
  z[lc++]="		PaHost_FreeFastMemory( pad, sizeof(internalPortAudioDevice) );";
  z[lc++]="		pad = nextPad;";
  z[lc++]="	}";
  z[lc++]="	sDeviceList = NULL;";
  z[lc++]="	return 0;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************";
  z[lc++]=" * Sleep for the requested number of milliseconds.";
  z[lc++]=" */";
  z[lc++]="void Pa_Sleep( long msec )";
  z[lc++]="{";
  z[lc++]="#if 0";
  z[lc++]="	struct timeval timeout;";
  z[lc++]="	timeout.tv_sec = msec / 1000;";
  z[lc++]="	timeout.tv_usec = (msec % 1000) * 1000;";
  z[lc++]="	select( 0, NULL, NULL, NULL, &timeout );";
  z[lc++]="#else";
  z[lc++]="	long usecs = msec * 1000;";
  z[lc++]="	usleep( usecs );";
  z[lc++]="#endif";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************";
  z[lc++]=" * Allocate memory that can be accessed in real-time.";
  z[lc++]=" * This may need to be held in physical memory so that it is not";
  z[lc++]=" * paged to virtual memory.";
  z[lc++]=" * This call MUST be balanced with a call to PaHost_FreeFastMemory().";
  z[lc++]=" */";
  z[lc++]="void *PaHost_AllocateFastMemory( long numBytes )";
  z[lc++]="{";
  z[lc++]="	void *addr = malloc( numBytes ); /* FIXME - do we need physical memory? */";
  z[lc++]="	if( addr != NULL ) memset( addr, 0, numBytes );";
  z[lc++]="	return addr;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/*************************************************************************";
  z[lc++]=" * Free memory that could be accessed in real-time.";
  z[lc++]=" * This call MUST be balanced with a call to PaHost_AllocateFastMemory().";
  z[lc++]=" */";
  z[lc++]="void PaHost_FreeFastMemory( void *addr, long numBytes )";
  z[lc++]="{";
  z[lc++]="	if( addr != NULL ) free( addr );";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="";
  z[lc++]="/***********************************************************************/";
  z[lc++]="PaError PaHost_StreamActive( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paInternalError;";
  z[lc++]="	return (PaError) (past->past_IsActive != 0);";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/***********************************************************************/";
  z[lc++]="PaTimestamp Pa_StreamTime( PortAudioStream *stream )";
  z[lc++]="{";
  z[lc++]="	internalPortAudioStream *past = (internalPortAudioStream *) stream; ";
  z[lc++]="/* FIXME - return actual frames played, not frames generated.";
  z[lc++]="** Need to query the output device somehow.";
  z[lc++]="*/";
  z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
  z[lc++]="	return past->past_FrameCount;";
  z[lc++]="}";
  z[lc++]="";
  z[lc++]="/***********************************************************************/";
  z[lc++]="long Pa_GetHostError( void )";
  z[lc++]="{";
  z[lc++]="	return (long) sPaHostError;";
  z[lc++]="}";
  printlib(lc);
}


void makepa_win_wmme(void)
{
  int lc = 0;

  z[lc++]="/*";
  z[lc++]=" * pa_win_wmme.c";
  z[lc++]=" * Implementation of PortAudio for Windows MultiMedia Extensions (WMME)";
  z[lc++]=" *";
  z[lc++]=" * PortAudio Portable Real-Time Audio Library";
  z[lc++]=" * Latest Version at: http://www.portaudio.com";
  z[lc++]=" *";
  z[lc++]=" * Authors: Ross Bencina and Phil Burk";
  z[lc++]=" * Copyright (c) 1999-2000 Ross Bencina and Phil Burk";
  z[lc++]=" *";
  z[lc++]=" * Permission is hereby granted, free of charge, to any person obtainingF";
  z[lc++]=" * a copy of this software and associated documentation files";
  z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
  z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
  z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
  z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
  z[lc++]=" * subject to the following conditions:";
  z[lc++]=" *";
  z[lc++]=" * The above copyright notice and this permission notice shall be";
  z[lc++]=" * included in all copies or substantial portions of the Software.";
  z[lc++]=" *";
  z[lc++]=" * Any person wishing to distribute modifications to the Software is";
  z[lc++]=" * requested to send the modifications to the original developer so that";
  z[lc++]=" * they can be incorporated into the canonical version.";
  z[lc++]=" *";
  z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
  z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
  z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
  z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
  z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
  z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
  z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
  z[lc++]=" *";
  z[lc++]=" */";
  z[lc++]="/*";
  z[lc++]="  All memory allocations and frees are marked with MEM for quick review.";
  z[lc++]="*/";
  z[lc++]="/* Modification History:";
  z[lc++]=" PLB = Phil Burk";
  z[lc++]=" PLB20010402 - sDevicePtrs now allocates based on sizeof(pointer)";
  z[lc++]=" PLB20010413 - check for excessive numbers of channels";
  z[lc++]=" PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC";
  z[lc++]="               including condition including of memory.h,";
  z[lc++]="			   and explicit typecasting on memory allocation";
  z[lc++]=" PLB20010802 - use GlobalAlloc for sDevicesPtr instead of PaHost_AllocFastMemory";
  z[lc++]=" PLB20010816 - pass process instead of thread to SetPriorityClass()";
  z[lc++]=" PLB20010927 - use number of frames instead of real-time for CPULoad calculation.";
  z[lc++]="*/";
  z[lc++]="#include <stdio.h>";
  z[lc++]="#include <stdlib.h>";
  z[lc++]="#include <math.h>";
  z[lc++]="#include <windows.h>";
  z[lc++]="#include <mmsystem.h>";
  z[lc++]="#include <process.h>";
  z[lc++]="/* PLB20010422 - \"memory.h\" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */";
  z[lc++]="#ifndef __MWERKS__";
  z[lc++]="#include <malloc.h>";
  z[lc++]="#include <memory.h>";
  z[lc++]="#endif /* __MWERKS__ */";
  z[lc++]="";
  z[lc++]="#if 0";
  z[lc++]="#include \"portaudio.h\"";
  z[lc++]="#include \"pa_host.h\"";
  z[lc++]="#include \"pa_trace.h\"";
  z[lc++]="#endif";
  z[lc++]="";
  z[lc++]="/************************************************* Constants ********/";
  z[lc++]="#define PA_USE_TIMER_CALLBACK    (0)  /* Select between two options for background task. 0=thread, 1=timer */";
  z[lc++]="#define PA_USE_HIGH_LATENCY      (0)  /* For debugging glitches. */";
  z[lc++]="/* Switches for debugging. */";
  z[lc++]="#define PA_SIMULATE_UNDERFLOW    (0)  /* Set to one to force an underflow of the output buffer. */";
  z[lc++]="/* To trace program, enable TRACE_REALTIME_EVENTS in pa_trace.h */";
  z[lc++]="#define PA_TRACE_RUN             (0)";
  z[lc++]="#define PA_TRACE_START_STOP      (1)";
  z[lc++]="#if PA_USE_HIGH_LATENCY";
  z[lc++]="	#define PA_MIN_MSEC_PER_HOST_BUFFER  (100)";
  z[lc++]="	#define PA_MAX_MSEC_PER_HOST_BUFFER  (300) /* Do not exceed unless user buffer exceeds */";
  z[lc++]="	#define PA_MIN_NUM_HOST_BUFFERS      (4)";
  z[lc++]="	#define PA_MAX_NUM_HOST_BUFFERS      (16)  /* OK to exceed if necessary */";
  z[lc++]="	#define PA_WIN_9X_LATENCY            (400)";
  z[lc++]="#else";
  z[lc++]="	#define PA_MIN_MSEC_PER_HOST_BUFFER  (10)";
  z[lc++]="	#define PA_MAX_MSEC_PER_HOST_BUFFER  (100) /* Do not exceed unless user buffer exceeds */";
  z[lc++]="	#define PA_MIN_NUM_HOST_BUFFERS      (3)";
  z[lc++]="	#define PA_MAX_NUM_HOST_BUFFERS      (16)  /* OK to exceed if necessary */";
  z[lc++]="	#define PA_WIN_9X_LATENCY            (200)";
  z[lc++]="#endif";
  z[lc++]="#define MIN_TIMEOUT_MSEC                 (1000)";
  z[lc++]="/*";
  z[lc++]="** Use higher latency for NT because it is even worse at real-time";
  z[lc++]="** operation than Win9x.";
  z[lc++]="*/";
  z[lc++]="#define PA_WIN_NT_LATENCY        (PA_WIN_9X_LATENCY * 2)";
  z[lc++]="#if PA_SIMULATE_UNDERFLOW";
  z[lc++]="static  gUnderCallbackCounter = 0;";
  z[lc++]="#define UNDER_SLEEP_AT       (40)";
  z[lc++]="#define UNDER_SLEEP_FOR      (500)";
  z[lc++]="#endif";
  z[lc++]="#define PRINT(x) { printf x; fflush(stdout); }";
  z[lc++]="#define ERR_RPT(x) PRINT(x)";
  z[lc++]="#define DBUG(x)  /* PRINT(x) */";
  z[lc++]="#define DBUGX(x) /* PRINT(x) */";
  z[lc++]="/************************************************* Definitions ********/";
  z[lc++]="/**************************************************************";
  z[lc++]=" * Structure for internal host specific stream data.";
  z[lc++]=" * This is allocated on a per stream basis.";
  z[lc++]=" */";
  z[lc++]="typedef struct PaHostSoundControl";
  z[lc++]="{";
  z[lc++]="/* Input -------------- */";
  z[lc++]="    HWAVEIN            pahsc_HWaveIn;";
  z[lc++]="    WAVEHDR           *pahsc_InputBuffers;";
  z[lc++]="    int                pahsc_CurrentInputBuffer;";
  z[lc++]="	int                pahsc_BytesPerHostInputBuffer;";
  z[lc++]="	int                pahsc_BytesPerUserInputBuffer;    /* native buffer size in bytes */";
  z[lc++]="/* Output -------------- */    ";
  z[lc++]="    HWAVEOUT           pahsc_HWaveOut;";
  z[lc++]="    WAVEHDR           *pahsc_OutputBuffers;";
  z[lc++]="    int                pahsc_CurrentOutputBuffer;";
  z[lc++]="	int                pahsc_BytesPerHostOutputBuffer;";
  z[lc++]="	int                pahsc_BytesPerUserOutputBuffer;    /* native buffer size in bytes */";
  z[lc++]="/* Run Time -------------- */    ";
  z[lc++]="	PaTimestamp        pahsc_FramesPlayed;";
  z[lc++]="	long               pahsc_LastPosition;                /* used to track frames played. */";
  z[lc++]="/* For measuring CPU utilization. */";
  z[lc++]="	LARGE_INTEGER      pahsc_EntryCount;";
  z[lc++]="	double             pahsc_InverseTicksPerHostBuffer;";
  z[lc++]="/* Init Time -------------- */    ";
  z[lc++]="	int                pahsc_NumHostBuffers;";
  z[lc++]="	int                pahsc_FramesPerHostBuffer;";
  z[lc++]="	int                pahsc_UserBuffersPerHostBuffer;";
  z[lc++]="    CRITICAL_SECTION   pahsc_StreamLock;                  /* Mutext to prevent threads from colliding. */";
  z[lc++]="	INT                pahsc_StreamLockInited;";
  z[lc++]="#if PA_USE_TIMER_CALLBACK";
  z[lc++]="	BOOL               pahsc_IfInsideCallback;            /* Test for reentrancy. */";
  z[lc++]="	MMRESULT           pahsc_TimerID;";
  z[lc++]="#else";
  z[lc++]="    HANDLE             pahsc_AbortEvent;";
  z[lc++]="    int                pahsc_AbortEventInited;";
  z[lc++]="    HANDLE             pahsc_BufferEvent;";
  z[lc++]="    int                pahsc_BufferEventInited;";
  z[lc++]="    HANDLE             pahsc_EngineThread;";
  z[lc++]="    DWORD              pahsc_EngineThreadID;";
  z[lc++]="#endif";
  z[lc++]="} PaHostSoundControl;";
  z[lc++]="/************************************************* Shared Data ********/";
  z[lc++]="/* FIXME - put Mutex around this shared data. */";
  z[lc++]="static int sNumInputDevices = 0;";
  z[lc++]="static int sNumOutputDevices = 0;";
  z[lc++]="static int sNumDevices = 0;";
  z[lc++]="static PaDeviceInfo **sDevicePtrs = NULL;";
  z[lc++]="static int sDefaultInputDeviceID = paNoDevice;";
  z[lc++]="static int sDefaultOutputDeviceID = paNoDevice;";
  z[lc++]="static int sPaHostError = 0;";
  z[lc++]="static const char sMapperSuffixInput[] = \" - Input\";";
  z[lc++]="static const char sMapperSuffixOutput[] = \" - Output\";";
  z[lc++]="/************************************************* Macros ********/";
  z[lc++]="/* Convert external PA ID to an internal ID that includes WAVE_MAPPER */";
  z[lc++]="#define PaDeviceIdToWinId(id) (((id) < sNumInputDevices) ? (id - 1) : (id - sNumInputDevices - 1))";
  z[lc++]="/************************************************* Prototypes **********/";
  z[lc++]="static Pa_QueryDevices( void );";
  z[lc++]="static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg,";
  z[lc++]="									  DWORD dwUser, DWORD dw1, DWORD dw2);";
  z[lc++]="PaError PaHost_GetTotalBufferFrames( internalPortAudioStream   *past );";
  z[lc++]="static PaError PaHost_UpdateStreamTime( PaHostSoundControl *pahsc );";
  z[lc++]="static PaError PaHost_BackgroundManager( internalPortAudioStream   *past );";
  z[lc++]="/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/";
  z[lc++]="static void Pa_StartUsageCalculation( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return;";
  z[lc++]="/* Query system timer for usage analysis and to prevent overuse of CPU. */";
  z[lc++]="	QueryPerformanceCounter( &pahsc->pahsc_EntryCount );";
  z[lc++]="}";
  z[lc++]="static void Pa_EndUsageCalculation( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	LARGE_INTEGER CurrentCount = { 0, 0 };";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return;";
  z[lc++]="/*";
  z[lc++]="** Measure CPU utilization during this callback. Note that this calculation";
  z[lc++]="** assumes that we had the processor the whole time.";
  z[lc++]="*/";
  z[lc++]="#define LOWPASS_COEFFICIENT_0   (0.9)";
  z[lc++]="#define LOWPASS_COEFFICIENT_1   (0.99999 - LOWPASS_COEFFICIENT_0)";
  z[lc++]="	if( QueryPerformanceCounter( &CurrentCount ) )";
  z[lc++]="	{";
  z[lc++]="		LONGLONG InsideCount = CurrentCount.QuadPart - pahsc->pahsc_EntryCount.QuadPart;	";
  z[lc++]="		double newUsage = InsideCount * pahsc->pahsc_InverseTicksPerHostBuffer;";
  z[lc++]="		past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +";
  z[lc++]="			(LOWPASS_COEFFICIENT_1 * newUsage);";
  z[lc++]="	}";
  z[lc++]="}";
  z[lc++]="/****************************************** END CPU UTILIZATION *******/";
  z[lc++]="static PaError Pa_QueryDevices( void )";
  z[lc++]="{";
  z[lc++]="	int numBytes;";
  z[lc++]="/* Count the devices and add one extra for the WAVE_MAPPER */";
  z[lc++]="    sNumInputDevices = waveInGetNumDevs() + 1;";
  z[lc++]="	sDefaultInputDeviceID = 0;";
  z[lc++]="    sNumOutputDevices = waveOutGetNumDevs() + 1;";
  z[lc++]="	sDefaultOutputDeviceID = sNumInputDevices;";
  z[lc++]="    sNumDevices = sNumInputDevices + sNumOutputDevices;";
  z[lc++]="/* Allocate structures to hold device info. */";
  z[lc++]="/* PLB20010402 - was allocating too much memory. */";
  z[lc++]="/*	numBytes = sNumDevices * sizeof(PaDeviceInfo);  // PLB20010402 */";
  z[lc++]="	numBytes = sNumDevices * sizeof(PaDeviceInfo *); /* PLB20010402 */";
  z[lc++]="	sDevicePtrs = (PaDeviceInfo **) GlobalAlloc( GPTR, numBytes ); /* MEM */";
  z[lc++]="	if( sDevicePtrs == NULL ) return paInsufficientMemory;";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="long Pa_GetHostError()";
  z[lc++]="{";
  z[lc++]="	return sPaHostError;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="int Pa_CountDevices()";
  z[lc++]="{";
  z[lc++]="	if( sNumDevices <= 0 ) Pa_Initialize();";
  z[lc++]="	return sNumDevices;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************";
  z[lc++]="** If a PaDeviceInfo structure has not already been created,";
  z[lc++]="** then allocate one and fill it in for the selected device.";
  z[lc++]="**";
  z[lc++]="** We create one extra input and one extra output device for the WAVE_MAPPER.";
  z[lc++]="** [Does anyone know how to query the default device and get its name?]";
  z[lc++]="*/";
  z[lc++]="const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )";
  z[lc++]="{	";
  z[lc++]="#define NUM_STANDARDSAMPLINGRATES   3   /* 11.025, 22.05, 44.1 */";
  z[lc++]="#define NUM_CUSTOMSAMPLINGRATES     5   /* must be the same number of elements as in the array below */";
  z[lc++]="#define MAX_NUMSAMPLINGRATES        (NUM_STANDARDSAMPLINGRATES+NUM_CUSTOMSAMPLINGRATES)";
  z[lc++]="    static DWORD customSamplingRates[] = { 32000, 48000, 64000, 88200, 96000 };";
  z[lc++]="    PaDeviceInfo *deviceInfo;";
  z[lc++]="    double *sampleRates; /* non-const ptr */";
  z[lc++]="    int i;";
  z[lc++]="    char *s;";
  z[lc++]="    ";
  z[lc++]="    if( id < 0 || id >= sNumDevices )";
  z[lc++]="        return NULL;";
  z[lc++]="    if( sDevicePtrs[ id ] != NULL )";
  z[lc++]="	{";
  z[lc++]="        return sDevicePtrs[ id ];";
  z[lc++]="    }";
  z[lc++]="    deviceInfo = (PaDeviceInfo *)GlobalAlloc( GPTR, sizeof(PaDeviceInfo) ); /* MEM */";
  z[lc++]="	if( deviceInfo == NULL ) return NULL;";
  z[lc++]="    deviceInfo->structVersion = 1;";
  z[lc++]="    deviceInfo->maxInputChannels = 0;";
  z[lc++]="    deviceInfo->maxOutputChannels = 0;";
  z[lc++]="    deviceInfo->numSampleRates = 0;";
  z[lc++]="    sampleRates = (double*)GlobalAlloc( GPTR, MAX_NUMSAMPLINGRATES * sizeof(double) ); /* MEM */";
  z[lc++]="    deviceInfo->sampleRates = sampleRates;";
  z[lc++]="    deviceInfo->nativeSampleFormats = paInt16;       /* should query for higher bit depths below */";
  z[lc++]="    if( id < sNumInputDevices )";
  z[lc++]="	{";
  z[lc++]="        /* input device */";
  z[lc++]="        int inputMmID = id - 1; /* WAVE_MAPPER is -1 so we start with WAVE_MAPPER */";
  z[lc++]="        WAVEINCAPS wic;";
  z[lc++]="        if( waveInGetDevCaps( inputMmID, &wic, sizeof( WAVEINCAPS ) ) != MMSYSERR_NOERROR )";
  z[lc++]="            goto error;";
  z[lc++]="        ";
  z[lc++]="	/* Append I/O suffix to WAVE_MAPPER device. */";
  z[lc++]="		if( inputMmID == WAVE_MAPPER )";
  z[lc++]="		{";
  z[lc++]="			s = (char *) GlobalAlloc( GMEM_FIXED, strlen( wic.szPname ) + 1 + sizeof(sMapperSuffixInput) ); /* MEM */";
  z[lc++]="			strcpy( s, wic.szPname );";
  z[lc++]="			strcat( s, sMapperSuffixInput );";
  z[lc++]="		}";
  z[lc++]="		else";
  z[lc++]="		{";
  z[lc++]="			s = (char *) GlobalAlloc( GMEM_FIXED, strlen( wic.szPname ) + 1 ); /* MEM */";
  z[lc++]="			strcpy( s, wic.szPname );";
  z[lc++]="		}";
  z[lc++]="        deviceInfo->name = s;";
  z[lc++]="        deviceInfo->maxInputChannels = wic.wChannels;";
  z[lc++]="	/* Sometimes a device can return a rediculously large number of channels.";
  z[lc++]="	** This happened with an SBLive card on a Windows ME box.";
  z[lc++]="	** If that happens, then force it to 2 channels.  PLB20010413";
  z[lc++]="	*/";
  z[lc++]="		if( (deviceInfo->maxInputChannels < 1) || (deviceInfo->maxInputChannels > 256) )";
  z[lc++]="		{";
  z[lc++]="			ERR_RPT((\"Pa_GetDeviceInfo: Num input channels reported as %d! Changed to 2.\\n\", deviceInfo->maxOutputChannels ));";
  z[lc++]="			deviceInfo->maxInputChannels = 2;";
  z[lc++]="		}";
  z[lc++]="	/* Add a sample rate to the list if we can do stereo 16 bit at that rate";
  z[lc++]="	 * based on the format flags. */";
  z[lc++]="        if( wic.dwFormats & WAVE_FORMAT_1M16 ||wic.dwFormats & WAVE_FORMAT_1S16 )";
  z[lc++]="            sampleRates[ deviceInfo->numSampleRates++ ] = 11025.;";
  z[lc++]="        if( wic.dwFormats & WAVE_FORMAT_2M16 ||wic.dwFormats & WAVE_FORMAT_2S16 )";
  z[lc++]="            sampleRates[ deviceInfo->numSampleRates++ ] = 22050.;";
  z[lc++]="        if( wic.dwFormats & WAVE_FORMAT_4M16 ||wic.dwFormats & WAVE_FORMAT_4S16 )";
  z[lc++]="            sampleRates[ deviceInfo->numSampleRates++ ] = 44100.;";
  z[lc++]="	/* Add a sample rate to the list if we can do stereo 16 bit at that rate";
  z[lc++]="	 * based on opening the device successfully. */";
  z[lc++]="        for( i=0; i < NUM_CUSTOMSAMPLINGRATES; i++ ){";
  z[lc++]="            WAVEFORMATEX wfx;";
  z[lc++]="            wfx.wFormatTag = WAVE_FORMAT_PCM;";
  z[lc++]="            wfx.nSamplesPerSec = customSamplingRates[i];";
  z[lc++]="            wfx.wBitsPerSample = 16;";
  z[lc++]="            wfx.cbSize = 0; /* ignored */";
  z[lc++]="            wfx.nChannels = (WORD)deviceInfo->maxInputChannels;";
  z[lc++]="            wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);";
  z[lc++]="            wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));";
  z[lc++]="            if( waveInOpen( NULL, inputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR )";
  z[lc++]="			{";
  z[lc++]="                sampleRates[ deviceInfo->numSampleRates++ ] = customSamplingRates[i];";
  z[lc++]="            }";
  z[lc++]="        }";
  z[lc++]="        ";
  z[lc++]="    }";
  z[lc++]="	else if( id - sNumInputDevices < sNumOutputDevices )";
  z[lc++]="	{";
  z[lc++]="        /* output device */";
  z[lc++]="        int outputMmID = id - sNumInputDevices - 1;";
  z[lc++]="        WAVEOUTCAPS woc;";
  z[lc++]="        if( waveOutGetDevCaps( outputMmID, &woc, sizeof( WAVEOUTCAPS ) ) != MMSYSERR_NOERROR )";
  z[lc++]="            goto error;";
  z[lc++]="	/* Append I/O suffix to WAVE_MAPPER device. */";
  z[lc++]="		if( outputMmID == WAVE_MAPPER )";
  z[lc++]="		{";
  z[lc++]="			s = (char *) GlobalAlloc( GMEM_FIXED, strlen( woc.szPname ) + 1 + sizeof(sMapperSuffixOutput) );  /* MEM */";
  z[lc++]="			strcpy( s, woc.szPname );";
  z[lc++]="			strcat( s, sMapperSuffixOutput );";
  z[lc++]="		}";
  z[lc++]="		else";
  z[lc++]="		{";
  z[lc++]="			s = (char *) GlobalAlloc( GMEM_FIXED, strlen( woc.szPname ) + 1 );  /* MEM */";
  z[lc++]="			strcpy( s, woc.szPname );";
  z[lc++]="		}";
  z[lc++]="        deviceInfo->name = s;";
  z[lc++]="        deviceInfo->maxOutputChannels = woc.wChannels;";
  z[lc++]="	/* Sometimes a device can return a rediculously large number of channels.";
  z[lc++]="	** This happened with an SBLive card on a Windows ME box.";
  z[lc++]="	** If that happens, then force it to 2 channels. PLB20010413";
  z[lc++]="	*/";
  z[lc++]="		if( (deviceInfo->maxOutputChannels < 1) || (deviceInfo->maxOutputChannels > 256) )";
  z[lc++]="		{";
  z[lc++]="			ERR_RPT((\"Pa_GetDeviceInfo: Num output channels reported as %d! Changed to 2.\\n\", deviceInfo->maxOutputChannels ));";
  z[lc++]="			deviceInfo->maxOutputChannels = 2;";
  z[lc++]="		}";
  z[lc++]="	/* Add a sample rate to the list if we can do stereo 16 bit at that rate";
  z[lc++]="	 * based on the format flags. */";
  z[lc++]="        if( woc.dwFormats & WAVE_FORMAT_1M16 ||woc.dwFormats & WAVE_FORMAT_1S16 )";
  z[lc++]="            sampleRates[ deviceInfo->numSampleRates++ ] = 11025.;";
  z[lc++]="        if( woc.dwFormats & WAVE_FORMAT_2M16 ||woc.dwFormats & WAVE_FORMAT_2S16 )";
  z[lc++]="            sampleRates[ deviceInfo->numSampleRates++ ] = 22050.;";
  z[lc++]="        if( woc.dwFormats & WAVE_FORMAT_4M16 ||woc.dwFormats & WAVE_FORMAT_4S16 )";
  z[lc++]="            sampleRates[ deviceInfo->numSampleRates++ ] = 44100.;";
  z[lc++]="	/* Add a sample rate to the list if we can do stereo 16 bit at that rate";
  z[lc++]="	 * based on opening the device successfully. */";
  z[lc++]="        for( i=0; i < NUM_CUSTOMSAMPLINGRATES; i++ )";
  z[lc++]="		{";
  z[lc++]="            WAVEFORMATEX wfx;";
  z[lc++]="            wfx.wFormatTag = WAVE_FORMAT_PCM;";
  z[lc++]="            wfx.nSamplesPerSec = customSamplingRates[i];";
  z[lc++]="            wfx.wBitsPerSample = 16;";
  z[lc++]="            wfx.cbSize = 0; /* ignored */";
  z[lc++]="            wfx.nChannels = (WORD)deviceInfo->maxOutputChannels;";
  z[lc++]="            wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);";
  z[lc++]="            wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));";
  z[lc++]="            if( waveOutOpen( NULL, outputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR ){";
  z[lc++]="                sampleRates[ deviceInfo->numSampleRates++ ] = customSamplingRates[i];";
  z[lc++]="            }";
  z[lc++]="        }";
  z[lc++]="    }";
  z[lc++]="    sDevicePtrs[ id ] = deviceInfo;";
  z[lc++]="    return deviceInfo;";
  z[lc++]="error:";
  z[lc++]="    GlobalFree( sampleRates ); /* MEM */";
  z[lc++]="    GlobalFree( deviceInfo ); /* MEM */";
  z[lc++]="    ";
  z[lc++]="    return NULL;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************";
  z[lc++]="** Returns recommended device ID.";
  z[lc++]="** On the PC, the recommended device can be specified by the user by";
  z[lc++]="** setting an environment variable. For example, to use device #1.";
  z[lc++]="**";
  z[lc++]="**    set PA_RECOMMENDED_OUTPUT_DEVICE=1";
  z[lc++]="**";
  z[lc++]="** The user should first determine the available device ID by using";
  z[lc++]="** the supplied application \"pa_devs\".";
  z[lc++]="*/";
  z[lc++]="#define PA_ENV_BUF_SIZE  (32)";
  z[lc++]="#define PA_REC_IN_DEV_ENV_NAME  (\"PA_RECOMMENDED_INPUT_DEVICE\")";
  z[lc++]="#define PA_REC_OUT_DEV_ENV_NAME  (\"PA_RECOMMENDED_OUTPUT_DEVICE\")";
  z[lc++]="static PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName )";
  z[lc++]="{";
  z[lc++]="	DWORD   hresult;";
  z[lc++]="	char    envbuf[PA_ENV_BUF_SIZE];";
  z[lc++]="	PaDeviceID recommendedID = paNoDevice;";
  z[lc++]="/* Let user determine default device by setting environment variable. */";
  z[lc++]="	hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE );";
  z[lc++]="	if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )";
  z[lc++]="	{";
  z[lc++]="		recommendedID = atoi( envbuf );";
  z[lc++]="	}";
  z[lc++]="	return recommendedID;";
  z[lc++]="}";
  z[lc++]="static PaError Pa_MaybeQueryDevices( void )";
  z[lc++]="{";
  z[lc++]="	if( sNumDevices == 0 )";
  z[lc++]="	{";
  z[lc++]="		return Pa_QueryDevices();";
  z[lc++]="	}";
  z[lc++]="	return 0;";
  z[lc++]="}";
  z[lc++]="/**********************************************************************";
  z[lc++]="** Check for environment variable, else query devices and use result.";
  z[lc++]="*/";
  z[lc++]="PaDeviceID Pa_GetDefaultInputDeviceID( void )";
  z[lc++]="{";
  z[lc++]="	PaError result;";
  z[lc++]="	result = PaHost_GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME );";
  z[lc++]="	if( result < 0 )";
  z[lc++]="	{";
  z[lc++]="		result = Pa_MaybeQueryDevices();";
  z[lc++]="		if( result < 0 ) return result;";
  z[lc++]="		result = sDefaultInputDeviceID;";
  z[lc++]="	}";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="PaDeviceID Pa_GetDefaultOutputDeviceID( void )";
  z[lc++]="{";
  z[lc++]="	PaError result;";
  z[lc++]="	result = PaHost_GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME );";
  z[lc++]="	if( result < 0 )";
  z[lc++]="	{";
  z[lc++]="		result = Pa_MaybeQueryDevices();";
  z[lc++]="		if( result < 0 ) return result;";
  z[lc++]="		result = sDefaultOutputDeviceID;";
  z[lc++]="	}";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/**********************************************************************";
  z[lc++]="** Initialize Host dependant part of API.";
  z[lc++]="*/";
  z[lc++]="PaError PaHost_Init( void )";
  z[lc++]="{";
  z[lc++]="#if PA_SIMULATE_UNDERFLOW";
  z[lc++]="	PRINT((\"WARNING - Underflow Simulation Enabled - Expect a Big Glitch!!!\\n\"));";
  z[lc++]="#endif";
  z[lc++]="	return Pa_MaybeQueryDevices();";
  z[lc++]="}";
  z[lc++]="/**********************************************************************";
  z[lc++]="** Check WAVE buffers to see if they are done.";
  z[lc++]="** Fill any available output buffers and use any available";
  z[lc++]="** input buffers by calling user callback.";
  z[lc++]="*/";
  z[lc++]="static PaError Pa_TimeSlice( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaError           result = 0;";
  z[lc++]="	long              bytesEmpty = 0;";
  z[lc++]="	long              bytesFilled = 0;";
  z[lc++]="	long              buffersEmpty = 0;";
  z[lc++]="	MMRESULT          mresult;";
  z[lc++]="	char             *inBufPtr;";
  z[lc++]="	char             *outBufPtr;";
  z[lc++]="	int               gotInput = 0;";
  z[lc++]="	int               gotOutput = 0;";
  z[lc++]="	int               i;";
  z[lc++]="	int               buffersProcessed = 0;";
  z[lc++]="	int               done = 0;";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paInternalError;";
  z[lc++]="	past->past_NumCallbacks += 1;";
  z[lc++]="#if PA_SIMULATE_UNDERFLOW";
  z[lc++]="	if(gUnderCallbackCounter++ == UNDER_SLEEP_AT)";
  z[lc++]="	{";
  z[lc++]="		Sleep(UNDER_SLEEP_FOR);";
  z[lc++]="	}";
  z[lc++]="#endif";
  z[lc++]="#if PA_TRACE_RUN";
  z[lc++]="	AddTraceMessage(\"Pa_TimeSlice: past_NumCallbacks \", past->past_NumCallbacks );";
  z[lc++]="#endif";
  z[lc++]="	while(!done)";
  z[lc++]="	{";
  z[lc++]="/* If we are using output, then we need an empty output buffer. */";
  z[lc++]="		gotOutput = 0;";
  z[lc++]="		outBufPtr = NULL;";
  z[lc++]="		if( past->past_NumOutputChannels > 0 )";
  z[lc++]="		{";
  z[lc++]="			if((pahsc->pahsc_OutputBuffers[ pahsc->pahsc_CurrentOutputBuffer ].dwFlags & WHDR_DONE) == 0)";
  z[lc++]="			{	";
  z[lc++]="				break;  /* If none empty then bail and try again later. */";
  z[lc++]="			}";
  z[lc++]="			else";
  z[lc++]="			{";
  z[lc++]="				outBufPtr = pahsc->pahsc_OutputBuffers[ pahsc->pahsc_CurrentOutputBuffer ].lpData;";
  z[lc++]="				gotOutput = 1;";
  z[lc++]="			}";
  z[lc++]="		}";
  z[lc++]="/* Use an input buffer if one is available. */";
  z[lc++]="		gotInput = 0;";
  z[lc++]="		inBufPtr = NULL;";
  z[lc++]="		if( ( past->past_NumInputChannels > 0 ) &&";
  z[lc++]="			(pahsc->pahsc_InputBuffers[ pahsc->pahsc_CurrentInputBuffer ].dwFlags & WHDR_DONE) )";
  z[lc++]="		{";
  z[lc++]="			inBufPtr = pahsc->pahsc_InputBuffers[ pahsc->pahsc_CurrentInputBuffer ].lpData;";
  z[lc++]="			gotInput = 1;";
  z[lc++]="#if PA_TRACE_RUN";
  z[lc++]="			AddTraceMessage(\"Pa_TimeSlice: got input buffer at \", (int)inBufPtr );";
  z[lc++]="			AddTraceMessage(\"Pa_TimeSlice: got input buffer # \", pahsc->pahsc_CurrentInputBuffer );";
  z[lc++]="#endif";
  z[lc++]="		}";
  z[lc++]="/* If we can't do anything then bail out. */";
  z[lc++]="		if( !gotInput && !gotOutput ) break;";
  z[lc++]="		buffersProcessed += 1;";
  z[lc++]="/* Each Wave buffer contains multiple user buffers so do them all now. */";
  z[lc++]="/* Base Usage on time it took to process one host buffer. */";
  z[lc++]="		Pa_StartUsageCalculation( past );";
  z[lc++]="		for( i=0; i<pahsc->pahsc_UserBuffersPerHostBuffer; i++ )";
  z[lc++]="		{";
  z[lc++]="			if( done )";
  z[lc++]="			{";
  z[lc++]="				if( gotOutput )";
  z[lc++]="				{";
  z[lc++]="		/* Clear remainder of wave buffer if we are waiting for stop. */";
  z[lc++]="					AddTraceMessage(\"Pa_TimeSlice: zero rest of wave buffer \", i );";
  z[lc++]="					memset( outBufPtr, 0, pahsc->pahsc_BytesPerUserOutputBuffer );";
  z[lc++]="				}";
  z[lc++]="			}";
  z[lc++]="			else";
  z[lc++]="			{";
  z[lc++]="	/* Convert 16 bit native data to user data and call user routine. */";
  z[lc++]="				result = Pa_CallConvertInt16( past, (short *) inBufPtr, (short *) outBufPtr );";
  z[lc++]="				if( result != 0) done = 1;";
  z[lc++]="			}";
  z[lc++]="			if( gotInput ) inBufPtr += pahsc->pahsc_BytesPerUserInputBuffer;";
  z[lc++]="			if( gotOutput) outBufPtr += pahsc->pahsc_BytesPerUserOutputBuffer;";
  z[lc++]="		}";
  z[lc++]="		Pa_EndUsageCalculation( past );";
  z[lc++]="/* Send WAVE buffer to Wave Device to be refilled. */";
  z[lc++]="		if( gotInput )";
  z[lc++]="		{";
  z[lc++]="			mresult = waveInAddBuffer( pahsc->pahsc_HWaveIn,";
  z[lc++]="				&pahsc->pahsc_InputBuffers[ pahsc->pahsc_CurrentInputBuffer ],";
  z[lc++]="				sizeof(WAVEHDR) );";
  z[lc++]="			if( mresult != MMSYSERR_NOERROR )";
  z[lc++]="			{";
  z[lc++]="				sPaHostError = mresult;";
  z[lc++]="				result = paHostError;";
  z[lc++]="				break;";
  z[lc++]="			}";
  z[lc++]="			pahsc->pahsc_CurrentInputBuffer = (pahsc->pahsc_CurrentInputBuffer+1 >= pahsc->pahsc_NumHostBuffers) ?";
  z[lc++]="				0 : pahsc->pahsc_CurrentInputBuffer+1;";
  z[lc++]="		}";
  z[lc++]="/* Write WAVE buffer to Wave Device. */";
  z[lc++]="		if( gotOutput )";
  z[lc++]="		{";
  z[lc++]="#if PA_TRACE_START_STOP";
  z[lc++]="    AddTraceMessage( \"Pa_TimeSlice: writing buffer \", pahsc->pahsc_CurrentOutputBuffer );";
  z[lc++]="#endif";
  z[lc++]="			mresult = waveOutWrite( pahsc->pahsc_HWaveOut,";
  z[lc++]="				&pahsc->pahsc_OutputBuffers[ pahsc->pahsc_CurrentOutputBuffer ],";
  z[lc++]="				sizeof(WAVEHDR) );";
  z[lc++]="			if( mresult != MMSYSERR_NOERROR )";
  z[lc++]="			{";
  z[lc++]="				sPaHostError = mresult;";
  z[lc++]="				result = paHostError;";
  z[lc++]="				break;";
  z[lc++]="			}";
  z[lc++]="			pahsc->pahsc_CurrentOutputBuffer = (pahsc->pahsc_CurrentOutputBuffer+1 >= pahsc->pahsc_NumHostBuffers) ?";
  z[lc++]="				0 : pahsc->pahsc_CurrentOutputBuffer+1;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="			";
  z[lc++]="#if PA_TRACE_RUN";
  z[lc++]="	AddTraceMessage(\"Pa_TimeSlice: buffersProcessed \", buffersProcessed );";
  z[lc++]="#endif";
  z[lc++]="	return (result != 0) ? result : done;";
  z[lc++]="}";
  z[lc++]="/*******************************************************************/";
  z[lc++]="static PaError PaHost_BackgroundManager( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaError      result = 0;";
  z[lc++]="    int          i;";
  z[lc++]="	int          numQueuedOutputBuffers = 0;";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="/* Has someone asked us to abort by calling Pa_AbortStream()? */";
  z[lc++]="	if( past->past_StopNow )";
  z[lc++]="	{";
  z[lc++]="        past->past_IsActive = 0; /* Will cause thread to return. */";
  z[lc++]="    }";
  z[lc++]="/* Has someone asked us to stop by calling Pa_StopStream()";
  z[lc++]=" * OR has a user callback returned '1' to indicate finished.";
  z[lc++]=" */";
  z[lc++]="	else if( past->past_StopSoon )";
  z[lc++]="	{";
  z[lc++]="/* Poll buffer and when all have played then exit thread. */";
  z[lc++]="/* Count how many output buffers are queued. */";
  z[lc++]="        numQueuedOutputBuffers = 0;";
  z[lc++]="        if( past->past_NumOutputChannels > 0 )";
  z[lc++]="		{";
  z[lc++]="			for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
  z[lc++]="			{";
  z[lc++]="				if( !( pahsc->pahsc_OutputBuffers[ i ].dwFlags & WHDR_DONE) )";
  z[lc++]="				{";
  z[lc++]="#if PA_TRACE_START_STOP";
  z[lc++]="AddTraceMessage( \"WinMMPa_OutputThreadProc: waiting for buffer \", i );";
  z[lc++]="#endif";
  z[lc++]="					numQueuedOutputBuffers++;";
  z[lc++]="				}";
  z[lc++]="			}";
  z[lc++]="		}";
  z[lc++]="#if PA_TRACE_START_STOP";
  z[lc++]="AddTraceMessage( \"WinMMPa_OutputThreadProc: numQueuedOutputBuffers \", numQueuedOutputBuffers );";
  z[lc++]="#endif";
  z[lc++]="        if( numQueuedOutputBuffers == 0 )";
  z[lc++]="		{";
  z[lc++]="            past->past_IsActive = 0; /* Will cause thread to return. */";
  z[lc++]="		}";
  z[lc++]="    }";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="/* Process full input buffer and fill up empty output buffers. */";
  z[lc++]="		if( (result = Pa_TimeSlice( past )) != 0) ";
  z[lc++]="		{";
  z[lc++]="	/* User callback has asked us to stop. */";
  z[lc++]="#if PA_TRACE_START_STOP";
  z[lc++]="AddTraceMessage( \"WinMMPa_OutputThreadProc: TimeSlice() returned \", result );";
  z[lc++]="#endif";
  z[lc++]="            past->past_StopSoon = 1; /* Request that audio play out then stop. */";
  z[lc++]="			result = paNoError;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="	PaHost_UpdateStreamTime( pahsc );";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="#if PA_USE_TIMER_CALLBACK";
  z[lc++]="/*******************************************************************/";
  z[lc++]="static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)";
  z[lc++]="{";
  z[lc++]="	internalPortAudioStream   *past;";
  z[lc++]="	PaHostSoundControl        *pahsc;";
  z[lc++]="	PaError                    result;";
  z[lc++]="	past = (internalPortAudioStream *) dwUser;";
  z[lc++]="	if( past == NULL ) return;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return;";
  z[lc++]="	if( pahsc->pahsc_IfInsideCallback )";
  z[lc++]="	{";
  z[lc++]="		if( pahsc->pahsc_TimerID != 0 )";
  z[lc++]="		{";
  z[lc++]="			timeKillEvent(pahsc->pahsc_TimerID);  /* Stop callback timer. */";
  z[lc++]="			pahsc->pahsc_TimerID = 0;";
  z[lc++]="		}";
  z[lc++]="		return;";
  z[lc++]="	}";
  z[lc++]="	pahsc->pahsc_IfInsideCallback = 1;";
  z[lc++]="/* Manage flags and audio processing. */";
  z[lc++]=" 	result = PaHost_BackgroundManager( past );";
  z[lc++]="	if( result != paNoError )";
  z[lc++]="	{";
  z[lc++]="		past->past_IsActive = 0;";
  z[lc++]="	}";
  z[lc++]="	pahsc->pahsc_IfInsideCallback = 0;";
  z[lc++]="}";
  z[lc++]="#else /* PA_USE_TIMER_CALLBACK */";
  z[lc++]="/*******************************************************************/";
  z[lc++]="static DWORD WINAPI WinMMPa_OutputThreadProc( void *pArg )";
  z[lc++]="{";
  z[lc++]="	internalPortAudioStream *past;";
  z[lc++]=" 	PaHostSoundControl      *pahsc;";
  z[lc++]="    void        *inputBuffer=NULL;";
  z[lc++]="    HANDLE       events[2];";
  z[lc++]="	int          numEvents = 0;";
  z[lc++]="	DWORD        result = 0;";
  z[lc++]="	DWORD        waitResult;";
  z[lc++]="	DWORD        numTimeouts = 0;";
  z[lc++]="	DWORD        timeOut;";
  z[lc++]="	past = (internalPortAudioStream *) pArg;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="#if PA_TRACE_START_STOP";
  z[lc++]="    AddTraceMessage( \"WinMMPa_OutputThreadProc: timeoutPeriod\", timeoutPeriod );";
  z[lc++]="    AddTraceMessage( \"WinMMPa_OutputThreadProc: past_NumUserBuffers\", past->past_NumUserBuffers );";
  z[lc++]="#endif";
  z[lc++]="/* Calculate timeOut as half the time it would take to play all buffers. */";
  z[lc++]="	timeOut = (DWORD) (500.0 * PaHost_GetTotalBufferFrames( past ) / past->past_SampleRate);";
  z[lc++]="/* Get event(s) ready for wait. */";
  z[lc++]="    events[numEvents++] = pahsc->pahsc_BufferEvent;";
  z[lc++]="    if( pahsc->pahsc_AbortEventInited ) events[numEvents++] = pahsc->pahsc_AbortEvent;";
  z[lc++]="/* Stay in this thread as long as we are \"active\". */";
  z[lc++]="    while( past->past_IsActive )";
  z[lc++]="	{";
  z[lc++]="/*******************************************************************/";
  z[lc++]="/******** WAIT here for an event from WMME or PA *******************/";
  z[lc++]="/*******************************************************************/";
  z[lc++]="        waitResult = WaitForMultipleObjects( numEvents, events, FALSE, timeOut );";
  z[lc++]="	/* Error? */";
  z[lc++]="		if( waitResult == WAIT_FAILED )";
  z[lc++]="		{";
  z[lc++]="			sPaHostError = GetLastError();";
  z[lc++]="			result = paHostError;";
  z[lc++]="			past->past_IsActive = 0;";
  z[lc++]="		}";
  z[lc++]="	/* Timeout? Don't stop. Just keep polling for DONE.*/";
  z[lc++]="		else if( waitResult == WAIT_TIMEOUT )";
  z[lc++]="		{";
  z[lc++]="#if PA_TRACE_START_STOP";
  z[lc++]="	AddTraceMessage( \"WinMMPa_OutputThreadProc: timed out \", numQueuedOutputBuffers );";
  z[lc++]="#endif";
  z[lc++]="			numTimeouts += 1;";
  z[lc++]="		}";
  z[lc++]="		/* Manage flags and audio processing. */";
  z[lc++]=" 		result = PaHost_BackgroundManager( past );";
  z[lc++]="		if( result != paNoError )";
  z[lc++]="		{";
  z[lc++]="			past->past_IsActive = 0;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="#endif";
  z[lc++]="/*******************************************************************/";
  z[lc++]="PaError PaHost_OpenInputStream( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	MMRESULT         mr;";
  z[lc++]="	PaError          result = paNoError;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	int              i;";
  z[lc++]="	int              inputMmId;";
  z[lc++]="	int              bytesPerInputFrame;";
  z[lc++]="	WAVEFORMATEX     wfx;";
  z[lc++]="	const PaDeviceInfo  *pad;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	DBUG((\"PaHost_OpenStream: deviceID = 0x%x\\n\", past->past_InputDeviceID));";
  z[lc++]="	pad = Pa_GetDeviceInfo( past->past_InputDeviceID );";
  z[lc++]="	if( pad == NULL ) return paInternalError;";
  z[lc++]="	switch( pad->nativeSampleFormats  )";
  z[lc++]="	{";
  z[lc++]="		case paInt32:";
  z[lc++]="		case paFloat32:";
  z[lc++]="			bytesPerInputFrame = sizeof(float) * past->past_NumInputChannels;";
  z[lc++]="			break;";
  z[lc++]="		default:";
  z[lc++]="			bytesPerInputFrame = sizeof(short) * past->past_NumInputChannels;";
  z[lc++]="			break;";
  z[lc++]="	}";
  z[lc++]="	wfx.wFormatTag = WAVE_FORMAT_PCM;";
  z[lc++]="	wfx.nChannels = (WORD) past->past_NumInputChannels;";
  z[lc++]="	wfx.nSamplesPerSec = (DWORD) past->past_SampleRate;";
  z[lc++]="	wfx.nAvgBytesPerSec = (DWORD)(bytesPerInputFrame * past->past_SampleRate);";
  z[lc++]="	wfx.nBlockAlign = (WORD)bytesPerInputFrame;";
  z[lc++]="	wfx.wBitsPerSample = (WORD)((bytesPerInputFrame/past->past_NumInputChannels) * 8);";
  z[lc++]="	wfx.cbSize = 0;";
  z[lc++]="	inputMmId = PaDeviceIdToWinId( past->past_InputDeviceID );";
  z[lc++]="#if PA_USE_TIMER_CALLBACK";
  z[lc++]="	mr = waveInOpen( &pahsc->pahsc_HWaveIn, inputMmId, &wfx,";
  z[lc++]="	                  0, 0, CALLBACK_NULL );";
  z[lc++]="#else";
  z[lc++]="	mr = waveInOpen( &pahsc->pahsc_HWaveIn, inputMmId, &wfx,";
  z[lc++]="	                  (DWORD)pahsc->pahsc_BufferEvent, (DWORD) past, CALLBACK_EVENT );";
  z[lc++]="#endif";
  z[lc++]="	if( mr != MMSYSERR_NOERROR )";
  z[lc++]="	{";
  z[lc++]="		ERR_RPT((\"PortAudio: PaHost_OpenInputStream() failed!\\n\"));";
  z[lc++]="		result = paHostError;";
  z[lc++]="		sPaHostError = mr;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="/* Allocate an array to hold the buffer pointers. */";
  z[lc++]="	pahsc->pahsc_InputBuffers = (WAVEHDR *) GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(WAVEHDR)*pahsc->pahsc_NumHostBuffers ); /* MEM */";
  z[lc++]="	if( pahsc->pahsc_InputBuffers == NULL )";
  z[lc++]="	{";
  z[lc++]="		result = paInsufficientMemory;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="/* Allocate each buffer. */";
  z[lc++]="	for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
  z[lc++]="	{";
  z[lc++]="		pahsc->pahsc_InputBuffers[i].lpData = (char *)GlobalAlloc( GMEM_FIXED, pahsc->pahsc_BytesPerHostInputBuffer ); /* MEM */";
  z[lc++]="		if( pahsc->pahsc_InputBuffers[i].lpData == NULL )";
  z[lc++]="		{";
  z[lc++]="			result = paInsufficientMemory;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="		pahsc->pahsc_InputBuffers[i].dwBufferLength = pahsc->pahsc_BytesPerHostInputBuffer;";
  z[lc++]="		pahsc->pahsc_InputBuffers[i].dwUser = i;";
  z[lc++]="		if( ( mr = waveInPrepareHeader( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )";
  z[lc++]="		{";
  z[lc++]="			result = paHostError;";
  z[lc++]="			sPaHostError = mr;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	return result;";
  z[lc++]="error:";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/*******************************************************************/";
  z[lc++]="PaError PaHost_OpenOutputStream( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	MMRESULT         mr;";
  z[lc++]="	PaError          result = paNoError;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	int              i;";
  z[lc++]="	int              outputMmID;";
  z[lc++]="	int              bytesPerOutputFrame;";
  z[lc++]="	WAVEFORMATEX     wfx;";
  z[lc++]="	const PaDeviceInfo *pad;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	DBUG((\"PaHost_OpenStream: deviceID = 0x%x\\n\", past->past_OutputDeviceID));";
  z[lc++]="	pad = Pa_GetDeviceInfo( past->past_OutputDeviceID );";
  z[lc++]="	if( pad == NULL ) return paInternalError;";
  z[lc++]="	switch( pad->nativeSampleFormats  )";
  z[lc++]="	{";
  z[lc++]="		case paInt32:";
  z[lc++]="		case paFloat32:";
  z[lc++]="			bytesPerOutputFrame = sizeof(float) * past->past_NumOutputChannels;";
  z[lc++]="			break;";
  z[lc++]="		default:";
  z[lc++]="			bytesPerOutputFrame = sizeof(short) * past->past_NumOutputChannels;";
  z[lc++]="			break;";
  z[lc++]="	}";
  z[lc++]="	wfx.wFormatTag = WAVE_FORMAT_PCM;";
  z[lc++]="	wfx.nChannels = (WORD) past->past_NumOutputChannels;";
  z[lc++]="	wfx.nSamplesPerSec = (DWORD) past->past_SampleRate;";
  z[lc++]="	wfx.nAvgBytesPerSec = (DWORD)(bytesPerOutputFrame * past->past_SampleRate);";
  z[lc++]="	wfx.nBlockAlign = (WORD)bytesPerOutputFrame;";
  z[lc++]="	wfx.wBitsPerSample = (WORD)((bytesPerOutputFrame/past->past_NumOutputChannels) * 8);";
  z[lc++]="	wfx.cbSize = 0;";
  z[lc++]="	outputMmID = PaDeviceIdToWinId( past->past_OutputDeviceID );";
  z[lc++]="#if PA_USE_TIMER_CALLBACK";
  z[lc++]="	mr = waveOutOpen( &pahsc->pahsc_HWaveOut, outputMmID, &wfx,";
  z[lc++]="	                  0, 0, CALLBACK_NULL );";
  z[lc++]="#else";
  z[lc++]="	        ";
  z[lc++]="	pahsc->pahsc_AbortEvent = CreateEvent( NULL, TRUE, FALSE, NULL );";
  z[lc++]="	if( pahsc->pahsc_AbortEvent == NULL )";
  z[lc++]="	{";
  z[lc++]="		result = paHostError;";
  z[lc++]="		sPaHostError = GetLastError();";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="	pahsc->pahsc_AbortEventInited = 1;";
  z[lc++]="	mr = waveOutOpen( &pahsc->pahsc_HWaveOut, outputMmID, &wfx,";
  z[lc++]="	                  (DWORD)pahsc->pahsc_BufferEvent, (DWORD) past, CALLBACK_EVENT );";
  z[lc++]="#endif";
  z[lc++]="	if( mr != MMSYSERR_NOERROR )";
  z[lc++]="	{";
  z[lc++]="		ERR_RPT((\"PortAudio: PaHost_OpenOutputStream() failed!\\n\"));";
  z[lc++]="		result = paHostError;";
  z[lc++]="		sPaHostError = mr;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="/* Allocate an array to hold the buffer pointers. */";
  z[lc++]="	pahsc->pahsc_OutputBuffers = (WAVEHDR *) GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(WAVEHDR)*pahsc->pahsc_NumHostBuffers ); /* MEM */";
  z[lc++]="	if( pahsc->pahsc_OutputBuffers == NULL )";
  z[lc++]="	{";
  z[lc++]="		result = paInsufficientMemory;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="/* Allocate each buffer. */";
  z[lc++]="	for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
  z[lc++]="	{";
  z[lc++]="		pahsc->pahsc_OutputBuffers[i].lpData = (char *) GlobalAlloc( GMEM_FIXED, pahsc->pahsc_BytesPerHostOutputBuffer ); /* MEM */";
  z[lc++]="		if( pahsc->pahsc_OutputBuffers[i].lpData == NULL )";
  z[lc++]="		{";
  z[lc++]="			result = paInsufficientMemory;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="		pahsc->pahsc_OutputBuffers[i].dwBufferLength = pahsc->pahsc_BytesPerHostOutputBuffer;";
  z[lc++]="		pahsc->pahsc_OutputBuffers[i].dwUser = i;";
  z[lc++]="		if( (mr = waveOutPrepareHeader( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )";
  z[lc++]="		{";
  z[lc++]="			result = paHostError;";
  z[lc++]="			sPaHostError = mr;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	return result;";
  z[lc++]="error:";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/*******************************************************************/";
  z[lc++]="PaError PaHost_GetTotalBufferFrames( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	return pahsc->pahsc_NumHostBuffers * pahsc->pahsc_FramesPerHostBuffer;";
  z[lc++]="}";
  z[lc++]="/*******************************************************************";
  z[lc++]="* Determine number of WAVE Buffers";
  z[lc++]="* and how many User Buffers we can put into each WAVE buffer.";
  z[lc++]="*/";
  z[lc++]="static void PaHost_CalcNumHostBuffers( internalPortAudioStream *past )";
  z[lc++]="{";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	unsigned int  minNumBuffers;";
  z[lc++]="	int           minFramesPerHostBuffer;";
  z[lc++]="	int           maxFramesPerHostBuffer;";
  z[lc++]="	int           minTotalFrames;";
  z[lc++]="	int           userBuffersPerHostBuffer;";
  z[lc++]="	int           framesPerHostBuffer;";
  z[lc++]="	int           numHostBuffers;";
  z[lc++]="/* Calculate minimum and maximum sizes based on timing and sample rate. */";
  z[lc++]="	minFramesPerHostBuffer = (int) (PA_MIN_MSEC_PER_HOST_BUFFER * past->past_SampleRate / 1000.0);";
  z[lc++]="	minFramesPerHostBuffer = (minFramesPerHostBuffer + 7) & ~7;";
  z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: minFramesPerHostBuffer = %d\\n\", minFramesPerHostBuffer ));";
  z[lc++]="	maxFramesPerHostBuffer = (int) (PA_MAX_MSEC_PER_HOST_BUFFER * past->past_SampleRate / 1000.0);";
  z[lc++]="	maxFramesPerHostBuffer = (maxFramesPerHostBuffer + 7) & ~7;";
  z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: maxFramesPerHostBuffer = %d\\n\", maxFramesPerHostBuffer ));";
  z[lc++]="/* Determine number of user buffers based on minimum latency. */";
  z[lc++]="	minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );";
  z[lc++]="	past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;";
  z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: min past_NumUserBuffers = %d\\n\", past->past_NumUserBuffers ));";
  z[lc++]="	minTotalFrames = past->past_NumUserBuffers * past->past_FramesPerUserBuffer;";
  z[lc++]="/* We cannot make the WAVE buffers too small because they may not get serviced quickly enough. */";
  z[lc++]="	if( (int) past->past_FramesPerUserBuffer < minFramesPerHostBuffer )";
  z[lc++]="	{";
  z[lc++]="		userBuffersPerHostBuffer =";
  z[lc++]="			(minFramesPerHostBuffer + past->past_FramesPerUserBuffer - 1) /";
  z[lc++]="			past->past_FramesPerUserBuffer;";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="		userBuffersPerHostBuffer = 1;";
  z[lc++]="	}";
  z[lc++]="	framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;";
  z[lc++]="/* Calculate number of WAVE buffers needed. Round up to cover minTotalFrames. */";
  z[lc++]="	numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;";
  z[lc++]="/* Make sure we have anough WAVE buffers. */";
  z[lc++]="	if( numHostBuffers < PA_MIN_NUM_HOST_BUFFERS)";
  z[lc++]="	{";
  z[lc++]="		numHostBuffers = PA_MIN_NUM_HOST_BUFFERS;";
  z[lc++]="	}";
  z[lc++]="	else if( (numHostBuffers > PA_MAX_NUM_HOST_BUFFERS) && ";
  z[lc++]="	         ((int) past->past_FramesPerUserBuffer < (maxFramesPerHostBuffer/2) ) )";
  z[lc++]="	{";
  z[lc++]="/* If we have too many WAVE buffers, try to put more user buffers in a wave buffer. */";
  z[lc++]="		while(numHostBuffers > PA_MAX_NUM_HOST_BUFFERS)";
  z[lc++]="		{";
  z[lc++]="			userBuffersPerHostBuffer += 1;";
  z[lc++]="			framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;";
  z[lc++]="			numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;";
  z[lc++]="	/* If we have gone too far, back up one. */";
  z[lc++]="			if( (framesPerHostBuffer > maxFramesPerHostBuffer) ||";
  z[lc++]="				(numHostBuffers < PA_MAX_NUM_HOST_BUFFERS) )";
  z[lc++]="			{";
  z[lc++]="				userBuffersPerHostBuffer -= 1;";
  z[lc++]="				framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;";
  z[lc++]="				numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;";
  z[lc++]="				break;";
  z[lc++]="			}";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="	pahsc->pahsc_UserBuffersPerHostBuffer = userBuffersPerHostBuffer;";
  z[lc++]="	pahsc->pahsc_FramesPerHostBuffer = framesPerHostBuffer;";
  z[lc++]="	pahsc->pahsc_NumHostBuffers = numHostBuffers;";
  z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: pahsc_UserBuffersPerHostBuffer = %d\\n\", pahsc->pahsc_UserBuffersPerHostBuffer ));";
  z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: pahsc_NumHostBuffers = %d\\n\", pahsc->pahsc_NumHostBuffers ));";
  z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: pahsc_FramesPerHostBuffer = %d\\n\", pahsc->pahsc_FramesPerHostBuffer ));";
  z[lc++]="	DBUG((\"PaHost_CalcNumHostBuffers: past_NumUserBuffers = %d\\n\", past->past_NumUserBuffers ));";
  z[lc++]="}";
  z[lc++]="/*******************************************************************/";
  z[lc++]="PaError PaHost_OpenStream( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaError             result = paNoError;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="/* Allocate and initialize host data. */";
  z[lc++]="	pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); /* MEM */";
  z[lc++]="	if( pahsc == NULL )";
  z[lc++]="	{";
  z[lc++]="		result = paInsufficientMemory;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="	memset( pahsc, 0, sizeof(PaHostSoundControl) );";
  z[lc++]="	past->past_DeviceData = (void *) pahsc;";
  z[lc++]="/* Figure out how user buffers fit into WAVE buffers. */";
  z[lc++]="	PaHost_CalcNumHostBuffers( past );";
  z[lc++]="	{";
  z[lc++]="		int msecLatency = (int) ((PaHost_GetTotalBufferFrames(past) * 1000) / past->past_SampleRate);";
  z[lc++]="		DBUG((\"PortAudio on WMME - Latency = %d frames, %d msec\\n\", PaHost_GetTotalBufferFrames(past), msecLatency ));";
  z[lc++]="	}";
  z[lc++]="    InitializeCriticalSection( &pahsc->pahsc_StreamLock );";
  z[lc++]="    pahsc->pahsc_StreamLockInited = 1;";
  z[lc++]="	";
  z[lc++]="#if (PA_USE_TIMER_CALLBACK == 0)";
  z[lc++]="    pahsc->pahsc_BufferEventInited = 0;";
  z[lc++]="    pahsc->pahsc_BufferEvent = CreateEvent( NULL, FALSE, FALSE, NULL );";
  z[lc++]="    if( pahsc->pahsc_BufferEvent == NULL ){";
  z[lc++]="        result = paHostError;";
  z[lc++]="        sPaHostError = GetLastError();";
  z[lc++]="        goto error;";
  z[lc++]="    }";
  z[lc++]="    pahsc->pahsc_BufferEventInited = 1;";
  z[lc++]="#endif /* (PA_USE_TIMER_CALLBACK == 0) */";
  z[lc++]="/* ------------------ OUTPUT */";
  z[lc++]="	pahsc->pahsc_BytesPerUserOutputBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels * sizeof(short);";
  z[lc++]="	pahsc->pahsc_BytesPerHostOutputBuffer = pahsc->pahsc_UserBuffersPerHostBuffer * pahsc->pahsc_BytesPerUserOutputBuffer;";
  z[lc++]="	if( (past->past_OutputDeviceID != paNoDevice) && (past->past_NumOutputChannels > 0) )";
  z[lc++]="	{";
  z[lc++]="		result = PaHost_OpenOutputStream( past );";
  z[lc++]="		if( result < 0 ) goto error;";
  z[lc++]="	}";
  z[lc++]="/* ------------------ INPUT */";
  z[lc++]="	pahsc->pahsc_BytesPerUserInputBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels * sizeof(short);";
  z[lc++]="	pahsc->pahsc_BytesPerHostInputBuffer = pahsc->pahsc_UserBuffersPerHostBuffer * pahsc->pahsc_BytesPerUserInputBuffer;";
  z[lc++]="	if( (past->past_InputDeviceID != paNoDevice) && (past->past_NumInputChannels > 0) )";
  z[lc++]="	{";
  z[lc++]="		result = PaHost_OpenInputStream( past );";
  z[lc++]="		if( result < 0 ) goto error;";
  z[lc++]="	}";
  z[lc++]="/* Calculate scalar used in CPULoad calculation. */ ";
  z[lc++]="	{";
  z[lc++]="		LARGE_INTEGER frequency;";
  z[lc++]="		if( QueryPerformanceFrequency( &frequency ) == 0 )";
  z[lc++]="		{";
  z[lc++]="			pahsc->pahsc_InverseTicksPerHostBuffer = 0.0;";
  z[lc++]="		}";
  z[lc++]="		else";
  z[lc++]="		{";
  z[lc++]="			pahsc->pahsc_InverseTicksPerHostBuffer = past->past_SampleRate /";
  z[lc++]="				( (double)frequency.QuadPart * past->past_FramesPerUserBuffer * pahsc->pahsc_UserBuffersPerHostBuffer );";
  z[lc++]="			DBUG((\"pahsc_InverseTicksPerHostBuffer = %g\\n\", pahsc->pahsc_InverseTicksPerHostBuffer ));";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	return result;";
  z[lc++]="error:";
  z[lc++]="	PaHost_CloseStream( past );";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StartOutput( internalPortAudioStream *past )";
  z[lc++]="{";
  z[lc++]="	MMRESULT         mr;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	PaError          result = paNoError;";
  z[lc++]="	int              i;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="    if( past->past_OutputDeviceID != paNoDevice )";
  z[lc++]="	{";
  z[lc++]="        if( (mr = waveOutPause( pahsc->pahsc_HWaveOut )) != MMSYSERR_NOERROR )";
  z[lc++]="		{";
  z[lc++]="			result = paHostError;";
  z[lc++]="			sPaHostError = mr;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="        for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
  z[lc++]="		{";
  z[lc++]="            ZeroMemory( pahsc->pahsc_OutputBuffers[i].lpData, pahsc->pahsc_OutputBuffers[i].dwBufferLength );";
  z[lc++]="            mr = waveOutWrite( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) );";
  z[lc++]="			if( mr != MMSYSERR_NOERROR )";
  z[lc++]="			{";
  z[lc++]="				result = paHostError;";
  z[lc++]="				sPaHostError = mr;";
  z[lc++]="				goto error;";
  z[lc++]="			}";
  z[lc++]="			past->past_FrameCount += pahsc->pahsc_FramesPerHostBuffer;";
  z[lc++]="        }";
  z[lc++]="        pahsc->pahsc_CurrentOutputBuffer = 0;";
  z[lc++]="		if( (mr = waveOutRestart( pahsc->pahsc_HWaveOut )) != MMSYSERR_NOERROR )";
  z[lc++]="		{";
  z[lc++]="			result = paHostError;";
  z[lc++]="			sPaHostError = mr;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	DBUG((\"PaHost_StartOutput: DSW_StartOutput returned = 0x%X.\\n\", hr));";
  z[lc++]="error:";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StartInput( internalPortAudioStream *past )";
  z[lc++]="{";
  z[lc++]="	PaError          result = paNoError;";
  z[lc++]="	MMRESULT         mr;";
  z[lc++]="	int              i;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="    if( past->past_InputDeviceID != paNoDevice )";
  z[lc++]="    {";
  z[lc++]="        for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
  z[lc++]="		{";
  z[lc++]="            mr = waveInAddBuffer( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) );";
  z[lc++]="			if( mr != MMSYSERR_NOERROR )";
  z[lc++]="			{";
  z[lc++]="				result = paHostError;";
  z[lc++]="				sPaHostError = mr;";
  z[lc++]="				goto error;";
  z[lc++]="			}";
  z[lc++]="        }";
  z[lc++]="        pahsc->pahsc_CurrentInputBuffer = 0;";
  z[lc++]="		mr = waveInStart( pahsc->pahsc_HWaveIn );";
  z[lc++]="		DBUG((\"Pa_StartStream: waveInStart returned = 0x%X.\\n\", hr));";
  z[lc++]="		if( mr != MMSYSERR_NOERROR )";
  z[lc++]="		{";
  z[lc++]="			result = paHostError;";
  z[lc++]="			sPaHostError = mr;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="error:";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StartEngine( internalPortAudioStream *past )";
  z[lc++]="{";
  z[lc++]="	PaError             result = paNoError;";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="#if PA_USE_TIMER_CALLBACK";
  z[lc++]="	int                 resolution;";
  z[lc++]="	int                 bufsPerTimerCallback;";
  z[lc++]="	int                 msecPerBuffer;";
  z[lc++]="#endif /* PA_USE_TIMER_CALLBACK */";
  z[lc++]="	";
  z[lc++]="    past->past_StopSoon = 0;";
  z[lc++]="    past->past_StopNow = 0;";
  z[lc++]="	past->past_IsActive = 1;";
  z[lc++]="	pahsc->pahsc_FramesPlayed = 0.0;";
  z[lc++]="	pahsc->pahsc_LastPosition = 0;";
  z[lc++]="#if PA_TRACE_START_STOP";
  z[lc++]="    AddTraceMessage( \"PaHost_StartEngine: TimeSlice() returned \", result );";
  z[lc++]="#endif";
  z[lc++]="#if PA_USE_TIMER_CALLBACK";
  z[lc++]="/* Create timer that will wake us up so we can fill the DSound buffer. */";
  z[lc++]="	bufsPerTimerCallback = pahsc->pahsc_NumHostBuffers/4;";
  z[lc++]="	if( bufsPerTimerCallback < 1 ) bufsPerTimerCallback = 1;";
  z[lc++]="	if( bufsPerTimerCallback < 1 ) bufsPerTimerCallback = 1;";
  z[lc++]="	msecPerBuffer = (1000 * bufsPerTimerCallback *";
  z[lc++]="		pahsc->pahsc_UserBuffersPerHostBuffer *";
  z[lc++]="		past->past_FramesPerUserBuffer ) / (int) past->past_SampleRate;";
  z[lc++]="	if( msecPerBuffer < 10 ) msecPerBuffer = 10;";
  z[lc++]="	else if( msecPerBuffer > 100 ) msecPerBuffer = 100;";
  z[lc++]="	resolution = msecPerBuffer/4;";
  z[lc++]="	pahsc->pahsc_TimerID = timeSetEvent( msecPerBuffer, resolution,";
  z[lc++]="	                                     (LPTIMECALLBACK) Pa_TimerCallback,";
  z[lc++]="	                                     (DWORD) past, TIME_PERIODIC );";
  z[lc++]="	if( pahsc->pahsc_TimerID == 0 )";
  z[lc++]="	{";
  z[lc++]="		result = paHostError;";
  z[lc++]="		sPaHostError = GetLastError();;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="#else /* PA_USE_TIMER_CALLBACK */";
  z[lc++]="	ResetEvent( pahsc->pahsc_AbortEvent );";
  z[lc++]="/* Create thread that waits for audio buffers to be ready for processing. */";
  z[lc++]="	pahsc->pahsc_EngineThread = CreateThread( 0, 0, WinMMPa_OutputThreadProc, past, 0, &pahsc->pahsc_EngineThreadID );";
  z[lc++]="	if( pahsc->pahsc_EngineThread == NULL )";
  z[lc++]="	{";
  z[lc++]="		result = paHostError;";
  z[lc++]="		sPaHostError = GetLastError();;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="#if PA_TRACE_START_STOP";
  z[lc++]="    AddTraceMessage( \"PaHost_StartEngine: thread \", (int) pahsc->pahsc_EngineThread );";
  z[lc++]="#endif";
  z[lc++]="/* I used to pass the thread which was failing. I now pass GetCurrentProcess().";
  z[lc++]="** This fix could improve latency for some applications. It could also result in CPU";
  z[lc++]="** starvation if the callback did too much processing.";
  z[lc++]="** I also added result checks, so we might see more failures at initialization.";
  z[lc++]="** Thanks to Alberto di Bene for spotting this.";
  z[lc++]="*/";
  z[lc++]="    if( !SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) ) /* PLB20010816 */";
  z[lc++]="	{";
  z[lc++]="		result = paHostError;";
  z[lc++]="		sPaHostError = GetLastError();;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="    if( !SetThreadPriority( pahsc->pahsc_EngineThread, THREAD_PRIORITY_HIGHEST ) )";
  z[lc++]="	{";
  z[lc++]="		result = paHostError;";
  z[lc++]="		sPaHostError = GetLastError();;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="#endif";
  z[lc++]="error:";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )";
  z[lc++]="{";
  z[lc++]="	int timeOut;";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paNoError;";
  z[lc++]="/* Tell background thread to stop generating more data and to let current data play out. */";
  z[lc++]="	past->past_StopSoon = 1;";
  z[lc++]="/* If aborting, tell background thread to stop NOW! */";
  z[lc++]="	if( abort ) past->past_StopNow = 1;";
  z[lc++]="/* Calculate timeOut longer than longest time it could take to play all buffers. */";
  z[lc++]="	timeOut = (DWORD) (1500.0 * PaHost_GetTotalBufferFrames( past ) / past->past_SampleRate);";
  z[lc++]="	if( timeOut < MIN_TIMEOUT_MSEC ) timeOut = MIN_TIMEOUT_MSEC;";
  z[lc++]="#if PA_USE_TIMER_CALLBACK";
  z[lc++]="	if( (past->past_OutputDeviceID != paNoDevice) &&";
  z[lc++]="		past->past_IsActive &&";
  z[lc++]="		(pahsc->pahsc_TimerID != 0) )";
  z[lc++]="	{";
  z[lc++]="	/* Wait for IsActive to drop. */";
  z[lc++]="		while( (past->past_IsActive) &&	(timeOut > 0) )";
  z[lc++]="		{";
  z[lc++]="			Sleep(10);";
  z[lc++]="			timeOut -= 10;";
  z[lc++]="		}";
  z[lc++]="		timeKillEvent(pahsc->pahsc_TimerID);  /* Stop callback timer. */";
  z[lc++]="		pahsc->pahsc_TimerID = 0;";
  z[lc++]="	}";
  z[lc++]="#else /* PA_USE_TIMER_CALLBACK */";
  z[lc++]="#if PA_TRACE_START_STOP";
  z[lc++]="    AddTraceMessage( \"PaHost_StopEngine: thread \", (int) pahsc->pahsc_EngineThread );";
  z[lc++]="#endif";
  z[lc++]="    if( (past->past_OutputDeviceID != paNoDevice) &&";
  z[lc++]="		(past->past_IsActive) &&";
  z[lc++]="		(pahsc->pahsc_EngineThread != NULL) )";
  z[lc++]="	{";
  z[lc++]="		DWORD got;";
  z[lc++]="/* Tell background thread to stop generating more data and to let current data play out. */";
  z[lc++]="		DBUG((\"PaHost_StopEngine: waiting for background thread.\\n\"));";
  z[lc++]="        got = WaitForSingleObject( pahsc->pahsc_EngineThread, timeOut );";
  z[lc++]="		if( got == WAIT_TIMEOUT )";
  z[lc++]="		{";
  z[lc++]="			ERR_RPT((\"PaHost_StopEngine: timed out while waiting for background thread.\\n\"));";
  z[lc++]="			return paTimedOut;";
  z[lc++]="		}";
  z[lc++]="		CloseHandle( pahsc->pahsc_EngineThread );";
  z[lc++]="		pahsc->pahsc_EngineThread = NULL;";
  z[lc++]="    }";
  z[lc++]="#endif /* PA_USE_TIMER_CALLBACK */";
  z[lc++]="	past->past_IsActive = 0;";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StopInput( internalPortAudioStream *past, int abort )";
  z[lc++]="{";
  z[lc++]="	MMRESULT mr;";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paNoError;";
  z[lc++]="	(void) abort;";
  z[lc++]="    if( pahsc->pahsc_HWaveIn != NULL )";
  z[lc++]="	{";
  z[lc++]="		mr = waveInReset( pahsc->pahsc_HWaveIn );";
  z[lc++]="		if( mr != MMSYSERR_NOERROR )";
  z[lc++]="		{";
  z[lc++]="			sPaHostError = mr;";
  z[lc++]="			return paHostError;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )";
  z[lc++]="{";
  z[lc++]="	MMRESULT mr;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paNoError;";
  z[lc++]="	(void) abort;";
  z[lc++]="#if PA_TRACE_START_STOP";
  z[lc++]="    AddTraceMessage( \"PaHost_StopOutput: pahsc_HWaveOut \", (int) pahsc->pahsc_HWaveOut );";
  z[lc++]="#endif";
  z[lc++]="   if( pahsc->pahsc_HWaveOut != NULL )";
  z[lc++]="	{";
  z[lc++]="		mr = waveOutReset( pahsc->pahsc_HWaveOut );";
  z[lc++]="		if( mr != MMSYSERR_NOERROR )";
  z[lc++]="		{";
  z[lc++]="			sPaHostError = mr;";
  z[lc++]="			return paHostError;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="/*******************************************************************/";
  z[lc++]="PaError PaHost_CloseStream( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	int                 i;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paNoError;";
  z[lc++]="#if PA_TRACE_START_STOP";
  z[lc++]="    AddTraceMessage( \"PaHost_CloseStream: pahsc_HWaveOut \", (int) pahsc->pahsc_HWaveOut );";
  z[lc++]="#endif";
  z[lc++]="/* Free data and device for output. */";
  z[lc++]="    if( pahsc->pahsc_HWaveOut )";
  z[lc++]="	{";
  z[lc++]="        if( pahsc->pahsc_OutputBuffers )";
  z[lc++]="		{";
  z[lc++]="            for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
  z[lc++]="			{";
  z[lc++]="                waveOutUnprepareHeader( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) );";
  z[lc++]="                GlobalFree( pahsc->pahsc_OutputBuffers[i].lpData ); /* MEM */";
  z[lc++]="            }";
  z[lc++]="            GlobalFree( pahsc->pahsc_OutputBuffers ); /* MEM */";
  z[lc++]="        }";
  z[lc++]="        waveOutClose( pahsc->pahsc_HWaveOut );";
  z[lc++]="    }";
  z[lc++]=" /* Free data and device for input. */";
  z[lc++]="   if( pahsc->pahsc_HWaveIn )";
  z[lc++]="	{";
  z[lc++]="        if( pahsc->pahsc_InputBuffers )";
  z[lc++]="		{";
  z[lc++]="            for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )";
  z[lc++]="			{";
  z[lc++]="                waveInUnprepareHeader( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) );";
  z[lc++]="                GlobalFree( pahsc->pahsc_InputBuffers[i].lpData ); /* MEM */";
  z[lc++]="            }";
  z[lc++]="            GlobalFree( pahsc->pahsc_InputBuffers ); /* MEM */";
  z[lc++]="        }";
  z[lc++]="        waveInClose( pahsc->pahsc_HWaveIn );";
  z[lc++]="    }";
  z[lc++]="#if (PA_USE_TIMER_CALLBACK == 0)";
  z[lc++]="    if( pahsc->pahsc_AbortEventInited ) CloseHandle( pahsc->pahsc_AbortEvent );";
  z[lc++]="    if( pahsc->pahsc_BufferEventInited ) CloseHandle( pahsc->pahsc_BufferEvent );";
  z[lc++]="#endif";
  z[lc++]="	if( pahsc->pahsc_StreamLockInited )";
  z[lc++]="	DeleteCriticalSection( &pahsc->pahsc_StreamLock );";
  z[lc++]="	PaHost_FreeFastMemory( pahsc, sizeof(PaHostSoundControl) ); /* MEM */";
  z[lc++]="	past->past_DeviceData = NULL;";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************";
  z[lc++]="** Determine minimum number of buffers required for this host based";
  z[lc++]="** on minimum latency. Latency can be optionally set by user by setting";
  z[lc++]="** an environment variable. For example, to set latency to 200 msec, put:";
  z[lc++]="**";
  z[lc++]="**    set PA_MIN_LATENCY_MSEC=200";
  z[lc++]="**";
  z[lc++]="** in the AUTOEXEC.BAT file and reboot.";
  z[lc++]="** If the environment variable is not set, then the latency will be determined";
  z[lc++]="** based on the OS. Windows NT has higher latency than Win95.";
  z[lc++]="*/";
  z[lc++]="#define PA_LATENCY_ENV_NAME  (\"PA_MIN_LATENCY_MSEC\")";
  z[lc++]="int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )";
  z[lc++]="{";
  z[lc++]="	char      envbuf[PA_ENV_BUF_SIZE];";
  z[lc++]="	DWORD     hostVersion;";
  z[lc++]="	DWORD     hresult;";
  z[lc++]="	int       minLatencyMsec = 0;";
  z[lc++]="	double    msecPerBuffer = (1000.0 * framesPerBuffer) / sampleRate;";
  z[lc++]="	int       minBuffers;";
  z[lc++]="/* Let user determine minimal latency by setting environment variable. */";
  z[lc++]="	hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );";
  z[lc++]="	if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )";
  z[lc++]="	{";
  z[lc++]="		minLatencyMsec = atoi( envbuf );";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="/* Set minimal latency based on whether NT or Win95.";
  z[lc++]=" * NT has higher latency.";
  z[lc++]=" */";
  z[lc++]="		hostVersion = GetVersion();";
  z[lc++]="/* High bit clear if NT */";
  z[lc++]="		minLatencyMsec = ( (hostVersion & 0x80000000) == 0 ) ? PA_WIN_NT_LATENCY : PA_WIN_9X_LATENCY  ;";
  z[lc++]="#if PA_USE_HIGH_LATENCY";
  z[lc++]="		PRINT((\"PA - Minimum Latency set to %d msec!\\n\", minLatencyMsec ));";
  z[lc++]="#endif";
  z[lc++]="	}";
  z[lc++]="	DBUG((\"PA - Minimum Latency set to %d msec!\\n\", minLatencyMsec ));";
  z[lc++]="	minBuffers = (int) (1.0 + ((double)minLatencyMsec / msecPerBuffer));";
  z[lc++]="	if( minBuffers < 2 ) minBuffers = 2;";
  z[lc++]="	return minBuffers;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************";
  z[lc++]="** Cleanup device info.";
  z[lc++]="*/";
  z[lc++]="PaError PaHost_Term( void )";
  z[lc++]="{";
  z[lc++]="    int i;";
  z[lc++]="    if( sNumDevices > 0 ){";
  z[lc++]="        if( sDevicePtrs != NULL ){";
  z[lc++]="            for( i=0; i<sNumDevices; i++ )";
  z[lc++]="			{";
  z[lc++]="                if( sDevicePtrs[i] != NULL )";
  z[lc++]="				{";
  z[lc++]="                    GlobalFree( (char*)sDevicePtrs[i]->name ); /* MEM */";
  z[lc++]="                    GlobalFree( (void*)sDevicePtrs[i]->sampleRates ); /* MEM */";
  z[lc++]="                    GlobalFree( sDevicePtrs[i] ); /* MEM */";
  z[lc++]="                }";
  z[lc++]="            }";
  z[lc++]="            GlobalFree( sDevicePtrs ); /* MEM */";
  z[lc++]="            sDevicePtrs = NULL;";
  z[lc++]="        }";
  z[lc++]="        sNumDevices = 0;";
  z[lc++]="    }";
  z[lc++]="    return paNoError;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="void Pa_Sleep( long msec )";
  z[lc++]="{";
  z[lc++]="	Sleep( msec );";
  z[lc++]="}";
  z[lc++]="/*************************************************************************";
  z[lc++]=" * Allocate memory that can be accessed in real-time.";
  z[lc++]=" * This may need to be held in physical memory so that it is not";
  z[lc++]=" * paged to virtual memory.";
  z[lc++]=" * This call MUST be balanced with a call to PaHost_FreeFastMemory().";
  z[lc++]=" * Memory will be set to zero.";
  z[lc++]=" */";
  z[lc++]="void *PaHost_AllocateFastMemory( long numBytes )";
  z[lc++]="{";
  z[lc++]="	void *addr = GlobalAlloc( GPTR, numBytes ); /* FIXME - do we need physical memory? Use VirtualLock() */ /* MEM */";
  z[lc++]="	return addr;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************";
  z[lc++]=" * Free memory that could be accessed in real-time.";
  z[lc++]=" * This call MUST be balanced with a call to PaHost_AllocateFastMemory().";
  z[lc++]=" */";
  z[lc++]="void PaHost_FreeFastMemory( void *addr, long numBytes )";
  z[lc++]="{";
  z[lc++]="	if( addr != NULL ) GlobalFree( addr ); /* MEM */";
  z[lc++]="}";
  z[lc++]="/***********************************************************************/";
  z[lc++]="PaError PaHost_StreamActive( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paInternalError;";
  z[lc++]="	return (PaError) past->past_IsActive;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************";
  z[lc++]=" * This must be called periodically because mmtime.u.sample";
  z[lc++]=" * is a DWORD and can wrap and lose sync after a few hours.";
  z[lc++]=" */";
  z[lc++]="static PaError PaHost_UpdateStreamTime( PaHostSoundControl *pahsc )";
  z[lc++]="{";
  z[lc++]="	MMRESULT  mr;";
  z[lc++]="	MMTIME    mmtime;";
  z[lc++]="	mmtime.wType = TIME_SAMPLES;";
  z[lc++]="	if( pahsc->pahsc_HWaveOut != NULL )";
  z[lc++]="	{";
  z[lc++]="		mr = waveOutGetPosition( pahsc->pahsc_HWaveOut, &mmtime, sizeof(mmtime) );";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="		mr = waveInGetPosition( pahsc->pahsc_HWaveIn, &mmtime, sizeof(mmtime) );";
  z[lc++]="	}";
  z[lc++]="	if( mr != MMSYSERR_NOERROR )";
  z[lc++]="	{";
  z[lc++]="		sPaHostError = mr;";
  z[lc++]="		return paHostError;";
  z[lc++]="	}";
  z[lc++]="/* This data has two variables and is shared by foreground and background. */";
  z[lc++]="/* So we need to make it thread safe. */";
  z[lc++]="	EnterCriticalSection( &pahsc->pahsc_StreamLock );";
  z[lc++]="		pahsc->pahsc_FramesPlayed += ((long)mmtime.u.sample) - pahsc->pahsc_LastPosition;";
  z[lc++]="		pahsc->pahsc_LastPosition = (long)mmtime.u.sample;";
  z[lc++]="    LeaveCriticalSection( &pahsc->pahsc_StreamLock );";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaTimestamp Pa_StreamTime( PortAudioStream *stream )";
  z[lc++]="{";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	internalPortAudioStream   *past = (internalPortAudioStream *) stream;";
  z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	PaHost_UpdateStreamTime( pahsc );";
  z[lc++]="	return pahsc->pahsc_FramesPlayed;";
  z[lc++]="}";
  printlib(lc);
}


void makepa_dshdr(void)
{
  int lc = 0;

  z[lc++]="#ifndef __DSOUND_WRAPPER_H";
  z[lc++]="#define __DSOUND_WRAPPER_H";
  z[lc++]="/*";
  z[lc++]=" * Simplified DirectSound interface.";
  z[lc++]=" *";
  z[lc++]=" * Author: Phil Burk & Robert Marsanyi";
  z[lc++]=" *";
  z[lc++]=" * For PortAudio Portable Real-Time Audio Library";
  z[lc++]=" * For more information see: http://www.softsynth.com/portaudio/";
  z[lc++]=" * DirectSound Implementation";
  z[lc++]=" * Copyright (c) 1999-2000 Phil Burk & Robert Marsanyi";
  z[lc++]=" *";
  z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
  z[lc++]=" * a copy of this software and associated documentation files";
  z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
  z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
  z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
  z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
  z[lc++]=" * subject to the following conditions:";
  z[lc++]=" *";
  z[lc++]=" * The above copyright notice and this permission notice shall be";
  z[lc++]=" * included in all copies or substantial portions of the Software.";
  z[lc++]=" *";
  z[lc++]=" * Any person wishing to distribute modifications to the Software is";
  z[lc++]=" * requested to send the modifications to the original developer so that";
  z[lc++]=" * they can be incorporated into the canonical version.";
  z[lc++]=" *";
  z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
  z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
  z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
  z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
  z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
  z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
  z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
  z[lc++]=" *";
  z[lc++]=" */";
  z[lc++]="#include <DSound.h>";
  z[lc++]="#if !defined(BOOL)";
  z[lc++]="#define BOOL short";
  z[lc++]="#endif";
  z[lc++]="#ifndef SUPPORT_AUDIO_CAPTURE";
  z[lc++]="#define SUPPORT_AUDIO_CAPTURE  (1)";
  z[lc++]="#endif";
  z[lc++]="#ifdef __cplusplus";
  z[lc++]="extern \"C\" {";
  z[lc++]="#endif /* __cplusplus */	";
  z[lc++]="#define DSW_NUM_POSITIONS     (4)";
  z[lc++]="#define DSW_NUM_EVENTS        (5)";
  z[lc++]="#define DSW_TERMINATION_EVENT     (DSW_NUM_POSITIONS)";
  z[lc++]="typedef struct";
  z[lc++]="{";
  z[lc++]="/* Output */";
  z[lc++]="	LPDIRECTSOUND        dsw_pDirectSound;";
  z[lc++]="	LPDIRECTSOUNDBUFFER  dsw_OutputBuffer;";
  z[lc++]="	DWORD                dsw_WriteOffset;     /* last write position */";
  z[lc++]="	INT                  dsw_OutputSize;";
  z[lc++]="	INT                  dsw_BytesPerFrame;";
  z[lc++]="/* Try to detect play buffer underflows. */";
  z[lc++]="	LARGE_INTEGER        dsw_CounterTicksPerBuffer; /* counter ticks it should take to play a full buffer */";
  z[lc++]="	LARGE_INTEGER        dsw_LastPlayTime;";
  z[lc++]="	UINT                 dsw_LastPlayCursor;";
  z[lc++]="	UINT                 dsw_OutputUnderflows;";
  z[lc++]="	BOOL                 dsw_OutputRunning;";
  z[lc++]="/* use double which lets us can play for several thousand years with enough precision */";
  z[lc++]="	double               dsw_FramesWritten;";
  z[lc++]="	double               dsw_FramesPlayed;";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="	/* Input */";
  z[lc++]="	LPDIRECTSOUNDCAPTURE dsw_pDirectSoundCapture;";
  z[lc++]="	LPDIRECTSOUNDCAPTUREBUFFER   dsw_InputBuffer;";
  z[lc++]="	UINT                 dsw_ReadOffset;      /* last read position */";
  z[lc++]="	UINT                 dsw_InputSize;";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="} DSoundWrapper;";
  z[lc++]="HRESULT DSW_Init( DSoundWrapper *dsw );";
  z[lc++]="void DSW_Term( DSoundWrapper *dsw );";
  z[lc++]="HRESULT DSW_InitOutputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate,";
  z[lc++]="							 int nChannels, int bufSize );";
  z[lc++]="HRESULT DSW_StartOutput( DSoundWrapper *dsw );";
  z[lc++]="HRESULT DSW_StopOutput( DSoundWrapper *dsw );";
  z[lc++]="DWORD   DSW_GetOutputStatus( DSoundWrapper *dsw );";
  z[lc++]="HRESULT DSW_WriteBlock( DSoundWrapper *dsw, char *buf, long numBytes );";
  z[lc++]="HRESULT DSW_ZeroEmptySpace( DSoundWrapper *dsw );";
  z[lc++]="HRESULT DSW_QueryOutputSpace( DSoundWrapper *dsw, long *bytesEmpty );";
  z[lc++]="HRESULT DSW_Enumerate( DSoundWrapper *dsw );";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="HRESULT DSW_InitInputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate,";
  z[lc++]="							 int nChannels, int bufSize );";
  z[lc++]="HRESULT DSW_StartInput( DSoundWrapper *dsw );";
  z[lc++]="HRESULT DSW_StopInput( DSoundWrapper *dsw );";
  z[lc++]="HRESULT DSW_ReadBlock( DSoundWrapper *dsw, char *buf, long numBytes );";
  z[lc++]="HRESULT DSW_QueryInputFilled( DSoundWrapper *dsw, long *bytesFilled );";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="#ifdef __cplusplus";
  z[lc++]="}";
  z[lc++]="#endif /* __cplusplus */";
  z[lc++]="#endif  /* __DSOUND_WRAPPER_H */";
  printlib(lc);
}


void makepa_dswrap(void)
{
  int lc = 0;

  z[lc++]="/*";
  z[lc++]=" * Simplified DirectSound interface.";
  z[lc++]=" *";
  z[lc++]=" * Author: Phil Burk & Robert Marsanyi";
  z[lc++]=" *";
  z[lc++]=" * PortAudio Portable Real-Time Audio Library";
  z[lc++]=" * For more information see: http://www.softsynth.com/portaudio/";
  z[lc++]=" * DirectSound Implementation";
  z[lc++]=" * Copyright (c) 1999-2000 Phil Burk & Robert Marsanyi";
  z[lc++]=" *";
  z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
  z[lc++]=" * a copy of this software and associated documentation files";
  z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
  z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
  z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
  z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
  z[lc++]=" * subject to the following conditions:";
  z[lc++]=" *";
  z[lc++]=" * The above copyright notice and this permission notice shall be";
  z[lc++]=" * included in all copies or substantial portions of the Software.";
  z[lc++]=" *";
  z[lc++]=" * Any person wishing to distribute modifications to the Software is";
  z[lc++]=" * requested to send the modifications to the original developer so that";
  z[lc++]=" * they can be incorporated into the canonical version.";
  z[lc++]=" *";
  z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
  z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
  z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
  z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
  z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
  z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
  z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
  z[lc++]=" *";
  z[lc++]=" */";
  z[lc++]="#include <stdio.h>";
  z[lc++]="#include <stdlib.h>";
  z[lc++]="#include <math.h>";
  z[lc++]="#define INITGUID     // Needed to build IID_IDirectSoundNotify. See objbase.h for info.";
  z[lc++]="#include <objbase.h>";
  z[lc++]="#include <unknwn.h>";
  z[lc++]="#if 0";
  z[lc++]="#include \"dsound_wrapper.h\"";
  z[lc++]="#include \"pa_trace.h\"";
  z[lc++]="#endif";
  z[lc++]="/************************************************************************************/";
  z[lc++]="void DSW_Term( DSoundWrapper *dsw )";
  z[lc++]="{";
  z[lc++]="// Cleanup the sound buffers";
  z[lc++]="	if (dsw->dsw_OutputBuffer)";
  z[lc++]="	{";
  z[lc++]="		IDirectSoundBuffer_Stop( dsw->dsw_OutputBuffer );";
  z[lc++]="		IDirectSoundBuffer_Release( dsw->dsw_OutputBuffer );";
  z[lc++]="		dsw->dsw_OutputBuffer = NULL;";
  z[lc++]="	}";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="	if (dsw->dsw_InputBuffer)";
  z[lc++]="	{";
  z[lc++]="		IDirectSoundCaptureBuffer_Stop( dsw->dsw_InputBuffer );";
  z[lc++]="		IDirectSoundCaptureBuffer_Release( dsw->dsw_InputBuffer );";
  z[lc++]="		dsw->dsw_InputBuffer = NULL;";
  z[lc++]="	}";
  z[lc++]="	if (dsw->dsw_pDirectSoundCapture)";
  z[lc++]="	{";
  z[lc++]="		IDirectSoundCapture_Release( dsw->dsw_pDirectSoundCapture );";
  z[lc++]="		dsw->dsw_pDirectSoundCapture = NULL;";
  z[lc++]="	}";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="	if (dsw->dsw_pDirectSound)";
  z[lc++]="	{";
  z[lc++]="		IDirectSound_Release( dsw->dsw_pDirectSound );";
  z[lc++]="		dsw->dsw_pDirectSound = NULL;";
  z[lc++]="	}";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_Init( DSoundWrapper *dsw )";
  z[lc++]="{";
  z[lc++]="	memset( dsw, 0, sizeof(DSoundWrapper) );";
  z[lc++]="	return 0;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_InitOutputDevice( DSoundWrapper *dsw, LPGUID lpGUID )";
  z[lc++]="{";
  z[lc++]="// Create the DS object";
  z[lc++]="	HRESULT hr = DirectSoundCreate( lpGUID, &dsw->dsw_pDirectSound, NULL );";
  z[lc++]="	if( hr != DS_OK ) return hr;";
  z[lc++]="	return hr;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_InitOutputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate, int nChannels, int bytesPerBuffer )";
  z[lc++]="{";
  z[lc++]="	DWORD          dwDataLen;";
  z[lc++]="	DWORD          playCursor;";
  z[lc++]="	HRESULT        result;";
  z[lc++]="	LPDIRECTSOUNDBUFFER pPrimaryBuffer;";
  z[lc++]="	HWND           hWnd;";
  z[lc++]="	HRESULT        hr;";
  z[lc++]="	WAVEFORMATEX   wfFormat;";
  z[lc++]="	DSBUFFERDESC   primaryDesc;";
  z[lc++]="	DSBUFFERDESC   secondaryDesc;";
  z[lc++]="	unsigned char* pDSBuffData;";
  z[lc++]="	LARGE_INTEGER  counterFrequency;";
  z[lc++]="	dsw->dsw_OutputSize = bytesPerBuffer;";
  z[lc++]="	dsw->dsw_OutputRunning = FALSE;";
  z[lc++]="	dsw->dsw_OutputUnderflows = 0;";
  z[lc++]="	dsw->dsw_FramesWritten = 0;";
  z[lc++]="	dsw->dsw_BytesPerFrame = nChannels * sizeof(short);";
  z[lc++]="// We were using getForegroundWindow() but sometimes the ForegroundWindow may not be the";
  z[lc++]="// applications's window. Also if that window is closed before the Buffer is closed";
  z[lc++]="// then DirectSound can crash. (Thanks for Scott Patterson for reporting this.)";
  z[lc++]="// So we will use GetDesktopWindow() which was suggested by Miller Puckette.";
  z[lc++]="//	hWnd = GetForegroundWindow();";
  z[lc++]="	hWnd = GetDesktopWindow();";
  z[lc++]="// Set cooperative level to DSSCL_EXCLUSIVE so that we can get 16 bit output, 44.1 KHz.";
  z[lc++]="// Exclusize also prevents unexpected sounds from other apps during a performance.";
  z[lc++]="	if ((hr = IDirectSound_SetCooperativeLevel( dsw->dsw_pDirectSound,";
  z[lc++]="			hWnd, DSSCL_EXCLUSIVE)) != DS_OK)";
  z[lc++]="	{";
  z[lc++]="		return hr;";
  z[lc++]="	}";
  z[lc++]="// -----------------------------------------------------------------------";
  z[lc++]="// Create primary buffer and set format just so we can specify our custom format.";
  z[lc++]="// Otherwise we would be stuck with the default which might be 8 bit or 22050 Hz.";
  z[lc++]="// Setup the primary buffer description";
  z[lc++]="	ZeroMemory(&primaryDesc, sizeof(DSBUFFERDESC));";
  z[lc++]="	primaryDesc.dwSize        = sizeof(DSBUFFERDESC);";
  z[lc++]="	primaryDesc.dwFlags       = DSBCAPS_PRIMARYBUFFER; // all panning, mixing, etc done by synth";
  z[lc++]="	primaryDesc.dwBufferBytes = 0;";
  z[lc++]="	primaryDesc.lpwfxFormat   = NULL;";
  z[lc++]="// Create the buffer";
  z[lc++]="	if ((result = IDirectSound_CreateSoundBuffer( dsw->dsw_pDirectSound,";
  z[lc++]="			&primaryDesc, &pPrimaryBuffer, NULL)) != DS_OK) return result;";
  z[lc++]="// Define the buffer format";
  z[lc++]="	wfFormat.wFormatTag = WAVE_FORMAT_PCM;";
  z[lc++]="	wfFormat.nChannels = nChannels;";
  z[lc++]="	wfFormat.nSamplesPerSec = nFrameRate;";
  z[lc++]="	wfFormat.wBitsPerSample = 8 * sizeof(short);";
  z[lc++]="	wfFormat.nBlockAlign = wfFormat.nChannels * wfFormat.wBitsPerSample / 8;";
  z[lc++]="	wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;";
  z[lc++]="	wfFormat.cbSize = 0;  /* No extended format info. */";
  z[lc++]="// Set the primary buffer's format";
  z[lc++]="	if((result = IDirectSoundBuffer_SetFormat( pPrimaryBuffer, &wfFormat)) != DS_OK) return result;";
  z[lc++]="// ----------------------------------------------------------------------";
  z[lc++]="// Setup the secondary buffer description";
  z[lc++]="	ZeroMemory(&secondaryDesc, sizeof(DSBUFFERDESC));";
  z[lc++]="	secondaryDesc.dwSize = sizeof(DSBUFFERDESC);";
  z[lc++]="	secondaryDesc.dwFlags =  DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;";
  z[lc++]="	secondaryDesc.dwBufferBytes = bytesPerBuffer;";
  z[lc++]="	secondaryDesc.lpwfxFormat = &wfFormat;";
  z[lc++]="// Create the secondary buffer";
  z[lc++]="	if ((result = IDirectSound_CreateSoundBuffer( dsw->dsw_pDirectSound,";
  z[lc++]="			&secondaryDesc, &dsw->dsw_OutputBuffer, NULL)) != DS_OK) return result;";
  z[lc++]="// Lock the DS buffer";
  z[lc++]="	if ((result = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, 0, dsw->dsw_OutputSize, (LPVOID*)&pDSBuffData,";
  z[lc++]="	  &dwDataLen, NULL, 0, 0)) != DS_OK) return result;";
  z[lc++]="// Zero the DS buffer";
  z[lc++]="	ZeroMemory(pDSBuffData, dwDataLen);";
  z[lc++]="// Unlock the DS buffer";
  z[lc++]="	if ((result = IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) return result;";
  z[lc++]="	if( QueryPerformanceFrequency( &counterFrequency ) )";
  z[lc++]="	{";
  z[lc++]="		int framesInBuffer = bytesPerBuffer / (nChannels * sizeof(short));";
  z[lc++]="		dsw->dsw_CounterTicksPerBuffer.QuadPart = (counterFrequency.QuadPart * framesInBuffer) / nFrameRate;";
  z[lc++]="		AddTraceMessage(\"dsw_CounterTicksPerBuffer = %d\\n\", dsw->dsw_CounterTicksPerBuffer.LowPart );";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="		dsw->dsw_CounterTicksPerBuffer.QuadPart = 0;";
  z[lc++]="	}";
  z[lc++]="// Let DSound set the starting write position because if we set it to zero, it looks like the";
  z[lc++]="// buffer is full to begin with. This causes a long pause before sound starts when using large buffers.";
  z[lc++]="	hr = IDirectSoundBuffer_GetCurrentPosition( dsw->dsw_OutputBuffer, &playCursor, &dsw->dsw_WriteOffset );";
  z[lc++]="	if( hr != DS_OK )";
  z[lc++]="	{";
  z[lc++]="		return hr;";
  z[lc++]="	}";
  z[lc++]="	dsw->dsw_FramesWritten = dsw->dsw_WriteOffset / dsw->dsw_BytesPerFrame;";
  z[lc++]="	/* printf(\"DSW_InitOutputBuffer: playCursor = %d, writeCursor = %d\\n\", playCursor, dsw->dsw_WriteOffset ); */";
  z[lc++]="	return DS_OK;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_StartOutput( DSoundWrapper *dsw )";
  z[lc++]="{";
  z[lc++]="	HRESULT        hr;";
  z[lc++]="	QueryPerformanceCounter( &dsw->dsw_LastPlayTime );";
  z[lc++]="	dsw->dsw_LastPlayCursor = 0;";
  z[lc++]="	dsw->dsw_FramesPlayed = 0;";
  z[lc++]="	hr = IDirectSoundBuffer_SetCurrentPosition( dsw->dsw_OutputBuffer, 0 );";
  z[lc++]="	if( hr != DS_OK )";
  z[lc++]="	{";
  z[lc++]="		return hr;";
  z[lc++]="	}";
  z[lc++]="// Start the buffer playback in a loop.";
  z[lc++]="	if( dsw->dsw_OutputBuffer != NULL )";
  z[lc++]="	{";
  z[lc++]="		hr = IDirectSoundBuffer_Play( dsw->dsw_OutputBuffer, 0, 0, DSBPLAY_LOOPING );";
  z[lc++]="		if( hr != DS_OK )";
  z[lc++]="		{";
  z[lc++]="			return hr;";
  z[lc++]="		}";
  z[lc++]="		dsw->dsw_OutputRunning = TRUE;";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="	return 0;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_StopOutput( DSoundWrapper *dsw )";
  z[lc++]="{";
  z[lc++]="// Stop the buffer playback";
  z[lc++]="	if( dsw->dsw_OutputBuffer != NULL )";
  z[lc++]="	{";
  z[lc++]="		dsw->dsw_OutputRunning = FALSE;";
  z[lc++]="		return IDirectSoundBuffer_Stop( dsw->dsw_OutputBuffer );";
  z[lc++]="	}";
  z[lc++]="	else return 0;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_QueryOutputSpace( DSoundWrapper *dsw, long *bytesEmpty )";
  z[lc++]="{";
  z[lc++]="	HRESULT hr;";
  z[lc++]="	DWORD   playCursor;";
  z[lc++]="	DWORD   writeCursor;";
  z[lc++]="	long    numBytesEmpty;";
  z[lc++]="	long    playWriteGap;";
  z[lc++]="// Query to see how much room is in buffer.";
  z[lc++]="// Note: Even though writeCursor is not used, it must be passed to prevent DirectSound from dieing";
  z[lc++]="// under WinNT. The Microsoft documentation says we can pass NULL but apparently not.";
  z[lc++]="// Thanks to Max Rheiner for the fix.";
  z[lc++]="	hr = IDirectSoundBuffer_GetCurrentPosition( dsw->dsw_OutputBuffer, &playCursor, &writeCursor );";
  z[lc++]="	if( hr != DS_OK )";
  z[lc++]="	{";
  z[lc++]="		return hr;";
  z[lc++]="	}";
  z[lc++]="	AddTraceMessage(\"playCursor\", playCursor);";
  z[lc++]="	AddTraceMessage(\"dsw_WriteOffset\", dsw->dsw_WriteOffset);";
  z[lc++]="// Determine size of gap between playIndex and WriteIndex that we cannot write into.";
  z[lc++]="	playWriteGap = writeCursor - playCursor;";
  z[lc++]="	if( playWriteGap < 0 ) playWriteGap += dsw->dsw_OutputSize; // unwrap";
  z[lc++]="/* DirectSound doesn't have a large enough playCursor so we cannot detect wrap-around. */";
  z[lc++]="/* Attempt to detect playCursor wrap-around and correct it. */";
  z[lc++]="	if( dsw->dsw_OutputRunning && (dsw->dsw_CounterTicksPerBuffer.QuadPart != 0) )";
  z[lc++]="	{";
  z[lc++]="/* How much time has elapsed since last check. */";
  z[lc++]="		LARGE_INTEGER   currentTime;";
  z[lc++]="		LARGE_INTEGER   elapsedTime;";
  z[lc++]="		long            bytesPlayed;";
  z[lc++]="		long            bytesExpected;";
  z[lc++]="		long            buffersWrapped;";
  z[lc++]="		QueryPerformanceCounter( &currentTime );";
  z[lc++]="		elapsedTime.QuadPart = currentTime.QuadPart - dsw->dsw_LastPlayTime.QuadPart;";
  z[lc++]="		dsw->dsw_LastPlayTime = currentTime;";
  z[lc++]="/* How many bytes does DirectSound say have been played. */";
  z[lc++]="		bytesPlayed = playCursor - dsw->dsw_LastPlayCursor;";
  z[lc++]="		if( bytesPlayed < 0 ) bytesPlayed += dsw->dsw_OutputSize; // unwrap";
  z[lc++]="		dsw->dsw_LastPlayCursor = playCursor;";
  z[lc++]="/* Calculate how many bytes we would have expected to been played by now. */";
  z[lc++]="		bytesExpected = (long) ((elapsedTime.QuadPart * dsw->dsw_OutputSize) / dsw->dsw_CounterTicksPerBuffer.QuadPart);";
  z[lc++]="		buffersWrapped = (bytesExpected - bytesPlayed) / dsw->dsw_OutputSize;";
  z[lc++]="		if( buffersWrapped > 0 )";
  z[lc++]="		{";
  z[lc++]="			AddTraceMessage(\"playCursor wrapped! bytesPlayed\", bytesPlayed );";
  z[lc++]="			AddTraceMessage(\"playCursor wrapped! bytesExpected\", bytesExpected );";
  z[lc++]="			playCursor += (buffersWrapped * dsw->dsw_OutputSize);";
  z[lc++]="			bytesPlayed += (buffersWrapped * dsw->dsw_OutputSize);";
  z[lc++]="		}";
  z[lc++]="	/* Maintain frame output cursor. */";
  z[lc++]="		dsw->dsw_FramesPlayed += (bytesPlayed / dsw->dsw_BytesPerFrame);";
  z[lc++]="	}";
  z[lc++]="	numBytesEmpty = playCursor - dsw->dsw_WriteOffset;";
  z[lc++]="	if( numBytesEmpty < 0 ) numBytesEmpty += dsw->dsw_OutputSize; // unwrap offset";
  z[lc++]="/* Have we underflowed? */";
  z[lc++]="	if( numBytesEmpty > (dsw->dsw_OutputSize - playWriteGap) )";
  z[lc++]="	{";
  z[lc++]="		if( dsw->dsw_OutputRunning )";
  z[lc++]="		{";
  z[lc++]="			dsw->dsw_OutputUnderflows += 1;";
  z[lc++]="			AddTraceMessage(\"underflow detected! numBytesEmpty\", numBytesEmpty );";
  z[lc++]="		}";
  z[lc++]="		dsw->dsw_WriteOffset = writeCursor;";
  z[lc++]="		numBytesEmpty = dsw->dsw_OutputSize - playWriteGap;";
  z[lc++]="	}";
  z[lc++]="	*bytesEmpty = numBytesEmpty;";
  z[lc++]="	return hr;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_ZeroEmptySpace( DSoundWrapper *dsw )";
  z[lc++]="{";
  z[lc++]="	HRESULT hr;";
  z[lc++]="	LPBYTE lpbuf1 = NULL;";
  z[lc++]="	LPBYTE lpbuf2 = NULL;";
  z[lc++]="	DWORD dwsize1 = 0;";
  z[lc++]="	DWORD dwsize2 = 0;";
  z[lc++]="	long  bytesEmpty;";
  z[lc++]="	hr = DSW_QueryOutputSpace( dsw, &bytesEmpty ); // updates dsw_FramesPlayed";
  z[lc++]="	if (hr != DS_OK) return hr;";
  z[lc++]="	if( bytesEmpty == 0 ) return DS_OK;";
  z[lc++]="	// Lock free space in the DS";
  z[lc++]="	hr = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, dsw->dsw_WriteOffset, bytesEmpty, (void **) &lpbuf1, &dwsize1,";
  z[lc++]="		(void **) &lpbuf2, &dwsize2, 0);";
  z[lc++]="	if (hr == DS_OK)";
  z[lc++]="	{";
  z[lc++]="		// Copy the buffer into the DS";
  z[lc++]="		ZeroMemory(lpbuf1, dwsize1);";
  z[lc++]="		if(lpbuf2 != NULL)";
  z[lc++]="		{";
  z[lc++]="			ZeroMemory(lpbuf2, dwsize2);";
  z[lc++]="		}";
  z[lc++]="		// Update our buffer offset and unlock sound buffer";
  z[lc++]=" 		dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + dwsize1 + dwsize2) % dsw->dsw_OutputSize;";
  z[lc++]="		IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);";
  z[lc++]="		dsw->dsw_FramesWritten += bytesEmpty / dsw->dsw_BytesPerFrame;";
  z[lc++]="	}";
  z[lc++]="	return hr;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_WriteBlock( DSoundWrapper *dsw, char *buf, long numBytes )";
  z[lc++]="{";
  z[lc++]="	HRESULT hr;";
  z[lc++]="	LPBYTE lpbuf1 = NULL;";
  z[lc++]="	LPBYTE lpbuf2 = NULL;";
  z[lc++]="	DWORD dwsize1 = 0;";
  z[lc++]="	DWORD dwsize2 = 0;";
  z[lc++]="	// Lock free space in the DS";
  z[lc++]="	hr = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, dsw->dsw_WriteOffset, numBytes, (void **) &lpbuf1, &dwsize1,";
  z[lc++]="		(void **) &lpbuf2, &dwsize2, 0);";
  z[lc++]="	if (hr == DS_OK)";
  z[lc++]="	{";
  z[lc++]="		// Copy the buffer into the DS";
  z[lc++]="		CopyMemory(lpbuf1, buf, dwsize1);";
  z[lc++]="		if(lpbuf2 != NULL)";
  z[lc++]="		{";
  z[lc++]="			CopyMemory(lpbuf2, buf+dwsize1, dwsize2);";
  z[lc++]="		}";
  z[lc++]="		// Update our buffer offset and unlock sound buffer";
  z[lc++]=" 		dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + dwsize1 + dwsize2) % dsw->dsw_OutputSize;";
  z[lc++]="		IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);";
  z[lc++]="		dsw->dsw_FramesWritten += numBytes / dsw->dsw_BytesPerFrame;";
  z[lc++]="	}";
  z[lc++]="	return hr;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="DWORD DSW_GetOutputStatus( DSoundWrapper *dsw )";
  z[lc++]="{";
  z[lc++]="	DWORD status;";
  z[lc++]="	if (IDirectSoundBuffer_GetStatus( dsw->dsw_OutputBuffer, &status ) != DS_OK)";
  z[lc++]="		return( DSERR_INVALIDPARAM );";
  z[lc++]="	else";
  z[lc++]="		return( status );";
  z[lc++]="}";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="/* These routines are used to support audio input.";
  z[lc++]=" * Do NOT compile these calls when using NT4 because it does";
  z[lc++]=" * not support the entry points.";
  z[lc++]=" */";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_InitInputDevice( DSoundWrapper *dsw, LPGUID lpGUID )";
  z[lc++]="{";
  z[lc++]="	HRESULT hr = DirectSoundCaptureCreate(  lpGUID, &dsw->dsw_pDirectSoundCapture,   NULL );";
  z[lc++]="	if( hr != DS_OK ) return hr;";
  z[lc++]="	return hr;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_InitInputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate, int nChannels, int bytesPerBuffer )";
  z[lc++]="{";
  z[lc++]="	DSCBUFFERDESC  captureDesc;";
  z[lc++]="	WAVEFORMATEX   wfFormat;";
  z[lc++]="	HRESULT        result;";
  z[lc++]="// Define the buffer format";
  z[lc++]="	wfFormat.wFormatTag      = WAVE_FORMAT_PCM;";
  z[lc++]="	wfFormat.nChannels       = nChannels;";
  z[lc++]="	wfFormat.nSamplesPerSec  = nFrameRate;";
  z[lc++]="	wfFormat.wBitsPerSample  = 8 * sizeof(short);";
  z[lc++]="	wfFormat.nBlockAlign     = wfFormat.nChannels * (wfFormat.wBitsPerSample / 8);";
  z[lc++]="	wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;";
  z[lc++]="	wfFormat.cbSize          = 0;   /* No extended format info. */";
  z[lc++]="	dsw->dsw_InputSize = bytesPerBuffer;";
  z[lc++]="// ----------------------------------------------------------------------";
  z[lc++]="// Setup the secondary buffer description";
  z[lc++]="	ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC));";
  z[lc++]="	captureDesc.dwSize = sizeof(DSCBUFFERDESC);";
  z[lc++]="	captureDesc.dwFlags =  0;";
  z[lc++]="	captureDesc.dwBufferBytes = bytesPerBuffer;";
  z[lc++]="	captureDesc.lpwfxFormat = &wfFormat;";
  z[lc++]="	// Create the capture buffer";
  z[lc++]="	if ((result = IDirectSoundCapture_CreateCaptureBuffer( dsw->dsw_pDirectSoundCapture,";
  z[lc++]="		&captureDesc, &dsw->dsw_InputBuffer, NULL)) != DS_OK) return result;";
  z[lc++]="	dsw->dsw_ReadOffset = 0;  // reset last read position to start of buffer";
  z[lc++]="	return DS_OK;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_StartInput( DSoundWrapper *dsw )";
  z[lc++]="{";
  z[lc++]="// Start the buffer playback";
  z[lc++]="	if( dsw->dsw_InputBuffer != NULL )";
  z[lc++]="	{";
  z[lc++]="		return IDirectSoundCaptureBuffer_Start( dsw->dsw_InputBuffer, DSCBSTART_LOOPING );";
  z[lc++]="	}";
  z[lc++]="	else return 0;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_StopInput( DSoundWrapper *dsw )";
  z[lc++]="{";
  z[lc++]="// Stop the buffer playback";
  z[lc++]="	if( dsw->dsw_InputBuffer != NULL )";
  z[lc++]="	{";
  z[lc++]="		return IDirectSoundCaptureBuffer_Stop( dsw->dsw_InputBuffer );";
  z[lc++]="	}";
  z[lc++]="	else return 0;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_QueryInputFilled( DSoundWrapper *dsw, long *bytesFilled )";
  z[lc++]="{";
  z[lc++]="	HRESULT hr;";
  z[lc++]="	DWORD capturePos;";
  z[lc++]="	DWORD readPos;";
  z[lc++]="	long  filled;";
  z[lc++]="// Query to see how much data is in buffer.";
  z[lc++]="// We don't need the capture position but sometimes DirectSound doesn't handle NULLS correctly";
  z[lc++]="// so let's pass a pointer just to be safe.";
  z[lc++]="	hr = IDirectSoundCaptureBuffer_GetCurrentPosition( dsw->dsw_InputBuffer, &capturePos, &readPos );";
  z[lc++]="	if( hr != DS_OK )";
  z[lc++]="	{";
  z[lc++]="		return hr;";
  z[lc++]="	}";
  z[lc++]="	filled = readPos - dsw->dsw_ReadOffset;";
  z[lc++]="	if( filled < 0 ) filled += dsw->dsw_InputSize; // unwrap offset";
  z[lc++]="	*bytesFilled = filled;";
  z[lc++]="	return hr;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="HRESULT DSW_ReadBlock( DSoundWrapper *dsw, char *buf, long numBytes )";
  z[lc++]="{";
  z[lc++]="	HRESULT hr;";
  z[lc++]="	LPBYTE lpbuf1 = NULL;";
  z[lc++]="	LPBYTE lpbuf2 = NULL;";
  z[lc++]="	DWORD dwsize1 = 0;";
  z[lc++]="	DWORD dwsize2 = 0;";
  z[lc++]="	// Lock free space in the DS";
  z[lc++]="	hr = IDirectSoundCaptureBuffer_Lock ( dsw->dsw_InputBuffer, dsw->dsw_ReadOffset, numBytes, (void **) &lpbuf1, &dwsize1,";
  z[lc++]="		(void **) &lpbuf2, &dwsize2, 0);";
  z[lc++]="	if (hr == DS_OK)";
  z[lc++]="	{";
  z[lc++]="		// Copy from DS to the buffer";
  z[lc++]="		CopyMemory( buf, lpbuf1, dwsize1);";
  z[lc++]="		if(lpbuf2 != NULL)";
  z[lc++]="		{";
  z[lc++]="			CopyMemory( buf+dwsize1, lpbuf2, dwsize2);";
  z[lc++]="		}";
  z[lc++]="		// Update our buffer offset and unlock sound buffer";
  z[lc++]=" 		dsw->dsw_ReadOffset = (dsw->dsw_ReadOffset + dwsize1 + dwsize2) % dsw->dsw_InputSize;";
  z[lc++]="		IDirectSoundCaptureBuffer_Unlock ( dsw->dsw_InputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);";
  z[lc++]="	}";
  z[lc++]="	return hr;";
  z[lc++]="}";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  printlib(lc);
}


void makepa_dsound(void)
{
  int lc = 0;

  z[lc++]="/*";
  z[lc++]=" * PortAudio Portable Real-Time Audio Library";
  z[lc++]=" * Latest Version at: http://www.softsynth.com/portaudio/";
  z[lc++]=" * DirectSound Implementation";
  z[lc++]=" *";
  z[lc++]=" * Copyright (c) 1999-2000 Phil Burk";
  z[lc++]=" *";
  z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining";
  z[lc++]=" * a copy of this software and associated documentation files";
  z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,";
  z[lc++]=" * including without limitation the rights to use, copy, modify, merge,";
  z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,";
  z[lc++]=" * and to permit persons to whom the Software is furnished to do so,";
  z[lc++]=" * subject to the following conditions:";
  z[lc++]=" *";
  z[lc++]=" * The above copyright notice and this permission notice shall be";
  z[lc++]=" * included in all copies or substantial portions of the Software.";
  z[lc++]=" *";
  z[lc++]=" * Any person wishing to distribute modifications to the Software is";
  z[lc++]=" * requested to send the modifications to the original developer so that";
  z[lc++]=" * they can be incorporated into the canonical version.";
  z[lc++]=" *";
  z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,";
  z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF";
  z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.";
  z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR";
  z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF";
  z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION";
  z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.";
  z[lc++]=" *";
  z[lc++]=" */";
  z[lc++]="/* Modifications";
  z[lc++]=" *    7/19/01 Mike Berry - casts for compiling with __MWERKS__ CodeWarrior";
  z[lc++]=" *    9/27/01 Phil Burk - use number of frames instead of real-time for CPULoad calculation.";
  z[lc++]=" */";
  z[lc++]="/* Compiler flags:";
  z[lc++]="	SUPPORT_AUDIO_CAPTURE - define this flag if you want to SUPPORT_AUDIO_CAPTURE";
  z[lc++]=" */";
  z[lc++]="#include <stdio.h>";
  z[lc++]="#include <stdlib.h>";
  z[lc++]="#ifndef __MWERKS__";
  z[lc++]="#include <malloc.h>";
  z[lc++]="#include <memory.h>";
  z[lc++]="#endif //__MWERKS__";
  z[lc++]="#include <math.h>";
  z[lc++]="#if 0";
  z[lc++]="#include \"portaudio.h\"";
  z[lc++]="#include \"pa_host.h\"";
  z[lc++]="#include \"pa_trace.h\"";
  z[lc++]="#include \"dsound_wrapper.h\"";
  z[lc++]="#endif";
  z[lc++]="#define PRINT(x) { printf x; fflush(stdout); }";
  z[lc++]="#define ERR_RPT(x) PRINT(x)";
  z[lc++]="#define DBUG(x)  /* PRINT(x) */";
  z[lc++]="#define DBUGX(x) /* PRINT(x) */";
  z[lc++]="#define PA_USE_HIGH_LATENCY   (0)";
  z[lc++]="#if PA_USE_HIGH_LATENCY";
  z[lc++]="#define PA_WIN_9X_LATENCY     (500)";
  z[lc++]="#define PA_WIN_NT_LATENCY     (600)";
  z[lc++]="#else";
  z[lc++]="#define PA_WIN_9X_LATENCY     (140)";
  z[lc++]="#define PA_WIN_NT_LATENCY     (280)";
  z[lc++]="#endif";
  z[lc++]="/* Trigger an underflow for testing purposes. Should normally be (0). */";
  z[lc++]="#define PA_SIMULATE_UNDERFLOW (0)";
  z[lc++]="#if PA_SIMULATE_UNDERFLOW";
  z[lc++]="static  gUnderCallbackCounter = 0;";
  z[lc++]="#define UNDER_START_GAP       (10)";
  z[lc++]="#define UNDER_STOP_GAP        (UNDER_START_GAP + 4)";
  z[lc++]="#endif";
  z[lc++]="/************************************************* Definitions ********/";
  z[lc++]="typedef struct internalPortAudioStream internalPortAudioStream;";
  z[lc++]="typedef struct internalPortAudioDevice";
  z[lc++]="{";
  z[lc++]="	GUID                             pad_GUID;";
  z[lc++]="	GUID                            *pad_lpGUID;";
  z[lc++]="	double                           pad_SampleRates[10]; /* for pointing to from pad_Info FIXME?!*/";
  z[lc++]="	PaDeviceInfo                     pad_Info;";
  z[lc++]="} internalPortAudioDevice;";
  z[lc++]="/* Define structure to contain all DirectSound and Windows specific data. */";
  z[lc++]="typedef struct PaHostSoundControl";
  z[lc++]="{";
  z[lc++]="	DSoundWrapper    pahsc_DSoundWrapper;";
  z[lc++]="	MMRESULT         pahsc_TimerID;";
  z[lc++]="	BOOL             pahsc_IfInsideCallback;  /* Test for reentrancy. */";
  z[lc++]="	short           *pahsc_NativeBuffer;";
  z[lc++]="	unsigned int     pahsc_BytesPerBuffer;    /* native buffer size in bytes */";
  z[lc++]="	double           pahsc_ValidFramesWritten;";
  z[lc++]="	int              pahsc_FramesPerDSBuffer;";
  z[lc++]="/* For measuring CPU utilization. */";
  z[lc++]="	LARGE_INTEGER    pahsc_EntryCount;";
  z[lc++]="	double           pahsc_InverseTicksPerUserBuffer;";
  z[lc++]="} PaHostSoundControl;";
  z[lc++]="/************************************************* Shared Data ********/";
  z[lc++]="/* FIXME - put Mutex around this shared data. */";
  z[lc++]="static int sNumDevices = 0;";
  z[lc++]="static int sDeviceIndex = 0;";
  z[lc++]="static internalPortAudioDevice *sDevices = NULL;";
  z[lc++]="static int sDefaultInputDeviceID = paNoDevice;";
  z[lc++]="static int sDefaultOutputDeviceID = paNoDevice;";
  z[lc++]="static int sEnumerationError;";
  z[lc++]="static int sPaHostError = 0;";
  z[lc++]="/************************************************* Prototypes **********/";
  z[lc++]="static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id );";
  z[lc++]="static BOOL CALLBACK Pa_EnumProc(LPGUID lpGUID, ";
  z[lc++]="				         LPCTSTR lpszDesc,";
  z[lc++]="				         LPCTSTR lpszDrvName, ";
  z[lc++]="				         LPVOID lpContext );";
  z[lc++]="static BOOL CALLBACK Pa_CountDevProc(LPGUID lpGUID, ";
  z[lc++]="				         LPCTSTR lpszDesc,";
  z[lc++]="				         LPCTSTR lpszDrvName, ";
  z[lc++]="				         LPVOID lpContext );";
  z[lc++]="static Pa_QueryDevices( void );";
  z[lc++]="static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg,";
  z[lc++]="									  DWORD dwUser, DWORD dw1, DWORD dw2);";
  z[lc++]="/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/";
  z[lc++]="static void Pa_StartUsageCalculation( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return;";
  z[lc++]="/* Query system timer for usage analysis and to prevent overuse of CPU. */";
  z[lc++]="	QueryPerformanceCounter( &pahsc->pahsc_EntryCount );";
  z[lc++]="}";
  z[lc++]="static void Pa_EndUsageCalculation( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	LARGE_INTEGER CurrentCount = { 0, 0 };";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return;";
  z[lc++]="/*";
  z[lc++]="** Measure CPU utilization during this callback. Note that this calculation";
  z[lc++]="** assumes that we had the processor the whole time.";
  z[lc++]="*/";
  z[lc++]="#define LOWPASS_COEFFICIENT_0   (0.9)";
  z[lc++]="#define LOWPASS_COEFFICIENT_1   (0.99999 - LOWPASS_COEFFICIENT_0)";
  z[lc++]="	if( QueryPerformanceCounter( &CurrentCount ) )";
  z[lc++]="	{";
  z[lc++]="		LONGLONG InsideCount = CurrentCount.QuadPart - pahsc->pahsc_EntryCount.QuadPart;	";
  z[lc++]="		double newUsage = InsideCount * pahsc->pahsc_InverseTicksPerUserBuffer;";
  z[lc++]="		past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +";
  z[lc++]="			(LOWPASS_COEFFICIENT_1 * newUsage);";
  z[lc++]="	}";
  z[lc++]="}";
  z[lc++]="/****************************************** END CPU UTILIZATION *******/";
  z[lc++]="static PaError Pa_QueryDevices( void )";
  z[lc++]="{";
  z[lc++]="	int numBytes;";
  z[lc++]="	sDefaultInputDeviceID = paNoDevice;";
  z[lc++]="	sDefaultOutputDeviceID = paNoDevice;";
  z[lc++]="/* Enumerate once just to count devices. */";
  z[lc++]="	sNumDevices = 0; // for default device";
  z[lc++]="	DirectSoundEnumerate( (LPDSENUMCALLBACK)Pa_CountDevProc, NULL );";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="	DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)Pa_CountDevProc, NULL );";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="/* Allocate structures to hold device info. */";
  z[lc++]="	numBytes = sNumDevices * sizeof(internalPortAudioDevice);";
  z[lc++]="	sDevices = (internalPortAudioDevice *)PaHost_AllocateFastMemory( numBytes ); /* MEM */";
  z[lc++]="	if( sDevices == NULL ) return paInsufficientMemory;";
  z[lc++]="/* Enumerate again to fill in structures. */";
  z[lc++]="	sDeviceIndex = 0;";
  z[lc++]="	sEnumerationError = 0;";
  z[lc++]="	DirectSoundEnumerate( (LPDSENUMCALLBACK)Pa_EnumProc, (void *)0 );";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="	if( sEnumerationError != paNoError ) return sEnumerationError;";
  z[lc++]="	sEnumerationError = 0;";
  z[lc++]="	DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)Pa_EnumProc, (void *)1 );";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="	return sEnumerationError;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************/";
  z[lc++]="long Pa_GetHostError()";
  z[lc++]="{";
  z[lc++]="	return sPaHostError;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************";
  z[lc++]="** Just count devices so we know how much memory to allocate.";
  z[lc++]="*/";
  z[lc++]="static BOOL CALLBACK Pa_CountDevProc(LPGUID lpGUID, ";
  z[lc++]="				         LPCTSTR lpszDesc,";
  z[lc++]="				         LPCTSTR lpszDrvName, ";
  z[lc++]="				         LPVOID lpContext )";
  z[lc++]="{";
  z[lc++]="	sNumDevices++;";
  z[lc++]="	return TRUE;";
  z[lc++]="}";
  z[lc++]="/************************************************************************************";
  z[lc++]="** Extract capabilities info from each device.";
  z[lc++]="*/";
  z[lc++]="static BOOL CALLBACK Pa_EnumProc(LPGUID lpGUID, ";
  z[lc++]="				         LPCTSTR lpszDesc,";
  z[lc++]="				         LPCTSTR lpszDrvName, ";
  z[lc++]="				         LPVOID lpContext )";
  z[lc++]="{";
  z[lc++]="	HRESULT    hr;";
  z[lc++]="	LPDIRECTSOUND          lpDirectSound;";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="	LPDIRECTSOUNDCAPTURE   lpDirectSoundCapture;";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="	int        isInput  = (int) lpContext;  /* Passed from Pa_CountDevices() */";
  z[lc++]="	internalPortAudioDevice *pad;";
  z[lc++]="		";
  z[lc++]="	if( sDeviceIndex >= sNumDevices )";
  z[lc++]="	{";
  z[lc++]="		sEnumerationError = paInternalError;";
  z[lc++]="		return FALSE;";
  z[lc++]="	}";
  z[lc++]="	pad = &sDevices[sDeviceIndex];";
  z[lc++]="/* Copy GUID to static array. Set pointer. */";
  z[lc++]="	if( lpGUID == NULL )";
  z[lc++]="	{";
  z[lc++]="		pad->pad_lpGUID = NULL;";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="		memcpy( &pad->pad_GUID, lpGUID, sizeof(GUID) );";
  z[lc++]="		pad->pad_lpGUID = &pad->pad_GUID;";
  z[lc++]="	}";
  z[lc++]="	pad->pad_Info.sampleRates = pad->pad_SampleRates;  /* Point to array. */";
  z[lc++]="/* Allocate room for descriptive name. */";
  z[lc++]="	if( lpszDesc != NULL )";
  z[lc++]="	{";
  z[lc++]="		int len = strlen(lpszDesc);";
  z[lc++]="		pad->pad_Info.name = (char *)malloc( len+1 );";
  z[lc++]="		if( pad->pad_Info.name == NULL )";
  z[lc++]="		{";
  z[lc++]="			sEnumerationError = paInsufficientMemory;";
  z[lc++]="			return FALSE;";
  z[lc++]="		}";
  z[lc++]="		memcpy( (void *) pad->pad_Info.name, lpszDesc, len+1 );";
  z[lc++]="	}";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="	if( isInput )";
  z[lc++]="	{";
  z[lc++]="	/********** Input ******************************/";
  z[lc++]="		DSCCAPS     caps;";
  z[lc++]="		if( lpGUID == NULL ) sDefaultInputDeviceID = sDeviceIndex;";
  z[lc++]="		hr = DirectSoundCaptureCreate(  lpGUID, &lpDirectSoundCapture,   NULL );";
  z[lc++]="		if( hr != DS_OK )";
  z[lc++]="		{";
  z[lc++]="			pad->pad_Info.maxInputChannels = 0;";
  z[lc++]="			DBUG((\"Cannot create Capture for %s. Result = 0x%x\\n\", lpszDesc, hr ));";
  z[lc++]="		}";
  z[lc++]="		else";
  z[lc++]="		{";
  z[lc++]="	/* Query device characteristics. */";
  z[lc++]="			caps.dwSize = sizeof(caps);";
  z[lc++]="			IDirectSoundCapture_GetCaps( lpDirectSoundCapture, &caps );";
  z[lc++]="			/* printf(\"caps.dwFormats = 0x%x\\n\", caps.dwFormats ); */";
  z[lc++]="			pad->pad_Info.maxInputChannels = caps.dwChannels;";
  z[lc++]="	/* Determine sample rates from flags. */";
  z[lc++]="			if( caps.dwChannels == 2 )";
  z[lc++]="			{";
  z[lc++]="				int index = 0;";
  z[lc++]="				if( caps.dwFormats & WAVE_FORMAT_1S16) pad->pad_SampleRates[index++] = 11025.0;";
  z[lc++]="				if( caps.dwFormats & WAVE_FORMAT_2S16) pad->pad_SampleRates[index++] = 22050.0;";
  z[lc++]="				if( caps.dwFormats & WAVE_FORMAT_4S16) pad->pad_SampleRates[index++] = 44100.0;";
  z[lc++]="				pad->pad_Info.numSampleRates = index;";
  z[lc++]="			}";
  z[lc++]="			else if( caps.dwChannels == 1 )";
  z[lc++]="			{";
  z[lc++]="				int index = 0;";
  z[lc++]="				if( caps.dwFormats & WAVE_FORMAT_1M16) pad->pad_SampleRates[index++] = 11025.0;";
  z[lc++]="				if( caps.dwFormats & WAVE_FORMAT_2M16) pad->pad_SampleRates[index++] = 22050.0;";
  z[lc++]="				if( caps.dwFormats & WAVE_FORMAT_4M16) pad->pad_SampleRates[index++] = 44100.0;";
  z[lc++]="				pad->pad_Info.numSampleRates = index;";
  z[lc++]="			}";
  z[lc++]="			else pad->pad_Info.numSampleRates = 0;";
  z[lc++]="			IDirectSoundCapture_Release( lpDirectSoundCapture );";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="	{";
  z[lc++]="	/********** Output ******************************/";
  z[lc++]="		DSCAPS     caps;";
  z[lc++]="		if( lpGUID == NULL ) sDefaultOutputDeviceID = sDeviceIndex;";
  z[lc++]="	/* Create interfaces for each object. */";
  z[lc++]="		hr = DirectSoundCreate(  lpGUID, &lpDirectSound,   NULL );";
  z[lc++]="		if( hr != DS_OK )";
  z[lc++]="		{";
  z[lc++]="			pad->pad_Info.maxOutputChannels = 0;";
  z[lc++]="			DBUG((\"Cannot create dsound for %s. Result = 0x%x\\n\", lpszDesc, hr ));";
  z[lc++]="		}";
  z[lc++]="		else";
  z[lc++]="		{";
  z[lc++]="		/* Query device characteristics. */";
  z[lc++]="			caps.dwSize = sizeof(caps);";
  z[lc++]="			IDirectSound_GetCaps( lpDirectSound, &caps );";
  z[lc++]="			pad->pad_Info.maxOutputChannels = ( caps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1;";
  z[lc++]="		/* Get sample rates. */";
  z[lc++]="			pad->pad_SampleRates[0] = (double) caps.dwMinSecondarySampleRate;";
  z[lc++]="			pad->pad_SampleRates[1] = (double) caps.dwMaxSecondarySampleRate;";
  z[lc++]="			if( caps.dwFlags & DSCAPS_CONTINUOUSRATE ) pad->pad_Info.numSampleRates = -1;";
  z[lc++]="			else if( caps.dwMinSecondarySampleRate == caps.dwMaxSecondarySampleRate )";
  z[lc++]="			{";
  z[lc++]="				if( caps.dwMinSecondarySampleRate == 0 )";
  z[lc++]="				{";
  z[lc++]="			/*";
  z[lc++]="			** On my Thinkpad 380Z, DirectSoundV6 returns min-max=0 !!";
  z[lc++]="			** But it supports continuous sampling.";
  z[lc++]="			** So fake range of rates, and hope it really supports it.";
  z[lc++]="			*/";
  z[lc++]="					pad->pad_SampleRates[0] = 11025.0f;";
  z[lc++]="					pad->pad_SampleRates[1] = 48000.0f;";
  z[lc++]="					pad->pad_Info.numSampleRates = -1; /* continuous range */";
  z[lc++]="					";
  z[lc++]="					DBUG((\"PA - Reported rates both zero. Setting to fake values for device #%d\\n\", sDeviceIndex ));";
  z[lc++]="				}";
  z[lc++]="				else";
  z[lc++]="				{";
  z[lc++]="					pad->pad_Info.numSampleRates = 1;";
  z[lc++]="				}";
  z[lc++]="			}";
  z[lc++]="			else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) )";
  z[lc++]="			{";
  z[lc++]="			/* The EWS88MT drivers lie, lie, lie. The say they only support two rates, 100 & 100000.";
  z[lc++]="			** But we know that they really support a range of rates!";
  z[lc++]="			** So when we see a ridiculous set of rates, assume it is a range.";
  z[lc++]="			*/";
  z[lc++]="				pad->pad_Info.numSampleRates = -1;";
  z[lc++]="				DBUG((\"PA - Sample rate range used instead of two odd values for device #%d\\n\", sDeviceIndex ));";
  z[lc++]="			}";
  z[lc++]="			else pad->pad_Info.numSampleRates = 2;";
  z[lc++]="			IDirectSound_Release( lpDirectSound );";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	pad->pad_Info.nativeSampleFormats = paInt16;";
  z[lc++]="	sDeviceIndex++;";
  z[lc++]="	return( TRUE );";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="int Pa_CountDevices()";
  z[lc++]="{";
  z[lc++]="	if( sNumDevices <= 0 ) Pa_Initialize();";
  z[lc++]="	return sNumDevices;";
  z[lc++]="}";
  z[lc++]="static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id )";
  z[lc++]="{";
  z[lc++]="	if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;";
  z[lc++]="	return &sDevices[id];";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )";
  z[lc++]="{";
  z[lc++]="	internalPortAudioDevice *pad;";
  z[lc++]="	if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;";
  z[lc++]="	pad = Pa_GetInternalDevice( id );";
  z[lc++]="	return  &pad->pad_Info ;";
  z[lc++]="}";
  z[lc++]="static PaError Pa_MaybeQueryDevices( void )";
  z[lc++]="{";
  z[lc++]="	if( sNumDevices == 0 )";
  z[lc++]="	{";
  z[lc++]="		return Pa_QueryDevices();";
  z[lc++]="	}";
  z[lc++]="	return 0;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************";
  z[lc++]="** Returns recommended device ID.";
  z[lc++]="** On the PC, the recommended device can be specified by the user by";
  z[lc++]="** setting an environment variable. For example, to use device #1.";
  z[lc++]="**";
  z[lc++]="**    set PA_RECOMMENDED_OUTPUT_DEVICE=1";
  z[lc++]="**";
  z[lc++]="** The user should first determine the available device ID by using";
  z[lc++]="** the supplied application \"pa_devs\".";
  z[lc++]="*/";
  z[lc++]="#define PA_ENV_BUF_SIZE  (32)";
  z[lc++]="#define PA_REC_IN_DEV_ENV_NAME  (\"PA_RECOMMENDED_INPUT_DEVICE\")";
  z[lc++]="#define PA_REC_OUT_DEV_ENV_NAME  (\"PA_RECOMMENDED_OUTPUT_DEVICE\")";
  z[lc++]="static PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName )";
  z[lc++]="{";
  z[lc++]="	DWORD   hresult;";
  z[lc++]="	char    envbuf[PA_ENV_BUF_SIZE];";
  z[lc++]="	PaDeviceID recommendedID = paNoDevice;";
  z[lc++]="/* Let user determine default device by setting environment variable. */";
  z[lc++]="	hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE );";
  z[lc++]="	if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )";
  z[lc++]="	{";
  z[lc++]="		recommendedID = atoi( envbuf );";
  z[lc++]="	}";
  z[lc++]="	return recommendedID;";
  z[lc++]="}";
  z[lc++]="PaDeviceID Pa_GetDefaultInputDeviceID( void )";
  z[lc++]="{";
  z[lc++]="	PaError result;";
  z[lc++]="	result = PaHost_GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME );";
  z[lc++]="	if( result < 0 )";
  z[lc++]="	{";
  z[lc++]="		result = Pa_MaybeQueryDevices();";
  z[lc++]="		if( result < 0 ) return result;";
  z[lc++]="		result = sDefaultInputDeviceID;";
  z[lc++]="	}";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="PaDeviceID Pa_GetDefaultOutputDeviceID( void )";
  z[lc++]="{";
  z[lc++]="	PaError result;";
  z[lc++]="	result = PaHost_GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME );";
  z[lc++]="	if( result < 0 )";
  z[lc++]="	{";
  z[lc++]="		result = Pa_MaybeQueryDevices();";
  z[lc++]="		if( result < 0 ) return result;";
  z[lc++]="		result = sDefaultOutputDeviceID;";
  z[lc++]="	}";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/**********************************************************************";
  z[lc++]="** Make sure that we have queried the device capabilities.";
  z[lc++]="*/";
  z[lc++]="PaError PaHost_Init( void )";
  z[lc++]="{";
  z[lc++]="#if PA_SIMULATE_UNDERFLOW";
  z[lc++]="	PRINT((\"WARNING - Underflow Simulation Enabled - Expect a Big Glitch!!!\\n\"));";
  z[lc++]="#endif";
  z[lc++]="	return Pa_MaybeQueryDevices();";
  z[lc++]="}";
  z[lc++]="static PaError Pa_TimeSlice( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaError           result = 0;";
  z[lc++]="	long              bytesEmpty = 0;";
  z[lc++]="	long              bytesFilled = 0;";
  z[lc++]="	long              bytesToXfer = 0;";
  z[lc++]="	long              numChunks;";
  z[lc++]="	HRESULT           hresult;";
  z[lc++]="	PaHostSoundControl  *pahsc;";
  z[lc++]="	short            *nativeBufPtr;";
  z[lc++]="	past->past_NumCallbacks += 1;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paInternalError;";
  z[lc++]="/* How much input data is available? */";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="	if( past->past_NumInputChannels > 0 )";
  z[lc++]="	{";
  z[lc++]="		DSW_QueryInputFilled( &pahsc->pahsc_DSoundWrapper, &bytesFilled );";
  z[lc++]="		bytesToXfer = bytesFilled;";
  z[lc++]="	}";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="/* How much output room is available? */";
  z[lc++]="	if( past->past_NumOutputChannels > 0 )";
  z[lc++]="	{";
  z[lc++]="		DSW_QueryOutputSpace( &pahsc->pahsc_DSoundWrapper, &bytesEmpty );";
  z[lc++]="		bytesToXfer = bytesEmpty;";
  z[lc++]="	}";
  z[lc++]="	AddTraceMessage( \"bytesEmpty \", bytesEmpty );";
  z[lc++]="/* Choose smallest value if both are active. */";
  z[lc++]="	if( (past->past_NumInputChannels > 0) && (past->past_NumOutputChannels > 0) )";
  z[lc++]="	{";
  z[lc++]="		bytesToXfer = ( bytesFilled < bytesEmpty ) ? bytesFilled : bytesEmpty;";
  z[lc++]="	}";
  z[lc++]="/*	printf(\"bytesFilled = %d, bytesEmpty = %d, bytesToXfer = %d\\n\",";
  z[lc++]="		bytesFilled, bytesEmpty, bytesToXfer);";
  z[lc++]="*/";
  z[lc++]="/* Quantize to multiples of a buffer. */";
  z[lc++]="	numChunks = bytesToXfer / pahsc->pahsc_BytesPerBuffer;";
  z[lc++]="	if( numChunks > (long)(past->past_NumUserBuffers/2) )";
  z[lc++]="	{";
  z[lc++]="		numChunks = (long)past->past_NumUserBuffers/2;";
  z[lc++]="	}";
  z[lc++]="	else if( numChunks < 0 )";
  z[lc++]="	{";
  z[lc++]="		numChunks = 0;";
  z[lc++]="	}";
  z[lc++]="	AddTraceMessage( \"numChunks \", numChunks );";
  z[lc++]="	nativeBufPtr = pahsc->pahsc_NativeBuffer;";
  z[lc++]="	if( numChunks > 0 )";
  z[lc++]="	{";
  z[lc++]="		while( numChunks-- > 0 )";
  z[lc++]="		{";
  z[lc++]="		/* Measure usage based on time to process one user buffer. */";
  z[lc++]="			Pa_StartUsageCalculation( past );";
  z[lc++]="	#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="	/* Get native data from DirectSound. */";
  z[lc++]="			if( past->past_NumInputChannels > 0 )";
  z[lc++]="			{";
  z[lc++]="				hresult = DSW_ReadBlock( &pahsc->pahsc_DSoundWrapper, (char *) nativeBufPtr, pahsc->pahsc_BytesPerBuffer );";
  z[lc++]="				if( hresult < 0 )";
  z[lc++]="				{";
  z[lc++]="					ERR_RPT((\"DirectSound ReadBlock failed, hresult = 0x%x\\n\",hresult));";
  z[lc++]="					sPaHostError = hresult;";
  z[lc++]="					break;";
  z[lc++]="				}";
  z[lc++]="			}";
  z[lc++]="	#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="	/* Convert 16 bit native data to user data and call user routine. */";
  z[lc++]="			result = Pa_CallConvertInt16( past, nativeBufPtr, nativeBufPtr );";
  z[lc++]="			if( result != 0) break;";
  z[lc++]="	/* Pass native data to DirectSound. */";
  z[lc++]="			if( past->past_NumOutputChannels > 0 )";
  z[lc++]="			{";
  z[lc++]="			/*	static short DEBUGHACK = 0;";
  z[lc++]="				DEBUGHACK += 0x0049;";
  z[lc++]="				nativeBufPtr[0] = DEBUGHACK; /* Make buzz to see if DirectSound still running. */";
  z[lc++]="				hresult = DSW_WriteBlock( &pahsc->pahsc_DSoundWrapper, (char *) nativeBufPtr, pahsc->pahsc_BytesPerBuffer );";
  z[lc++]="				if( hresult < 0 )";
  z[lc++]="				{";
  z[lc++]="					ERR_RPT((\"DirectSound WriteBlock failed, result = 0x%x\\n\",hresult));";
  z[lc++]="					sPaHostError = hresult;";
  z[lc++]="					break;";
  z[lc++]="				}";
  z[lc++]="			}";
  z[lc++]="			Pa_EndUsageCalculation( past );";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/*******************************************************************/";
  z[lc++]="static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)";
  z[lc++]="{";
  z[lc++]="	internalPortAudioStream   *past;";
  z[lc++]="	PaHostSoundControl  *pahsc;";
  z[lc++]="#if PA_SIMULATE_UNDERFLOW";
  z[lc++]="	gUnderCallbackCounter++;";
  z[lc++]="	if( (gUnderCallbackCounter >= UNDER_START_GAP) &&";
  z[lc++]="		(gUnderCallbackCounter <= UNDER_STOP_GAP) )";
  z[lc++]="	{";
  z[lc++]="		if( gUnderCallbackCounter == UNDER_START_GAP)";
  z[lc++]="		{";
  z[lc++]="			AddTraceMessage(\"Begin stall: gUnderCallbackCounter =======\", gUnderCallbackCounter );";
  z[lc++]="		}";
  z[lc++]="		if( gUnderCallbackCounter == UNDER_STOP_GAP)";
  z[lc++]="		{";
  z[lc++]="			AddTraceMessage(\"End stall: gUnderCallbackCounter =======\", gUnderCallbackCounter );";
  z[lc++]="		}";
  z[lc++]="		return;";
  z[lc++]="	}";
  z[lc++]="#endif";
  z[lc++]="	past = (internalPortAudioStream *) dwUser;";
  z[lc++]="	if( past == NULL ) return;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return;";
  z[lc++]="	if( !pahsc->pahsc_IfInsideCallback && past->past_IsActive )";
  z[lc++]="	{";
  z[lc++]="		if( past->past_StopNow )";
  z[lc++]="		{";
  z[lc++]="			past->past_IsActive = 0;";
  z[lc++]="		}";
  z[lc++]="		else if( past->past_StopSoon )";
  z[lc++]="		{";
  z[lc++]="			DSoundWrapper   *dsw = &pahsc->pahsc_DSoundWrapper;";
  z[lc++]="			if( past->past_NumOutputChannels > 0 )";
  z[lc++]="			{";
  z[lc++]="				DSW_ZeroEmptySpace( dsw ); ";
  z[lc++]="				AddTraceMessage(\"Pa_TimerCallback: waiting - written \", (int) dsw->dsw_FramesWritten );";
  z[lc++]="				AddTraceMessage(\"Pa_TimerCallback: waiting - played \", (int) dsw->dsw_FramesPlayed );";
  z[lc++]="		/* clear past_IsActive when all sound played */";
  z[lc++]="				if( dsw->dsw_FramesPlayed >= past->past_FrameCount )";
  z[lc++]="				{";
  z[lc++]="					past->past_IsActive = 0;";
  z[lc++]="				}";
  z[lc++]="			}";
  z[lc++]="			else";
  z[lc++]="			{";
  z[lc++]="				past->past_IsActive = 0;";
  z[lc++]="			}";
  z[lc++]="		}";
  z[lc++]="		else";
  z[lc++]="		{";
  z[lc++]="			pahsc->pahsc_IfInsideCallback = 1;";
  z[lc++]="			if( Pa_TimeSlice( past ) != 0)  /* Call time slice independant of timing method. */";
  z[lc++]="			{";
  z[lc++]="				past->past_StopSoon = 1;";
  z[lc++]="			}";
  z[lc++]="			pahsc->pahsc_IfInsideCallback = 0;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="}";
  z[lc++]="/*******************************************************************/";
  z[lc++]="PaError PaHost_OpenStream( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	HRESULT          hr;";
  z[lc++]="	PaError          result = paNoError;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	int              numBytes, maxChannels;";
  z[lc++]="	unsigned int     minNumBuffers;";
  z[lc++]="	internalPortAudioDevice *pad;";
  z[lc++]="	DSoundWrapper   *dsw;";
  z[lc++]="/* Allocate and initialize host data. */";
  z[lc++]="	pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); /* MEM */";
  z[lc++]="	if( pahsc == NULL )";
  z[lc++]="	{";
  z[lc++]="		result = paInsufficientMemory;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="	memset( pahsc, 0, sizeof(PaHostSoundControl) );";
  z[lc++]="	past->past_DeviceData = (void *) pahsc;";
  z[lc++]="	pahsc->pahsc_TimerID = 0;";
  z[lc++]="	dsw = &pahsc->pahsc_DSoundWrapper;";
  z[lc++]="	DSW_Init( dsw );";
  z[lc++]="/* Allocate native buffer. */";
  z[lc++]="	maxChannels = ( past->past_NumOutputChannels > past->past_NumInputChannels ) ?";
  z[lc++]="		past->past_NumOutputChannels : past->past_NumInputChannels;";
  z[lc++]="	pahsc->pahsc_BytesPerBuffer = past->past_FramesPerUserBuffer * maxChannels * sizeof(short);";
  z[lc++]="	if( maxChannels > 0 )";
  z[lc++]="	{";
  z[lc++]="		pahsc->pahsc_NativeBuffer = (short *) PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerBuffer); /* MEM */";
  z[lc++]="		if( pahsc->pahsc_NativeBuffer == NULL )";
  z[lc++]="		{";
  z[lc++]="			result = paInsufficientMemory;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="		result = paInvalidChannelCount;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="	";
  z[lc++]="	DBUG((\"PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\\n\", pahsc->pahsc_MinFramesPerHostBuffer ));";
  z[lc++]="	minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );";
  z[lc++]="	past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;";
  z[lc++]="	numBytes = pahsc->pahsc_BytesPerBuffer * past->past_NumUserBuffers;";
  z[lc++]="	if( numBytes < DSBSIZE_MIN )";
  z[lc++]="	{";
  z[lc++]="		result = paBufferTooSmall;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="	if( numBytes > DSBSIZE_MAX )";
  z[lc++]="	{";
  z[lc++]="		result = paBufferTooBig;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="	pahsc->pahsc_FramesPerDSBuffer = past->past_FramesPerUserBuffer * past->past_NumUserBuffers;";
  z[lc++]="	{";
  z[lc++]="		int msecLatency = (int) ((pahsc->pahsc_FramesPerDSBuffer * 1000) / past->past_SampleRate);";
  z[lc++]="		PRINT((\"PortAudio on DirectSound - Latency = %d frames, %d msec\\n\", pahsc->pahsc_FramesPerDSBuffer, msecLatency ));";
  z[lc++]="	}";
  z[lc++]="/* ------------------ OUTPUT */";
  z[lc++]="	if( (past->past_OutputDeviceID >= 0) && (past->past_NumOutputChannels > 0) )";
  z[lc++]="	{";
  z[lc++]="		DBUG((\"PaHost_OpenStream: deviceID = 0x%x\\n\", past->past_OutputDeviceID));";
  z[lc++]="		pad = Pa_GetInternalDevice( past->past_OutputDeviceID );";
  z[lc++]="		hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound,   NULL );";
  z[lc++]="/* If this fails, then try each output device until we find one that works. */";
  z[lc++]="		if( hr != DS_OK )";
  z[lc++]="		{";
  z[lc++]="			int i;";
  z[lc++]="			ERR_RPT((\"Creation of requested Audio Output device '%s' failed.\\n\",";
  z[lc++]="				((pad->pad_lpGUID == NULL) ? \"Default\" : pad->pad_Info.name) ));";
  z[lc++]="			for( i=0; i<Pa_CountDevices(); i++ )";
  z[lc++]="			{";
  z[lc++]="				pad = Pa_GetInternalDevice( i );";
  z[lc++]="				if( pad->pad_Info.maxOutputChannels >= past->past_NumOutputChannels )";
  z[lc++]="				{";
  z[lc++]="					DBUG((\"Try device '%s' instead.\\n\", pad->pad_Info.name ));";
  z[lc++]="					hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound,   NULL );";
  z[lc++]="					if( hr == DS_OK )";
  z[lc++]="					{";
  z[lc++]="						ERR_RPT((\"Using device '%s' instead.\\n\", pad->pad_Info.name ));";
  z[lc++]="						break;";
  z[lc++]="					}";
  z[lc++]="				}";
  z[lc++]="			}";
  z[lc++]="		}";
  z[lc++]="		if( hr != DS_OK )";
  z[lc++]="		{";
  z[lc++]="			ERR_RPT((\"PortAudio: DirectSoundCreate() failed!\\n\"));";
  z[lc++]="			result = paHostError;";
  z[lc++]="			sPaHostError = hr;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="		hr = DSW_InitOutputBuffer( dsw,";
  z[lc++]="			(unsigned long) (past->past_SampleRate + 0.5),";
  z[lc++]="			past->past_NumOutputChannels, numBytes );";
  z[lc++]="		DBUG((\"DSW_InitOutputBuffer() returns %x\\n\", hr));";
  z[lc++]="		if( hr != DS_OK )";
  z[lc++]="		{";
  z[lc++]="			result = paHostError;";
  z[lc++]="			sPaHostError = hr;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="		past->past_FrameCount = pahsc->pahsc_DSoundWrapper.dsw_FramesWritten;";
  z[lc++]="	}";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="/* ------------------ INPUT */";
  z[lc++]="	if( (past->past_InputDeviceID >= 0) && (past->past_NumInputChannels > 0) )";
  z[lc++]="	{";
  z[lc++]="		pad = Pa_GetInternalDevice( past->past_InputDeviceID );";
  z[lc++]="		hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture,   NULL );";
  z[lc++]="/* If this fails, then try each input device until we find one that works. */";
  z[lc++]="		if( hr != DS_OK )";
  z[lc++]="		{";
  z[lc++]="			int i;";
  z[lc++]="			ERR_RPT((\"Creation of requested Audio Capture device '%s' failed.\\n\",";
  z[lc++]="				((pad->pad_lpGUID == NULL) ? \"Default\" : pad->pad_Info.name) ));";
  z[lc++]="			for( i=0; i<Pa_CountDevices(); i++ )";
  z[lc++]="			{";
  z[lc++]="				pad = Pa_GetInternalDevice( i );";
  z[lc++]="				if( pad->pad_Info.maxInputChannels >= past->past_NumInputChannels )";
  z[lc++]="				{";
  z[lc++]="					PRINT((\"Try device '%s' instead.\\n\", pad->pad_Info.name ));";
  z[lc++]="					hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture,   NULL );";
  z[lc++]="					if( hr == DS_OK ) break;";
  z[lc++]="				}";
  z[lc++]="			}";
  z[lc++]="		}";
  z[lc++]="		if( hr != DS_OK )";
  z[lc++]="		{";
  z[lc++]="			ERR_RPT((\"PortAudio: DirectSoundCaptureCreate() failed!\\n\"));";
  z[lc++]="			result = paHostError;";
  z[lc++]="			sPaHostError = hr;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="		hr = DSW_InitInputBuffer( dsw,";
  z[lc++]="			(unsigned long) (past->past_SampleRate + 0.5),";
  z[lc++]="			past->past_NumInputChannels, numBytes );";
  z[lc++]="		DBUG((\"DSW_InitInputBuffer() returns %x\\n\", hr));";
  z[lc++]="		if( hr != DS_OK )";
  z[lc++]="		{";
  z[lc++]="			ERR_RPT((\"PortAudio: DSW_InitInputBuffer() returns %x\\n\", hr));";
  z[lc++]="			result = paHostError;";
  z[lc++]="			sPaHostError = hr;";
  z[lc++]="			goto error;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="	/* Calculate scalar used in CPULoad calculation. */ ";
  z[lc++]="	{";
  z[lc++]="		LARGE_INTEGER frequency;";
  z[lc++]="		if( QueryPerformanceFrequency( &frequency ) == 0 )";
  z[lc++]="		{";
  z[lc++]="			pahsc->pahsc_InverseTicksPerUserBuffer = 0.0;";
  z[lc++]="		}";
  z[lc++]="		else";
  z[lc++]="		{";
  z[lc++]="			pahsc->pahsc_InverseTicksPerUserBuffer = past->past_SampleRate /";
  z[lc++]="				( (double)frequency.QuadPart * past->past_FramesPerUserBuffer );";
  z[lc++]="			DBUG((\"pahsc_InverseTicksPerUserBuffer = %g\\n\", pahsc->pahsc_InverseTicksPerUserBuffer ));";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	return result;";
  z[lc++]="error:";
  z[lc++]="	PaHost_CloseStream( past );";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StartOutput( internalPortAudioStream *past )";
  z[lc++]="{";
  z[lc++]="	HRESULT          hr;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	PaError          result = paNoError;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="/* Give user callback a chance to pre-fill buffer. */";
  z[lc++]="	result = Pa_TimeSlice( past );";
  z[lc++]="	if( result != paNoError ) return result; // FIXME - what if finished?";
  z[lc++]="	hr = DSW_StartOutput( &pahsc->pahsc_DSoundWrapper );";
  z[lc++]="	DBUG((\"PaHost_StartOutput: DSW_StartOutput returned = 0x%X.\\n\", hr));";
  z[lc++]="	if( hr != DS_OK )";
  z[lc++]="	{";
  z[lc++]="		result = paHostError;";
  z[lc++]="		sPaHostError = hr;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="error:";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StartInput( internalPortAudioStream *past )";
  z[lc++]="{";
  z[lc++]="	PaError          result = paNoError;";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="	HRESULT          hr;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	hr = DSW_StartInput( &pahsc->pahsc_DSoundWrapper );";
  z[lc++]="	DBUG((\"Pa_StartStream: DSW_StartInput returned = 0x%X.\\n\", hr));";
  z[lc++]="	if( hr != DS_OK )";
  z[lc++]="	{";
  z[lc++]="		result = paHostError;";
  z[lc++]="		sPaHostError = hr;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="error:";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StartEngine( internalPortAudioStream *past )";
  z[lc++]="{";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	PaError          result = paNoError;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	past->past_StopNow = 0;";
  z[lc++]="	past->past_StopSoon = 0;";
  z[lc++]="	past->past_IsActive = 1;";
  z[lc++]="/* Create timer that will wake us up so we can fill the DSound buffer. */";
  z[lc++]="	{";
  z[lc++]="		int msecPerBuffer;";
  z[lc++]="		int resolution;";
  z[lc++]="		int bufsPerInterrupt = past->past_NumUserBuffers/4;";
  z[lc++]="		if( bufsPerInterrupt < 1 ) bufsPerInterrupt = 1;";
  z[lc++]="		msecPerBuffer = 1000 * (bufsPerInterrupt * past->past_FramesPerUserBuffer) / (int) past->past_SampleRate;";
  z[lc++]="		if( msecPerBuffer < 10 ) msecPerBuffer = 10;";
  z[lc++]="		else if( msecPerBuffer > 100 ) msecPerBuffer = 100;";
  z[lc++]="		resolution = msecPerBuffer/4;";
  z[lc++]="		pahsc->pahsc_TimerID = timeSetEvent( msecPerBuffer, resolution, (LPTIMECALLBACK) Pa_TimerCallback,";
  z[lc++]="		(DWORD) past, TIME_PERIODIC );";
  z[lc++]="	}";
  z[lc++]="	if( pahsc->pahsc_TimerID == 0 )";
  z[lc++]="	{";
  z[lc++]="		past->past_IsActive = 0;";
  z[lc++]="		result = paHostError;";
  z[lc++]="		sPaHostError = 0;";
  z[lc++]="		goto error;";
  z[lc++]="	}";
  z[lc++]="error:";
  z[lc++]="	return result;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )";
  z[lc++]="{";
  z[lc++]="	int timeoutMsec;";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paNoError;";
  z[lc++]="	if( abort ) past->past_StopNow = 1;";
  z[lc++]="	past->past_StopSoon = 1;";
  z[lc++]="/* Set timeout at 20% beyond maximum time we might wait. */";
  z[lc++]="	timeoutMsec = (int) (1200.0 * pahsc->pahsc_FramesPerDSBuffer / past->past_SampleRate);";
  z[lc++]="	while( past->past_IsActive && (timeoutMsec > 0)  )";
  z[lc++]="	{";
  z[lc++]="		Sleep(10);";
  z[lc++]="		timeoutMsec -= 10;";
  z[lc++]="	}";
  z[lc++]="	if( pahsc->pahsc_TimerID != 0 )";
  z[lc++]="	{";
  z[lc++]="		timeKillEvent(pahsc->pahsc_TimerID);  /* Stop callback timer. */";
  z[lc++]="		pahsc->pahsc_TimerID = 0;";
  z[lc++]="	}";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StopInput( internalPortAudioStream *past, int abort )";
  z[lc++]="{";
  z[lc++]="#if SUPPORT_AUDIO_CAPTURE";
  z[lc++]="	HRESULT hr;";
  z[lc++]="	PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paNoError;";
  z[lc++]="	(void) abort;";
  z[lc++]="	hr = DSW_StopInput( &pahsc->pahsc_DSoundWrapper );";
  z[lc++]="	DBUG((\"DSW_StopInput() result is %x\\n\", hr));";
  z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )";
  z[lc++]="{";
  z[lc++]="	HRESULT hr;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paNoError;";
  z[lc++]="	(void) abort;";
  z[lc++]="	hr = DSW_StopOutput( &pahsc->pahsc_DSoundWrapper );";
  z[lc++]="	DBUG((\"DSW_StopOutput() result is %x\\n\", hr));";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="/*******************************************************************/";
  z[lc++]="PaError PaHost_CloseStream( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paNoError;";
  z[lc++]="	DSW_Term( &pahsc->pahsc_DSoundWrapper );";
  z[lc++]="	if( pahsc->pahsc_NativeBuffer )";
  z[lc++]="	{";
  z[lc++]="		PaHost_FreeFastMemory( pahsc->pahsc_NativeBuffer, pahsc->pahsc_BytesPerBuffer ); /* MEM */";
  z[lc++]="		pahsc->pahsc_NativeBuffer = NULL;";
  z[lc++]="	}";
  z[lc++]="	PaHost_FreeFastMemory( pahsc, sizeof(PaHostSoundControl) ); /* MEM */";
  z[lc++]="	past->past_DeviceData = NULL;";
  z[lc++]="	return paNoError;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************";
  z[lc++]="** Determine minimum number of buffers required for this host based";
  z[lc++]="** on minimum latency. Latency can be optionally set by user by setting";
  z[lc++]="** an environment variable. For example, to set latency to 200 msec, put:";
  z[lc++]="**";
  z[lc++]="**    set PA_MIN_LATENCY_MSEC=200";
  z[lc++]="**";
  z[lc++]="** in the AUTOEXEC.BAT file and reboot.";
  z[lc++]="** If the environment variable is not set, then the latency will be determined";
  z[lc++]="** based on the OS. Windows NT has higher latency than Win95.";
  z[lc++]="*/";
  z[lc++]="#define PA_LATENCY_ENV_NAME  (\"PA_MIN_LATENCY_MSEC\")";
  z[lc++]="int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )";
  z[lc++]="{";
  z[lc++]="	char      envbuf[PA_ENV_BUF_SIZE];";
  z[lc++]="	DWORD     hostVersion;";
  z[lc++]="	DWORD     hresult;";
  z[lc++]="	int       minLatencyMsec = 0;";
  z[lc++]="	double    msecPerBuffer = (1000.0 * framesPerBuffer) / sampleRate;";
  z[lc++]="	int       minBuffers;";
  z[lc++]="/* Let user determine minimal latency by setting environment variable. */";
  z[lc++]="	hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );";
  z[lc++]="	if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )";
  z[lc++]="	{";
  z[lc++]="		minLatencyMsec = atoi( envbuf );";
  z[lc++]="	}";
  z[lc++]="	else";
  z[lc++]="	{";
  z[lc++]="/* Set minimal latency based on whether NT or Win95.";
  z[lc++]=" * NT has higher latency.";
  z[lc++]=" */";
  z[lc++]="		hostVersion = GetVersion();";
  z[lc++]="/* High bit clear if NT */";
  z[lc++]="		minLatencyMsec = ( (hostVersion & 0x80000000) == 0 ) ? PA_WIN_NT_LATENCY : PA_WIN_9X_LATENCY  ;";
  z[lc++]="#if PA_USE_HIGH_LATENCY";
  z[lc++]="		PRINT((\"PA - Minimum Latency set to %d msec!\\n\", minLatencyMsec ));";
  z[lc++]="#endif";
  z[lc++]="	}";
  z[lc++]="	minBuffers = (int) (1.0 + ((double)minLatencyMsec / msecPerBuffer));";
  z[lc++]="	if( minBuffers < 2 ) minBuffers = 2;";
  z[lc++]="	return minBuffers;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaError PaHost_Term( void )";
  z[lc++]="{";
  z[lc++]="	int i;";
  z[lc++]="/* Free names allocated during enumeration. */";
  z[lc++]="	for( i=0; i<sNumDevices; i++ )";
  z[lc++]="	{";
  z[lc++]="		if( sDevices[i].pad_Info.name != NULL )";
  z[lc++]="		{";
  z[lc++]="			free( (void *) sDevices[i].pad_Info.name );";
  z[lc++]="			sDevices[i].pad_Info.name = NULL;";
  z[lc++]="		}";
  z[lc++]="	}";
  z[lc++]="	if( sDevices != NULL )";
  z[lc++]="	{";
  z[lc++]="		PaHost_FreeFastMemory( sDevices, sNumDevices * sizeof(internalPortAudioDevice) ); /* MEM */";
  z[lc++]="		sDevices = NULL;";
  z[lc++]="		sNumDevices = 0;";
  z[lc++]="	}";
  z[lc++]="	return 0;";
  z[lc++]="}";
  z[lc++]="void Pa_Sleep( long msec )";
  z[lc++]="{";
  z[lc++]="	Sleep( msec );";
  z[lc++]="}";
  z[lc++]="/*************************************************************************";
  z[lc++]=" * Allocate memory that can be accessed in real-time.";
  z[lc++]=" * This may need to be held in physical memory so that it is not";
  z[lc++]=" * paged to virtual memory.";
  z[lc++]=" * This call MUST be balanced with a call to PaHost_FreeFastMemory().";
  z[lc++]=" * Memory will be set to zero.";
  z[lc++]=" */";
  z[lc++]="void *PaHost_AllocateFastMemory( long numBytes )";
  z[lc++]="{";
  z[lc++]="	void *addr = GlobalAlloc( GPTR, numBytes ); /* FIXME - do we need physical memory? Use VirtualLock() */ /* MEM */";
  z[lc++]="	return addr;";
  z[lc++]="}";
  z[lc++]="/*************************************************************************";
  z[lc++]=" * Free memory that could be accessed in real-time.";
  z[lc++]=" * This call MUST be balanced with a call to PaHost_AllocateFastMemory().";
  z[lc++]=" */";
  z[lc++]="void PaHost_FreeFastMemory( void *addr, long numBytes )";
  z[lc++]="{";
  z[lc++]="	if( addr != NULL ) GlobalFree( addr ); /* MEM */";
  z[lc++]="}";
  z[lc++]="/***********************************************************************/";
  z[lc++]="PaError PaHost_StreamActive( internalPortAudioStream   *past )";
  z[lc++]="{";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	if( pahsc == NULL ) return paInternalError;";
  z[lc++]="	return (PaError) (past->past_IsActive);";
  z[lc++]="}";
  z[lc++]="/*************************************************************************/";
  z[lc++]="PaTimestamp Pa_StreamTime( PortAudioStream *stream )";
  z[lc++]="{";
  z[lc++]="	DSoundWrapper   *dsw;";
  z[lc++]="	internalPortAudioStream   *past = (internalPortAudioStream *) stream;";
  z[lc++]="	PaHostSoundControl *pahsc;";
  z[lc++]="	if( past == NULL ) return paBadStreamPtr;";
  z[lc++]="	pahsc = (PaHostSoundControl *) past->past_DeviceData;";
  z[lc++]="	dsw = &pahsc->pahsc_DSoundWrapper;";
  z[lc++]="	return dsw->dsw_FramesPlayed;";
  z[lc++]="}";
  printlib(lc);
}


