1 2 /* 3 * Copyright (c) 1999-2006, Regents of the University of California 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * Neither the name of the University of California, Berkeley nor the 18 * names of its contributors may be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 * Automatically generated library file psys 34 35 * The drivers embedded in this file may be covered by a different 36 * license. Scroll down to see the license appearing before each 37 * driver, or see sfront/src/lib/ directories for driver source file. 38 39 */ 40 41 #include "tree.h" 42 43 44 45 void makepa_hosthdr(void) 46 { 47 int lc = 0; 48 49 z[lc++]="#ifndef PA_HOST_H"; 50 z[lc++]="#define PA_HOST_H"; 51 z[lc++]=""; 52 z[lc++]="/*"; 53 z[lc++]=" * Host dependant internal API for PortAudio"; 54 z[lc++]=" *"; 55 z[lc++]=" * Author: Phil Burk <philburk@softsynth.com>"; 56 z[lc++]=" *"; 57 z[lc++]=" * PortAudio Portable Real-Time Audio Library"; 58 z[lc++]=" * Latest Version at: http://www.softsynth.com/portaudio/"; 59 z[lc++]=" * DirectSound and Macintosh Implementation"; 60 z[lc++]=" * Copyright (c) 1999-2000 Phil Burk"; 61 z[lc++]=" *"; 62 z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining"; 63 z[lc++]=" * a copy of this software and associated documentation files"; 64 z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,"; 65 z[lc++]=" * including without limitation the rights to use, copy, modify, merge,"; 66 z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,"; 67 z[lc++]=" * and to permit persons to whom the Software is furnished to do so,"; 68 z[lc++]=" * subject to the following conditions:"; 69 z[lc++]=" *"; 70 z[lc++]=" * The above copyright notice and this permission notice shall be"; 71 z[lc++]=" * included in all copies or substantial portions of the Software."; 72 z[lc++]=" *"; 73 z[lc++]=" * Any person wishing to distribute modifications to the Software is"; 74 z[lc++]=" * requested to send the modifications to the original developer so that"; 75 z[lc++]=" * they can be incorporated into the canonical version."; 76 z[lc++]=" *"; 77 z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,"; 78 z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF"; 79 z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT."; 80 z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR"; 81 z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF"; 82 z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION"; 83 z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."; 84 z[lc++]=" *"; 85 z[lc++]=" */"; 86 z[lc++]=""; 87 z[lc++]="#ifdef __cplusplus"; ExecVacuum(ParseState * pstate,VacuumStmt * vacstmt,bool isTopLevel)88 z[lc++]="extern \"C\" {"; 89 z[lc++]="#endif /* __cplusplus */"; 90 z[lc++]=""; 91 z[lc++]="#ifndef SUPPORT_AUDIO_CAPTURE"; 92 z[lc++]="#define SUPPORT_AUDIO_CAPTURE (1)"; 93 z[lc++]="#endif"; 94 z[lc++]=""; 95 z[lc++]="#ifndef int32"; 96 z[lc++]="typedef long int32;"; 97 z[lc++]="#endif"; 98 z[lc++]="#ifndef uint32"; 99 z[lc++]="typedef unsigned long uint32;"; 100 z[lc++]="#endif"; 101 z[lc++]="#ifndef int16"; 102 z[lc++]="typedef short int16;"; 103 z[lc++]="#endif"; 104 z[lc++]="#ifndef uint16"; 105 z[lc++]="typedef unsigned short uint16;"; 106 z[lc++]="#endif"; 107 z[lc++]=""; 108 z[lc++]="#define PA_MAGIC (0x18273645)"; 109 z[lc++]=""; 110 z[lc++]="/************************************************************************************/"; 111 z[lc++]="/****************** Structures ******************************************************/"; 112 z[lc++]="/************************************************************************************/"; 113 z[lc++]=" "; 114 z[lc++]="typedef struct internalPortAudioStream"; 115 z[lc++]="{"; 116 z[lc++]=" uint32 past_Magic; /* ID for struct to catch bugs. */"; 117 z[lc++]="/* User specified information. */"; 118 z[lc++]=" uint32 past_FramesPerUserBuffer;"; 119 z[lc++]=" uint32 past_NumUserBuffers;"; 120 z[lc++]=" double past_SampleRate; /* Closest supported sample rate. */"; 121 z[lc++]=" int past_NumInputChannels;"; 122 z[lc++]=" int past_NumOutputChannels;"; 123 z[lc++]=" PaDeviceID past_InputDeviceID;"; 124 z[lc++]=" PaDeviceID past_OutputDeviceID;"; 125 z[lc++]=" PaSampleFormat past_InputSampleFormat;"; 126 z[lc++]=" PaSampleFormat past_OutputSampleFormat;"; 127 z[lc++]=" void *past_DeviceData;"; 128 z[lc++]=" PortAudioCallback *past_Callback;"; 129 z[lc++]=" void *past_UserData;"; 130 z[lc++]=" uint32 past_Flags;"; 131 z[lc++]="/* Flags for communicating between foreground and background. */"; 132 z[lc++]=" volatile int past_IsActive; /* Background is still playing. */"; 133 z[lc++]=" volatile int past_StopSoon; /* Background should keep playing when buffers empty. */"; 134 z[lc++]=" volatile int past_StopNow; /* Background should stop playing now. */"; 135 z[lc++]="/* These buffers are used when the native format does not match the user format. */"; 136 z[lc++]=" void *past_InputBuffer;"; 137 z[lc++]=" uint32 past_InputBufferSize;"; 138 z[lc++]=" void *past_OutputBuffer;"; 139 z[lc++]=" uint32 past_OutputBufferSize;"; 140 z[lc++]="/* Measurements */"; 141 z[lc++]=" uint32 past_NumCallbacks;"; 142 z[lc++]=" PaTimestamp past_FrameCount; /* Frames output to buffer. */"; 143 z[lc++]="/* For measuring CPU utilization. */"; 144 z[lc++]=" double past_AverageInsideCount;"; 145 z[lc++]=" double past_AverageTotalCount;"; 146 z[lc++]=" double past_Usage;"; 147 z[lc++]=" int past_IfLastExitValid;"; 148 z[lc++]="} internalPortAudioStream;"; 149 z[lc++]=""; 150 z[lc++]="/************************************************************************************/"; 151 z[lc++]="/****************** Prototypes ******************************************************/"; 152 z[lc++]="/************************************************************************************/"; 153 z[lc++]=""; 154 z[lc++]="PaError PaHost_Init( void );"; 155 z[lc++]="PaError PaHost_Term( void );"; 156 z[lc++]=""; 157 z[lc++]="PaError PaHost_OpenStream( internalPortAudioStream *past );"; 158 z[lc++]="PaError PaHost_CloseStream( internalPortAudioStream *past );"; 159 z[lc++]=""; 160 z[lc++]="PaError PaHost_StartOutput( internalPortAudioStream *past );"; 161 z[lc++]="PaError PaHost_StopOutput( internalPortAudioStream *past, int abort );"; 162 z[lc++]="PaError PaHost_StartInput( internalPortAudioStream *past );"; 163 z[lc++]="PaError PaHost_StopInput( internalPortAudioStream *past, int abort );"; 164 z[lc++]="PaError PaHost_StartEngine( internalPortAudioStream *past );"; 165 z[lc++]="PaError PaHost_StopEngine( internalPortAudioStream *past, int abort );"; 166 z[lc++]="PaError PaHost_StreamActive( internalPortAudioStream *past );"; 167 z[lc++]=""; 168 z[lc++]="long Pa_CallConvertInt16( internalPortAudioStream *past, "; 169 z[lc++]=" short *nativeInputBuffer,"; 170 z[lc++]=" short *nativeOutputBuffer );"; 171 z[lc++]=""; 172 z[lc++]="long Pa_CallConvertFloat32( internalPortAudioStream *past, "; 173 z[lc++]=" float *nativeInputBuffer,"; 174 z[lc++]=" float *nativeOutputBuffer );"; 175 z[lc++]=""; 176 z[lc++]="void *PaHost_AllocateFastMemory( long numBytes );"; 177 z[lc++]="void PaHost_FreeFastMemory( void *addr, long numBytes );"; 178 z[lc++]=""; 179 z[lc++]="PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate,"; 180 z[lc++]=" double *closestFrameRatePtr );"; 181 z[lc++]="int PaHost_FindClosestTableEntry( double allowableError, const double *rateTable,"; 182 z[lc++]=" int numRates, double frameRate );"; 183 z[lc++]=""; 184 z[lc++]="#ifdef __cplusplus"; 185 z[lc++]="}"; 186 z[lc++]="#endif /* __cplusplus */"; 187 z[lc++]="#endif /* PA_HOST_H */"; 188 printlib(lc); 189 } 190 191 192 void makepa_porthdr(void) 193 { 194 int lc = 0; 195 196 z[lc++]="#ifndef PORT_AUDIO_H"; 197 z[lc++]="#define PORT_AUDIO_H"; 198 z[lc++]=""; 199 z[lc++]="#ifdef __cplusplus"; 200 z[lc++]="extern \"C\" {"; 201 z[lc++]="#endif /* __cplusplus */"; 202 z[lc++]=""; 203 z[lc++]="/*"; 204 z[lc++]=" * PortAudio Portable Real-Time Audio Library"; 205 z[lc++]=" * PortAudio API Header File"; 206 z[lc++]=" * Latest version available at: http://www.audiomulch.com/portaudio/"; 207 z[lc++]=" *"; 208 z[lc++]=" * Copyright (c) 1999-2000 Ross Bencina and Phil Burk"; 209 z[lc++]=" *"; 210 z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining"; 211 z[lc++]=" * a copy of this software and associated documentation files"; 212 z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,"; 213 z[lc++]=" * including without limitation the rights to use, copy, modify, merge,"; 214 z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,"; 215 z[lc++]=" * and to permit persons to whom the Software is furnished to do so,"; 216 z[lc++]=" * subject to the following conditions:"; 217 z[lc++]=" *"; 218 z[lc++]=" * The above copyright notice and this permission notice shall be"; 219 z[lc++]=" * included in all copies or substantial portions of the Software."; 220 z[lc++]=" *"; 221 z[lc++]=" * Any person wishing to distribute modifications to the Software is"; vacuum(List * relations,VacuumParams * params,BufferAccessStrategy bstrategy,bool isTopLevel)222 z[lc++]=" * requested to send the modifications to the original developer so that"; 223 z[lc++]=" * they can be incorporated into the canonical version."; 224 z[lc++]=" *"; 225 z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,"; 226 z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF"; 227 z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT."; 228 z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR"; 229 z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF"; 230 z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION"; 231 z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."; 232 z[lc++]=" *"; 233 z[lc++]=" */"; 234 z[lc++]=""; 235 z[lc++]="typedef int PaError;"; 236 z[lc++]="typedef enum {"; 237 z[lc++]=" paNoError = 0,"; 238 z[lc++]=""; 239 z[lc++]=" paHostError = -10000,"; 240 z[lc++]=" paInvalidChannelCount,"; 241 z[lc++]=" paInvalidSampleRate,"; 242 z[lc++]=" paInvalidDeviceId,"; 243 z[lc++]=" paInvalidFlag,"; 244 z[lc++]=" paSampleFormatNotSupported,"; 245 z[lc++]=" paBadIODeviceCombination,"; 246 z[lc++]=" paInsufficientMemory,"; 247 z[lc++]=" paBufferTooBig,"; 248 z[lc++]=" paBufferTooSmall,"; 249 z[lc++]=" paNullCallback,"; 250 z[lc++]=" paBadStreamPtr,"; 251 z[lc++]=" paTimedOut,"; 252 z[lc++]=" paInternalError"; 253 z[lc++]="} PaErrorNum;"; 254 z[lc++]=""; 255 z[lc++]="/*"; 256 z[lc++]=" Pa_Initialize() is the library initialisation function - call this before"; 257 z[lc++]=" using the library."; 258 z[lc++]="*/"; 259 z[lc++]=""; 260 z[lc++]="PaError Pa_Initialize( void );"; 261 z[lc++]=""; 262 z[lc++]="/*"; 263 z[lc++]=" Pa_Terminate() is the library termination function - call this after"; 264 z[lc++]=" using the library."; 265 z[lc++]="*/"; 266 z[lc++]=""; 267 z[lc++]="PaError Pa_Terminate( void );"; 268 z[lc++]=""; 269 z[lc++]="/*"; 270 z[lc++]=" Return host specific error."; 271 z[lc++]=" This can be called after receiving a paHostError."; 272 z[lc++]="*/"; 273 z[lc++]="long Pa_GetHostError( void );"; 274 z[lc++]=""; 275 z[lc++]="/*"; 276 z[lc++]=" Translate the error number into a human readable message."; 277 z[lc++]="*/"; 278 z[lc++]="const char *Pa_GetErrorText( PaError errnum );"; 279 z[lc++]=""; 280 z[lc++]="/*"; 281 z[lc++]=" Sample formats"; 282 z[lc++]=""; 283 z[lc++]=" These are formats used to pass sound data between the callback and the"; 284 z[lc++]=" stream. Each device has a \"native\" format which may be used when optimum"; 285 z[lc++]=" efficiency or control over conversion is required."; 286 z[lc++]=""; 287 z[lc++]=" Formats marked \"always available\" are supported (emulated) by all devices."; 288 z[lc++]=""; 289 z[lc++]=" The floating point representation uses +1.0 and -1.0 as the respective"; 290 z[lc++]=" maximum and minimum."; 291 z[lc++]=" "; 292 z[lc++]="*/"; 293 z[lc++]=""; 294 z[lc++]="typedef unsigned long PaSampleFormat;"; 295 z[lc++]="#define paFloat32 ((PaSampleFormat) (1<<0)) /*always available*/"; 296 z[lc++]="#define paInt16 ((PaSampleFormat) (1<<1)) /*always available*/"; 297 z[lc++]="#define paInt32 ((PaSampleFormat) (1<<2)) /*always available*/"; 298 z[lc++]="#define paInt24 ((PaSampleFormat) (1<<3))"; 299 z[lc++]="#define paPackedInt24 ((PaSampleFormat) (1<<4))"; 300 z[lc++]="#define paInt8 ((PaSampleFormat) (1<<5))"; 301 z[lc++]="#define paUInt8 ((PaSampleFormat) (1<<6)) /* unsigned 8 bit, 128 is \"ground\" */"; 302 z[lc++]="#define paCustomFormat ((PaSampleFormat) (1<<16))"; 303 z[lc++]=""; 304 z[lc++]="/*"; 305 z[lc++]=" Device enumeration mechanism."; 306 z[lc++]=""; 307 z[lc++]=" Device ids range from 0 to Pa_CountDevices()-1."; 308 z[lc++]=""; 309 z[lc++]=" Devices may support input, output or both. Device 0 is always the \"default\""; 310 z[lc++]=" device and should support at least stereo in and out if that is available"; 311 z[lc++]=" on the taget platform _even_ if this involves kludging an input/output"; 312 z[lc++]=" device on platforms that usually separate input from output. Other platform"; 313 z[lc++]=" specific devices are specified by positive device ids."; 314 z[lc++]="*/"; 315 z[lc++]=""; 316 z[lc++]="typedef int PaDeviceID;"; 317 z[lc++]="#define paNoDevice -1"; 318 z[lc++]=""; 319 z[lc++]="typedef struct{"; 320 z[lc++]=" int structVersion; "; 321 z[lc++]=" const char *name;"; 322 z[lc++]=" int maxInputChannels;"; 323 z[lc++]=" int maxOutputChannels;"; 324 z[lc++]="/* Number of discrete rates, or -1 if range supported. */"; 325 z[lc++]=" int numSampleRates;"; 326 z[lc++]="/* Array of supported sample rates, or {min,max} if range supported. */"; 327 z[lc++]=" const double *sampleRates;"; 328 z[lc++]=" PaSampleFormat nativeSampleFormats;"; 329 z[lc++]="} PaDeviceInfo;"; 330 z[lc++]=""; 331 z[lc++]=""; 332 z[lc++]="int Pa_CountDevices();"; 333 z[lc++]="/*"; 334 z[lc++]=" Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID()"; 335 z[lc++]=""; 336 z[lc++]=" Return the default device ID or paNoDevice if there is no devices."; 337 z[lc++]=" The result can be passed to Pa_OpenStream()."; 338 z[lc++]=" "; 339 z[lc++]=" On the PC, the user can specify a default device by"; 340 z[lc++]=" setting an environment variable. For example, to use device #1."; 341 z[lc++]=""; 342 z[lc++]=" set PA_RECOMMENDED_OUTPUT_DEVICE=1"; 343 z[lc++]=" "; 344 z[lc++]=" The user should first determine the available device ID by using"; 345 z[lc++]=" the supplied application \"pa_devs\"."; 346 z[lc++]="*/"; 347 z[lc++]="PaDeviceID Pa_GetDefaultInputDeviceID( void );"; 348 z[lc++]="PaDeviceID Pa_GetDefaultOutputDeviceID( void );"; 349 z[lc++]=""; 350 z[lc++]="/*"; 351 z[lc++]=" PaTimestamp is used to represent a continuous sample clock with arbitrary"; 352 z[lc++]=" start time useful for syncronisation. The type is used in the outTime"; 353 z[lc++]=" argument to the callback function and the result of Pa_StreamTime()"; 354 z[lc++]="*/"; 355 z[lc++]=""; 356 z[lc++]="typedef double PaTimestamp;"; 357 z[lc++]=""; 358 z[lc++]="/*"; 359 z[lc++]=" Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure"; 360 z[lc++]=" referring to the device specified by id."; 361 z[lc++]=" If id is out of range the function returns NULL."; 362 z[lc++]=""; 363 z[lc++]=" The returned structure is owned by the PortAudio implementation and must"; 364 z[lc++]=" not be manipulated or freed. The pointer is guaranteed to be valid until"; 365 z[lc++]=" between calls to Pa_Initialize() and Pa_Terminate()."; 366 z[lc++]="*/"; 367 z[lc++]=""; 368 z[lc++]="const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID devID );"; 369 z[lc++]=""; 370 z[lc++]="/*"; 371 z[lc++]=" PortAudioCallback is implemented by clients of the portable audio api."; 372 z[lc++]=""; 373 z[lc++]=" inputBuffer and outputBuffer are arrays of interleaved samples,"; 374 z[lc++]=" the format, packing and number of channels used by the buffers are"; 375 z[lc++]=" determined by parameters to Pa_OpenStream() (see below)."; 376 z[lc++]=""; 377 z[lc++]=" framesPerBuffer is the number of sample frames to be processed by the callback."; 378 z[lc++]=""; 379 z[lc++]=" outTime is the time in samples when the buffer(s) processed by"; 380 z[lc++]=" this callback will begin being played at the audio output."; 381 z[lc++]=" See also Pa_StreamTime()"; 382 z[lc++]=""; 383 z[lc++]=" userData is the value of a user supplied pointer passed to Pa_OpenStream()"; 384 z[lc++]=" intended for storing synthesis data etc."; 385 z[lc++]=""; 386 z[lc++]=" return value:"; 387 z[lc++]=" The callback can return a nonzero value to stop the stream. This may be"; 388 z[lc++]=" useful in applications such as soundfile players where a specific duration"; 389 z[lc++]=" of output is required. However, it is not necessary to utilise this mechanism"; 390 z[lc++]=" as StopStream() will also terminate the stream. A callback returning a"; 391 z[lc++]=" nonzero value must fill the entire outputBuffer."; 392 z[lc++]=""; 393 z[lc++]=" NOTE: None of the other stream functions may be called from within the"; 394 z[lc++]=" callback function except for Pa_GetCPULoad()."; 395 z[lc++]=""; 396 z[lc++]="*/"; 397 z[lc++]=""; 398 z[lc++]="typedef int (PortAudioCallback)("; 399 z[lc++]=" void *inputBuffer, void *outputBuffer,"; 400 z[lc++]=" unsigned long framesPerBuffer,"; 401 z[lc++]=" PaTimestamp outTime, void *userData );"; 402 z[lc++]=""; 403 z[lc++]=""; 404 z[lc++]="/*"; 405 z[lc++]=" Stream flags"; 406 z[lc++]=""; 407 z[lc++]=" These flags may be supplied (ored together) in the streamFlags argument to"; 408 z[lc++]=" the Pa_OpenStream() function."; 409 z[lc++]=""; 410 z[lc++]=" [ suggestions? ]"; 411 z[lc++]="*/"; 412 z[lc++]=""; 413 z[lc++]="#define paNoFlag (0)"; 414 z[lc++]="#define paClipOff (1<<0) /* disable defult clipping of out of range samples */"; 415 z[lc++]="#define paDitherOff (1<<1) /* disable default dithering */"; 416 z[lc++]="#define paPlatformSpecificFlags (0x00010000)"; 417 z[lc++]="typedef unsigned long PaStreamFlags;"; 418 z[lc++]=""; 419 z[lc++]="/*"; 420 z[lc++]=" A single PortAudioStream provides multiple channels of real-time"; 421 z[lc++]=" input and output audio streaming to a client application."; 422 z[lc++]=" Pointers to PortAudioStream objects are passed between PortAudio functions."; 423 z[lc++]="*/"; 424 z[lc++]=""; 425 z[lc++]="typedef void PortAudioStream;"; 426 z[lc++]="#define PaStream PortAudioStream"; 427 z[lc++]=""; 428 z[lc++]="/*"; 429 z[lc++]=" Pa_OpenStream() opens a stream for either input, output or both."; 430 z[lc++]=""; 431 z[lc++]=" stream is the address of a PortAudioStream pointer which will receive"; 432 z[lc++]=" a pointer to the newly opened stream."; 433 z[lc++]=""; 434 z[lc++]=" inputDevice is the id of the device used for input (see PaDeviceID above.)"; 435 z[lc++]=" inputDevice may be paNoDevice to indicate that an input device is not required."; 436 z[lc++]=""; 437 z[lc++]=" numInputChannels is the number of channels of sound to be delivered to the"; 438 z[lc++]=" callback. It can range from 1 to the value of maxInputChannels in the"; 439 z[lc++]=" device input record for the device specified in the inputDevice parameter."; 440 z[lc++]=" If inputDevice is paNoDevice numInputChannels is ignored."; 441 z[lc++]=""; 442 z[lc++]=" inputSampleFormat is the format of inputBuffer provided to the callback"; 443 z[lc++]=" function. inputSampleFormat may be any of the formats described by the"; 444 z[lc++]=" PaSampleFormat enumeration (see above). PortAudio guarantees support for"; 445 z[lc++]=" the sound devices native formats (nativeSampleFormats in the device info"; 446 z[lc++]=" record) and additionally 16 and 32 bit integer and 32 bit floating point"; 447 z[lc++]=" formats. Support for other formats is implementation defined."; 448 z[lc++]=""; 449 z[lc++]=" inputDriverInfo is a pointer to an optional driver specific data structure"; 450 z[lc++]=" containing additional information for device setup or stream processing."; 451 z[lc++]=" inputDriverInfo is never required for correct operation. If not used"; 452 z[lc++]=" inputDriverInfo should be NULL."; 453 z[lc++]=""; 454 z[lc++]=" outputDevice is the id of the device used for output (see PaDeviceID above.)"; 455 z[lc++]=" outputDevice may be paNoDevice to indicate that an output device is not required."; 456 z[lc++]=""; 457 z[lc++]=" numOutputChannels is the number of channels of sound to be supplied by the"; 458 z[lc++]=" callback. See the definition of numInputChannels above for more details."; 459 z[lc++]=""; 460 z[lc++]=" outputSampleFormat is the sample format of the outputBuffer filled by the"; 461 z[lc++]=" callback function. See the definition of inputSampleFormat above for more"; 462 z[lc++]=" details."; 463 z[lc++]=""; 464 z[lc++]=" outputDriverInfo is a pointer to an optional driver specific data structure"; 465 z[lc++]=" containing additional information for device setup or stream processing."; 466 z[lc++]=" outputDriverInfo is never required for correct operation. If not used"; 467 z[lc++]=" outputDriverInfo should be NULL."; 468 z[lc++]=""; 469 z[lc++]=" sampleRate is the desired sampleRate for input and output"; 470 z[lc++]=""; 471 z[lc++]=" framesPerBuffer is the length in sample frames of all internal sample buffers"; 472 z[lc++]=" used for communication with platform specific audio routines. Wherever"; 473 z[lc++]=" possible this corresponds to the framesPerBuffer parameter passed to the"; 474 z[lc++]=" callback function."; 475 z[lc++]=""; 476 z[lc++]=" numberOfBuffers is the number of buffers used for multibuffered"; 477 z[lc++]=" communication with the platform specific audio routines. This parameter is"; 478 z[lc++]=" provided only as a guide - and does not imply that an implementation must"; 479 z[lc++]=" use multibuffered i/o when reliable double buffering is available (such as"; 480 z[lc++]=" SndPlayDoubleBuffer() on the Macintosh.)"; 481 z[lc++]=""; 482 z[lc++]=" streamFlags may contain a combination of flags ORed together."; 483 z[lc++]=" These flags modify the behavior of the"; vacuum_is_relation_owner(Oid relid,Form_pg_class reltuple,int options)484 z[lc++]=" streaming process. Some flags may only be relevant to certain buffer formats."; 485 z[lc++]=""; 486 z[lc++]=" callback is a pointer to a client supplied function that is responsible"; 487 z[lc++]=" for processing and filling input and output buffers (see above for details.)"; 488 z[lc++]=""; 489 z[lc++]=" userData is a client supplied pointer which is passed to the callback"; 490 z[lc++]=" function. It could for example, contain a pointer to instance data necessary"; 491 z[lc++]=" for processing the audio buffers."; 492 z[lc++]=""; 493 z[lc++]=" return value:"; 494 z[lc++]=" Apon success Pa_OpenStream() returns PaNoError and places a pointer to a"; 495 z[lc++]=" valid PortAudioStream in the stream argument. The stream is inactive (stopped)."; 496 z[lc++]=" If a call to Pa_OpenStream() fails a nonzero error code is returned (see"; 497 z[lc++]=" PAError above) and the value of stream is invalid."; 498 z[lc++]=""; 499 z[lc++]="*/"; 500 z[lc++]=""; 501 z[lc++]="PaError Pa_OpenStream( PortAudioStream** stream,"; 502 z[lc++]=" PaDeviceID inputDevice,"; 503 z[lc++]=" int numInputChannels,"; 504 z[lc++]=" PaSampleFormat inputSampleFormat,"; 505 z[lc++]=" void *inputDriverInfo,"; 506 z[lc++]=" PaDeviceID outputDevice,"; 507 z[lc++]=" int numOutputChannels,"; 508 z[lc++]=" PaSampleFormat outputSampleFormat,"; 509 z[lc++]=" void *outputDriverInfo,"; 510 z[lc++]=" double sampleRate,"; 511 z[lc++]=" unsigned long framesPerBuffer,"; 512 z[lc++]=" unsigned long numberOfBuffers,"; 513 z[lc++]=" PaStreamFlags streamFlags,"; 514 z[lc++]=" PortAudioCallback *callback,"; 515 z[lc++]=" void *userData );"; 516 z[lc++]=""; 517 z[lc++]=""; 518 z[lc++]="/*"; 519 z[lc++]=" Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that"; 520 z[lc++]=" opens the default input and/or ouput devices. Most parameters have"; 521 z[lc++]=" identical meaning to their Pa_OpenStream() counterparts, with the following"; 522 z[lc++]=" exceptions:"; 523 z[lc++]=""; 524 z[lc++]=" If either numInputChannels or numOutputChannels is 0 the respective device"; 525 z[lc++]=" is not opened (same as passing paNoDevice in the device arguments to Pa_OpenStream() )"; 526 z[lc++]=""; 527 z[lc++]=" sampleFormat applies to both the input and output buffers."; 528 z[lc++]="*/"; 529 z[lc++]=""; 530 z[lc++]="PaError Pa_OpenDefaultStream( PortAudioStream** stream,"; 531 z[lc++]=" int numInputChannels,"; 532 z[lc++]=" int numOutputChannels,"; 533 z[lc++]=" PaSampleFormat sampleFormat,"; 534 z[lc++]=" double sampleRate,"; 535 z[lc++]=" unsigned long framesPerBuffer,"; 536 z[lc++]=" unsigned long numberOfBuffers,"; 537 z[lc++]=" PortAudioCallback *callback,"; 538 z[lc++]=" void *userData );"; 539 z[lc++]=" "; 540 z[lc++]="/*"; 541 z[lc++]=" Pa_CloseStream() closes an audio stream, flushing any pending buffers."; 542 z[lc++]="*/"; 543 z[lc++]=""; 544 z[lc++]="PaError Pa_CloseStream( PortAudioStream* );"; 545 z[lc++]=""; 546 z[lc++]="/*"; 547 z[lc++]=" Pa_StartStream() and Pa_StopStream() begin and terminate audio processing."; 548 z[lc++]=" Pa_StopStream() waits until all pending audio buffers have been played."; 549 z[lc++]=" Pa_AbortStream() stops playing immediately without waiting for pending"; 550 z[lc++]=" buffers to complete."; 551 z[lc++]="*/"; 552 z[lc++]=""; 553 z[lc++]="PaError Pa_StartStream( PortAudioStream *stream );"; 554 z[lc++]=""; 555 z[lc++]="PaError Pa_StopStream( PortAudioStream *stream );"; 556 z[lc++]=""; 557 z[lc++]="PaError Pa_AbortStream( PortAudioStream *stream );"; vacuum_open_relation(Oid relid,RangeVar * relation,int options,bool verbose,LOCKMODE lmode)558 z[lc++]=""; 559 z[lc++]="/*"; 560 z[lc++]=" Pa_StreamActive() returns one when the stream is playing audio,"; 561 z[lc++]=" zero when not playing, or a negative error number if the"; 562 z[lc++]=" stream is invalid."; 563 z[lc++]=" The stream is active between calls to Pa_StartStream() and Pa_StopStream(),"; 564 z[lc++]=" but may also become inactive if the callback returns a non-zero value."; 565 z[lc++]=" In the latter case, the stream is considered inactive after the last"; 566 z[lc++]=" buffer has finished playing."; 567 z[lc++]="*/"; 568 z[lc++]=""; 569 z[lc++]="PaError Pa_StreamActive( PortAudioStream *stream );"; 570 z[lc++]=""; 571 z[lc++]="/*"; 572 z[lc++]=" Pa_StreamTime() returns the current output time for the stream in samples."; 573 z[lc++]=" This time may be used as a time reference (for example syncronising audio to"; 574 z[lc++]=" MIDI)."; 575 z[lc++]="*/"; 576 z[lc++]=""; 577 z[lc++]="PaTimestamp Pa_StreamTime( PortAudioStream *stream );"; 578 z[lc++]=""; 579 z[lc++]="/*"; 580 z[lc++]=" The \"CPU Load\" is a fraction of total CPU time consumed by the"; 581 z[lc++]=" stream's audio processing."; 582 z[lc++]=" A value of 0.5 would imply that PortAudio and the sound generating"; 583 z[lc++]=" callback was consuming roughly 50% of the available CPU time."; 584 z[lc++]=" This function may be called from the callback function or the application."; 585 z[lc++]="*/"; 586 z[lc++]="double Pa_GetCPULoad( PortAudioStream* stream );"; 587 z[lc++]=""; 588 z[lc++]="/*"; 589 z[lc++]=" Use Pa_GetMinNumBuffers() to determine minimum number of buffers required for"; 590 z[lc++]=" the current host based on minimum latency. "; 591 z[lc++]=" On the PC, for the DirectSound implementation, latency can be optionally set"; 592 z[lc++]=" by user by setting an environment variable."; 593 z[lc++]=" For example, to set latency to 200 msec, put:"; 594 z[lc++]=" "; 595 z[lc++]=" set PA_MIN_LATENCY_MSEC=200"; 596 z[lc++]=" "; 597 z[lc++]=" in the AUTOEXEC.BAT file and reboot."; 598 z[lc++]=" If the environment variable is not set, then the latency will be determined"; 599 z[lc++]=" based on the OS. Windows NT has higher latency than Win95."; 600 z[lc++]="*/"; 601 z[lc++]=""; 602 z[lc++]="int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate );"; 603 z[lc++]=""; 604 z[lc++]="/*"; 605 z[lc++]=" Sleep for at least 'msec' milliseconds."; 606 z[lc++]=" You may sleep longer than the requested time so don't rely"; 607 z[lc++]=" on this for accurate musical timing."; 608 z[lc++]="*/"; 609 z[lc++]="void Pa_Sleep( long msec );"; 610 z[lc++]=""; 611 z[lc++]="/*"; 612 z[lc++]=" Return size in bytes of a single sample in a given PaSampleFormat"; 613 z[lc++]=" or paSampleFormatNotSupported. "; 614 z[lc++]="*/"; 615 z[lc++]="PaError Pa_GetSampleSize( PaSampleFormat format );"; 616 z[lc++]=""; 617 z[lc++]="#ifdef __cplusplus"; 618 z[lc++]="}"; 619 z[lc++]="#endif /* __cplusplus */"; 620 z[lc++]="#endif /* PORT_AUDIO_H */"; 621 printlib(lc); 622 } 623 624 625 void makepa_tracehdr(void) 626 { 627 int lc = 0; 628 629 z[lc++]="#ifndef PA_TRACE_H"; 630 z[lc++]="#define PA_TRACE_H"; 631 z[lc++]="/*"; 632 z[lc++]=" * Portable Audio I/O Library Trace Facility"; 633 z[lc++]=" * Store trace information in real-time for later printing."; 634 z[lc++]=" *"; 635 z[lc++]=" * Based on the Open Source API proposed by Ross Bencina"; 636 z[lc++]=" * Copyright (c) 1999-2000 Phil Burk"; 637 z[lc++]=" *"; 638 z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining"; 639 z[lc++]=" * a copy of this software and associated documentation files"; 640 z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,"; 641 z[lc++]=" * including without limitation the rights to use, copy, modify, merge,"; 642 z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,"; 643 z[lc++]=" * and to permit persons to whom the Software is furnished to do so,"; 644 z[lc++]=" * subject to the following conditions:"; 645 z[lc++]=" *"; 646 z[lc++]=" * The above copyright notice and this permission notice shall be"; 647 z[lc++]=" * included in all copies or substantial portions of the Software."; 648 z[lc++]=" *"; 649 z[lc++]=" * Any person wishing to distribute modifications to the Software is"; 650 z[lc++]=" * requested to send the modifications to the original developer so that"; 651 z[lc++]=" * they can be incorporated into the canonical version."; 652 z[lc++]=" *"; 653 z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,"; 654 z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF"; 655 z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT."; 656 z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR"; 657 z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF"; 658 z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION"; 659 z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."; 660 z[lc++]=" */"; 661 z[lc++]=""; 662 z[lc++]=""; 663 z[lc++]="#define TRACE_REALTIME_EVENTS (0) /* Keep log of various real-time events. */"; 664 z[lc++]="#define MAX_TRACE_RECORDS (2048)"; 665 z[lc++]=""; 666 z[lc++]="#ifdef __cplusplus"; 667 z[lc++]="extern \"C\" {"; 668 z[lc++]="#endif /* __cplusplus */"; 669 z[lc++]=""; expand_vacuum_rel(VacuumRelation * vrel,int options)670 z[lc++]=""; 671 z[lc++]="/************************************************************************************/"; 672 z[lc++]="/****************** Prototypes ******************************************************/"; 673 z[lc++]="/************************************************************************************/"; 674 z[lc++]=""; 675 z[lc++]="#if TRACE_REALTIME_EVENTS"; 676 z[lc++]=""; 677 z[lc++]="void DumpTraceMessages();"; 678 z[lc++]="void ResetTraceMessages();"; 679 z[lc++]="void AddTraceMessage( char *msg, int data );"; 680 z[lc++]=""; 681 z[lc++]="#else"; 682 z[lc++]=""; 683 z[lc++]="#define AddTraceMessage(msg,data) /* noop */"; 684 z[lc++]="#define ResetTraceMessages() /* noop */"; 685 z[lc++]="#define DumpTraceMessages() /* noop */"; 686 z[lc++]=""; 687 z[lc++]="#endif"; 688 z[lc++]=""; 689 z[lc++]="#ifdef __cplusplus"; 690 z[lc++]="}"; 691 z[lc++]="#endif /* __cplusplus */"; 692 z[lc++]=""; 693 z[lc++]="#endif /* PA_TRACE_H */"; 694 printlib(lc); 695 } 696 697 698 void makepa_lib(void) 699 { 700 int lc = 0; 701 702 z[lc++]="/*"; 703 z[lc++]=" * Portable Audio I/O Library"; 704 z[lc++]=" * Host Independant Layer"; 705 z[lc++]=" *"; 706 z[lc++]=" * Based on the Open Source API proposed by Ross Bencina"; 707 z[lc++]=" * Copyright (c) 1999-2000 Phil Burk"; 708 z[lc++]=" *"; 709 z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining"; 710 z[lc++]=" * a copy of this software and associated documentation files"; 711 z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,"; 712 z[lc++]=" * including without limitation the rights to use, copy, modify, merge,"; 713 z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,"; 714 z[lc++]=" * and to permit persons to whom the Software is furnished to do so,"; 715 z[lc++]=" * subject to the following conditions:"; 716 z[lc++]=" *"; 717 z[lc++]=" * The above copyright notice and this permission notice shall be"; 718 z[lc++]=" * included in all copies or substantial portions of the Software."; 719 z[lc++]=" *"; 720 z[lc++]=" * Any person wishing to distribute modifications to the Software is"; 721 z[lc++]=" * requested to send the modifications to the original developer so that"; 722 z[lc++]=" * they can be incorporated into the canonical version."; 723 z[lc++]=" *"; 724 z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,"; 725 z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF"; 726 z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT."; 727 z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR"; 728 z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF"; 729 z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION"; 730 z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."; 731 z[lc++]=" *"; 732 z[lc++]=" */"; 733 z[lc++]=""; 734 z[lc++]="/* Modification History:"; 735 z[lc++]=" PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC"; 736 z[lc++]=" PLB20010820 - fix dither and shift for recording PaUInt8 format "; 737 z[lc++]="*/"; 738 z[lc++]=""; 739 z[lc++]="#include <stdio.h>"; 740 z[lc++]="#include <stdlib.h>"; 741 z[lc++]="#include <string.h>"; 742 z[lc++]="#include <math.h>"; 743 z[lc++]=""; 744 z[lc++]="/* PLB20010422 - \"memory.h\" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */"; 745 z[lc++]="#ifdef _WIN32"; 746 z[lc++]="#ifndef __MWERKS__"; 747 z[lc++]="#include <memory.h>"; 748 z[lc++]="#endif /* __MWERKS__ */"; 749 z[lc++]="#else /* !_WIN32 */"; 750 z[lc++]="#include <memory.h>"; 751 z[lc++]="#endif /* _WIN32 */"; 752 z[lc++]=""; 753 z[lc++]="#if 0"; 754 z[lc++]="#include \"portaudio.h\""; 755 z[lc++]="#include \"pa_host.h\""; 756 z[lc++]="#include \"pa_trace.h\""; 757 z[lc++]="#endif"; 758 z[lc++]=""; 759 z[lc++]="/* The reason we might NOT want to validate the rate before opening the stream"; 760 z[lc++]=" * is because many DirectSound drivers lie about the rates they actually support."; 761 z[lc++]=" */"; 762 z[lc++]="#define PA_VALIDATE_RATE (0) /* If true validate sample rate against driver info. */"; 763 z[lc++]=""; 764 z[lc++]="/*"; 765 z[lc++]="O- maybe not allocate past_InputBuffer and past_OutputBuffer if not needed for conversion"; 766 z[lc++]="*/"; 767 z[lc++]=""; 768 z[lc++]="#ifndef FALSE"; 769 z[lc++]=" #define FALSE (0)"; 770 z[lc++]=" #define TRUE (!FALSE)"; 771 z[lc++]="#endif"; 772 z[lc++]=""; 773 z[lc++]="#define PRINT(x) { printf x; fflush(stdout); }"; 774 z[lc++]="#define ERR_RPT(x) PRINT(x)"; 775 z[lc++]="#define DBUG(x) /* PRINT(x) */"; 776 z[lc++]="#define DBUGX(x) /* PRINT(x) */"; 777 z[lc++]=""; 778 z[lc++]="static int gInitCount = 0; /* Count number of times Pa_Initialize() called to allow nesting and overlapping. */"; 779 z[lc++]=""; 780 z[lc++]="static PaError Pa_KillStream( PortAudioStream *stream, int abort );"; 781 z[lc++]=""; 782 z[lc++]="/***********************************************************************/"; 783 z[lc++]="int PaHost_FindClosestTableEntry( double allowableError, const double *rateTable, int numRates, double frameRate )"; 784 z[lc++]="{"; 785 z[lc++]=" double err, minErr = allowableError;"; 786 z[lc++]=" int i, bestFit = -1;"; 787 z[lc++]=" "; 788 z[lc++]=" for( i=0; i<numRates; i++ )"; 789 z[lc++]=" {"; 790 z[lc++]=" err = fabs( frameRate - rateTable[i] );"; 791 z[lc++]=" if( err < minErr )"; 792 z[lc++]=" {"; 793 z[lc++]=" minErr = err;"; 794 z[lc++]=" bestFit = i;"; 795 z[lc++]=" }"; 796 z[lc++]=" }"; 797 z[lc++]=" return bestFit;"; 798 z[lc++]="}"; 799 z[lc++]=""; 800 z[lc++]="/**************************************************************************"; 801 z[lc++]="** Make sure sample rate is legal and also convert to enumeration for driver."; 802 z[lc++]="*/"; 803 z[lc++]="PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate,"; 804 z[lc++]=" double *closestFrameRatePtr )"; 805 z[lc++]="{"; 806 z[lc++]=" long bestRateIndex;"; 807 z[lc++]=" const PaDeviceInfo *pdi;"; 808 z[lc++]=" pdi = Pa_GetDeviceInfo( id );"; get_all_vacuum_rels(int options)809 z[lc++]=" if( pdi == NULL )"; 810 z[lc++]=" {"; 811 z[lc++]=" return paInvalidDeviceId;"; 812 z[lc++]=" }"; 813 z[lc++]=""; 814 z[lc++]=" if( pdi->numSampleRates == -1 )"; 815 z[lc++]=" {"; 816 z[lc++]=" /* Is it out of range? */"; 817 z[lc++]=" if( (requestedFrameRate < pdi->sampleRates[0]) ||"; 818 z[lc++]=" (requestedFrameRate > pdi->sampleRates[1]) )"; 819 z[lc++]=" {"; 820 z[lc++]=" return paInvalidSampleRate;"; 821 z[lc++]=" }"; 822 z[lc++]=" "; 823 z[lc++]=" *closestFrameRatePtr = requestedFrameRate;"; 824 z[lc++]=" }"; 825 z[lc++]=" else"; 826 z[lc++]=" {"; 827 z[lc++]=" bestRateIndex = PaHost_FindClosestTableEntry( 1.0, pdi->sampleRates, pdi->numSampleRates, requestedFrameRate );"; 828 z[lc++]=" if( bestRateIndex < 0 ) return paInvalidSampleRate;"; 829 z[lc++]=" *closestFrameRatePtr = pdi->sampleRates[bestRateIndex];"; 830 z[lc++]=" }"; 831 z[lc++]=" return paNoError;"; 832 z[lc++]="}"; 833 z[lc++]=""; 834 z[lc++]="/*************************************************************************/"; 835 z[lc++]="PaError Pa_OpenStream("; 836 z[lc++]=" PortAudioStream** streamPtrPtr,"; 837 z[lc++]=" PaDeviceID inputDeviceID,"; 838 z[lc++]=" int numInputChannels,"; 839 z[lc++]=" PaSampleFormat inputSampleFormat,"; 840 z[lc++]=" void *inputDriverInfo,"; 841 z[lc++]=" PaDeviceID outputDeviceID,"; 842 z[lc++]=" int numOutputChannels,"; 843 z[lc++]=" PaSampleFormat outputSampleFormat,"; 844 z[lc++]=" void *outputDriverInfo,"; 845 z[lc++]=" double sampleRate,"; 846 z[lc++]=" unsigned long framesPerBuffer,"; 847 z[lc++]=" unsigned long numberOfBuffers,"; 848 z[lc++]=" unsigned long streamFlags,"; 849 z[lc++]=" PortAudioCallback *callback,"; 850 z[lc++]=" void *userData )"; 851 z[lc++]="{"; 852 z[lc++]=" internalPortAudioStream *past = NULL;"; 853 z[lc++]=" PaError result = paNoError;"; 854 z[lc++]=" int bitsPerInputSample;"; 855 z[lc++]=" int bitsPerOutputSample;"; 856 z[lc++]="/* Print passed parameters. */"; 857 z[lc++]=" DBUG((\"Pa_OpenStream( %p, %d, %d, %d, %p, /* input */ \\n\","; 858 z[lc++]=" streamPtrPtr, inputDeviceID, numInputChannels,"; 859 z[lc++]=" inputSampleFormat, inputDriverInfo ));"; 860 z[lc++]=" DBUG((\" %d, %d, %d, %p, /* output */\\n\","; 861 z[lc++]=" outputDeviceID, numOutputChannels,"; 862 z[lc++]=" outputSampleFormat, outputDriverInfo ));"; 863 z[lc++]=" DBUG((\" %g, %d, %d, 0x%x, , %p )\\n\","; 864 z[lc++]=" sampleRate, framesPerBuffer, numberOfBuffers,"; 865 z[lc++]=" streamFlags, userData ));"; 866 z[lc++]=""; 867 z[lc++]="/* Check for parameter errors. */"; 868 z[lc++]=" if( (streamFlags & ~(paClipOff | paDitherOff)) != 0 ) return paInvalidFlag;"; 869 z[lc++]=" if( streamPtrPtr == NULL ) return paBadStreamPtr;"; 870 z[lc++]=" if( inputDriverInfo != NULL ) return paHostError; /* REVIEW */"; 871 z[lc++]=" if( outputDriverInfo != NULL ) return paHostError; /* REVIEW */"; 872 z[lc++]=" if( (inputDeviceID < 0) && ( outputDeviceID < 0) ) return paInvalidDeviceId;"; 873 z[lc++]=" if( (outputDeviceID >= Pa_CountDevices()) || (inputDeviceID >= Pa_CountDevices()) )"; 874 z[lc++]=" {"; 875 z[lc++]=" return paInvalidDeviceId;"; 876 z[lc++]=" }"; 877 z[lc++]=" if( (numInputChannels <= 0) && ( numOutputChannels <= 0) ) return paInvalidChannelCount;"; 878 z[lc++]=""; 879 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; vacuum_set_xid_limits(Relation rel,int freeze_min_age,int freeze_table_age,int multixact_freeze_min_age,int multixact_freeze_table_age,TransactionId * oldestXmin,TransactionId * freezeLimit,TransactionId * xidFullScanLimit,MultiXactId * multiXactCutoff,MultiXactId * mxactFullScanLimit)880 z[lc++]=" if( inputDeviceID >= 0 )"; 881 z[lc++]=" {"; 882 z[lc++]=" PaError size = Pa_GetSampleSize( inputSampleFormat );"; 883 z[lc++]=" if( size < 0 ) return size;"; 884 z[lc++]=" bitsPerInputSample = 8 * size;"; 885 z[lc++]=" if( (numInputChannels <= 0) ) return paInvalidChannelCount;"; 886 z[lc++]=" }"; 887 z[lc++]="#else"; 888 z[lc++]=" if( inputDeviceID >= 0 )"; 889 z[lc++]=" {"; 890 z[lc++]=" return paInvalidChannelCount;"; 891 z[lc++]=" }"; 892 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 893 z[lc++]=" else"; 894 z[lc++]=" {"; 895 z[lc++]=" if( numInputChannels > 0 ) return paInvalidChannelCount;"; 896 z[lc++]=" bitsPerInputSample = 0;"; 897 z[lc++]=" }"; 898 z[lc++]=""; 899 z[lc++]=" if( outputDeviceID >= 0 )"; 900 z[lc++]=" {"; 901 z[lc++]=" PaError size = Pa_GetSampleSize( outputSampleFormat );"; 902 z[lc++]=" if( size < 0 ) return size;"; 903 z[lc++]=" bitsPerOutputSample = 8 * size;"; 904 z[lc++]=" if( (numOutputChannels <= 0) ) return paInvalidChannelCount;"; 905 z[lc++]=" }"; 906 z[lc++]=" else"; 907 z[lc++]=" {"; 908 z[lc++]=" if( numOutputChannels > 0 ) return paInvalidChannelCount;"; 909 z[lc++]=" bitsPerOutputSample = 0;"; 910 z[lc++]=" }"; 911 z[lc++]=""; 912 z[lc++]=" if( callback == NULL ) return paNullCallback;"; 913 z[lc++]=""; 914 z[lc++]="/* Allocate and clear stream structure. */"; 915 z[lc++]=" past = (internalPortAudioStream *) PaHost_AllocateFastMemory( sizeof(internalPortAudioStream) );"; 916 z[lc++]=" if( past == NULL ) return paInsufficientMemory;"; 917 z[lc++]=" memset( past, 0, sizeof(internalPortAudioStream) );"; 918 z[lc++]=" AddTraceMessage(\"Pa_OpenStream: past\", (long) past );"; 919 z[lc++]=" "; 920 z[lc++]=" past->past_Magic = PA_MAGIC; /* Set ID to catch bugs. */"; 921 z[lc++]=" past->past_FramesPerUserBuffer = framesPerBuffer;"; 922 z[lc++]=" past->past_NumUserBuffers = numberOfBuffers; /* NOTE - PaHost_OpenStream() NMUST CHECK FOR ZERO! */"; 923 z[lc++]=" past->past_Callback = callback;"; 924 z[lc++]=" past->past_UserData = userData;"; 925 z[lc++]=" past->past_OutputSampleFormat = outputSampleFormat;"; 926 z[lc++]=" past->past_InputSampleFormat = inputSampleFormat;"; 927 z[lc++]=" past->past_OutputDeviceID = outputDeviceID;"; 928 z[lc++]=" past->past_InputDeviceID = inputDeviceID;"; 929 z[lc++]=" past->past_NumInputChannels = numInputChannels;"; 930 z[lc++]=" past->past_NumOutputChannels = numOutputChannels;"; 931 z[lc++]=" past->past_Flags = streamFlags;"; 932 z[lc++]=""; 933 z[lc++]="/* Check for absurd sample rates. */"; 934 z[lc++]=" if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )"; 935 z[lc++]=" {"; 936 z[lc++]=" result = paInvalidSampleRate;"; 937 z[lc++]=" goto cleanup;"; 938 z[lc++]=" }"; 939 z[lc++]=""; 940 z[lc++]="/* Allocate buffers that may be used for format conversion from user to native buffers. */"; 941 z[lc++]=" if( numInputChannels > 0 )"; 942 z[lc++]=" {"; 943 z[lc++]=" "; 944 z[lc++]="#if PA_VALIDATE_RATE"; 945 z[lc++]=" result = PaHost_ValidateSampleRate( inputDeviceID, sampleRate, &past->past_SampleRate );"; 946 z[lc++]=" if( result < 0 )"; 947 z[lc++]=" {"; 948 z[lc++]=" goto cleanup;"; 949 z[lc++]=" }"; 950 z[lc++]="#else"; 951 z[lc++]=" past->past_SampleRate = sampleRate;"; 952 z[lc++]="#endif"; 953 z[lc++]="/* Allocate single Input buffer. */"; 954 z[lc++]=" past->past_InputBufferSize = framesPerBuffer * numInputChannels * ((bitsPerInputSample+7) / 8);"; 955 z[lc++]=" past->past_InputBuffer = PaHost_AllocateFastMemory(past->past_InputBufferSize);"; 956 z[lc++]=" if( past->past_InputBuffer == NULL )"; 957 z[lc++]=" {"; 958 z[lc++]=" result = paInsufficientMemory;"; 959 z[lc++]=" goto cleanup;"; 960 z[lc++]=" }"; 961 z[lc++]=" }"; 962 z[lc++]=" else"; 963 z[lc++]=" {"; 964 z[lc++]=" past->past_InputBuffer = NULL;"; 965 z[lc++]=" }"; 966 z[lc++]=""; 967 z[lc++]="/* Allocate single Output buffer. */"; 968 z[lc++]=" if( numOutputChannels > 0 )"; 969 z[lc++]=" {"; 970 z[lc++]="#if PA_VALIDATE_RATE"; 971 z[lc++]=" result = PaHost_ValidateSampleRate( outputDeviceID, sampleRate, &past->past_SampleRate );"; 972 z[lc++]=" if( result < 0 )"; 973 z[lc++]=" {"; 974 z[lc++]=" goto cleanup;"; 975 z[lc++]=" }"; 976 z[lc++]="#else"; 977 z[lc++]=" past->past_SampleRate = sampleRate;"; 978 z[lc++]="#endif"; 979 z[lc++]=" past->past_OutputBufferSize = framesPerBuffer * numOutputChannels * ((bitsPerOutputSample+7) / 8);"; 980 z[lc++]=" past->past_OutputBuffer = PaHost_AllocateFastMemory(past->past_OutputBufferSize);"; 981 z[lc++]=" if( past->past_OutputBuffer == NULL )"; 982 z[lc++]=" {"; 983 z[lc++]=" result = paInsufficientMemory;"; 984 z[lc++]=" goto cleanup;"; 985 z[lc++]=" }"; 986 z[lc++]=" }"; 987 z[lc++]=" else"; 988 z[lc++]=" {"; 989 z[lc++]=" past->past_OutputBuffer = NULL;"; 990 z[lc++]=" }"; 991 z[lc++]=""; 992 z[lc++]=" result = PaHost_OpenStream( past );"; 993 z[lc++]=" if( result < 0 ) goto cleanup;"; 994 z[lc++]=""; 995 z[lc++]=" *streamPtrPtr = (void *) past;"; 996 z[lc++]=""; 997 z[lc++]=" return result;"; 998 z[lc++]=""; 999 z[lc++]="cleanup:"; 1000 z[lc++]=" if( past != NULL ) Pa_CloseStream( past );"; 1001 z[lc++]=" *streamPtrPtr = NULL;"; 1002 z[lc++]=" return result;"; 1003 z[lc++]="}"; 1004 z[lc++]=""; 1005 z[lc++]=""; 1006 z[lc++]="/*************************************************************************/"; 1007 z[lc++]="PaError Pa_OpenDefaultStream( PortAudioStream** stream,"; 1008 z[lc++]=" int numInputChannels,"; 1009 z[lc++]=" int numOutputChannels,"; 1010 z[lc++]=" PaSampleFormat sampleFormat,"; 1011 z[lc++]=" double sampleRate,"; 1012 z[lc++]=" unsigned long framesPerBuffer,"; 1013 z[lc++]=" unsigned long numberOfBuffers,"; 1014 z[lc++]=" PortAudioCallback *callback,"; 1015 z[lc++]=" void *userData )"; 1016 z[lc++]="{"; 1017 z[lc++]=" return Pa_OpenStream("; 1018 z[lc++]=" stream,"; 1019 z[lc++]=" ((numInputChannels > 0) ? Pa_GetDefaultInputDeviceID() : paNoDevice),"; 1020 z[lc++]=" numInputChannels, sampleFormat, NULL,"; 1021 z[lc++]=" ((numOutputChannels > 0) ? Pa_GetDefaultOutputDeviceID() : paNoDevice),"; 1022 z[lc++]=" numOutputChannels, sampleFormat, NULL,"; 1023 z[lc++]=" sampleRate, framesPerBuffer, numberOfBuffers, paNoFlag, callback, userData );"; 1024 z[lc++]="}"; 1025 z[lc++]=""; 1026 z[lc++]="/*************************************************************************/"; 1027 z[lc++]="PaError Pa_CloseStream( PortAudioStream* stream)"; 1028 z[lc++]="{"; 1029 z[lc++]=" PaError result;"; 1030 z[lc++]=" internalPortAudioStream *past;"; 1031 z[lc++]=" "; 1032 z[lc++]=" DBUG((\"Pa_CloseStream()\\n\"));"; 1033 z[lc++]=" if( stream == NULL ) return paBadStreamPtr;"; 1034 z[lc++]=" past = (internalPortAudioStream *) stream;"; 1035 z[lc++]=""; 1036 z[lc++]=" Pa_AbortStream( past );"; 1037 z[lc++]=" result = PaHost_CloseStream( past );"; 1038 z[lc++]=" "; 1039 z[lc++]=" if( past->past_InputBuffer ) PaHost_FreeFastMemory( past->past_InputBuffer, past->past_InputBufferSize );"; 1040 z[lc++]=" if( past->past_OutputBuffer ) PaHost_FreeFastMemory( past->past_OutputBuffer, past->past_OutputBufferSize );"; 1041 z[lc++]=" PaHost_FreeFastMemory( past, sizeof(internalPortAudioStream) );"; 1042 z[lc++]=""; 1043 z[lc++]=" return result;"; 1044 z[lc++]="}"; 1045 z[lc++]=""; 1046 z[lc++]="/*************************************************************************/"; 1047 z[lc++]="PaError Pa_StartStream( PortAudioStream *stream )"; 1048 z[lc++]="{"; 1049 z[lc++]=" PaError result = paHostError;"; 1050 z[lc++]=" internalPortAudioStream *past;"; 1051 z[lc++]=""; 1052 z[lc++]=" if( stream == NULL ) return paBadStreamPtr;"; 1053 z[lc++]=" past = (internalPortAudioStream *) stream;"; 1054 z[lc++]=""; 1055 z[lc++]=" past->past_FrameCount = 0.0;"; 1056 z[lc++]=""; 1057 z[lc++]=" if( past->past_NumInputChannels > 0 )"; 1058 z[lc++]=" {"; 1059 z[lc++]=" result = PaHost_StartInput( past );"; 1060 z[lc++]=" DBUG((\"Pa_StartStream: PaHost_StartInput returned = 0x%X.\\n\", result));"; 1061 z[lc++]=" if( result < 0 ) goto error;"; 1062 z[lc++]=" }"; 1063 z[lc++]=""; 1064 z[lc++]=" if( past->past_NumOutputChannels > 0 )"; 1065 z[lc++]=" {"; 1066 z[lc++]=" result = PaHost_StartOutput( past );"; 1067 z[lc++]=" DBUG((\"Pa_StartStream: PaHost_StartOutput returned = 0x%X.\\n\", result));"; 1068 z[lc++]=" if( result < 0 ) goto error;"; 1069 z[lc++]=" }"; 1070 z[lc++]=""; 1071 z[lc++]=" result = PaHost_StartEngine( past );"; vac_estimate_reltuples(Relation relation,BlockNumber total_pages,BlockNumber scanned_pages,double scanned_tuples)1072 z[lc++]=" DBUG((\"Pa_StartStream: PaHost_StartEngine returned = 0x%X.\\n\", result));"; 1073 z[lc++]=" if( result < 0 ) goto error;"; 1074 z[lc++]=""; 1075 z[lc++]=" return paNoError;"; 1076 z[lc++]=""; 1077 z[lc++]="error:"; 1078 z[lc++]=" return result;"; 1079 z[lc++]="}"; 1080 z[lc++]=""; 1081 z[lc++]="/*************************************************************************/"; 1082 z[lc++]="PaError Pa_StopStream( PortAudioStream *stream )"; 1083 z[lc++]="{"; 1084 z[lc++]=" return Pa_KillStream( stream, 0 );"; 1085 z[lc++]="}"; 1086 z[lc++]=""; 1087 z[lc++]="/*************************************************************************/"; 1088 z[lc++]="PaError Pa_AbortStream( PortAudioStream *stream )"; 1089 z[lc++]="{"; 1090 z[lc++]=" return Pa_KillStream( stream, 1 );"; 1091 z[lc++]="}"; 1092 z[lc++]=""; 1093 z[lc++]="/*************************************************************************/"; 1094 z[lc++]="static PaError Pa_KillStream( PortAudioStream *stream, int abort )"; 1095 z[lc++]="{"; 1096 z[lc++]=" PaError result = paNoError;"; 1097 z[lc++]=" internalPortAudioStream *past;"; 1098 z[lc++]=""; 1099 z[lc++]=" DBUG((\"Pa_StopStream().\\n\"));"; 1100 z[lc++]=" if( stream == NULL ) return paBadStreamPtr;"; 1101 z[lc++]=" past = (internalPortAudioStream *) stream;"; 1102 z[lc++]=""; 1103 z[lc++]=" if( (past->past_NumInputChannels > 0) || (past->past_NumOutputChannels > 0) )"; 1104 z[lc++]=" {"; 1105 z[lc++]=" result = PaHost_StopEngine( past, abort );"; 1106 z[lc++]=" DBUG((\"Pa_StopStream: PaHost_StopEngine returned = 0x%X.\\n\", result));"; 1107 z[lc++]=" if( result < 0 ) goto error;"; 1108 z[lc++]=" }"; 1109 z[lc++]=""; 1110 z[lc++]=" if( past->past_NumInputChannels > 0 )"; 1111 z[lc++]=" {"; 1112 z[lc++]=" result = PaHost_StopInput( past, abort );"; 1113 z[lc++]=" DBUG((\"Pa_StopStream: PaHost_StopInput returned = 0x%X.\\n\", result));"; 1114 z[lc++]=" if( result != paNoError ) goto error;"; 1115 z[lc++]=" }"; 1116 z[lc++]=""; 1117 z[lc++]=" if( past->past_NumOutputChannels > 0 )"; 1118 z[lc++]=" {"; 1119 z[lc++]=" result = PaHost_StopOutput( past, abort );"; 1120 z[lc++]=" DBUG((\"Pa_StopStream: PaHost_StopOutput returned = 0x%X.\\n\", result));"; 1121 z[lc++]=" if( result != paNoError ) goto error;"; 1122 z[lc++]=" }"; 1123 z[lc++]=""; 1124 z[lc++]="error:"; 1125 z[lc++]=" past->past_Usage = 0;"; 1126 z[lc++]=" past->past_IfLastExitValid = 0;"; 1127 z[lc++]=" "; 1128 z[lc++]=" return result;"; 1129 z[lc++]="}"; 1130 z[lc++]=""; 1131 z[lc++]="/*************************************************************************/"; 1132 z[lc++]="PaError Pa_StreamActive( PortAudioStream *stream )"; 1133 z[lc++]="{"; 1134 z[lc++]=" internalPortAudioStream *past;"; 1135 z[lc++]=" if( stream == NULL ) return paBadStreamPtr;"; 1136 z[lc++]=" past = (internalPortAudioStream *) stream;"; 1137 z[lc++]=" return PaHost_StreamActive( past );"; 1138 z[lc++]="}"; 1139 z[lc++]=""; 1140 z[lc++]="/*************************************************************************/"; 1141 z[lc++]="const char *Pa_GetErrorText( PaError errnum )"; 1142 z[lc++]="{"; 1143 z[lc++]=" const char *msg;"; 1144 z[lc++]=""; 1145 z[lc++]=" switch(errnum)"; 1146 z[lc++]=" {"; 1147 z[lc++]=" case paNoError: msg = \"Success\"; break;"; 1148 z[lc++]=" case paHostError: msg = \"Host error.\"; break;"; 1149 z[lc++]=" case paInvalidChannelCount: msg = \"Invalid number of channels.\"; break;"; 1150 z[lc++]=" case paInvalidSampleRate: msg = \"Invalid sample rate.\"; break;"; 1151 z[lc++]=" case paInvalidDeviceId: msg = \"Invalid device ID.\"; break;"; 1152 z[lc++]=" case paInvalidFlag: msg = \"Invalid flag.\"; break;"; 1153 z[lc++]=" case paSampleFormatNotSupported: msg = \"Sample format not supported\"; break;"; 1154 z[lc++]=" case paBadIODeviceCombination: msg = \"Illegal combination of I/O devices.\"; break;"; 1155 z[lc++]=" case paInsufficientMemory: msg = \"Insufficient memory.\"; break;"; 1156 z[lc++]=" case paBufferTooBig: msg = \"Buffer too big.\"; break;"; vac_update_relstats(Relation relation,BlockNumber num_pages,double num_tuples,BlockNumber num_all_visible_pages,bool hasindex,TransactionId frozenxid,MultiXactId minmulti,bool in_outer_xact)1157 z[lc++]=" case paBufferTooSmall: msg = \"Buffer too small.\"; break;"; 1158 z[lc++]=" case paNullCallback: msg = \"No callback routine specified.\"; break;"; 1159 z[lc++]=" case paBadStreamPtr: msg = \"Invalid stream pointer.\"; break;"; 1160 z[lc++]=" case paTimedOut : msg = \"Wait Timed Out.\"; break;"; 1161 z[lc++]=" case paInternalError: msg = \"Internal PortAudio Error.\"; break;"; 1162 z[lc++]=" default: msg = \"Illegal error number.\"; break;"; 1163 z[lc++]=" }"; 1164 z[lc++]=" return msg;"; 1165 z[lc++]="}"; 1166 z[lc++]=""; 1167 z[lc++]="/*"; 1168 z[lc++]=" Get CPU Load as a fraction of total CPU time."; 1169 z[lc++]=" A value of 0.5 would imply that PortAudio and the sound generating"; 1170 z[lc++]=" callback was consuming roughly 50% of the available CPU time."; 1171 z[lc++]=" The amount may vary depending on CPU load."; 1172 z[lc++]=" This function may be called from the callback function."; 1173 z[lc++]="*/"; 1174 z[lc++]="double Pa_GetCPULoad( PortAudioStream* stream)"; 1175 z[lc++]="{"; 1176 z[lc++]=" internalPortAudioStream *past;"; 1177 z[lc++]=" if( stream == NULL ) return (double) paBadStreamPtr;"; 1178 z[lc++]=" past = (internalPortAudioStream *) stream;"; 1179 z[lc++]=" return past->past_Usage;"; 1180 z[lc++]="}"; 1181 z[lc++]=""; 1182 z[lc++]="/*************************************************************"; 1183 z[lc++]="** Calculate 2 LSB dither signal with a triangular distribution."; 1184 z[lc++]="** Ranged properly for adding to a 32 bit integer prior to >>15."; 1185 z[lc++]="*/"; 1186 z[lc++]="#define DITHER_BITS (15)"; 1187 z[lc++]="#define DITHER_SCALE (1.0f / ((1<<DITHER_BITS)-1))"; 1188 z[lc++]="static long Pa_TriangularDither( void )"; 1189 z[lc++]="{"; 1190 z[lc++]=" static unsigned long previous = 0;"; 1191 z[lc++]=" static unsigned long randSeed1 = 22222;"; 1192 z[lc++]=" static unsigned long randSeed2 = 5555555;"; 1193 z[lc++]=" long current, highPass;"; 1194 z[lc++]="/* Generate two random numbers. */"; 1195 z[lc++]=" randSeed1 = (randSeed1 * 196314165) + 907633515;"; 1196 z[lc++]=" randSeed2 = (randSeed2 * 196314165) + 907633515;"; 1197 z[lc++]="/* Generate triangular distribution about 0. */"; 1198 z[lc++]=" current = (((long)randSeed1)>>(32-DITHER_BITS)) + (((long)randSeed2)>>(32-DITHER_BITS));"; 1199 z[lc++]=" /* High pass filter to reduce audibility. */"; 1200 z[lc++]=" highPass = current - previous;"; 1201 z[lc++]=" previous = current;"; 1202 z[lc++]=" return highPass;"; 1203 z[lc++]="}"; 1204 z[lc++]=""; 1205 z[lc++]="/*************************************************************************"; 1206 z[lc++]="** Called by host code."; 1207 z[lc++]="** Convert input from Int16, call user code, then convert output"; 1208 z[lc++]="** to Int16 format for native use."; 1209 z[lc++]="** Assumes host native format is paInt16."; 1210 z[lc++]="** Returns result from user callback."; 1211 z[lc++]="*/"; 1212 z[lc++]="long Pa_CallConvertInt16( internalPortAudioStream *past, "; 1213 z[lc++]=" short *nativeInputBuffer,"; 1214 z[lc++]=" short *nativeOutputBuffer )"; 1215 z[lc++]="{"; 1216 z[lc++]=" long temp;"; 1217 z[lc++]=" long bytesEmpty = 0;"; 1218 z[lc++]=" long bytesFilled = 0;"; 1219 z[lc++]=" int userResult;"; 1220 z[lc++]=" unsigned int i;"; 1221 z[lc++]=" void *inputBuffer = NULL;"; 1222 z[lc++]=" void *outputBuffer = NULL;"; 1223 z[lc++]=" "; 1224 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 1225 z[lc++]="/* Get native data from DirectSound. */"; 1226 z[lc++]=" if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )"; 1227 z[lc++]=" {"; 1228 z[lc++]="/* Convert from native format to PA format. */"; 1229 z[lc++]=" unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels;"; 1230 z[lc++]=" switch(past->past_InputSampleFormat)"; 1231 z[lc++]=" {"; 1232 z[lc++]=" "; 1233 z[lc++]=" case paFloat32:"; 1234 z[lc++]=" {"; 1235 z[lc++]=" float *inBufPtr = (float *) past->past_InputBuffer;"; 1236 z[lc++]=" inputBuffer = past->past_InputBuffer;"; 1237 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1238 z[lc++]=" {"; 1239 z[lc++]=" inBufPtr[i] = nativeInputBuffer[i] * (1.0f / 32767.0f);"; 1240 z[lc++]=" }"; 1241 z[lc++]=" break;"; 1242 z[lc++]=" }"; 1243 z[lc++]=" "; 1244 z[lc++]=" case paInt32:"; 1245 z[lc++]=" {"; 1246 z[lc++]=" /* Convert 16 bit data to 32 bit integers */"; 1247 z[lc++]=" int *inBufPtr = (int *) past->past_InputBuffer;"; 1248 z[lc++]=" inputBuffer = past->past_InputBuffer;"; 1249 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1250 z[lc++]=" {"; 1251 z[lc++]=" inBufPtr[i] = nativeInputBuffer[i] << 16;"; 1252 z[lc++]=" }"; 1253 z[lc++]=" break;"; 1254 z[lc++]=" }"; 1255 z[lc++]=" "; 1256 z[lc++]=" case paInt16:"; 1257 z[lc++]=" {"; 1258 z[lc++]=" /* Already in correct format so don't copy. */"; 1259 z[lc++]=" inputBuffer = nativeInputBuffer;"; 1260 z[lc++]=" break;"; 1261 z[lc++]=" }"; 1262 z[lc++]=""; 1263 z[lc++]=" case paInt8:"; 1264 z[lc++]=" {"; 1265 z[lc++]=" /* Convert 16 bit data to 8 bit chars */"; 1266 z[lc++]=" char *inBufPtr = (char *) past->past_InputBuffer;"; 1267 z[lc++]=" inputBuffer = past->past_InputBuffer;"; 1268 z[lc++]=" if( past->past_Flags & paDitherOff )"; 1269 z[lc++]=" {"; 1270 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1271 z[lc++]=" {"; 1272 z[lc++]=" inBufPtr[i] = (char)(nativeInputBuffer[i] >> 8);"; 1273 z[lc++]=" }"; 1274 z[lc++]=" }"; 1275 z[lc++]=" else"; 1276 z[lc++]=" {"; 1277 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1278 z[lc++]=" {"; 1279 z[lc++]=" temp = nativeInputBuffer[i];"; 1280 z[lc++]=" temp += Pa_TriangularDither() >> 8; /* PLB20010820 */"; 1281 z[lc++]=" temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));"; 1282 z[lc++]=" inBufPtr[i] = (char)(temp >> 8);"; 1283 z[lc++]=" }"; vac_update_datfrozenxid(void)1284 z[lc++]=" }"; 1285 z[lc++]=" break;"; 1286 z[lc++]=" }"; 1287 z[lc++]=""; 1288 z[lc++]=" case paUInt8:"; 1289 z[lc++]=" {"; 1290 z[lc++]=" /* Convert 16 bit data to 8 bit unsigned chars */"; 1291 z[lc++]=" unsigned char *inBufPtr = (unsigned char *) past->past_InputBuffer;"; 1292 z[lc++]=" inputBuffer = past->past_InputBuffer;"; 1293 z[lc++]=" if( past->past_Flags & paDitherOff )"; 1294 z[lc++]=" {"; 1295 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1296 z[lc++]=" {"; 1297 z[lc++]=" inBufPtr[i] = ((unsigned char)(nativeInputBuffer[i] >> 8)) + 0x80;"; 1298 z[lc++]=" }"; 1299 z[lc++]=" }"; 1300 z[lc++]=" else"; 1301 z[lc++]=" {"; 1302 z[lc++]=" /* If you dither then you have to clip because dithering could push the signal out of range! */"; 1303 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1304 z[lc++]=" {"; 1305 z[lc++]=" temp = nativeInputBuffer[i];"; 1306 z[lc++]=" temp += Pa_TriangularDither() >> 8; /* PLB20010820 */"; 1307 z[lc++]=" temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));"; 1308 z[lc++]=" inBufPtr[i] = (unsigned char)((temp>>8) + 0x80); /* PLB20010820 */"; 1309 z[lc++]=" }"; 1310 z[lc++]=" }"; 1311 z[lc++]=" break;"; 1312 z[lc++]=" }"; 1313 z[lc++]=" "; 1314 z[lc++]=" default:"; 1315 z[lc++]=" break;"; 1316 z[lc++]=" }"; 1317 z[lc++]=" }"; 1318 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 1319 z[lc++]=""; 1320 z[lc++]="/* Are we doing output time? */"; 1321 z[lc++]=" if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )"; 1322 z[lc++]=" {"; 1323 z[lc++]=" /* May already be in native format so just write directly to native buffer. */"; 1324 z[lc++]=" outputBuffer = (past->past_OutputSampleFormat == paInt16) ?"; 1325 z[lc++]=" nativeOutputBuffer : past->past_OutputBuffer;"; 1326 z[lc++]=" }"; 1327 z[lc++]="/* "; 1328 z[lc++]=" AddTraceMessage(\"Pa_CallConvertInt16: inputBuffer = \", (int) inputBuffer );"; 1329 z[lc++]=" AddTraceMessage(\"Pa_CallConvertInt16: outputBuffer = \", (int) outputBuffer );"; 1330 z[lc++]="*/ "; 1331 z[lc++]="/* Call user callback routine. */"; 1332 z[lc++]=" userResult = past->past_Callback("; 1333 z[lc++]=" inputBuffer,"; 1334 z[lc++]=" outputBuffer,"; 1335 z[lc++]=" past->past_FramesPerUserBuffer,"; 1336 z[lc++]=" past->past_FrameCount,"; 1337 z[lc++]=" past->past_UserData );"; 1338 z[lc++]=""; 1339 z[lc++]=" past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;"; 1340 z[lc++]=""; 1341 z[lc++]="/* Convert to native format if necessary. */"; 1342 z[lc++]=" if( outputBuffer != NULL )"; 1343 z[lc++]=" {"; 1344 z[lc++]=" unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels;"; 1345 z[lc++]=" switch(past->past_OutputSampleFormat)"; 1346 z[lc++]=" {"; 1347 z[lc++]=" case paFloat32:"; 1348 z[lc++]=" {"; 1349 z[lc++]=" float *outBufPtr = (float *) past->past_OutputBuffer;"; 1350 z[lc++]=" if( past->past_Flags & paDitherOff )"; 1351 z[lc++]=" {"; 1352 z[lc++]=" if( past->past_Flags & paClipOff ) /* NOTHING */"; 1353 z[lc++]=" {"; 1354 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1355 z[lc++]=" {"; 1356 z[lc++]=" *nativeOutputBuffer++ = (short) (outBufPtr[i] * (32767.0f));"; 1357 z[lc++]=" }"; 1358 z[lc++]=" }"; 1359 z[lc++]=" else /* CLIP */"; 1360 z[lc++]=" {"; 1361 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1362 z[lc++]=" {"; 1363 z[lc++]=" temp = (long)(outBufPtr[i] * 32767.0f);"; 1364 z[lc++]=" *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));"; 1365 z[lc++]=" }"; 1366 z[lc++]=" }"; 1367 z[lc++]=" }"; 1368 z[lc++]=" else"; 1369 z[lc++]=" {"; 1370 z[lc++]=" /* If you dither then you have to clip because dithering could push the signal out of range! */"; 1371 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1372 z[lc++]=" {"; 1373 z[lc++]=" float dither = Pa_TriangularDither()*DITHER_SCALE;"; 1374 z[lc++]=" float dithered = (outBufPtr[i] * (32767.0f)) + dither;"; 1375 z[lc++]=" temp = (long) (dithered);"; 1376 z[lc++]=" *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));"; 1377 z[lc++]=" }"; 1378 z[lc++]=" }"; 1379 z[lc++]=" break;"; 1380 z[lc++]=" }"; 1381 z[lc++]=" "; 1382 z[lc++]=" case paInt32:"; 1383 z[lc++]=" {"; 1384 z[lc++]=" int *outBufPtr = (int *) past->past_OutputBuffer;"; 1385 z[lc++]=" if( past->past_Flags & paDitherOff )"; 1386 z[lc++]=" {"; 1387 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1388 z[lc++]=" {"; 1389 z[lc++]=" *nativeOutputBuffer++ = (short) (outBufPtr[i] >> 16 );"; 1390 z[lc++]=" }"; 1391 z[lc++]=" }"; 1392 z[lc++]=" else"; 1393 z[lc++]=" {"; 1394 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1395 z[lc++]=" {"; 1396 z[lc++]=" /* Shift one bit down before dithering so that we have room for overflow from add. */"; 1397 z[lc++]=" temp = (outBufPtr[i] >> 1) + Pa_TriangularDither();"; 1398 z[lc++]=" temp = temp >> 15;"; 1399 z[lc++]=" *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));"; 1400 z[lc++]=" }"; 1401 z[lc++]=" }"; 1402 z[lc++]=" break;"; 1403 z[lc++]=" }"; 1404 z[lc++]=""; 1405 z[lc++]=" case paInt8:"; 1406 z[lc++]=" {"; 1407 z[lc++]=" char *outBufPtr = (char *) past->past_OutputBuffer;"; 1408 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1409 z[lc++]=" {"; 1410 z[lc++]=" *nativeOutputBuffer++ = ((short)outBufPtr[i]) << 8;"; 1411 z[lc++]=" }"; 1412 z[lc++]=" break;"; 1413 z[lc++]=" }"; 1414 z[lc++]=""; 1415 z[lc++]=" case paUInt8:"; 1416 z[lc++]=" {"; 1417 z[lc++]=" unsigned char *outBufPtr = (unsigned char *) past->past_OutputBuffer;"; 1418 z[lc++]=" for( i=0; i<samplesPerBuffer; i++ )"; 1419 z[lc++]=" {"; 1420 z[lc++]=" *nativeOutputBuffer++ = ((short)(outBufPtr[i] - 0x80)) << 8;"; 1421 z[lc++]=" }"; 1422 z[lc++]=" break;"; 1423 z[lc++]=" }"; 1424 z[lc++]=""; 1425 z[lc++]=" default:"; 1426 z[lc++]=" break;"; 1427 z[lc++]=" }"; 1428 z[lc++]=""; 1429 z[lc++]=" }"; 1430 z[lc++]=" "; 1431 z[lc++]=" return userResult;"; 1432 z[lc++]="}"; 1433 z[lc++]=""; 1434 z[lc++]="/*************************************************************************"; 1435 z[lc++]="** Called by host code."; 1436 z[lc++]="** Convert input from Float32, call user code, then convert output"; 1437 z[lc++]="** to Float32 format for native use."; 1438 z[lc++]="** Assumes host native format is Float32."; 1439 z[lc++]="** Returns result from user callback."; 1440 z[lc++]="** FIXME - Unimplemented for formats other than paFloat32!!!!"; 1441 z[lc++]="*/"; 1442 z[lc++]="long Pa_CallConvertFloat32( internalPortAudioStream *past, "; 1443 z[lc++]=" float *nativeInputBuffer,"; 1444 z[lc++]=" float *nativeOutputBuffer )"; 1445 z[lc++]="{"; 1446 z[lc++]=" long bytesEmpty = 0;"; 1447 z[lc++]=" long bytesFilled = 0;"; 1448 z[lc++]=" int userResult;"; 1449 z[lc++]=" void *inputBuffer = NULL;"; 1450 z[lc++]=" void *outputBuffer = NULL;"; 1451 z[lc++]=" "; 1452 z[lc++]="/* Get native data from DirectSound. */"; 1453 z[lc++]=" if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )"; 1454 z[lc++]=" {"; 1455 z[lc++]=" inputBuffer = nativeInputBuffer; /* FIXME */"; 1456 z[lc++]=" }"; 1457 z[lc++]=" "; 1458 z[lc++]="/* Are we doing output time? */"; 1459 z[lc++]=" if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )"; 1460 z[lc++]=" {"; 1461 z[lc++]=" /* May already be in native format so just write directly to native buffer. */"; 1462 z[lc++]=" outputBuffer = (past->past_OutputSampleFormat == paFloat32) ?"; 1463 z[lc++]=" nativeOutputBuffer : past->past_OutputBuffer;"; 1464 z[lc++]=" }"; 1465 z[lc++]="/* "; 1466 z[lc++]=" AddTraceMessage(\"Pa_CallConvertInt16: inputBuffer = \", (int) inputBuffer );"; 1467 z[lc++]=" AddTraceMessage(\"Pa_CallConvertInt16: outputBuffer = \", (int) outputBuffer );"; 1468 z[lc++]="*/ "; 1469 z[lc++]="/* Call user callback routine. */"; 1470 z[lc++]=" userResult = past->past_Callback("; 1471 z[lc++]=" inputBuffer,"; 1472 z[lc++]=" outputBuffer,"; 1473 z[lc++]=" past->past_FramesPerUserBuffer,"; 1474 z[lc++]=" past->past_FrameCount,"; 1475 z[lc++]=" past->past_UserData );"; 1476 z[lc++]=""; 1477 z[lc++]=" past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;"; 1478 z[lc++]=""; 1479 z[lc++]="/* Convert to native format if necessary. */ /* FIXME */ "; 1480 z[lc++]=" return userResult;"; vac_truncate_clog(TransactionId frozenXID,MultiXactId minMulti,TransactionId lastSaneFrozenXid,MultiXactId lastSaneMinMulti)1481 z[lc++]="}"; 1482 z[lc++]=""; 1483 z[lc++]="/*************************************************************************/"; 1484 z[lc++]="PaError Pa_Initialize( void )"; 1485 z[lc++]="{"; 1486 z[lc++]=" if( gInitCount++ > 0 ) return paNoError;"; 1487 z[lc++]=" ResetTraceMessages();"; 1488 z[lc++]=" return PaHost_Init();"; 1489 z[lc++]="}"; 1490 z[lc++]=""; 1491 z[lc++]="PaError Pa_Terminate( void )"; 1492 z[lc++]="{"; 1493 z[lc++]=" PaError result = paNoError;"; 1494 z[lc++]=""; 1495 z[lc++]=" if( gInitCount == 0 ) return paNoError;"; 1496 z[lc++]=" else if( --gInitCount == 0 )"; 1497 z[lc++]=" {"; 1498 z[lc++]=" result = PaHost_Term();"; 1499 z[lc++]=" DumpTraceMessages();"; 1500 z[lc++]=" }"; 1501 z[lc++]=" return result;"; 1502 z[lc++]="}"; 1503 z[lc++]=""; 1504 z[lc++]="/*************************************************************************/"; 1505 z[lc++]="PaError Pa_GetSampleSize( PaSampleFormat format )"; 1506 z[lc++]="{"; 1507 z[lc++]=" int size;"; 1508 z[lc++]=" switch(format )"; 1509 z[lc++]=" {"; 1510 z[lc++]=""; 1511 z[lc++]=" case paUInt8:"; 1512 z[lc++]=" case paInt8:"; 1513 z[lc++]=" size = 1;"; 1514 z[lc++]=" break;"; 1515 z[lc++]=""; 1516 z[lc++]=" case paInt16:"; 1517 z[lc++]=" size = 2;"; 1518 z[lc++]=" break;"; 1519 z[lc++]=""; 1520 z[lc++]=" case paPackedInt24:"; 1521 z[lc++]=" size = 3;"; 1522 z[lc++]=" break;"; 1523 z[lc++]=""; 1524 z[lc++]=" case paFloat32:"; 1525 z[lc++]=" case paInt32:"; 1526 z[lc++]=" case paInt24:"; 1527 z[lc++]=" size = 4;"; 1528 z[lc++]=" break;"; 1529 z[lc++]=""; 1530 z[lc++]=" default:"; 1531 z[lc++]=" size = paSampleFormatNotSupported;"; 1532 z[lc++]=" break;"; 1533 z[lc++]=" }"; 1534 z[lc++]=" return (PaError) size;"; 1535 z[lc++]="}"; 1536 z[lc++]=""; 1537 z[lc++]=""; 1538 printlib(lc); 1539 } 1540 1541 1542 void makepa_unix_oss(void) 1543 { 1544 int lc = 0; 1545 1546 z[lc++]="/*"; 1547 z[lc++]=" * PortAudio Portable Real-Time Audio Library"; 1548 z[lc++]=" * Latest Version at: http://www.portaudio.com"; 1549 z[lc++]=" * Linux OSS Implementation by douglas repetto and Phil Burk"; 1550 z[lc++]=" *"; 1551 z[lc++]=" * Copyright (c) 1999-2000 Phil Burk"; 1552 z[lc++]=" *"; 1553 z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining"; 1554 z[lc++]=" * a copy of this software and associated documentation files"; 1555 z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,"; 1556 z[lc++]=" * including without limitation the rights to use, copy, modify, merge,"; 1557 z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,"; 1558 z[lc++]=" * and to permit persons to whom the Software is furnished to do so,"; 1559 z[lc++]=" * subject to the following conditions:"; 1560 z[lc++]=" *"; 1561 z[lc++]=" * The above copyright notice and this permission notice shall be"; 1562 z[lc++]=" * included in all copies or substantial portions of the Software."; 1563 z[lc++]=" *"; 1564 z[lc++]=" * Any person wishing to distribute modifications to the Software is"; 1565 z[lc++]=" * requested to send the modifications to the original developer so that"; 1566 z[lc++]=" * they can be incorporated into the canonical version."; 1567 z[lc++]=" *"; 1568 z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,"; 1569 z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF"; 1570 z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT."; 1571 z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR"; 1572 z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF"; 1573 z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION"; 1574 z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."; 1575 z[lc++]=" *"; 1576 z[lc++]=" */"; 1577 z[lc++]="/*"; 1578 z[lc++]="Modfication History"; 1579 z[lc++]=" 1/2001 - Phil Burk - initial hack for Linux"; 1580 z[lc++]=" 2/2001 - Douglas Repetto - many improvements, initial query support"; 1581 z[lc++]=" 4/2/2001 - Phil - stop/abort thread control, separate in/out native buffers"; 1582 z[lc++]=" 5/28/2001 - Phil - use pthread_create() instead of clone(). Thanks Stephen Brandon!"; 1583 z[lc++]=" use pthread_join() after thread shutdown."; 1584 z[lc++]=" 5/29/2001 - Phil - query for multiple devices, multiple formats,"; 1585 z[lc++]=" input mode and input+output mode working,"; 1586 z[lc++]=" Pa_GetCPULoad() implemented."; 1587 z[lc++]=" PLB20010817 - Phil & Janos Haber - don't halt if test of sample rate fails."; 1588 z[lc++]=" SB20010904 - Stephen Brandon - mods needed for GNUSTEP and SndKit"; 1589 z[lc++]=" JH20010905 - Janos Haber - FreeBSD mods"; 1590 z[lc++]=" 2001-09-22 - Heiko - (i.e. Heiko Purnhagen <purnhage@tnt.uni-hannover.de> ;-)"; 1591 z[lc++]=" added 24k and 16k to ratesToTry[]"; 1592 z[lc++]=" fixed Pa_GetInternalDevice()"; 1593 z[lc++]=" changed DEVICE_NAME_BASE from /dev/audio to /dev/dsp"; 1594 z[lc++]=" handled SNDCTL_DSP_SPEED in Pq_QueryDevice() more graceful"; 1595 z[lc++]=" fixed Pa_StreamTime() for paqa_errs.c"; 1596 z[lc++]=" fixed numCannel=2 oddity and error handling in Pa_SetupDeviceFormat()"; 1597 z[lc++]=" grep also for HP20010922 ..."; 1598 z[lc++]=" PLB20010924 - Phil - merged Heiko's changes"; 1599 z[lc++]=" removed sNumDevices and potential related bugs,"; 1600 z[lc++]=" use getenv(\"PA_MIN_LATENCY_MSEC\") to set desired latency,"; 1601 z[lc++]=" simplify CPU Load calculation by comparing real-time to framesPerBuffer,"; 1602 z[lc++]=" always close device when querying even if error occurs,"; 1603 z[lc++]=" PLB20010927 - Phil - Improved negotiation for numChannels."; 1604 z[lc++]=" "; 1605 z[lc++]=" "; 1606 z[lc++]="TODO"; 1607 z[lc++]="O- change Pa_StreamTime() to query device (patest_sync.c)"; 1608 z[lc++]="O- put semaphore lock around shared data?"; 1609 z[lc++]="O- handle native formats better"; 1610 z[lc++]="O- handle stereo-only device better ???"; 1611 z[lc++]="O- what if input and output of a device capabilities differ (e.g. es1371) ???"; 1612 z[lc++]="*/"; 1613 z[lc++]="/*"; 1614 z[lc++]=" PROPOSED - should we add this to \"portaudio.h\". Problem with "; 1615 z[lc++]=" Pa_QueryDevice() not having same driver name os Pa_OpenStream()."; 1616 z[lc++]=""; 1617 z[lc++]=" A PaDriverInfo structure can be passed to the underlying device"; 1618 z[lc++]=" on the Pa_OpenStream() call. The contents and interpretation of"; 1619 z[lc++]=" the structure is determined by the PA implementation."; 1620 z[lc++]="*/"; 1621 z[lc++]="typedef struct PaDriverInfo /* PROPOSED */"; 1622 z[lc++]="{"; 1623 z[lc++]="/* Size of structure. Allows driver to extend the structure without breaking existing applications. */"; 1624 z[lc++]=" int size;"; 1625 z[lc++]="/* Can be used to request a specific device name. */"; 1626 z[lc++]=" const char *name;"; 1627 z[lc++]=" unsigned long data;"; 1628 z[lc++]="} PaDriverInfo;"; 1629 z[lc++]=""; 1630 z[lc++]=""; 1631 z[lc++]=""; vacuum_rel(Oid relid,RangeVar * relation,VacuumParams * params)1632 z[lc++]="#include <stdio.h>"; 1633 z[lc++]="#include <stdlib.h>"; 1634 z[lc++]="#include <malloc.h>"; 1635 z[lc++]="#include <memory.h>"; 1636 z[lc++]="#include <math.h>"; 1637 z[lc++]="#if 0"; 1638 z[lc++]="#include \"portaudio.h\""; 1639 z[lc++]="#include \"pa_host.h\""; 1640 z[lc++]="#include \"pa_trace.h\""; 1641 z[lc++]="#endif"; 1642 z[lc++]="#include <sys/ioctl.h>"; 1643 z[lc++]="#include <sys/time.h>"; 1644 z[lc++]="#include <fcntl.h> "; 1645 z[lc++]="#include <unistd.h> "; 1646 z[lc++]="#include <signal.h> "; 1647 z[lc++]="#include <stdio.h> "; 1648 z[lc++]="#include <stdlib.h>"; 1649 z[lc++]=""; 1650 z[lc++]="#ifdef __linux__"; 1651 z[lc++]="#include <linux/soundcard.h>"; 1652 z[lc++]="#else"; 1653 z[lc++]="#include <machine/soundcard.h> /* JH20010905 */"; 1654 z[lc++]="#endif"; 1655 z[lc++]=""; 1656 z[lc++]="#include <sched.h> "; 1657 z[lc++]="#include <pthread.h> "; 1658 z[lc++]=" "; 1659 z[lc++]="/* Some versions of OSS do not define AFMT_S16_NE. Assume little endian. FIXME - check CPU*/ "; 1660 z[lc++]="#ifndef AFMT_S16_NE"; 1661 z[lc++]=" #define AFMT_S16_NE AFMT_S16_LE"; 1662 z[lc++]="#endif"; 1663 z[lc++]=""; 1664 z[lc++]="#define PRINT(x) { printf x; fflush(stdout); }"; 1665 z[lc++]="#define ERR_RPT(x) PRINT(x)"; 1666 z[lc++]="#define DBUG(x) /* PRINT(x) */"; 1667 z[lc++]="#define DBUGX(x) /* PRINT(x) */"; 1668 z[lc++]=""; 1669 z[lc++]="#define BAD_DEVICE_ID (-1)"; 1670 z[lc++]=""; 1671 z[lc++]="#define MIN_LATENCY_MSEC (2)"; 1672 z[lc++]="#define MIN_TIMEOUT_MSEC (100)"; 1673 z[lc++]="#define MAX_TIMEOUT_MSEC (1000)"; 1674 z[lc++]=""; 1675 z[lc++]="/************************************************* Definitions ********/"; 1676 z[lc++]="#ifdef __linux__"; 1677 z[lc++]=" #define DEVICE_NAME_BASE \"/dev/dsp\""; 1678 z[lc++]="#else"; 1679 z[lc++]=" #define DEVICE_NAME_BASE \"/dev/audio\""; 1680 z[lc++]="#endif"; 1681 z[lc++]=""; 1682 z[lc++]="#define MAX_CHARS_DEVNAME (32)"; 1683 z[lc++]="#define MAX_SAMPLE_RATES (10)"; 1684 z[lc++]="typedef struct internalPortAudioDevice"; 1685 z[lc++]="{"; 1686 z[lc++]=" struct internalPortAudioDevice *pad_Next; /* Singly linked list. */"; 1687 z[lc++]=" double pad_SampleRates[MAX_SAMPLE_RATES]; /* for pointing to from pad_Info */"; 1688 z[lc++]=" char pad_DeviceName[MAX_CHARS_DEVNAME];"; 1689 z[lc++]=" PaDeviceInfo pad_Info;"; 1690 z[lc++]="} internalPortAudioDevice;"; 1691 z[lc++]=""; 1692 z[lc++]="/* Define structure to contain all OSS and Linux specific data. */"; 1693 z[lc++]="typedef struct PaHostSoundControl"; 1694 z[lc++]="{"; 1695 z[lc++]=" int pahsc_OutputHandle;"; 1696 z[lc++]=" int pahsc_InputHandle;"; 1697 z[lc++]=" pthread_t pahsc_ThreadPID;"; 1698 z[lc++]=" short *pahsc_NativeInputBuffer;"; 1699 z[lc++]=" short *pahsc_NativeOutputBuffer;"; 1700 z[lc++]=" unsigned int pahsc_BytesPerInputBuffer; /* native buffer size in bytes */"; 1701 z[lc++]=" unsigned int pahsc_BytesPerOutputBuffer; /* native buffer size in bytes */"; 1702 z[lc++]="/* For measuring CPU utilization. */"; 1703 z[lc++]=" struct timeval pahsc_EntryTime;"; 1704 z[lc++]=" double pahsc_InverseMicrosPerBuffer; /* 1/Microseconds of real-time audio per user buffer. */"; 1705 z[lc++]="} PaHostSoundControl;"; 1706 z[lc++]=""; 1707 z[lc++]="/************************************************* Shared Data ********/"; 1708 z[lc++]="/* FIXME - put Mutex around this shared data. */"; 1709 z[lc++]="static int sDeviceIndex = 0;"; 1710 z[lc++]="static internalPortAudioDevice *sDeviceList = NULL;"; 1711 z[lc++]="static int sDefaultInputDeviceID = paNoDevice;"; 1712 z[lc++]="static int sDefaultOutputDeviceID = paNoDevice;"; 1713 z[lc++]="static int sEnumerationError;"; 1714 z[lc++]="static int sPaHostError = 0;"; 1715 z[lc++]=""; 1716 z[lc++]="/************************************************* Prototypes **********/"; 1717 z[lc++]=""; 1718 z[lc++]="static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id );"; 1719 z[lc++]="static Pa_QueryDevices( void );"; 1720 z[lc++]="static PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *pad );"; 1721 z[lc++]="static PaError Pa_SetupDeviceFormat( int devHandle, int numChannels, int sampleRate );"; 1722 z[lc++]=""; 1723 z[lc++]="/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/"; 1724 z[lc++]="static void Pa_StartUsageCalculation( internalPortAudioStream *past )"; 1725 z[lc++]="{"; 1726 z[lc++]=" struct itimerval itimer;"; 1727 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 1728 z[lc++]=" if( pahsc == NULL ) return;"; 1729 z[lc++]="/* Query system timer for usage analysis and to prevent overuse of CPU. */"; 1730 z[lc++]=" gettimeofday( &pahsc->pahsc_EntryTime, NULL );"; 1731 z[lc++]="}"; 1732 z[lc++]=""; 1733 z[lc++]="static long SubtractTime_AminusB( struct timeval *timeA, struct timeval *timeB )"; 1734 z[lc++]="{"; 1735 z[lc++]=" long secs = timeA->tv_sec - timeB->tv_sec;"; 1736 z[lc++]=" long usecs = secs * 1000000;"; 1737 z[lc++]=" usecs += (timeA->tv_usec - timeB->tv_usec);"; 1738 z[lc++]=" return usecs;"; 1739 z[lc++]="}"; 1740 z[lc++]=""; 1741 z[lc++]="/******************************************************************************"; 1742 z[lc++]="** Measure fractional CPU load based on real-time it took to calculate"; 1743 z[lc++]="** buffers worth of output."; 1744 z[lc++]="*/"; 1745 z[lc++]="static void Pa_EndUsageCalculation( internalPortAudioStream *past )"; 1746 z[lc++]="{"; 1747 z[lc++]=" struct timeval currentTime;"; 1748 z[lc++]=" long usecsElapsed;"; 1749 z[lc++]=" double newUsage;"; 1750 z[lc++]=""; 1751 z[lc++]="#define LOWPASS_COEFFICIENT_0 (0.95)"; 1752 z[lc++]="#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0)"; 1753 z[lc++]=""; 1754 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 1755 z[lc++]=" if( pahsc == NULL ) return;"; 1756 z[lc++]=""; 1757 z[lc++]=" if( gettimeofday( ¤tTime, NULL ) == 0 )"; 1758 z[lc++]=" {"; 1759 z[lc++]=" usecsElapsed = SubtractTime_AminusB( ¤tTime, &pahsc->pahsc_EntryTime );"; 1760 z[lc++]=" /* Use inverse because it is faster than the divide. */"; 1761 z[lc++]=" newUsage = usecsElapsed * pahsc->pahsc_InverseMicrosPerBuffer;"; 1762 z[lc++]=" "; 1763 z[lc++]=" past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +"; 1764 z[lc++]=" (LOWPASS_COEFFICIENT_1 * newUsage);"; 1765 z[lc++]=" }"; 1766 z[lc++]="}"; 1767 z[lc++]="/****************************************** END CPU UTILIZATION *******/"; 1768 z[lc++]=""; 1769 z[lc++]="/*********************************************************************"; 1770 z[lc++]=" * Try to open the named device."; 1771 z[lc++]=" * If it opens, try to set various rates and formats and fill in "; 1772 z[lc++]=" * the device info structure."; 1773 z[lc++]=" */"; 1774 z[lc++]="static PaError Pa_QueryDevice( const char *deviceName, internalPortAudioDevice *pad )"; 1775 z[lc++]="{"; 1776 z[lc++]=" int result = paHostError;"; 1777 z[lc++]=" int numBytes;"; 1778 z[lc++]=" int tempDevHandle;"; 1779 z[lc++]=" int numChannels, maxNumChannels;"; 1780 z[lc++]=" int format;"; 1781 z[lc++]=" int numSampleRates;"; 1782 z[lc++]=" int sampleRate;"; 1783 z[lc++]=" int numRatesToTry;"; 1784 z[lc++]=" int ratesToTry[9] = {96000, 48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000};"; 1785 z[lc++]=" int i;"; 1786 z[lc++]=""; 1787 z[lc++]="/* douglas: "; 1788 z[lc++]=" we have to do this querying in a slightly different order. apparently"; 1789 z[lc++]=" some sound cards will give you different info based on their settins. "; 1790 z[lc++]=" e.g. a card might give you stereo at 22kHz but only mono at 44kHz."; 1791 z[lc++]=" the correct order for OSS is: format, channels, sample rate"; 1792 z[lc++]=""; 1793 z[lc++]="*/"; 1794 z[lc++]=" if ( (tempDevHandle = open(deviceName,O_WRONLY)) == -1 )"; 1795 z[lc++]=" {"; 1796 z[lc++]=" DBUG((\"Pa_QueryDevice: could not open %s\\n\", deviceName ));"; 1797 z[lc++]=" return paHostError;"; 1798 z[lc++]=" }"; 1799 z[lc++]=" "; 1800 z[lc++]="/* Ask OSS what formats are supported by the hardware. */"; 1801 z[lc++]=" pad->pad_Info.nativeSampleFormats = 0;"; 1802 z[lc++]=" if (ioctl(tempDevHandle, SNDCTL_DSP_GETFMTS, &format) == -1)"; 1803 z[lc++]=" {"; 1804 z[lc++]=" ERR_RPT((\"Pa_QueryDevice: could not get format info\\n\" ));"; 1805 z[lc++]=" goto error;"; 1806 z[lc++]=" }"; 1807 z[lc++]=" if( format & AFMT_U8 ) pad->pad_Info.nativeSampleFormats |= paUInt8;"; 1808 z[lc++]=" if( format & AFMT_S16_NE ) pad->pad_Info.nativeSampleFormats |= paInt16;"; 1809 z[lc++]=""; 1810 z[lc++]="/* Negotiate for the maximum number of channels for this device. PLB20010927"; 1811 z[lc++]=" * Start with 16 as a hard coded upper number of channels."; 1812 z[lc++]=" * Variable numChannels should contain the actual upper limit after the call."; 1813 z[lc++]=" * Thanks to John Lazzaro and Heiko Purnhagen for suggestions."; 1814 z[lc++]=" */"; 1815 z[lc++]=" maxNumChannels = 0;"; 1816 z[lc++]=" for( numChannels = 1; numChannels <= 16; numChannels++ )"; 1817 z[lc++]=" {"; 1818 z[lc++]=" int temp = numChannels;"; 1819 z[lc++]=" DBUG((\"Pa_QueryDevice: use SNDCTL_DSP_CHANNELS, numChannels = %d\\n\", numChannels ))"; 1820 z[lc++]=" if(ioctl(tempDevHandle, SNDCTL_DSP_CHANNELS, &temp) < 0 )"; 1821 z[lc++]=" {"; 1822 z[lc++]=" /* ioctl() failed so bail out if we already have stereo */"; 1823 z[lc++]=" if( numChannels > 2 ) break;"; 1824 z[lc++]=" }"; 1825 z[lc++]=" else"; 1826 z[lc++]=" {"; 1827 z[lc++]=" /* ioctl() worked but bail out if it does not support numChannels."; 1828 z[lc++]=" * We don't want to leave gaps in the numChannels supported."; 1829 z[lc++]=" */"; 1830 z[lc++]=" if( (numChannels > 2) && (temp != numChannels) ) break;"; 1831 z[lc++]=" DBUG((\"Pa_QueryDevice: temp = %d\\n\", temp ))"; 1832 z[lc++]=" if( temp > maxNumChannels ) maxNumChannels = temp; /* Save maximum. */"; 1833 z[lc++]=" }"; 1834 z[lc++]=" }"; 1835 z[lc++]="/* The above negotiation may fail for an old driver so try this older technique. */"; 1836 z[lc++]=" if( maxNumChannels < 1 )"; 1837 z[lc++]=" {"; 1838 z[lc++]=" int stereo = 1;"; 1839 z[lc++]=" if(ioctl(tempDevHandle, SNDCTL_DSP_STEREO, &stereo) < 0)"; 1840 z[lc++]=" {"; 1841 z[lc++]=" maxNumChannels = 1;"; 1842 z[lc++]=" }"; 1843 z[lc++]=" else"; 1844 z[lc++]=" {"; 1845 z[lc++]=" maxNumChannels = (stereo) ? 2 : 1;"; 1846 z[lc++]=" }"; 1847 z[lc++]=" DBUG((\"Pa_QueryDevice: use SNDCTL_DSP_STEREO, maxNumChannels = %d\\n\", maxNumChannels ))"; 1848 z[lc++]=" }"; 1849 z[lc++]=" "; 1850 z[lc++]=" pad->pad_Info.maxOutputChannels = maxNumChannels;"; 1851 z[lc++]=" DBUG((\"Pa_QueryDevice: maxNumChannels = %d\\n\", maxNumChannels))"; 1852 z[lc++]=" "; 1853 z[lc++]="/* FIXME - for now, assume maxInputChannels = maxOutputChannels."; 1854 z[lc++]=" * Eventually do separate queries for O_WRONLY and O_RDONLY"; 1855 z[lc++]="*/"; 1856 z[lc++]=" pad->pad_Info.maxInputChannels = pad->pad_Info.maxOutputChannels;"; 1857 z[lc++]=" "; 1858 z[lc++]=" DBUG((\"Pa_QueryDevice: maxInputChannels = %d\\n\", "; 1859 z[lc++]=" pad->pad_Info.maxInputChannels))"; 1860 z[lc++]=""; 1861 z[lc++]=""; 1862 z[lc++]="/* Determine available sample rates by trying each one and seeing result."; 1863 z[lc++]=" */"; 1864 z[lc++]=" numSampleRates = 0;"; 1865 z[lc++]=" numRatesToTry = sizeof(ratesToTry)/sizeof(int);"; 1866 z[lc++]=" for (i = 0; i < numRatesToTry; i++)"; 1867 z[lc++]=" {"; 1868 z[lc++]=" sampleRate = ratesToTry[i];"; 1869 z[lc++]=" "; 1870 z[lc++]=" if (ioctl(tempDevHandle, SNDCTL_DSP_SPEED, &sampleRate) >= 0 ) // PLB20010817"; 1871 z[lc++]=" {"; 1872 z[lc++]=" if (sampleRate == ratesToTry[i])"; 1873 z[lc++]=" {"; 1874 z[lc++]=" DBUG((\"Pa_QueryDevice: got sample rate: %d\\n\", sampleRate))"; 1875 z[lc++]=" pad->pad_SampleRates[numSampleRates] = (float)ratesToTry[i];"; 1876 z[lc++]=" numSampleRates++;"; 1877 z[lc++]=" }"; 1878 z[lc++]=" }"; 1879 z[lc++]=" }"; 1880 z[lc++]=""; 1881 z[lc++]=" DBUG((\"Pa_QueryDevice: final numSampleRates = %d\\n\", numSampleRates))"; 1882 z[lc++]=" if (numSampleRates==0) /* HP20010922 */"; 1883 z[lc++]=" {"; 1884 z[lc++]=" ERR_RPT((\"Pa_QueryDevice: no supported sample rate (or SNDCTL_DSP_SPEED ioctl call failed).\\n\" ));"; 1885 z[lc++]=" goto error;"; 1886 z[lc++]=" }"; 1887 z[lc++]=""; 1888 z[lc++]=" pad->pad_Info.numSampleRates = numSampleRates;"; 1889 z[lc++]=" pad->pad_Info.sampleRates = pad->pad_SampleRates;"; 1890 z[lc++]=" "; 1891 z[lc++]=" pad->pad_Info.name = deviceName;"; 1892 z[lc++]=""; 1893 z[lc++]=" result = paNoError;"; 1894 z[lc++]=" "; vac_open_indexes(Relation relation,LOCKMODE lockmode,int * nindexes,Relation ** Irel)1895 z[lc++]="error:"; 1896 z[lc++]="/* We MUST close the handle here or we won't be able to reopen it later!!! */"; 1897 z[lc++]=" close(tempDevHandle);"; 1898 z[lc++]=""; 1899 z[lc++]=" return result;"; 1900 z[lc++]="}"; 1901 z[lc++]=""; 1902 z[lc++]="/*********************************************************************"; 1903 z[lc++]=" * Determines the number of available devices by trying to open"; 1904 z[lc++]=" * each \"/dev/dsp#\" or \"/dsp/audio#\" in order until it fails."; 1905 z[lc++]=" * Add each working device to a singly linked list of devices."; 1906 z[lc++]=" */"; 1907 z[lc++]="static PaError Pa_QueryDevices( void )"; 1908 z[lc++]="{"; 1909 z[lc++]=" internalPortAudioDevice *pad, *lastPad;"; 1910 z[lc++]=" int numBytes;"; 1911 z[lc++]=" int go = 1;"; 1912 z[lc++]=" int numDevices = 0;"; 1913 z[lc++]=" PaError testResult;"; 1914 z[lc++]=" PaError result = paNoError;"; 1915 z[lc++]=" "; 1916 z[lc++]=" sDefaultInputDeviceID = paNoDevice;"; 1917 z[lc++]=" sDefaultOutputDeviceID = paNoDevice;"; 1918 z[lc++]=""; 1919 z[lc++]=" lastPad = NULL;"; 1920 z[lc++]=" "; 1921 z[lc++]=" while( go )"; 1922 z[lc++]=" {"; 1923 z[lc++]="/* Allocate structure to hold device info. */"; 1924 z[lc++]=" pad = PaHost_AllocateFastMemory( sizeof(internalPortAudioDevice) );"; 1925 z[lc++]=" if( pad == NULL ) return paInsufficientMemory;"; 1926 z[lc++]=" memset( pad, 0, sizeof(internalPortAudioDevice) );"; 1927 z[lc++]=" "; 1928 z[lc++]="/* Build name for device. */"; 1929 z[lc++]=" if( numDevices == 0 )"; 1930 z[lc++]=" {"; 1931 z[lc++]=" sprintf( pad->pad_DeviceName, DEVICE_NAME_BASE);"; 1932 z[lc++]=" }"; 1933 z[lc++]=" else"; 1934 z[lc++]=" {"; 1935 z[lc++]=" sprintf( pad->pad_DeviceName, DEVICE_NAME_BASE \"%d\", numDevices );"; 1936 z[lc++]=" }"; 1937 z[lc++]=" "; vac_close_indexes(int nindexes,Relation * Irel,LOCKMODE lockmode)1938 z[lc++]=" DBUG((\"Try device %s\\n\", pad->pad_DeviceName ));"; 1939 z[lc++]=" testResult = Pa_QueryDevice( pad->pad_DeviceName, pad );"; 1940 z[lc++]=" DBUG((\"Pa_QueryDevice returned %d\\n\", testResult ));"; 1941 z[lc++]=" if( testResult != paNoError )"; 1942 z[lc++]=" {"; 1943 z[lc++]=" if( lastPad == NULL )"; 1944 z[lc++]=" {"; 1945 z[lc++]=" result = testResult; /* No good devices! */"; 1946 z[lc++]=" }"; 1947 z[lc++]=" go = 0;"; 1948 z[lc++]=" PaHost_FreeFastMemory( pad, sizeof(internalPortAudioDevice) );"; 1949 z[lc++]=" }"; 1950 z[lc++]=" else"; 1951 z[lc++]=" {"; 1952 z[lc++]=" numDevices += 1;"; 1953 z[lc++]=" /* Add to linked list of devices. */"; 1954 z[lc++]=" if( lastPad )"; 1955 z[lc++]=" {"; 1956 z[lc++]=" lastPad->pad_Next = pad;"; 1957 z[lc++]=" }"; 1958 z[lc++]=" else"; vacuum_delay_point(void)1959 z[lc++]=" {"; 1960 z[lc++]=" sDeviceList = pad; /* First element in linked list. */"; 1961 z[lc++]=" }"; 1962 z[lc++]=" lastPad = pad;"; 1963 z[lc++]=" }"; 1964 z[lc++]=" }"; 1965 z[lc++]=" "; 1966 z[lc++]=" return result;"; 1967 z[lc++]=" "; 1968 z[lc++]="}"; 1969 z[lc++]=""; 1970 z[lc++]="/*************************************************************************/"; 1971 z[lc++]="int Pa_CountDevices()"; 1972 z[lc++]="{"; 1973 z[lc++]=" int numDevices = 0;"; 1974 z[lc++]=" internalPortAudioDevice *pad;"; 1975 z[lc++]=" "; 1976 z[lc++]=" if( sDeviceList == NULL ) Pa_Initialize();"; 1977 z[lc++]="/* Count devices in list. */"; 1978 z[lc++]=" pad = sDeviceList;"; 1979 z[lc++]=" while( pad != NULL )"; 1980 z[lc++]=" {"; 1981 z[lc++]=" pad = pad->pad_Next;"; 1982 z[lc++]=" numDevices++;"; 1983 z[lc++]=" }"; 1984 z[lc++]=" "; 1985 z[lc++]=" return numDevices;"; 1986 z[lc++]="}"; 1987 z[lc++]=""; 1988 z[lc++]="static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id )"; 1989 z[lc++]="{"; 1990 z[lc++]=" internalPortAudioDevice *pad;"; 1991 z[lc++]=" if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;"; 1992 z[lc++]=" pad = sDeviceList;"; get_vacopt_ternary_value(DefElem * def)1993 z[lc++]=" while( id > 0 )"; 1994 z[lc++]=" {"; 1995 z[lc++]=" pad = pad->pad_Next;"; 1996 z[lc++]=" id--;"; 1997 z[lc++]=" }"; 1998 z[lc++]=" return pad;"; 1999 z[lc++]="}"; 2000 z[lc++]=""; 2001 z[lc++]="/*************************************************************************/"; 2002 z[lc++]="const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )"; 2003 z[lc++]="{"; 2004 z[lc++]=" internalPortAudioDevice *pad;"; 2005 z[lc++]=" if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;"; 2006 z[lc++]=" pad = Pa_GetInternalDevice( id );"; 2007 z[lc++]=" return &pad->pad_Info ;"; 2008 z[lc++]="}"; 2009 z[lc++]=""; 2010 z[lc++]="static PaError Pa_MaybeQueryDevices( void )"; 2011 z[lc++]="{"; 2012 z[lc++]=" if( sDeviceList == NULL )"; 2013 z[lc++]=" {"; 2014 z[lc++]=" return Pa_QueryDevices();"; 2015 z[lc++]=" }"; 2016 z[lc++]=" return 0;"; 2017 z[lc++]="}"; 2018 z[lc++]=""; 2019 z[lc++]="PaDeviceID Pa_GetDefaultInputDeviceID( void )"; 2020 z[lc++]="{"; 2021 z[lc++]=" /* return paNoDevice; */"; 2022 z[lc++]=" return 0;"; 2023 z[lc++]="}"; 2024 z[lc++]=""; 2025 z[lc++]="PaDeviceID Pa_GetDefaultOutputDeviceID( void )"; 2026 z[lc++]="{"; 2027 z[lc++]=" return 0;"; 2028 z[lc++]="}"; 2029 z[lc++]=""; 2030 z[lc++]="/**********************************************************************"; 2031 z[lc++]="** Make sure that we have queried the device capabilities."; 2032 z[lc++]="*/"; 2033 z[lc++]=""; 2034 z[lc++]="PaError PaHost_Init( void )"; 2035 z[lc++]="{"; 2036 z[lc++]=" return Pa_MaybeQueryDevices();"; 2037 z[lc++]="}"; 2038 z[lc++]=""; 2039 z[lc++]="/*******************************************************************************************/"; 2040 z[lc++]="static PaError Pa_AudioThreadProc( internalPortAudioStream *past )"; 2041 z[lc++]="{"; 2042 z[lc++]=" PaError result = 0;"; 2043 z[lc++]=" PaHostSoundControl *pahsc;"; 2044 z[lc++]=" short bytes_read = 0;"; 2045 z[lc++]=" "; 2046 z[lc++]="#ifdef GNUSTEP"; 2047 z[lc++]=" GSRegisterCurrentThread(); /* SB20010904 */"; 2048 z[lc++]="#endif"; 2049 z[lc++]=" "; 2050 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 2051 z[lc++]=" if( pahsc == NULL ) return paInternalError;"; 2052 z[lc++]=""; 2053 z[lc++]=" past->past_IsActive = 1;"; 2054 z[lc++]=" DBUG((\"entering thread.\\n\"));"; 2055 z[lc++]=" "; 2056 z[lc++]=" while( (past->past_StopNow == 0) && (past->past_StopSoon == 0) )"; 2057 z[lc++]=" {"; 2058 z[lc++]=""; 2059 z[lc++]=" DBUG((\"go!\\n\"));"; 2060 z[lc++]=" /* Read data from device */"; 2061 z[lc++]=" if(pahsc->pahsc_NativeInputBuffer)"; 2062 z[lc++]=" {"; 2063 z[lc++]=" bytes_read = read(pahsc->pahsc_InputHandle,"; 2064 z[lc++]=" (void *)pahsc->pahsc_NativeInputBuffer,"; 2065 z[lc++]=" pahsc->pahsc_BytesPerInputBuffer); "; 2066 z[lc++]=" "; 2067 z[lc++]=" DBUG((\"bytes_read: %d\\n\", bytes_read));"; 2068 z[lc++]=" }"; 2069 z[lc++]=" "; 2070 z[lc++]=" /* Convert 16 bit native data to user data and call user routine. */"; 2071 z[lc++]=" DBUG((\"converting...\\n\"));"; 2072 z[lc++]=" Pa_StartUsageCalculation( past );"; 2073 z[lc++]=" result = Pa_CallConvertInt16( past,"; 2074 z[lc++]=" pahsc->pahsc_NativeInputBuffer,"; 2075 z[lc++]=" pahsc->pahsc_NativeOutputBuffer );"; 2076 z[lc++]=" Pa_EndUsageCalculation( past );"; 2077 z[lc++]=" if( result != 0) "; 2078 z[lc++]=" {"; 2079 z[lc++]=" DBUG((\"hmm, Pa_CallConvertInt16() says: %d. i'm bailing.\\n\","; 2080 z[lc++]=" result));"; 2081 z[lc++]=" break;"; 2082 z[lc++]=" }"; 2083 z[lc++]=""; 2084 z[lc++]=" /* Write data to device. */"; 2085 z[lc++]=" if( pahsc->pahsc_NativeOutputBuffer )"; 2086 z[lc++]=" {"; 2087 z[lc++]=""; 2088 z[lc++]=" write(pahsc->pahsc_OutputHandle,"; 2089 z[lc++]=" (void *)pahsc->pahsc_NativeOutputBuffer,"; 2090 z[lc++]=" pahsc->pahsc_BytesPerOutputBuffer); "; 2091 z[lc++]=" }"; 2092 z[lc++]=" }"; 2093 z[lc++]=""; 2094 z[lc++]=" past->past_IsActive = 0;"; 2095 z[lc++]=" DBUG((\"leaving thread.\\n\"));"; 2096 z[lc++]=" "; 2097 z[lc++]="#ifdef GNUSTEP"; 2098 z[lc++]=" GSUnregisterCurrentThread(); /* SB20010904 */"; 2099 z[lc++]="#endif"; 2100 z[lc++]=" return 0;"; 2101 z[lc++]="}"; 2102 z[lc++]=""; 2103 z[lc++]="/*******************************************************************************************/"; 2104 z[lc++]="static PaError Pa_SetupDeviceFormat( int devHandle, int numChannels, int sampleRate )"; 2105 z[lc++]="{"; 2106 z[lc++]=" PaError result = paNoError;"; 2107 z[lc++]=" int tmp;"; 2108 z[lc++]=""; 2109 z[lc++]="/* Set format, channels, and rate in this order to keep OSS happy. */"; 2110 z[lc++]="/* Set data format. FIXME - handle more native formats. */"; 2111 z[lc++]=" tmp = AFMT_S16_NE; "; 2112 z[lc++]=" if( ioctl(devHandle,SNDCTL_DSP_SETFMT,&tmp) == -1)"; 2113 z[lc++]=" {"; 2114 z[lc++]=" ERR_RPT((\"Pa_SetupDeviceFormat: could not SNDCTL_DSP_SETFMT\\n\" ));"; 2115 z[lc++]=" return paHostError;"; 2116 z[lc++]=" }"; 2117 z[lc++]=" if( tmp != AFMT_S16_NE)"; 2118 z[lc++]=" {"; 2119 z[lc++]=" ERR_RPT((\"Pa_SetupDeviceFormat: HW does not support AFMT_S16_NE\\n\" ));"; 2120 z[lc++]=" return paHostError;"; 2121 z[lc++]=" }"; 2122 z[lc++]=" "; 2123 z[lc++]=""; 2124 z[lc++]="/* Set number of channels. */"; 2125 z[lc++]=" tmp = numChannels;"; 2126 z[lc++]=" if (ioctl(devHandle, SNDCTL_DSP_CHANNELS, &numChannels) == -1)"; 2127 z[lc++]=" {"; 2128 z[lc++]=" ERR_RPT((\"Pa_SetupDeviceFormat: could not SNDCTL_DSP_CHANNELS\\n\" ));"; 2129 z[lc++]=" return paHostError;"; 2130 z[lc++]=" }"; 2131 z[lc++]=" if( tmp != numChannels)"; 2132 z[lc++]=" {"; 2133 z[lc++]=" ERR_RPT((\"Pa_SetupDeviceFormat: HW does not support %d channels\\n\", numChannels ));"; 2134 z[lc++]=" return paHostError;"; 2135 z[lc++]=" }"; 2136 z[lc++]=" "; 2137 z[lc++]="/* Set playing frequency. 44100, 22050 and 11025 are safe bets. */"; 2138 z[lc++]=" tmp = sampleRate;"; 2139 z[lc++]=" if( ioctl(devHandle,SNDCTL_DSP_SPEED,&tmp) == -1)"; 2140 z[lc++]=" {"; 2141 z[lc++]=" ERR_RPT((\"Pa_SetupDeviceFormat: could not SNDCTL_DSP_SPEED\\n\" ));"; 2142 z[lc++]=" return paHostError;"; 2143 z[lc++]=" }"; 2144 z[lc++]=" if( tmp != sampleRate)"; 2145 z[lc++]=" {"; 2146 z[lc++]=" ERR_RPT((\"Pa_SetupDeviceFormat: HW does not support %d Hz sample rate\\n\",sampleRate ));"; 2147 z[lc++]=" return paHostError;"; 2148 z[lc++]=" }"; 2149 z[lc++]=" "; 2150 z[lc++]=" return result;"; 2151 z[lc++]="} "; 2152 z[lc++]=""; 2153 z[lc++]="static int CalcHigherLogTwo( int n )"; 2154 z[lc++]="{"; 2155 z[lc++]=" int log2 = 0;"; 2156 z[lc++]=" while( (1<<log2) < n ) log2++;"; 2157 z[lc++]=" return log2;"; 2158 z[lc++]="}"; 2159 z[lc++]=""; 2160 z[lc++]="/*******************************************************************************************"; 2161 z[lc++]="** Set number of fragments and size of fragments to achieve desired latency."; 2162 z[lc++]="*/"; 2163 z[lc++]="static void Pa_SetLatency( int devHandle, int numBuffers, int framesPerBuffer, int channelsPerFrame )"; 2164 z[lc++]="{"; 2165 z[lc++]=" int tmp;"; 2166 z[lc++]=" int numFrames , bufferSize, powerOfTwo;"; 2167 z[lc++]=""; 2168 z[lc++]="/* Increase size of buffers and reduce number of buffers to reduce latency inside driver. */"; 2169 z[lc++]=" while( numBuffers > 8 )"; 2170 z[lc++]=" {"; 2171 z[lc++]=" numBuffers = (numBuffers + 1) >> 1;"; 2172 z[lc++]=" framesPerBuffer = framesPerBuffer << 1;"; 2173 z[lc++]=" }"; 2174 z[lc++]=" "; 2175 z[lc++]="/* calculate size of buffers in bytes */"; 2176 z[lc++]=" bufferSize = framesPerBuffer * channelsPerFrame * sizeof(short); /* FIXME */"; 2177 z[lc++]=" "; 2178 z[lc++]="/* Calculate next largest power of two */"; 2179 z[lc++]=" powerOfTwo = CalcHigherLogTwo( bufferSize );"; 2180 z[lc++]=" DBUG((\"Pa_SetLatency: numBuffers = %d, framesPerBuffer = %d, powerOfTwo = %d\\n\","; 2181 z[lc++]=" numBuffers, framesPerBuffer, powerOfTwo ));"; 2182 z[lc++]=""; 2183 z[lc++]="/* Encode info into a single int */"; 2184 z[lc++]=" tmp=(numBuffers<<16) + powerOfTwo;"; 2185 z[lc++]=" "; 2186 z[lc++]=" if(ioctl(devHandle,SNDCTL_DSP_SETFRAGMENT,&tmp) == -1)"; 2187 z[lc++]=" {"; 2188 z[lc++]=" ERR_RPT((\"Pa_SetLatency: could not SNDCTL_DSP_SETFRAGMENT\\n\" ));"; 2189 z[lc++]=" /* Don't return an error. Best to just continue and hope for the best. */"; 2190 z[lc++]=" ERR_RPT((\"Pa_SetLatency: numBuffers = %d, framesPerBuffer = %d, powerOfTwo = %d\\n\","; 2191 z[lc++]=" numBuffers, framesPerBuffer, powerOfTwo ));"; 2192 z[lc++]=" }"; 2193 z[lc++]="}"; 2194 z[lc++]=""; 2195 z[lc++]="/*************************************************************************"; 2196 z[lc++]="** Determine minimum number of buffers required for this host based"; 2197 z[lc++]="** on minimum latency. Latency can be optionally set by user by setting"; 2198 z[lc++]="** an environment variable. For example, to set latency to 200 msec, put:"; 2199 z[lc++]="**"; 2200 z[lc++]="** set PA_MIN_LATENCY_MSEC=200"; 2201 z[lc++]="**"; 2202 z[lc++]="** in the cshrc file."; 2203 z[lc++]="*/"; 2204 z[lc++]="#define PA_LATENCY_ENV_NAME (\"PA_MIN_LATENCY_MSEC\")"; 2205 z[lc++]=""; 2206 z[lc++]="int Pa_GetMinNumBuffers( int framesPerBuffer, double framesPerSecond )"; 2207 z[lc++]="{"; 2208 z[lc++]=" int minBuffers;"; 2209 z[lc++]=" int minLatencyMsec = MIN_LATENCY_MSEC;"; 2210 z[lc++]=" char *minLatencyText = getenv(PA_LATENCY_ENV_NAME);"; 2211 z[lc++]=" if( minLatencyText != NULL )"; 2212 z[lc++]=" {"; 2213 z[lc++]=" PRINT((\"PA_MIN_LATENCY_MSEC = %s\\n\", minLatencyText ));"; 2214 z[lc++]=" minLatencyMsec = atoi( minLatencyText );"; 2215 z[lc++]=" if( minLatencyMsec < 1 ) minLatencyMsec = 1;"; 2216 z[lc++]=" else if( minLatencyMsec > 5000 ) minLatencyMsec = 5000;"; 2217 z[lc++]=" }"; 2218 z[lc++]=" "; 2219 z[lc++]=" minBuffers = (int) ((minLatencyMsec * framesPerSecond) / ( 1000.0 * framesPerBuffer ));"; 2220 z[lc++]=" if( minBuffers < 2 ) minBuffers = 2;"; 2221 z[lc++]=" return minBuffers;"; 2222 z[lc++]="}"; 2223 z[lc++]=""; 2224 z[lc++]="/*******************************************************************/"; 2225 z[lc++]="PaError PaHost_OpenStream( internalPortAudioStream *past )"; 2226 z[lc++]="{"; 2227 z[lc++]=" PaError result = paNoError;"; 2228 z[lc++]=" PaHostSoundControl *pahsc;"; 2229 z[lc++]=" int tmp;"; 2230 z[lc++]=" int flags;"; 2231 z[lc++]=" int numBytes, maxChannels;"; 2232 z[lc++]=" unsigned int minNumBuffers;"; 2233 z[lc++]=" internalPortAudioDevice *pad;"; 2234 z[lc++]=" DBUG((\"PaHost_OpenStream() called.\\n\" ));"; 2235 z[lc++]=""; 2236 z[lc++]="/* Allocate and initialize host data. */"; 2237 z[lc++]=" pahsc = (PaHostSoundControl *) malloc(sizeof(PaHostSoundControl));"; 2238 z[lc++]=" if( pahsc == NULL )"; 2239 z[lc++]=" {"; 2240 z[lc++]=" result = paInsufficientMemory;"; 2241 z[lc++]=" goto error;"; 2242 z[lc++]=" }"; 2243 z[lc++]=" memset( pahsc, 0, sizeof(PaHostSoundControl) );"; 2244 z[lc++]=" past->past_DeviceData = (void *) pahsc;"; 2245 z[lc++]=""; 2246 z[lc++]=" pahsc->pahsc_OutputHandle = BAD_DEVICE_ID; /* No device currently opened. */"; 2247 z[lc++]=" pahsc->pahsc_InputHandle = BAD_DEVICE_ID;"; 2248 z[lc++]=" "; 2249 z[lc++]="/* Allocate native buffers. */"; 2250 z[lc++]=" pahsc->pahsc_BytesPerInputBuffer = past->past_FramesPerUserBuffer *"; 2251 z[lc++]=" past->past_NumInputChannels * sizeof(short);"; 2252 z[lc++]=" if( past->past_NumInputChannels > 0)"; 2253 z[lc++]=" {"; 2254 z[lc++]=" pahsc->pahsc_NativeInputBuffer = (short *) malloc(pahsc->pahsc_BytesPerInputBuffer);"; 2255 z[lc++]=" if( pahsc->pahsc_NativeInputBuffer == NULL )"; 2256 z[lc++]=" {"; 2257 z[lc++]=" result = paInsufficientMemory;"; 2258 z[lc++]=" goto error;"; 2259 z[lc++]=" }"; 2260 z[lc++]=" }"; 2261 z[lc++]=" pahsc->pahsc_BytesPerOutputBuffer = past->past_FramesPerUserBuffer *"; 2262 z[lc++]=" past->past_NumOutputChannels * sizeof(short);"; 2263 z[lc++]=" if( past->past_NumOutputChannels > 0)"; 2264 z[lc++]=" {"; 2265 z[lc++]=" pahsc->pahsc_NativeOutputBuffer = (short *) malloc(pahsc->pahsc_BytesPerOutputBuffer);"; 2266 z[lc++]=" if( pahsc->pahsc_NativeOutputBuffer == NULL )"; 2267 z[lc++]=" {"; 2268 z[lc++]=" result = paInsufficientMemory;"; 2269 z[lc++]=" goto error;"; 2270 z[lc++]=" }"; 2271 z[lc++]=" }"; 2272 z[lc++]=" "; 2273 z[lc++]=" /* DBUG((\"PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\\n\", pahsc->pahsc_MinFramesPerHostBuffer )); */"; 2274 z[lc++]=" minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );"; 2275 z[lc++]=" past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;"; 2276 z[lc++]=""; 2277 z[lc++]=" pahsc->pahsc_InverseMicrosPerBuffer = past->past_SampleRate / (1000000.0 * past->past_FramesPerUserBuffer);"; 2278 z[lc++]=" DBUG((\"pahsc_InverseMicrosPerBuffer = %g\\n\", pahsc->pahsc_InverseMicrosPerBuffer ));"; 2279 z[lc++]=" "; 2280 z[lc++]="/* ------------------------- OPEN DEVICE -----------------------*/"; 2281 z[lc++]=" "; 2282 z[lc++]=" /* just output */"; 2283 z[lc++]=" if (past->past_OutputDeviceID == past->past_InputDeviceID)"; 2284 z[lc++]=" {"; 2285 z[lc++]=" "; 2286 z[lc++]=" if ((past->past_NumOutputChannels > 0) && (past->past_NumInputChannels > 0) )"; 2287 z[lc++]=" {"; 2288 z[lc++]=" pad = Pa_GetInternalDevice( past->past_OutputDeviceID );"; 2289 z[lc++]=" DBUG((\"PaHost_OpenStream: attempt to open %s for O_RDWR\\n\", pad->pad_DeviceName ));"; 2290 z[lc++]=" pahsc->pahsc_OutputHandle = pahsc->pahsc_InputHandle ="; 2291 z[lc++]=" open(pad->pad_DeviceName,O_RDWR); "; 2292 z[lc++]=" if(pahsc->pahsc_InputHandle==-1)"; 2293 z[lc++]=" {"; 2294 z[lc++]=" ERR_RPT((\"PaHost_OpenStream: could not open %s for O_RDWR\\n\", pad->pad_DeviceName ));"; 2295 z[lc++]=" result = paHostError;"; 2296 z[lc++]=" goto error;"; 2297 z[lc++]=" } "; 2298 z[lc++]=" Pa_SetLatency( pahsc->pahsc_OutputHandle,"; 2299 z[lc++]=" past->past_NumUserBuffers, past->past_FramesPerUserBuffer,"; 2300 z[lc++]=" past->past_NumOutputChannels );"; 2301 z[lc++]=" result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle,"; 2302 z[lc++]=" past->past_NumOutputChannels, (int)past->past_SampleRate );"; 2303 z[lc++]=" }"; 2304 z[lc++]=" }"; 2305 z[lc++]=" else"; 2306 z[lc++]=" {"; 2307 z[lc++]=" if (past->past_NumOutputChannels > 0)"; 2308 z[lc++]=" { "; 2309 z[lc++]=" pad = Pa_GetInternalDevice( past->past_OutputDeviceID );"; 2310 z[lc++]=" DBUG((\"PaHost_OpenStream: attempt to open %s for O_WRONLY\\n\", pad->pad_DeviceName ));"; 2311 z[lc++]=" pahsc->pahsc_OutputHandle = open(pad->pad_DeviceName,O_WRONLY); "; 2312 z[lc++]=" if(pahsc->pahsc_OutputHandle==-1)"; 2313 z[lc++]=" {"; 2314 z[lc++]=" ERR_RPT((\"PaHost_OpenStream: could not open %s for O_WRONLY\\n\", pad->pad_DeviceName ));"; 2315 z[lc++]=" result = paHostError;"; 2316 z[lc++]=" goto error;"; 2317 z[lc++]=" } "; 2318 z[lc++]=" Pa_SetLatency( pahsc->pahsc_OutputHandle,"; 2319 z[lc++]=" past->past_NumUserBuffers, past->past_FramesPerUserBuffer,"; 2320 z[lc++]=" past->past_NumOutputChannels );"; 2321 z[lc++]=" result = Pa_SetupDeviceFormat( pahsc->pahsc_OutputHandle,"; 2322 z[lc++]=" past->past_NumOutputChannels, (int)past->past_SampleRate );"; 2323 z[lc++]=" }"; 2324 z[lc++]=""; 2325 z[lc++]=" if (past->past_NumInputChannels > 0)"; 2326 z[lc++]=" { "; 2327 z[lc++]=" pad = Pa_GetInternalDevice( past->past_InputDeviceID );"; 2328 z[lc++]=" DBUG((\"PaHost_OpenStream: attempt to open %s for O_RDONLY\\n\", pad->pad_DeviceName ));"; 2329 z[lc++]=" pahsc->pahsc_InputHandle = open(pad->pad_DeviceName,O_RDONLY); "; 2330 z[lc++]=" if(pahsc->pahsc_InputHandle==-1)"; 2331 z[lc++]=" {"; 2332 z[lc++]=" ERR_RPT((\"PaHost_OpenStream: could not open %s for O_RDONLY\\n\", pad->pad_DeviceName ));"; 2333 z[lc++]=" result = paHostError;"; 2334 z[lc++]=" goto error;"; 2335 z[lc++]=" } "; 2336 z[lc++]=" Pa_SetLatency( pahsc->pahsc_OutputHandle,"; 2337 z[lc++]=" past->past_NumUserBuffers, past->past_FramesPerUserBuffer,"; 2338 z[lc++]=" past->past_NumInputChannels );"; 2339 z[lc++]=" result = Pa_SetupDeviceFormat( pahsc->pahsc_InputHandle,"; 2340 z[lc++]=" past->past_NumInputChannels, (int)past->past_SampleRate );"; 2341 z[lc++]=" }"; 2342 z[lc++]=" }"; 2343 z[lc++]=" "; 2344 z[lc++]=" "; 2345 z[lc++]=" DBUG((\"PaHost_OpenStream: SUCCESS - result = %d\\n\", result ));"; 2346 z[lc++]=" return result;"; 2347 z[lc++]=" "; 2348 z[lc++]="error:"; 2349 z[lc++]=" ERR_RPT((\"PaHost_OpenStream: ERROR - result = %d\\n\", result ));"; 2350 z[lc++]=" PaHost_CloseStream( past );"; 2351 z[lc++]=" return result;"; 2352 z[lc++]="}"; 2353 z[lc++]=""; 2354 z[lc++]="/*************************************************************************/"; 2355 z[lc++]="PaError PaHost_StartOutput( internalPortAudioStream *past )"; 2356 z[lc++]="{"; 2357 z[lc++]=" return paNoError;"; 2358 z[lc++]="}"; 2359 z[lc++]=""; 2360 z[lc++]="/*************************************************************************/"; 2361 z[lc++]="PaError PaHost_StartInput( internalPortAudioStream *past )"; 2362 z[lc++]="{"; 2363 z[lc++]=" return paNoError;"; 2364 z[lc++]="}"; 2365 z[lc++]=""; 2366 z[lc++]="/*************************************************************************/"; 2367 z[lc++]="PaError PaHost_StartEngine( internalPortAudioStream *past )"; 2368 z[lc++]="{"; 2369 z[lc++]=" PaHostSoundControl *pahsc;"; 2370 z[lc++]=" PaError result = paNoError;"; 2371 z[lc++]=" int hres;"; 2372 z[lc++]=" "; 2373 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 2374 z[lc++]=""; 2375 z[lc++]=" past->past_StopSoon = 0;"; 2376 z[lc++]=" past->past_StopNow = 0;"; 2377 z[lc++]=" past->past_IsActive = 1; "; 2378 z[lc++]=""; 2379 z[lc++]="/* Use pthread_create() instead of __clone() because:"; 2380 z[lc++]=" * - pthread_create also works for other UNIX systems like Solaris,"; 2381 z[lc++]=" * - the Java HotSpot VM crashes in pthread_setcanceltype() when using __clone()"; 2382 z[lc++]=" */"; 2383 z[lc++]=" hres = pthread_create(&(pahsc->pahsc_ThreadPID),"; 2384 z[lc++]=" NULL /*pthread_attr_t * attr*/,"; 2385 z[lc++]=" (void*)Pa_AudioThreadProc, past);"; 2386 z[lc++]=" if( hres != 0 )"; 2387 z[lc++]=" {"; 2388 z[lc++]=" result = paHostError;"; 2389 z[lc++]=" sPaHostError = hres;"; 2390 z[lc++]=" goto error;"; 2391 z[lc++]=" }"; 2392 z[lc++]=""; 2393 z[lc++]="error:"; 2394 z[lc++]=" return result;"; 2395 z[lc++]="}"; 2396 z[lc++]=""; 2397 z[lc++]="/*************************************************************************/"; 2398 z[lc++]="PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )"; 2399 z[lc++]="{"; 2400 z[lc++]=" int hres;"; 2401 z[lc++]=" long timeOut;"; 2402 z[lc++]=" PaError result = paNoError;"; 2403 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 2404 z[lc++]=" "; 2405 z[lc++]=" if( pahsc == NULL ) return paNoError;"; 2406 z[lc++]=" "; 2407 z[lc++]="/* Tell background thread to stop generating more data and to let current data play out. */"; 2408 z[lc++]=" past->past_StopSoon = 1;"; 2409 z[lc++]="/* If aborting, tell background thread to stop NOW! */"; 2410 z[lc++]=" if( abort ) past->past_StopNow = 1;"; 2411 z[lc++]=""; 2412 z[lc++]="/* Join thread to recover memory resources. */"; 2413 z[lc++]=" if( pahsc->pahsc_ThreadPID != -1 )"; 2414 z[lc++]=" {"; 2415 z[lc++]=" /* This check is needed for GNUSTEP - SB20010904 */"; 2416 z[lc++]=" if ( !pthread_equal( pahsc->pahsc_ThreadPID, pthread_self() ) )"; 2417 z[lc++]=" {"; 2418 z[lc++]=" hres = pthread_join( pahsc->pahsc_ThreadPID, NULL );"; 2419 z[lc++]=" }"; 2420 z[lc++]=" else {"; 2421 z[lc++]=" DBUG((\"Play thread was stopped from itself - can't do pthread_join()\\n\"));"; 2422 z[lc++]=" hres = 0;"; 2423 z[lc++]=" }"; 2424 z[lc++]=""; 2425 z[lc++]=" if( hres != 0 )"; 2426 z[lc++]=" {"; 2427 z[lc++]=" result = paHostError;"; 2428 z[lc++]=" sPaHostError = hres;"; 2429 z[lc++]=" }"; 2430 z[lc++]=" pahsc->pahsc_ThreadPID = -1;"; 2431 z[lc++]=" }"; 2432 z[lc++]=" "; 2433 z[lc++]=" past->past_IsActive = 0; "; 2434 z[lc++]=""; 2435 z[lc++]=" return result;"; 2436 z[lc++]="}"; 2437 z[lc++]=""; 2438 z[lc++]="/*************************************************************************/"; 2439 z[lc++]="PaError PaHost_StopInput( internalPortAudioStream *past, int abort )"; 2440 z[lc++]="{"; 2441 z[lc++]=" return paNoError;"; 2442 z[lc++]="}"; 2443 z[lc++]=""; 2444 z[lc++]="/*************************************************************************/"; 2445 z[lc++]="PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )"; 2446 z[lc++]="{"; 2447 z[lc++]=" return paNoError;"; 2448 z[lc++]="}"; 2449 z[lc++]=""; 2450 z[lc++]="/*******************************************************************/"; 2451 z[lc++]="PaError PaHost_CloseStream( internalPortAudioStream *past )"; 2452 z[lc++]="{"; 2453 z[lc++]=" PaHostSoundControl *pahsc;"; 2454 z[lc++]=" if( past == NULL ) return paBadStreamPtr;"; 2455 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 2456 z[lc++]=" if( pahsc == NULL ) return paNoError;"; 2457 z[lc++]=""; 2458 z[lc++]=" if( pahsc->pahsc_OutputHandle != BAD_DEVICE_ID )"; 2459 z[lc++]=" {"; 2460 z[lc++]=" int err;"; 2461 z[lc++]=" DBUG((\"PaHost_CloseStream: attempt to close output device handle = %d\\n\","; 2462 z[lc++]=" pahsc->pahsc_OutputHandle ));"; 2463 z[lc++]=" err = close(pahsc->pahsc_OutputHandle);"; 2464 z[lc++]=" if( err < 0 )"; 2465 z[lc++]=" {"; 2466 z[lc++]=" ERR_RPT((\"PaHost_CloseStream: warning, closing output device failed.\\n\"));"; 2467 z[lc++]=" }"; 2468 z[lc++]=" }"; 2469 z[lc++]=" "; 2470 z[lc++]=" if( (pahsc->pahsc_InputHandle != BAD_DEVICE_ID) &&"; 2471 z[lc++]=" (pahsc->pahsc_InputHandle != pahsc->pahsc_OutputHandle) )"; 2472 z[lc++]=" {"; 2473 z[lc++]=" int err;"; 2474 z[lc++]=" DBUG((\"PaHost_CloseStream: attempt to close input device handle = %d\\n\","; 2475 z[lc++]=" pahsc->pahsc_InputHandle ));"; 2476 z[lc++]=" err = close(pahsc->pahsc_InputHandle);"; 2477 z[lc++]=" if( err < 0 )"; 2478 z[lc++]=" {"; 2479 z[lc++]=" ERR_RPT((\"PaHost_CloseStream: warning, closing input device failed.\\n\"));"; 2480 z[lc++]=" }"; 2481 z[lc++]=" }"; 2482 z[lc++]=" pahsc->pahsc_OutputHandle = BAD_DEVICE_ID;"; 2483 z[lc++]=" pahsc->pahsc_InputHandle = BAD_DEVICE_ID;"; 2484 z[lc++]=" "; 2485 z[lc++]=" if( pahsc->pahsc_NativeInputBuffer )"; 2486 z[lc++]=" {"; 2487 z[lc++]=" free( pahsc->pahsc_NativeInputBuffer );"; 2488 z[lc++]=" pahsc->pahsc_NativeInputBuffer = NULL;"; 2489 z[lc++]=" }"; 2490 z[lc++]=" if( pahsc->pahsc_NativeOutputBuffer )"; 2491 z[lc++]=" {"; 2492 z[lc++]=" free( pahsc->pahsc_NativeOutputBuffer );"; 2493 z[lc++]=" pahsc->pahsc_NativeOutputBuffer = NULL;"; 2494 z[lc++]=" }"; 2495 z[lc++]=""; 2496 z[lc++]=" free( pahsc );"; 2497 z[lc++]=" past->past_DeviceData = NULL;"; 2498 z[lc++]=" return paNoError;"; 2499 z[lc++]="}"; 2500 z[lc++]=""; 2501 z[lc++]="/*************************************************************************/"; 2502 z[lc++]="PaError PaHost_Term( void )"; 2503 z[lc++]="{"; 2504 z[lc++]="/* Free all of the linked devices. */"; 2505 z[lc++]=" internalPortAudioDevice *pad, *nextPad;"; 2506 z[lc++]=" pad = sDeviceList;"; 2507 z[lc++]=" while( pad != NULL )"; 2508 z[lc++]=" {"; 2509 z[lc++]=" nextPad = pad->pad_Next;"; 2510 z[lc++]=" DBUG((\"PaHost_Term: freeing %s\\n\", pad->pad_DeviceName ));"; 2511 z[lc++]=" PaHost_FreeFastMemory( pad, sizeof(internalPortAudioDevice) );"; 2512 z[lc++]=" pad = nextPad;"; 2513 z[lc++]=" }"; 2514 z[lc++]=" sDeviceList = NULL;"; 2515 z[lc++]=" return 0;"; 2516 z[lc++]="}"; 2517 z[lc++]=""; 2518 z[lc++]="/*************************************************************************"; 2519 z[lc++]=" * Sleep for the requested number of milliseconds."; 2520 z[lc++]=" */"; 2521 z[lc++]="void Pa_Sleep( long msec )"; 2522 z[lc++]="{"; 2523 z[lc++]="#if 0"; 2524 z[lc++]=" struct timeval timeout;"; 2525 z[lc++]=" timeout.tv_sec = msec / 1000;"; 2526 z[lc++]=" timeout.tv_usec = (msec % 1000) * 1000;"; 2527 z[lc++]=" select( 0, NULL, NULL, NULL, &timeout );"; 2528 z[lc++]="#else"; 2529 z[lc++]=" long usecs = msec * 1000;"; 2530 z[lc++]=" usleep( usecs );"; 2531 z[lc++]="#endif"; 2532 z[lc++]="}"; 2533 z[lc++]=""; 2534 z[lc++]="/*************************************************************************"; 2535 z[lc++]=" * Allocate memory that can be accessed in real-time."; 2536 z[lc++]=" * This may need to be held in physical memory so that it is not"; 2537 z[lc++]=" * paged to virtual memory."; 2538 z[lc++]=" * This call MUST be balanced with a call to PaHost_FreeFastMemory()."; 2539 z[lc++]=" */"; 2540 z[lc++]="void *PaHost_AllocateFastMemory( long numBytes )"; 2541 z[lc++]="{"; 2542 z[lc++]=" void *addr = malloc( numBytes ); /* FIXME - do we need physical memory? */"; 2543 z[lc++]=" if( addr != NULL ) memset( addr, 0, numBytes );"; 2544 z[lc++]=" return addr;"; 2545 z[lc++]="}"; 2546 z[lc++]=""; 2547 z[lc++]="/*************************************************************************"; 2548 z[lc++]=" * Free memory that could be accessed in real-time."; 2549 z[lc++]=" * This call MUST be balanced with a call to PaHost_AllocateFastMemory()."; 2550 z[lc++]=" */"; 2551 z[lc++]="void PaHost_FreeFastMemory( void *addr, long numBytes )"; 2552 z[lc++]="{"; 2553 z[lc++]=" if( addr != NULL ) free( addr );"; 2554 z[lc++]="}"; 2555 z[lc++]=""; 2556 z[lc++]=""; 2557 z[lc++]="/***********************************************************************/"; 2558 z[lc++]="PaError PaHost_StreamActive( internalPortAudioStream *past )"; 2559 z[lc++]="{"; 2560 z[lc++]=" PaHostSoundControl *pahsc;"; 2561 z[lc++]=" if( past == NULL ) return paBadStreamPtr;"; 2562 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 2563 z[lc++]=" if( pahsc == NULL ) return paInternalError;"; 2564 z[lc++]=" return (PaError) (past->past_IsActive != 0);"; 2565 z[lc++]="}"; 2566 z[lc++]=""; 2567 z[lc++]="/***********************************************************************/"; 2568 z[lc++]="PaTimestamp Pa_StreamTime( PortAudioStream *stream )"; 2569 z[lc++]="{"; 2570 z[lc++]=" internalPortAudioStream *past = (internalPortAudioStream *) stream; "; 2571 z[lc++]="/* FIXME - return actual frames played, not frames generated."; 2572 z[lc++]="** Need to query the output device somehow."; 2573 z[lc++]="*/"; 2574 z[lc++]=" if( past == NULL ) return paBadStreamPtr;"; 2575 z[lc++]=" return past->past_FrameCount;"; 2576 z[lc++]="}"; 2577 z[lc++]=""; 2578 z[lc++]="/***********************************************************************/"; 2579 z[lc++]="long Pa_GetHostError( void )"; 2580 z[lc++]="{"; 2581 z[lc++]=" return (long) sPaHostError;"; 2582 z[lc++]="}"; 2583 printlib(lc); 2584 } 2585 2586 2587 void makepa_win_wmme(void) 2588 { 2589 int lc = 0; 2590 2591 z[lc++]="/*"; 2592 z[lc++]=" * pa_win_wmme.c"; 2593 z[lc++]=" * Implementation of PortAudio for Windows MultiMedia Extensions (WMME)"; 2594 z[lc++]=" *"; 2595 z[lc++]=" * PortAudio Portable Real-Time Audio Library"; 2596 z[lc++]=" * Latest Version at: http://www.portaudio.com"; 2597 z[lc++]=" *"; 2598 z[lc++]=" * Authors: Ross Bencina and Phil Burk"; 2599 z[lc++]=" * Copyright (c) 1999-2000 Ross Bencina and Phil Burk"; 2600 z[lc++]=" *"; 2601 z[lc++]=" * Permission is hereby granted, free of charge, to any person obtainingF"; 2602 z[lc++]=" * a copy of this software and associated documentation files"; 2603 z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,"; 2604 z[lc++]=" * including without limitation the rights to use, copy, modify, merge,"; 2605 z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,"; 2606 z[lc++]=" * and to permit persons to whom the Software is furnished to do so,"; 2607 z[lc++]=" * subject to the following conditions:"; 2608 z[lc++]=" *"; 2609 z[lc++]=" * The above copyright notice and this permission notice shall be"; 2610 z[lc++]=" * included in all copies or substantial portions of the Software."; 2611 z[lc++]=" *"; 2612 z[lc++]=" * Any person wishing to distribute modifications to the Software is"; 2613 z[lc++]=" * requested to send the modifications to the original developer so that"; 2614 z[lc++]=" * they can be incorporated into the canonical version."; 2615 z[lc++]=" *"; 2616 z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,"; 2617 z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF"; 2618 z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT."; 2619 z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR"; 2620 z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF"; 2621 z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION"; 2622 z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."; 2623 z[lc++]=" *"; 2624 z[lc++]=" */"; 2625 z[lc++]="/*"; 2626 z[lc++]=" All memory allocations and frees are marked with MEM for quick review."; 2627 z[lc++]="*/"; 2628 z[lc++]="/* Modification History:"; 2629 z[lc++]=" PLB = Phil Burk"; 2630 z[lc++]=" PLB20010402 - sDevicePtrs now allocates based on sizeof(pointer)"; 2631 z[lc++]=" PLB20010413 - check for excessive numbers of channels"; 2632 z[lc++]=" PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC"; 2633 z[lc++]=" including condition including of memory.h,"; 2634 z[lc++]=" and explicit typecasting on memory allocation"; 2635 z[lc++]=" PLB20010802 - use GlobalAlloc for sDevicesPtr instead of PaHost_AllocFastMemory"; 2636 z[lc++]=" PLB20010816 - pass process instead of thread to SetPriorityClass()"; 2637 z[lc++]=" PLB20010927 - use number of frames instead of real-time for CPULoad calculation."; 2638 z[lc++]="*/"; 2639 z[lc++]="#include <stdio.h>"; 2640 z[lc++]="#include <stdlib.h>"; 2641 z[lc++]="#include <math.h>"; 2642 z[lc++]="#include <windows.h>"; 2643 z[lc++]="#include <mmsystem.h>"; 2644 z[lc++]="#include <process.h>"; 2645 z[lc++]="/* PLB20010422 - \"memory.h\" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */"; 2646 z[lc++]="#ifndef __MWERKS__"; 2647 z[lc++]="#include <malloc.h>"; 2648 z[lc++]="#include <memory.h>"; 2649 z[lc++]="#endif /* __MWERKS__ */"; 2650 z[lc++]=""; 2651 z[lc++]="#if 0"; 2652 z[lc++]="#include \"portaudio.h\""; 2653 z[lc++]="#include \"pa_host.h\""; 2654 z[lc++]="#include \"pa_trace.h\""; 2655 z[lc++]="#endif"; 2656 z[lc++]=""; 2657 z[lc++]="/************************************************* Constants ********/"; 2658 z[lc++]="#define PA_USE_TIMER_CALLBACK (0) /* Select between two options for background task. 0=thread, 1=timer */"; 2659 z[lc++]="#define PA_USE_HIGH_LATENCY (0) /* For debugging glitches. */"; 2660 z[lc++]="/* Switches for debugging. */"; 2661 z[lc++]="#define PA_SIMULATE_UNDERFLOW (0) /* Set to one to force an underflow of the output buffer. */"; 2662 z[lc++]="/* To trace program, enable TRACE_REALTIME_EVENTS in pa_trace.h */"; 2663 z[lc++]="#define PA_TRACE_RUN (0)"; 2664 z[lc++]="#define PA_TRACE_START_STOP (1)"; 2665 z[lc++]="#if PA_USE_HIGH_LATENCY"; 2666 z[lc++]=" #define PA_MIN_MSEC_PER_HOST_BUFFER (100)"; 2667 z[lc++]=" #define PA_MAX_MSEC_PER_HOST_BUFFER (300) /* Do not exceed unless user buffer exceeds */"; 2668 z[lc++]=" #define PA_MIN_NUM_HOST_BUFFERS (4)"; 2669 z[lc++]=" #define PA_MAX_NUM_HOST_BUFFERS (16) /* OK to exceed if necessary */"; 2670 z[lc++]=" #define PA_WIN_9X_LATENCY (400)"; 2671 z[lc++]="#else"; 2672 z[lc++]=" #define PA_MIN_MSEC_PER_HOST_BUFFER (10)"; 2673 z[lc++]=" #define PA_MAX_MSEC_PER_HOST_BUFFER (100) /* Do not exceed unless user buffer exceeds */"; 2674 z[lc++]=" #define PA_MIN_NUM_HOST_BUFFERS (3)"; 2675 z[lc++]=" #define PA_MAX_NUM_HOST_BUFFERS (16) /* OK to exceed if necessary */"; 2676 z[lc++]=" #define PA_WIN_9X_LATENCY (200)"; 2677 z[lc++]="#endif"; 2678 z[lc++]="#define MIN_TIMEOUT_MSEC (1000)"; 2679 z[lc++]="/*"; 2680 z[lc++]="** Use higher latency for NT because it is even worse at real-time"; 2681 z[lc++]="** operation than Win9x."; 2682 z[lc++]="*/"; 2683 z[lc++]="#define PA_WIN_NT_LATENCY (PA_WIN_9X_LATENCY * 2)"; 2684 z[lc++]="#if PA_SIMULATE_UNDERFLOW"; 2685 z[lc++]="static gUnderCallbackCounter = 0;"; 2686 z[lc++]="#define UNDER_SLEEP_AT (40)"; 2687 z[lc++]="#define UNDER_SLEEP_FOR (500)"; 2688 z[lc++]="#endif"; 2689 z[lc++]="#define PRINT(x) { printf x; fflush(stdout); }"; 2690 z[lc++]="#define ERR_RPT(x) PRINT(x)"; 2691 z[lc++]="#define DBUG(x) /* PRINT(x) */"; 2692 z[lc++]="#define DBUGX(x) /* PRINT(x) */"; 2693 z[lc++]="/************************************************* Definitions ********/"; 2694 z[lc++]="/**************************************************************"; 2695 z[lc++]=" * Structure for internal host specific stream data."; 2696 z[lc++]=" * This is allocated on a per stream basis."; 2697 z[lc++]=" */"; 2698 z[lc++]="typedef struct PaHostSoundControl"; 2699 z[lc++]="{"; 2700 z[lc++]="/* Input -------------- */"; 2701 z[lc++]=" HWAVEIN pahsc_HWaveIn;"; 2702 z[lc++]=" WAVEHDR *pahsc_InputBuffers;"; 2703 z[lc++]=" int pahsc_CurrentInputBuffer;"; 2704 z[lc++]=" int pahsc_BytesPerHostInputBuffer;"; 2705 z[lc++]=" int pahsc_BytesPerUserInputBuffer; /* native buffer size in bytes */"; 2706 z[lc++]="/* Output -------------- */ "; 2707 z[lc++]=" HWAVEOUT pahsc_HWaveOut;"; 2708 z[lc++]=" WAVEHDR *pahsc_OutputBuffers;"; 2709 z[lc++]=" int pahsc_CurrentOutputBuffer;"; 2710 z[lc++]=" int pahsc_BytesPerHostOutputBuffer;"; 2711 z[lc++]=" int pahsc_BytesPerUserOutputBuffer; /* native buffer size in bytes */"; 2712 z[lc++]="/* Run Time -------------- */ "; 2713 z[lc++]=" PaTimestamp pahsc_FramesPlayed;"; 2714 z[lc++]=" long pahsc_LastPosition; /* used to track frames played. */"; 2715 z[lc++]="/* For measuring CPU utilization. */"; 2716 z[lc++]=" LARGE_INTEGER pahsc_EntryCount;"; 2717 z[lc++]=" double pahsc_InverseTicksPerHostBuffer;"; 2718 z[lc++]="/* Init Time -------------- */ "; 2719 z[lc++]=" int pahsc_NumHostBuffers;"; 2720 z[lc++]=" int pahsc_FramesPerHostBuffer;"; 2721 z[lc++]=" int pahsc_UserBuffersPerHostBuffer;"; 2722 z[lc++]=" CRITICAL_SECTION pahsc_StreamLock; /* Mutext to prevent threads from colliding. */"; 2723 z[lc++]=" INT pahsc_StreamLockInited;"; 2724 z[lc++]="#if PA_USE_TIMER_CALLBACK"; 2725 z[lc++]=" BOOL pahsc_IfInsideCallback; /* Test for reentrancy. */"; 2726 z[lc++]=" MMRESULT pahsc_TimerID;"; 2727 z[lc++]="#else"; 2728 z[lc++]=" HANDLE pahsc_AbortEvent;"; 2729 z[lc++]=" int pahsc_AbortEventInited;"; 2730 z[lc++]=" HANDLE pahsc_BufferEvent;"; 2731 z[lc++]=" int pahsc_BufferEventInited;"; 2732 z[lc++]=" HANDLE pahsc_EngineThread;"; 2733 z[lc++]=" DWORD pahsc_EngineThreadID;"; 2734 z[lc++]="#endif"; 2735 z[lc++]="} PaHostSoundControl;"; 2736 z[lc++]="/************************************************* Shared Data ********/"; 2737 z[lc++]="/* FIXME - put Mutex around this shared data. */"; 2738 z[lc++]="static int sNumInputDevices = 0;"; 2739 z[lc++]="static int sNumOutputDevices = 0;"; 2740 z[lc++]="static int sNumDevices = 0;"; 2741 z[lc++]="static PaDeviceInfo **sDevicePtrs = NULL;"; 2742 z[lc++]="static int sDefaultInputDeviceID = paNoDevice;"; 2743 z[lc++]="static int sDefaultOutputDeviceID = paNoDevice;"; 2744 z[lc++]="static int sPaHostError = 0;"; 2745 z[lc++]="static const char sMapperSuffixInput[] = \" - Input\";"; 2746 z[lc++]="static const char sMapperSuffixOutput[] = \" - Output\";"; 2747 z[lc++]="/************************************************* Macros ********/"; 2748 z[lc++]="/* Convert external PA ID to an internal ID that includes WAVE_MAPPER */"; 2749 z[lc++]="#define PaDeviceIdToWinId(id) (((id) < sNumInputDevices) ? (id - 1) : (id - sNumInputDevices - 1))"; 2750 z[lc++]="/************************************************* Prototypes **********/"; 2751 z[lc++]="static Pa_QueryDevices( void );"; 2752 z[lc++]="static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg,"; 2753 z[lc++]=" DWORD dwUser, DWORD dw1, DWORD dw2);"; 2754 z[lc++]="PaError PaHost_GetTotalBufferFrames( internalPortAudioStream *past );"; 2755 z[lc++]="static PaError PaHost_UpdateStreamTime( PaHostSoundControl *pahsc );"; 2756 z[lc++]="static PaError PaHost_BackgroundManager( internalPortAudioStream *past );"; 2757 z[lc++]="/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/"; 2758 z[lc++]="static void Pa_StartUsageCalculation( internalPortAudioStream *past )"; 2759 z[lc++]="{"; 2760 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 2761 z[lc++]=" if( pahsc == NULL ) return;"; 2762 z[lc++]="/* Query system timer for usage analysis and to prevent overuse of CPU. */"; 2763 z[lc++]=" QueryPerformanceCounter( &pahsc->pahsc_EntryCount );"; 2764 z[lc++]="}"; 2765 z[lc++]="static void Pa_EndUsageCalculation( internalPortAudioStream *past )"; 2766 z[lc++]="{"; 2767 z[lc++]=" LARGE_INTEGER CurrentCount = { 0, 0 };"; 2768 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 2769 z[lc++]=" if( pahsc == NULL ) return;"; 2770 z[lc++]="/*"; 2771 z[lc++]="** Measure CPU utilization during this callback. Note that this calculation"; 2772 z[lc++]="** assumes that we had the processor the whole time."; 2773 z[lc++]="*/"; 2774 z[lc++]="#define LOWPASS_COEFFICIENT_0 (0.9)"; 2775 z[lc++]="#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0)"; 2776 z[lc++]=" if( QueryPerformanceCounter( &CurrentCount ) )"; 2777 z[lc++]=" {"; 2778 z[lc++]=" LONGLONG InsideCount = CurrentCount.QuadPart - pahsc->pahsc_EntryCount.QuadPart; "; 2779 z[lc++]=" double newUsage = InsideCount * pahsc->pahsc_InverseTicksPerHostBuffer;"; 2780 z[lc++]=" past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +"; 2781 z[lc++]=" (LOWPASS_COEFFICIENT_1 * newUsage);"; 2782 z[lc++]=" }"; 2783 z[lc++]="}"; 2784 z[lc++]="/****************************************** END CPU UTILIZATION *******/"; 2785 z[lc++]="static PaError Pa_QueryDevices( void )"; 2786 z[lc++]="{"; 2787 z[lc++]=" int numBytes;"; 2788 z[lc++]="/* Count the devices and add one extra for the WAVE_MAPPER */"; 2789 z[lc++]=" sNumInputDevices = waveInGetNumDevs() + 1;"; 2790 z[lc++]=" sDefaultInputDeviceID = 0;"; 2791 z[lc++]=" sNumOutputDevices = waveOutGetNumDevs() + 1;"; 2792 z[lc++]=" sDefaultOutputDeviceID = sNumInputDevices;"; 2793 z[lc++]=" sNumDevices = sNumInputDevices + sNumOutputDevices;"; 2794 z[lc++]="/* Allocate structures to hold device info. */"; 2795 z[lc++]="/* PLB20010402 - was allocating too much memory. */"; 2796 z[lc++]="/* numBytes = sNumDevices * sizeof(PaDeviceInfo); // PLB20010402 */"; 2797 z[lc++]=" numBytes = sNumDevices * sizeof(PaDeviceInfo *); /* PLB20010402 */"; 2798 z[lc++]=" sDevicePtrs = (PaDeviceInfo **) GlobalAlloc( GPTR, numBytes ); /* MEM */"; 2799 z[lc++]=" if( sDevicePtrs == NULL ) return paInsufficientMemory;"; 2800 z[lc++]=" return paNoError;"; 2801 z[lc++]="}"; 2802 z[lc++]="/************************************************************************************/"; 2803 z[lc++]="long Pa_GetHostError()"; 2804 z[lc++]="{"; 2805 z[lc++]=" return sPaHostError;"; 2806 z[lc++]="}"; 2807 z[lc++]="/*************************************************************************/"; 2808 z[lc++]="int Pa_CountDevices()"; 2809 z[lc++]="{"; 2810 z[lc++]=" if( sNumDevices <= 0 ) Pa_Initialize();"; 2811 z[lc++]=" return sNumDevices;"; 2812 z[lc++]="}"; 2813 z[lc++]="/*************************************************************************"; 2814 z[lc++]="** If a PaDeviceInfo structure has not already been created,"; 2815 z[lc++]="** then allocate one and fill it in for the selected device."; 2816 z[lc++]="**"; 2817 z[lc++]="** We create one extra input and one extra output device for the WAVE_MAPPER."; 2818 z[lc++]="** [Does anyone know how to query the default device and get its name?]"; 2819 z[lc++]="*/"; 2820 z[lc++]="const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )"; 2821 z[lc++]="{ "; 2822 z[lc++]="#define NUM_STANDARDSAMPLINGRATES 3 /* 11.025, 22.05, 44.1 */"; 2823 z[lc++]="#define NUM_CUSTOMSAMPLINGRATES 5 /* must be the same number of elements as in the array below */"; 2824 z[lc++]="#define MAX_NUMSAMPLINGRATES (NUM_STANDARDSAMPLINGRATES+NUM_CUSTOMSAMPLINGRATES)"; 2825 z[lc++]=" static DWORD customSamplingRates[] = { 32000, 48000, 64000, 88200, 96000 };"; 2826 z[lc++]=" PaDeviceInfo *deviceInfo;"; 2827 z[lc++]=" double *sampleRates; /* non-const ptr */"; 2828 z[lc++]=" int i;"; 2829 z[lc++]=" char *s;"; 2830 z[lc++]=" "; 2831 z[lc++]=" if( id < 0 || id >= sNumDevices )"; 2832 z[lc++]=" return NULL;"; 2833 z[lc++]=" if( sDevicePtrs[ id ] != NULL )"; 2834 z[lc++]=" {"; 2835 z[lc++]=" return sDevicePtrs[ id ];"; 2836 z[lc++]=" }"; 2837 z[lc++]=" deviceInfo = (PaDeviceInfo *)GlobalAlloc( GPTR, sizeof(PaDeviceInfo) ); /* MEM */"; 2838 z[lc++]=" if( deviceInfo == NULL ) return NULL;"; 2839 z[lc++]=" deviceInfo->structVersion = 1;"; 2840 z[lc++]=" deviceInfo->maxInputChannels = 0;"; 2841 z[lc++]=" deviceInfo->maxOutputChannels = 0;"; 2842 z[lc++]=" deviceInfo->numSampleRates = 0;"; 2843 z[lc++]=" sampleRates = (double*)GlobalAlloc( GPTR, MAX_NUMSAMPLINGRATES * sizeof(double) ); /* MEM */"; 2844 z[lc++]=" deviceInfo->sampleRates = sampleRates;"; 2845 z[lc++]=" deviceInfo->nativeSampleFormats = paInt16; /* should query for higher bit depths below */"; 2846 z[lc++]=" if( id < sNumInputDevices )"; 2847 z[lc++]=" {"; 2848 z[lc++]=" /* input device */"; 2849 z[lc++]=" int inputMmID = id - 1; /* WAVE_MAPPER is -1 so we start with WAVE_MAPPER */"; 2850 z[lc++]=" WAVEINCAPS wic;"; 2851 z[lc++]=" if( waveInGetDevCaps( inputMmID, &wic, sizeof( WAVEINCAPS ) ) != MMSYSERR_NOERROR )"; 2852 z[lc++]=" goto error;"; 2853 z[lc++]=" "; 2854 z[lc++]=" /* Append I/O suffix to WAVE_MAPPER device. */"; 2855 z[lc++]=" if( inputMmID == WAVE_MAPPER )"; 2856 z[lc++]=" {"; 2857 z[lc++]=" s = (char *) GlobalAlloc( GMEM_FIXED, strlen( wic.szPname ) + 1 + sizeof(sMapperSuffixInput) ); /* MEM */"; 2858 z[lc++]=" strcpy( s, wic.szPname );"; 2859 z[lc++]=" strcat( s, sMapperSuffixInput );"; 2860 z[lc++]=" }"; 2861 z[lc++]=" else"; 2862 z[lc++]=" {"; 2863 z[lc++]=" s = (char *) GlobalAlloc( GMEM_FIXED, strlen( wic.szPname ) + 1 ); /* MEM */"; 2864 z[lc++]=" strcpy( s, wic.szPname );"; 2865 z[lc++]=" }"; 2866 z[lc++]=" deviceInfo->name = s;"; 2867 z[lc++]=" deviceInfo->maxInputChannels = wic.wChannels;"; 2868 z[lc++]=" /* Sometimes a device can return a rediculously large number of channels."; 2869 z[lc++]=" ** This happened with an SBLive card on a Windows ME box."; 2870 z[lc++]=" ** If that happens, then force it to 2 channels. PLB20010413"; 2871 z[lc++]=" */"; 2872 z[lc++]=" if( (deviceInfo->maxInputChannels < 1) || (deviceInfo->maxInputChannels > 256) )"; 2873 z[lc++]=" {"; 2874 z[lc++]=" ERR_RPT((\"Pa_GetDeviceInfo: Num input channels reported as %d! Changed to 2.\\n\", deviceInfo->maxOutputChannels ));"; 2875 z[lc++]=" deviceInfo->maxInputChannels = 2;"; 2876 z[lc++]=" }"; 2877 z[lc++]=" /* Add a sample rate to the list if we can do stereo 16 bit at that rate"; 2878 z[lc++]=" * based on the format flags. */"; 2879 z[lc++]=" if( wic.dwFormats & WAVE_FORMAT_1M16 ||wic.dwFormats & WAVE_FORMAT_1S16 )"; 2880 z[lc++]=" sampleRates[ deviceInfo->numSampleRates++ ] = 11025.;"; 2881 z[lc++]=" if( wic.dwFormats & WAVE_FORMAT_2M16 ||wic.dwFormats & WAVE_FORMAT_2S16 )"; 2882 z[lc++]=" sampleRates[ deviceInfo->numSampleRates++ ] = 22050.;"; 2883 z[lc++]=" if( wic.dwFormats & WAVE_FORMAT_4M16 ||wic.dwFormats & WAVE_FORMAT_4S16 )"; 2884 z[lc++]=" sampleRates[ deviceInfo->numSampleRates++ ] = 44100.;"; 2885 z[lc++]=" /* Add a sample rate to the list if we can do stereo 16 bit at that rate"; 2886 z[lc++]=" * based on opening the device successfully. */"; 2887 z[lc++]=" for( i=0; i < NUM_CUSTOMSAMPLINGRATES; i++ ){"; 2888 z[lc++]=" WAVEFORMATEX wfx;"; 2889 z[lc++]=" wfx.wFormatTag = WAVE_FORMAT_PCM;"; 2890 z[lc++]=" wfx.nSamplesPerSec = customSamplingRates[i];"; 2891 z[lc++]=" wfx.wBitsPerSample = 16;"; 2892 z[lc++]=" wfx.cbSize = 0; /* ignored */"; 2893 z[lc++]=" wfx.nChannels = (WORD)deviceInfo->maxInputChannels;"; 2894 z[lc++]=" wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);"; 2895 z[lc++]=" wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));"; 2896 z[lc++]=" if( waveInOpen( NULL, inputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR )"; 2897 z[lc++]=" {"; 2898 z[lc++]=" sampleRates[ deviceInfo->numSampleRates++ ] = customSamplingRates[i];"; 2899 z[lc++]=" }"; 2900 z[lc++]=" }"; 2901 z[lc++]=" "; 2902 z[lc++]=" }"; 2903 z[lc++]=" else if( id - sNumInputDevices < sNumOutputDevices )"; 2904 z[lc++]=" {"; 2905 z[lc++]=" /* output device */"; 2906 z[lc++]=" int outputMmID = id - sNumInputDevices - 1;"; 2907 z[lc++]=" WAVEOUTCAPS woc;"; 2908 z[lc++]=" if( waveOutGetDevCaps( outputMmID, &woc, sizeof( WAVEOUTCAPS ) ) != MMSYSERR_NOERROR )"; 2909 z[lc++]=" goto error;"; 2910 z[lc++]=" /* Append I/O suffix to WAVE_MAPPER device. */"; 2911 z[lc++]=" if( outputMmID == WAVE_MAPPER )"; 2912 z[lc++]=" {"; 2913 z[lc++]=" s = (char *) GlobalAlloc( GMEM_FIXED, strlen( woc.szPname ) + 1 + sizeof(sMapperSuffixOutput) ); /* MEM */"; 2914 z[lc++]=" strcpy( s, woc.szPname );"; 2915 z[lc++]=" strcat( s, sMapperSuffixOutput );"; 2916 z[lc++]=" }"; 2917 z[lc++]=" else"; 2918 z[lc++]=" {"; 2919 z[lc++]=" s = (char *) GlobalAlloc( GMEM_FIXED, strlen( woc.szPname ) + 1 ); /* MEM */"; 2920 z[lc++]=" strcpy( s, woc.szPname );"; 2921 z[lc++]=" }"; 2922 z[lc++]=" deviceInfo->name = s;"; 2923 z[lc++]=" deviceInfo->maxOutputChannels = woc.wChannels;"; 2924 z[lc++]=" /* Sometimes a device can return a rediculously large number of channels."; 2925 z[lc++]=" ** This happened with an SBLive card on a Windows ME box."; 2926 z[lc++]=" ** If that happens, then force it to 2 channels. PLB20010413"; 2927 z[lc++]=" */"; 2928 z[lc++]=" if( (deviceInfo->maxOutputChannels < 1) || (deviceInfo->maxOutputChannels > 256) )"; 2929 z[lc++]=" {"; 2930 z[lc++]=" ERR_RPT((\"Pa_GetDeviceInfo: Num output channels reported as %d! Changed to 2.\\n\", deviceInfo->maxOutputChannels ));"; 2931 z[lc++]=" deviceInfo->maxOutputChannels = 2;"; 2932 z[lc++]=" }"; 2933 z[lc++]=" /* Add a sample rate to the list if we can do stereo 16 bit at that rate"; 2934 z[lc++]=" * based on the format flags. */"; 2935 z[lc++]=" if( woc.dwFormats & WAVE_FORMAT_1M16 ||woc.dwFormats & WAVE_FORMAT_1S16 )"; 2936 z[lc++]=" sampleRates[ deviceInfo->numSampleRates++ ] = 11025.;"; 2937 z[lc++]=" if( woc.dwFormats & WAVE_FORMAT_2M16 ||woc.dwFormats & WAVE_FORMAT_2S16 )"; 2938 z[lc++]=" sampleRates[ deviceInfo->numSampleRates++ ] = 22050.;"; 2939 z[lc++]=" if( woc.dwFormats & WAVE_FORMAT_4M16 ||woc.dwFormats & WAVE_FORMAT_4S16 )"; 2940 z[lc++]=" sampleRates[ deviceInfo->numSampleRates++ ] = 44100.;"; 2941 z[lc++]=" /* Add a sample rate to the list if we can do stereo 16 bit at that rate"; 2942 z[lc++]=" * based on opening the device successfully. */"; 2943 z[lc++]=" for( i=0; i < NUM_CUSTOMSAMPLINGRATES; i++ )"; 2944 z[lc++]=" {"; 2945 z[lc++]=" WAVEFORMATEX wfx;"; 2946 z[lc++]=" wfx.wFormatTag = WAVE_FORMAT_PCM;"; 2947 z[lc++]=" wfx.nSamplesPerSec = customSamplingRates[i];"; 2948 z[lc++]=" wfx.wBitsPerSample = 16;"; 2949 z[lc++]=" wfx.cbSize = 0; /* ignored */"; 2950 z[lc++]=" wfx.nChannels = (WORD)deviceInfo->maxOutputChannels;"; 2951 z[lc++]=" wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);"; 2952 z[lc++]=" wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));"; 2953 z[lc++]=" if( waveOutOpen( NULL, outputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR ){"; 2954 z[lc++]=" sampleRates[ deviceInfo->numSampleRates++ ] = customSamplingRates[i];"; 2955 z[lc++]=" }"; 2956 z[lc++]=" }"; 2957 z[lc++]=" }"; 2958 z[lc++]=" sDevicePtrs[ id ] = deviceInfo;"; 2959 z[lc++]=" return deviceInfo;"; 2960 z[lc++]="error:"; 2961 z[lc++]=" GlobalFree( sampleRates ); /* MEM */"; 2962 z[lc++]=" GlobalFree( deviceInfo ); /* MEM */"; 2963 z[lc++]=" "; 2964 z[lc++]=" return NULL;"; 2965 z[lc++]="}"; 2966 z[lc++]="/*************************************************************************"; 2967 z[lc++]="** Returns recommended device ID."; 2968 z[lc++]="** On the PC, the recommended device can be specified by the user by"; 2969 z[lc++]="** setting an environment variable. For example, to use device #1."; 2970 z[lc++]="**"; 2971 z[lc++]="** set PA_RECOMMENDED_OUTPUT_DEVICE=1"; 2972 z[lc++]="**"; 2973 z[lc++]="** The user should first determine the available device ID by using"; 2974 z[lc++]="** the supplied application \"pa_devs\"."; 2975 z[lc++]="*/"; 2976 z[lc++]="#define PA_ENV_BUF_SIZE (32)"; 2977 z[lc++]="#define PA_REC_IN_DEV_ENV_NAME (\"PA_RECOMMENDED_INPUT_DEVICE\")"; 2978 z[lc++]="#define PA_REC_OUT_DEV_ENV_NAME (\"PA_RECOMMENDED_OUTPUT_DEVICE\")"; 2979 z[lc++]="static PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName )"; 2980 z[lc++]="{"; 2981 z[lc++]=" DWORD hresult;"; 2982 z[lc++]=" char envbuf[PA_ENV_BUF_SIZE];"; 2983 z[lc++]=" PaDeviceID recommendedID = paNoDevice;"; 2984 z[lc++]="/* Let user determine default device by setting environment variable. */"; 2985 z[lc++]=" hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE );"; 2986 z[lc++]=" if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )"; 2987 z[lc++]=" {"; 2988 z[lc++]=" recommendedID = atoi( envbuf );"; 2989 z[lc++]=" }"; 2990 z[lc++]=" return recommendedID;"; 2991 z[lc++]="}"; 2992 z[lc++]="static PaError Pa_MaybeQueryDevices( void )"; 2993 z[lc++]="{"; 2994 z[lc++]=" if( sNumDevices == 0 )"; 2995 z[lc++]=" {"; 2996 z[lc++]=" return Pa_QueryDevices();"; 2997 z[lc++]=" }"; 2998 z[lc++]=" return 0;"; 2999 z[lc++]="}"; 3000 z[lc++]="/**********************************************************************"; 3001 z[lc++]="** Check for environment variable, else query devices and use result."; 3002 z[lc++]="*/"; 3003 z[lc++]="PaDeviceID Pa_GetDefaultInputDeviceID( void )"; 3004 z[lc++]="{"; 3005 z[lc++]=" PaError result;"; 3006 z[lc++]=" result = PaHost_GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME );"; 3007 z[lc++]=" if( result < 0 )"; 3008 z[lc++]=" {"; 3009 z[lc++]=" result = Pa_MaybeQueryDevices();"; 3010 z[lc++]=" if( result < 0 ) return result;"; 3011 z[lc++]=" result = sDefaultInputDeviceID;"; 3012 z[lc++]=" }"; 3013 z[lc++]=" return result;"; 3014 z[lc++]="}"; 3015 z[lc++]="PaDeviceID Pa_GetDefaultOutputDeviceID( void )"; 3016 z[lc++]="{"; 3017 z[lc++]=" PaError result;"; 3018 z[lc++]=" result = PaHost_GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME );"; 3019 z[lc++]=" if( result < 0 )"; 3020 z[lc++]=" {"; 3021 z[lc++]=" result = Pa_MaybeQueryDevices();"; 3022 z[lc++]=" if( result < 0 ) return result;"; 3023 z[lc++]=" result = sDefaultOutputDeviceID;"; 3024 z[lc++]=" }"; 3025 z[lc++]=" return result;"; 3026 z[lc++]="}"; 3027 z[lc++]="/**********************************************************************"; 3028 z[lc++]="** Initialize Host dependant part of API."; 3029 z[lc++]="*/"; 3030 z[lc++]="PaError PaHost_Init( void )"; 3031 z[lc++]="{"; 3032 z[lc++]="#if PA_SIMULATE_UNDERFLOW"; 3033 z[lc++]=" PRINT((\"WARNING - Underflow Simulation Enabled - Expect a Big Glitch!!!\\n\"));"; 3034 z[lc++]="#endif"; 3035 z[lc++]=" return Pa_MaybeQueryDevices();"; 3036 z[lc++]="}"; 3037 z[lc++]="/**********************************************************************"; 3038 z[lc++]="** Check WAVE buffers to see if they are done."; 3039 z[lc++]="** Fill any available output buffers and use any available"; 3040 z[lc++]="** input buffers by calling user callback."; 3041 z[lc++]="*/"; 3042 z[lc++]="static PaError Pa_TimeSlice( internalPortAudioStream *past )"; 3043 z[lc++]="{"; 3044 z[lc++]=" PaError result = 0;"; 3045 z[lc++]=" long bytesEmpty = 0;"; 3046 z[lc++]=" long bytesFilled = 0;"; 3047 z[lc++]=" long buffersEmpty = 0;"; 3048 z[lc++]=" MMRESULT mresult;"; 3049 z[lc++]=" char *inBufPtr;"; 3050 z[lc++]=" char *outBufPtr;"; 3051 z[lc++]=" int gotInput = 0;"; 3052 z[lc++]=" int gotOutput = 0;"; 3053 z[lc++]=" int i;"; 3054 z[lc++]=" int buffersProcessed = 0;"; 3055 z[lc++]=" int done = 0;"; 3056 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3057 z[lc++]=" if( pahsc == NULL ) return paInternalError;"; 3058 z[lc++]=" past->past_NumCallbacks += 1;"; 3059 z[lc++]="#if PA_SIMULATE_UNDERFLOW"; 3060 z[lc++]=" if(gUnderCallbackCounter++ == UNDER_SLEEP_AT)"; 3061 z[lc++]=" {"; 3062 z[lc++]=" Sleep(UNDER_SLEEP_FOR);"; 3063 z[lc++]=" }"; 3064 z[lc++]="#endif"; 3065 z[lc++]="#if PA_TRACE_RUN"; 3066 z[lc++]=" AddTraceMessage(\"Pa_TimeSlice: past_NumCallbacks \", past->past_NumCallbacks );"; 3067 z[lc++]="#endif"; 3068 z[lc++]=" while(!done)"; 3069 z[lc++]=" {"; 3070 z[lc++]="/* If we are using output, then we need an empty output buffer. */"; 3071 z[lc++]=" gotOutput = 0;"; 3072 z[lc++]=" outBufPtr = NULL;"; 3073 z[lc++]=" if( past->past_NumOutputChannels > 0 )"; 3074 z[lc++]=" {"; 3075 z[lc++]=" if((pahsc->pahsc_OutputBuffers[ pahsc->pahsc_CurrentOutputBuffer ].dwFlags & WHDR_DONE) == 0)"; 3076 z[lc++]=" { "; 3077 z[lc++]=" break; /* If none empty then bail and try again later. */"; 3078 z[lc++]=" }"; 3079 z[lc++]=" else"; 3080 z[lc++]=" {"; 3081 z[lc++]=" outBufPtr = pahsc->pahsc_OutputBuffers[ pahsc->pahsc_CurrentOutputBuffer ].lpData;"; 3082 z[lc++]=" gotOutput = 1;"; 3083 z[lc++]=" }"; 3084 z[lc++]=" }"; 3085 z[lc++]="/* Use an input buffer if one is available. */"; 3086 z[lc++]=" gotInput = 0;"; 3087 z[lc++]=" inBufPtr = NULL;"; 3088 z[lc++]=" if( ( past->past_NumInputChannels > 0 ) &&"; 3089 z[lc++]=" (pahsc->pahsc_InputBuffers[ pahsc->pahsc_CurrentInputBuffer ].dwFlags & WHDR_DONE) )"; 3090 z[lc++]=" {"; 3091 z[lc++]=" inBufPtr = pahsc->pahsc_InputBuffers[ pahsc->pahsc_CurrentInputBuffer ].lpData;"; 3092 z[lc++]=" gotInput = 1;"; 3093 z[lc++]="#if PA_TRACE_RUN"; 3094 z[lc++]=" AddTraceMessage(\"Pa_TimeSlice: got input buffer at \", (int)inBufPtr );"; 3095 z[lc++]=" AddTraceMessage(\"Pa_TimeSlice: got input buffer # \", pahsc->pahsc_CurrentInputBuffer );"; 3096 z[lc++]="#endif"; 3097 z[lc++]=" }"; 3098 z[lc++]="/* If we can't do anything then bail out. */"; 3099 z[lc++]=" if( !gotInput && !gotOutput ) break;"; 3100 z[lc++]=" buffersProcessed += 1;"; 3101 z[lc++]="/* Each Wave buffer contains multiple user buffers so do them all now. */"; 3102 z[lc++]="/* Base Usage on time it took to process one host buffer. */"; 3103 z[lc++]=" Pa_StartUsageCalculation( past );"; 3104 z[lc++]=" for( i=0; i<pahsc->pahsc_UserBuffersPerHostBuffer; i++ )"; 3105 z[lc++]=" {"; 3106 z[lc++]=" if( done )"; 3107 z[lc++]=" {"; 3108 z[lc++]=" if( gotOutput )"; 3109 z[lc++]=" {"; 3110 z[lc++]=" /* Clear remainder of wave buffer if we are waiting for stop. */"; 3111 z[lc++]=" AddTraceMessage(\"Pa_TimeSlice: zero rest of wave buffer \", i );"; 3112 z[lc++]=" memset( outBufPtr, 0, pahsc->pahsc_BytesPerUserOutputBuffer );"; 3113 z[lc++]=" }"; 3114 z[lc++]=" }"; 3115 z[lc++]=" else"; 3116 z[lc++]=" {"; 3117 z[lc++]=" /* Convert 16 bit native data to user data and call user routine. */"; 3118 z[lc++]=" result = Pa_CallConvertInt16( past, (short *) inBufPtr, (short *) outBufPtr );"; 3119 z[lc++]=" if( result != 0) done = 1;"; 3120 z[lc++]=" }"; 3121 z[lc++]=" if( gotInput ) inBufPtr += pahsc->pahsc_BytesPerUserInputBuffer;"; 3122 z[lc++]=" if( gotOutput) outBufPtr += pahsc->pahsc_BytesPerUserOutputBuffer;"; 3123 z[lc++]=" }"; 3124 z[lc++]=" Pa_EndUsageCalculation( past );"; 3125 z[lc++]="/* Send WAVE buffer to Wave Device to be refilled. */"; 3126 z[lc++]=" if( gotInput )"; 3127 z[lc++]=" {"; 3128 z[lc++]=" mresult = waveInAddBuffer( pahsc->pahsc_HWaveIn,"; 3129 z[lc++]=" &pahsc->pahsc_InputBuffers[ pahsc->pahsc_CurrentInputBuffer ],"; 3130 z[lc++]=" sizeof(WAVEHDR) );"; 3131 z[lc++]=" if( mresult != MMSYSERR_NOERROR )"; 3132 z[lc++]=" {"; 3133 z[lc++]=" sPaHostError = mresult;"; 3134 z[lc++]=" result = paHostError;"; 3135 z[lc++]=" break;"; 3136 z[lc++]=" }"; 3137 z[lc++]=" pahsc->pahsc_CurrentInputBuffer = (pahsc->pahsc_CurrentInputBuffer+1 >= pahsc->pahsc_NumHostBuffers) ?"; 3138 z[lc++]=" 0 : pahsc->pahsc_CurrentInputBuffer+1;"; 3139 z[lc++]=" }"; 3140 z[lc++]="/* Write WAVE buffer to Wave Device. */"; 3141 z[lc++]=" if( gotOutput )"; 3142 z[lc++]=" {"; 3143 z[lc++]="#if PA_TRACE_START_STOP"; 3144 z[lc++]=" AddTraceMessage( \"Pa_TimeSlice: writing buffer \", pahsc->pahsc_CurrentOutputBuffer );"; 3145 z[lc++]="#endif"; 3146 z[lc++]=" mresult = waveOutWrite( pahsc->pahsc_HWaveOut,"; 3147 z[lc++]=" &pahsc->pahsc_OutputBuffers[ pahsc->pahsc_CurrentOutputBuffer ],"; 3148 z[lc++]=" sizeof(WAVEHDR) );"; 3149 z[lc++]=" if( mresult != MMSYSERR_NOERROR )"; 3150 z[lc++]=" {"; 3151 z[lc++]=" sPaHostError = mresult;"; 3152 z[lc++]=" result = paHostError;"; 3153 z[lc++]=" break;"; 3154 z[lc++]=" }"; 3155 z[lc++]=" pahsc->pahsc_CurrentOutputBuffer = (pahsc->pahsc_CurrentOutputBuffer+1 >= pahsc->pahsc_NumHostBuffers) ?"; 3156 z[lc++]=" 0 : pahsc->pahsc_CurrentOutputBuffer+1;"; 3157 z[lc++]=" }"; 3158 z[lc++]=" }"; 3159 z[lc++]=" "; 3160 z[lc++]="#if PA_TRACE_RUN"; 3161 z[lc++]=" AddTraceMessage(\"Pa_TimeSlice: buffersProcessed \", buffersProcessed );"; 3162 z[lc++]="#endif"; 3163 z[lc++]=" return (result != 0) ? result : done;"; 3164 z[lc++]="}"; 3165 z[lc++]="/*******************************************************************/"; 3166 z[lc++]="static PaError PaHost_BackgroundManager( internalPortAudioStream *past )"; 3167 z[lc++]="{"; 3168 z[lc++]=" PaError result = 0;"; 3169 z[lc++]=" int i;"; 3170 z[lc++]=" int numQueuedOutputBuffers = 0;"; 3171 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3172 z[lc++]="/* Has someone asked us to abort by calling Pa_AbortStream()? */"; 3173 z[lc++]=" if( past->past_StopNow )"; 3174 z[lc++]=" {"; 3175 z[lc++]=" past->past_IsActive = 0; /* Will cause thread to return. */"; 3176 z[lc++]=" }"; 3177 z[lc++]="/* Has someone asked us to stop by calling Pa_StopStream()"; 3178 z[lc++]=" * OR has a user callback returned '1' to indicate finished."; 3179 z[lc++]=" */"; 3180 z[lc++]=" else if( past->past_StopSoon )"; 3181 z[lc++]=" {"; 3182 z[lc++]="/* Poll buffer and when all have played then exit thread. */"; 3183 z[lc++]="/* Count how many output buffers are queued. */"; 3184 z[lc++]=" numQueuedOutputBuffers = 0;"; 3185 z[lc++]=" if( past->past_NumOutputChannels > 0 )"; 3186 z[lc++]=" {"; 3187 z[lc++]=" for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )"; 3188 z[lc++]=" {"; 3189 z[lc++]=" if( !( pahsc->pahsc_OutputBuffers[ i ].dwFlags & WHDR_DONE) )"; 3190 z[lc++]=" {"; 3191 z[lc++]="#if PA_TRACE_START_STOP"; 3192 z[lc++]="AddTraceMessage( \"WinMMPa_OutputThreadProc: waiting for buffer \", i );"; 3193 z[lc++]="#endif"; 3194 z[lc++]=" numQueuedOutputBuffers++;"; 3195 z[lc++]=" }"; 3196 z[lc++]=" }"; 3197 z[lc++]=" }"; 3198 z[lc++]="#if PA_TRACE_START_STOP"; 3199 z[lc++]="AddTraceMessage( \"WinMMPa_OutputThreadProc: numQueuedOutputBuffers \", numQueuedOutputBuffers );"; 3200 z[lc++]="#endif"; 3201 z[lc++]=" if( numQueuedOutputBuffers == 0 )"; 3202 z[lc++]=" {"; 3203 z[lc++]=" past->past_IsActive = 0; /* Will cause thread to return. */"; 3204 z[lc++]=" }"; 3205 z[lc++]=" }"; 3206 z[lc++]=" else"; 3207 z[lc++]=" {"; 3208 z[lc++]="/* Process full input buffer and fill up empty output buffers. */"; 3209 z[lc++]=" if( (result = Pa_TimeSlice( past )) != 0) "; 3210 z[lc++]=" {"; 3211 z[lc++]=" /* User callback has asked us to stop. */"; 3212 z[lc++]="#if PA_TRACE_START_STOP"; 3213 z[lc++]="AddTraceMessage( \"WinMMPa_OutputThreadProc: TimeSlice() returned \", result );"; 3214 z[lc++]="#endif"; 3215 z[lc++]=" past->past_StopSoon = 1; /* Request that audio play out then stop. */"; 3216 z[lc++]=" result = paNoError;"; 3217 z[lc++]=" }"; 3218 z[lc++]=" }"; 3219 z[lc++]=" "; 3220 z[lc++]=" PaHost_UpdateStreamTime( pahsc );"; 3221 z[lc++]=" return result;"; 3222 z[lc++]="}"; 3223 z[lc++]="#if PA_USE_TIMER_CALLBACK"; 3224 z[lc++]="/*******************************************************************/"; 3225 z[lc++]="static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)"; 3226 z[lc++]="{"; 3227 z[lc++]=" internalPortAudioStream *past;"; 3228 z[lc++]=" PaHostSoundControl *pahsc;"; 3229 z[lc++]=" PaError result;"; 3230 z[lc++]=" past = (internalPortAudioStream *) dwUser;"; 3231 z[lc++]=" if( past == NULL ) return;"; 3232 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3233 z[lc++]=" if( pahsc == NULL ) return;"; 3234 z[lc++]=" if( pahsc->pahsc_IfInsideCallback )"; 3235 z[lc++]=" {"; 3236 z[lc++]=" if( pahsc->pahsc_TimerID != 0 )"; 3237 z[lc++]=" {"; 3238 z[lc++]=" timeKillEvent(pahsc->pahsc_TimerID); /* Stop callback timer. */"; 3239 z[lc++]=" pahsc->pahsc_TimerID = 0;"; 3240 z[lc++]=" }"; 3241 z[lc++]=" return;"; 3242 z[lc++]=" }"; 3243 z[lc++]=" pahsc->pahsc_IfInsideCallback = 1;"; 3244 z[lc++]="/* Manage flags and audio processing. */"; 3245 z[lc++]=" result = PaHost_BackgroundManager( past );"; 3246 z[lc++]=" if( result != paNoError )"; 3247 z[lc++]=" {"; 3248 z[lc++]=" past->past_IsActive = 0;"; 3249 z[lc++]=" }"; 3250 z[lc++]=" pahsc->pahsc_IfInsideCallback = 0;"; 3251 z[lc++]="}"; 3252 z[lc++]="#else /* PA_USE_TIMER_CALLBACK */"; 3253 z[lc++]="/*******************************************************************/"; 3254 z[lc++]="static DWORD WINAPI WinMMPa_OutputThreadProc( void *pArg )"; 3255 z[lc++]="{"; 3256 z[lc++]=" internalPortAudioStream *past;"; 3257 z[lc++]=" PaHostSoundControl *pahsc;"; 3258 z[lc++]=" void *inputBuffer=NULL;"; 3259 z[lc++]=" HANDLE events[2];"; 3260 z[lc++]=" int numEvents = 0;"; 3261 z[lc++]=" DWORD result = 0;"; 3262 z[lc++]=" DWORD waitResult;"; 3263 z[lc++]=" DWORD numTimeouts = 0;"; 3264 z[lc++]=" DWORD timeOut;"; 3265 z[lc++]=" past = (internalPortAudioStream *) pArg;"; 3266 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3267 z[lc++]="#if PA_TRACE_START_STOP"; 3268 z[lc++]=" AddTraceMessage( \"WinMMPa_OutputThreadProc: timeoutPeriod\", timeoutPeriod );"; 3269 z[lc++]=" AddTraceMessage( \"WinMMPa_OutputThreadProc: past_NumUserBuffers\", past->past_NumUserBuffers );"; 3270 z[lc++]="#endif"; 3271 z[lc++]="/* Calculate timeOut as half the time it would take to play all buffers. */"; 3272 z[lc++]=" timeOut = (DWORD) (500.0 * PaHost_GetTotalBufferFrames( past ) / past->past_SampleRate);"; 3273 z[lc++]="/* Get event(s) ready for wait. */"; 3274 z[lc++]=" events[numEvents++] = pahsc->pahsc_BufferEvent;"; 3275 z[lc++]=" if( pahsc->pahsc_AbortEventInited ) events[numEvents++] = pahsc->pahsc_AbortEvent;"; 3276 z[lc++]="/* Stay in this thread as long as we are \"active\". */"; 3277 z[lc++]=" while( past->past_IsActive )"; 3278 z[lc++]=" {"; 3279 z[lc++]="/*******************************************************************/"; 3280 z[lc++]="/******** WAIT here for an event from WMME or PA *******************/"; 3281 z[lc++]="/*******************************************************************/"; 3282 z[lc++]=" waitResult = WaitForMultipleObjects( numEvents, events, FALSE, timeOut );"; 3283 z[lc++]=" /* Error? */"; 3284 z[lc++]=" if( waitResult == WAIT_FAILED )"; 3285 z[lc++]=" {"; 3286 z[lc++]=" sPaHostError = GetLastError();"; 3287 z[lc++]=" result = paHostError;"; 3288 z[lc++]=" past->past_IsActive = 0;"; 3289 z[lc++]=" }"; 3290 z[lc++]=" /* Timeout? Don't stop. Just keep polling for DONE.*/"; 3291 z[lc++]=" else if( waitResult == WAIT_TIMEOUT )"; 3292 z[lc++]=" {"; 3293 z[lc++]="#if PA_TRACE_START_STOP"; 3294 z[lc++]=" AddTraceMessage( \"WinMMPa_OutputThreadProc: timed out \", numQueuedOutputBuffers );"; 3295 z[lc++]="#endif"; 3296 z[lc++]=" numTimeouts += 1;"; 3297 z[lc++]=" }"; 3298 z[lc++]=" /* Manage flags and audio processing. */"; 3299 z[lc++]=" result = PaHost_BackgroundManager( past );"; 3300 z[lc++]=" if( result != paNoError )"; 3301 z[lc++]=" {"; 3302 z[lc++]=" past->past_IsActive = 0;"; 3303 z[lc++]=" }"; 3304 z[lc++]=" }"; 3305 z[lc++]=" return result;"; 3306 z[lc++]="}"; 3307 z[lc++]="#endif"; 3308 z[lc++]="/*******************************************************************/"; 3309 z[lc++]="PaError PaHost_OpenInputStream( internalPortAudioStream *past )"; 3310 z[lc++]="{"; 3311 z[lc++]=" MMRESULT mr;"; 3312 z[lc++]=" PaError result = paNoError;"; 3313 z[lc++]=" PaHostSoundControl *pahsc;"; 3314 z[lc++]=" int i;"; 3315 z[lc++]=" int inputMmId;"; 3316 z[lc++]=" int bytesPerInputFrame;"; 3317 z[lc++]=" WAVEFORMATEX wfx;"; 3318 z[lc++]=" const PaDeviceInfo *pad;"; 3319 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3320 z[lc++]=" DBUG((\"PaHost_OpenStream: deviceID = 0x%x\\n\", past->past_InputDeviceID));"; 3321 z[lc++]=" pad = Pa_GetDeviceInfo( past->past_InputDeviceID );"; 3322 z[lc++]=" if( pad == NULL ) return paInternalError;"; 3323 z[lc++]=" switch( pad->nativeSampleFormats )"; 3324 z[lc++]=" {"; 3325 z[lc++]=" case paInt32:"; 3326 z[lc++]=" case paFloat32:"; 3327 z[lc++]=" bytesPerInputFrame = sizeof(float) * past->past_NumInputChannels;"; 3328 z[lc++]=" break;"; 3329 z[lc++]=" default:"; 3330 z[lc++]=" bytesPerInputFrame = sizeof(short) * past->past_NumInputChannels;"; 3331 z[lc++]=" break;"; 3332 z[lc++]=" }"; 3333 z[lc++]=" wfx.wFormatTag = WAVE_FORMAT_PCM;"; 3334 z[lc++]=" wfx.nChannels = (WORD) past->past_NumInputChannels;"; 3335 z[lc++]=" wfx.nSamplesPerSec = (DWORD) past->past_SampleRate;"; 3336 z[lc++]=" wfx.nAvgBytesPerSec = (DWORD)(bytesPerInputFrame * past->past_SampleRate);"; 3337 z[lc++]=" wfx.nBlockAlign = (WORD)bytesPerInputFrame;"; 3338 z[lc++]=" wfx.wBitsPerSample = (WORD)((bytesPerInputFrame/past->past_NumInputChannels) * 8);"; 3339 z[lc++]=" wfx.cbSize = 0;"; 3340 z[lc++]=" inputMmId = PaDeviceIdToWinId( past->past_InputDeviceID );"; 3341 z[lc++]="#if PA_USE_TIMER_CALLBACK"; 3342 z[lc++]=" mr = waveInOpen( &pahsc->pahsc_HWaveIn, inputMmId, &wfx,"; 3343 z[lc++]=" 0, 0, CALLBACK_NULL );"; 3344 z[lc++]="#else"; 3345 z[lc++]=" mr = waveInOpen( &pahsc->pahsc_HWaveIn, inputMmId, &wfx,"; 3346 z[lc++]=" (DWORD)pahsc->pahsc_BufferEvent, (DWORD) past, CALLBACK_EVENT );"; 3347 z[lc++]="#endif"; 3348 z[lc++]=" if( mr != MMSYSERR_NOERROR )"; 3349 z[lc++]=" {"; 3350 z[lc++]=" ERR_RPT((\"PortAudio: PaHost_OpenInputStream() failed!\\n\"));"; 3351 z[lc++]=" result = paHostError;"; 3352 z[lc++]=" sPaHostError = mr;"; 3353 z[lc++]=" goto error;"; 3354 z[lc++]=" }"; 3355 z[lc++]="/* Allocate an array to hold the buffer pointers. */"; 3356 z[lc++]=" pahsc->pahsc_InputBuffers = (WAVEHDR *) GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(WAVEHDR)*pahsc->pahsc_NumHostBuffers ); /* MEM */"; 3357 z[lc++]=" if( pahsc->pahsc_InputBuffers == NULL )"; 3358 z[lc++]=" {"; 3359 z[lc++]=" result = paInsufficientMemory;"; 3360 z[lc++]=" goto error;"; 3361 z[lc++]=" }"; 3362 z[lc++]="/* Allocate each buffer. */"; 3363 z[lc++]=" for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )"; 3364 z[lc++]=" {"; 3365 z[lc++]=" pahsc->pahsc_InputBuffers[i].lpData = (char *)GlobalAlloc( GMEM_FIXED, pahsc->pahsc_BytesPerHostInputBuffer ); /* MEM */"; 3366 z[lc++]=" if( pahsc->pahsc_InputBuffers[i].lpData == NULL )"; 3367 z[lc++]=" {"; 3368 z[lc++]=" result = paInsufficientMemory;"; 3369 z[lc++]=" goto error;"; 3370 z[lc++]=" }"; 3371 z[lc++]=" pahsc->pahsc_InputBuffers[i].dwBufferLength = pahsc->pahsc_BytesPerHostInputBuffer;"; 3372 z[lc++]=" pahsc->pahsc_InputBuffers[i].dwUser = i;"; 3373 z[lc++]=" if( ( mr = waveInPrepareHeader( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )"; 3374 z[lc++]=" {"; 3375 z[lc++]=" result = paHostError;"; 3376 z[lc++]=" sPaHostError = mr;"; 3377 z[lc++]=" goto error;"; 3378 z[lc++]=" }"; 3379 z[lc++]=" }"; 3380 z[lc++]=" return result;"; 3381 z[lc++]="error:"; 3382 z[lc++]=" return result;"; 3383 z[lc++]="}"; 3384 z[lc++]="/*******************************************************************/"; 3385 z[lc++]="PaError PaHost_OpenOutputStream( internalPortAudioStream *past )"; 3386 z[lc++]="{"; 3387 z[lc++]=" MMRESULT mr;"; 3388 z[lc++]=" PaError result = paNoError;"; 3389 z[lc++]=" PaHostSoundControl *pahsc;"; 3390 z[lc++]=" int i;"; 3391 z[lc++]=" int outputMmID;"; 3392 z[lc++]=" int bytesPerOutputFrame;"; 3393 z[lc++]=" WAVEFORMATEX wfx;"; 3394 z[lc++]=" const PaDeviceInfo *pad;"; 3395 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3396 z[lc++]=" DBUG((\"PaHost_OpenStream: deviceID = 0x%x\\n\", past->past_OutputDeviceID));"; 3397 z[lc++]=" pad = Pa_GetDeviceInfo( past->past_OutputDeviceID );"; 3398 z[lc++]=" if( pad == NULL ) return paInternalError;"; 3399 z[lc++]=" switch( pad->nativeSampleFormats )"; 3400 z[lc++]=" {"; 3401 z[lc++]=" case paInt32:"; 3402 z[lc++]=" case paFloat32:"; 3403 z[lc++]=" bytesPerOutputFrame = sizeof(float) * past->past_NumOutputChannels;"; 3404 z[lc++]=" break;"; 3405 z[lc++]=" default:"; 3406 z[lc++]=" bytesPerOutputFrame = sizeof(short) * past->past_NumOutputChannels;"; 3407 z[lc++]=" break;"; 3408 z[lc++]=" }"; 3409 z[lc++]=" wfx.wFormatTag = WAVE_FORMAT_PCM;"; 3410 z[lc++]=" wfx.nChannels = (WORD) past->past_NumOutputChannels;"; 3411 z[lc++]=" wfx.nSamplesPerSec = (DWORD) past->past_SampleRate;"; 3412 z[lc++]=" wfx.nAvgBytesPerSec = (DWORD)(bytesPerOutputFrame * past->past_SampleRate);"; 3413 z[lc++]=" wfx.nBlockAlign = (WORD)bytesPerOutputFrame;"; 3414 z[lc++]=" wfx.wBitsPerSample = (WORD)((bytesPerOutputFrame/past->past_NumOutputChannels) * 8);"; 3415 z[lc++]=" wfx.cbSize = 0;"; 3416 z[lc++]=" outputMmID = PaDeviceIdToWinId( past->past_OutputDeviceID );"; 3417 z[lc++]="#if PA_USE_TIMER_CALLBACK"; 3418 z[lc++]=" mr = waveOutOpen( &pahsc->pahsc_HWaveOut, outputMmID, &wfx,"; 3419 z[lc++]=" 0, 0, CALLBACK_NULL );"; 3420 z[lc++]="#else"; 3421 z[lc++]=" "; 3422 z[lc++]=" pahsc->pahsc_AbortEvent = CreateEvent( NULL, TRUE, FALSE, NULL );"; 3423 z[lc++]=" if( pahsc->pahsc_AbortEvent == NULL )"; 3424 z[lc++]=" {"; 3425 z[lc++]=" result = paHostError;"; 3426 z[lc++]=" sPaHostError = GetLastError();"; 3427 z[lc++]=" goto error;"; 3428 z[lc++]=" }"; 3429 z[lc++]=" pahsc->pahsc_AbortEventInited = 1;"; 3430 z[lc++]=" mr = waveOutOpen( &pahsc->pahsc_HWaveOut, outputMmID, &wfx,"; 3431 z[lc++]=" (DWORD)pahsc->pahsc_BufferEvent, (DWORD) past, CALLBACK_EVENT );"; 3432 z[lc++]="#endif"; 3433 z[lc++]=" if( mr != MMSYSERR_NOERROR )"; 3434 z[lc++]=" {"; 3435 z[lc++]=" ERR_RPT((\"PortAudio: PaHost_OpenOutputStream() failed!\\n\"));"; 3436 z[lc++]=" result = paHostError;"; 3437 z[lc++]=" sPaHostError = mr;"; 3438 z[lc++]=" goto error;"; 3439 z[lc++]=" }"; 3440 z[lc++]="/* Allocate an array to hold the buffer pointers. */"; 3441 z[lc++]=" pahsc->pahsc_OutputBuffers = (WAVEHDR *) GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(WAVEHDR)*pahsc->pahsc_NumHostBuffers ); /* MEM */"; 3442 z[lc++]=" if( pahsc->pahsc_OutputBuffers == NULL )"; 3443 z[lc++]=" {"; 3444 z[lc++]=" result = paInsufficientMemory;"; 3445 z[lc++]=" goto error;"; 3446 z[lc++]=" }"; 3447 z[lc++]="/* Allocate each buffer. */"; 3448 z[lc++]=" for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )"; 3449 z[lc++]=" {"; 3450 z[lc++]=" pahsc->pahsc_OutputBuffers[i].lpData = (char *) GlobalAlloc( GMEM_FIXED, pahsc->pahsc_BytesPerHostOutputBuffer ); /* MEM */"; 3451 z[lc++]=" if( pahsc->pahsc_OutputBuffers[i].lpData == NULL )"; 3452 z[lc++]=" {"; 3453 z[lc++]=" result = paInsufficientMemory;"; 3454 z[lc++]=" goto error;"; 3455 z[lc++]=" }"; 3456 z[lc++]=" pahsc->pahsc_OutputBuffers[i].dwBufferLength = pahsc->pahsc_BytesPerHostOutputBuffer;"; 3457 z[lc++]=" pahsc->pahsc_OutputBuffers[i].dwUser = i;"; 3458 z[lc++]=" if( (mr = waveOutPrepareHeader( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) )) != MMSYSERR_NOERROR )"; 3459 z[lc++]=" {"; 3460 z[lc++]=" result = paHostError;"; 3461 z[lc++]=" sPaHostError = mr;"; 3462 z[lc++]=" goto error;"; 3463 z[lc++]=" }"; 3464 z[lc++]=" }"; 3465 z[lc++]=" return result;"; 3466 z[lc++]="error:"; 3467 z[lc++]=" return result;"; 3468 z[lc++]="}"; 3469 z[lc++]="/*******************************************************************/"; 3470 z[lc++]="PaError PaHost_GetTotalBufferFrames( internalPortAudioStream *past )"; 3471 z[lc++]="{"; 3472 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3473 z[lc++]=" return pahsc->pahsc_NumHostBuffers * pahsc->pahsc_FramesPerHostBuffer;"; 3474 z[lc++]="}"; 3475 z[lc++]="/*******************************************************************"; 3476 z[lc++]="* Determine number of WAVE Buffers"; 3477 z[lc++]="* and how many User Buffers we can put into each WAVE buffer."; 3478 z[lc++]="*/"; 3479 z[lc++]="static void PaHost_CalcNumHostBuffers( internalPortAudioStream *past )"; 3480 z[lc++]="{"; 3481 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3482 z[lc++]=" unsigned int minNumBuffers;"; 3483 z[lc++]=" int minFramesPerHostBuffer;"; 3484 z[lc++]=" int maxFramesPerHostBuffer;"; 3485 z[lc++]=" int minTotalFrames;"; 3486 z[lc++]=" int userBuffersPerHostBuffer;"; 3487 z[lc++]=" int framesPerHostBuffer;"; 3488 z[lc++]=" int numHostBuffers;"; 3489 z[lc++]="/* Calculate minimum and maximum sizes based on timing and sample rate. */"; 3490 z[lc++]=" minFramesPerHostBuffer = (int) (PA_MIN_MSEC_PER_HOST_BUFFER * past->past_SampleRate / 1000.0);"; 3491 z[lc++]=" minFramesPerHostBuffer = (minFramesPerHostBuffer + 7) & ~7;"; 3492 z[lc++]=" DBUG((\"PaHost_CalcNumHostBuffers: minFramesPerHostBuffer = %d\\n\", minFramesPerHostBuffer ));"; 3493 z[lc++]=" maxFramesPerHostBuffer = (int) (PA_MAX_MSEC_PER_HOST_BUFFER * past->past_SampleRate / 1000.0);"; 3494 z[lc++]=" maxFramesPerHostBuffer = (maxFramesPerHostBuffer + 7) & ~7;"; 3495 z[lc++]=" DBUG((\"PaHost_CalcNumHostBuffers: maxFramesPerHostBuffer = %d\\n\", maxFramesPerHostBuffer ));"; 3496 z[lc++]="/* Determine number of user buffers based on minimum latency. */"; 3497 z[lc++]=" minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );"; 3498 z[lc++]=" past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;"; 3499 z[lc++]=" DBUG((\"PaHost_CalcNumHostBuffers: min past_NumUserBuffers = %d\\n\", past->past_NumUserBuffers ));"; 3500 z[lc++]=" minTotalFrames = past->past_NumUserBuffers * past->past_FramesPerUserBuffer;"; 3501 z[lc++]="/* We cannot make the WAVE buffers too small because they may not get serviced quickly enough. */"; 3502 z[lc++]=" if( (int) past->past_FramesPerUserBuffer < minFramesPerHostBuffer )"; 3503 z[lc++]=" {"; 3504 z[lc++]=" userBuffersPerHostBuffer ="; 3505 z[lc++]=" (minFramesPerHostBuffer + past->past_FramesPerUserBuffer - 1) /"; 3506 z[lc++]=" past->past_FramesPerUserBuffer;"; 3507 z[lc++]=" }"; 3508 z[lc++]=" else"; 3509 z[lc++]=" {"; 3510 z[lc++]=" userBuffersPerHostBuffer = 1;"; 3511 z[lc++]=" }"; 3512 z[lc++]=" framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;"; 3513 z[lc++]="/* Calculate number of WAVE buffers needed. Round up to cover minTotalFrames. */"; 3514 z[lc++]=" numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;"; 3515 z[lc++]="/* Make sure we have anough WAVE buffers. */"; 3516 z[lc++]=" if( numHostBuffers < PA_MIN_NUM_HOST_BUFFERS)"; 3517 z[lc++]=" {"; 3518 z[lc++]=" numHostBuffers = PA_MIN_NUM_HOST_BUFFERS;"; 3519 z[lc++]=" }"; 3520 z[lc++]=" else if( (numHostBuffers > PA_MAX_NUM_HOST_BUFFERS) && "; 3521 z[lc++]=" ((int) past->past_FramesPerUserBuffer < (maxFramesPerHostBuffer/2) ) )"; 3522 z[lc++]=" {"; 3523 z[lc++]="/* If we have too many WAVE buffers, try to put more user buffers in a wave buffer. */"; 3524 z[lc++]=" while(numHostBuffers > PA_MAX_NUM_HOST_BUFFERS)"; 3525 z[lc++]=" {"; 3526 z[lc++]=" userBuffersPerHostBuffer += 1;"; 3527 z[lc++]=" framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;"; 3528 z[lc++]=" numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;"; 3529 z[lc++]=" /* If we have gone too far, back up one. */"; 3530 z[lc++]=" if( (framesPerHostBuffer > maxFramesPerHostBuffer) ||"; 3531 z[lc++]=" (numHostBuffers < PA_MAX_NUM_HOST_BUFFERS) )"; 3532 z[lc++]=" {"; 3533 z[lc++]=" userBuffersPerHostBuffer -= 1;"; 3534 z[lc++]=" framesPerHostBuffer = past->past_FramesPerUserBuffer * userBuffersPerHostBuffer;"; 3535 z[lc++]=" numHostBuffers = (minTotalFrames + framesPerHostBuffer - 1) / framesPerHostBuffer;"; 3536 z[lc++]=" break;"; 3537 z[lc++]=" }"; 3538 z[lc++]=" }"; 3539 z[lc++]=" }"; 3540 z[lc++]=" "; 3541 z[lc++]=" pahsc->pahsc_UserBuffersPerHostBuffer = userBuffersPerHostBuffer;"; 3542 z[lc++]=" pahsc->pahsc_FramesPerHostBuffer = framesPerHostBuffer;"; 3543 z[lc++]=" pahsc->pahsc_NumHostBuffers = numHostBuffers;"; 3544 z[lc++]=" DBUG((\"PaHost_CalcNumHostBuffers: pahsc_UserBuffersPerHostBuffer = %d\\n\", pahsc->pahsc_UserBuffersPerHostBuffer ));"; 3545 z[lc++]=" DBUG((\"PaHost_CalcNumHostBuffers: pahsc_NumHostBuffers = %d\\n\", pahsc->pahsc_NumHostBuffers ));"; 3546 z[lc++]=" DBUG((\"PaHost_CalcNumHostBuffers: pahsc_FramesPerHostBuffer = %d\\n\", pahsc->pahsc_FramesPerHostBuffer ));"; 3547 z[lc++]=" DBUG((\"PaHost_CalcNumHostBuffers: past_NumUserBuffers = %d\\n\", past->past_NumUserBuffers ));"; 3548 z[lc++]="}"; 3549 z[lc++]="/*******************************************************************/"; 3550 z[lc++]="PaError PaHost_OpenStream( internalPortAudioStream *past )"; 3551 z[lc++]="{"; 3552 z[lc++]=" PaError result = paNoError;"; 3553 z[lc++]=" PaHostSoundControl *pahsc;"; 3554 z[lc++]="/* Allocate and initialize host data. */"; 3555 z[lc++]=" pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); /* MEM */"; 3556 z[lc++]=" if( pahsc == NULL )"; 3557 z[lc++]=" {"; 3558 z[lc++]=" result = paInsufficientMemory;"; 3559 z[lc++]=" goto error;"; 3560 z[lc++]=" }"; 3561 z[lc++]=" memset( pahsc, 0, sizeof(PaHostSoundControl) );"; 3562 z[lc++]=" past->past_DeviceData = (void *) pahsc;"; 3563 z[lc++]="/* Figure out how user buffers fit into WAVE buffers. */"; 3564 z[lc++]=" PaHost_CalcNumHostBuffers( past );"; 3565 z[lc++]=" {"; 3566 z[lc++]=" int msecLatency = (int) ((PaHost_GetTotalBufferFrames(past) * 1000) / past->past_SampleRate);"; 3567 z[lc++]=" DBUG((\"PortAudio on WMME - Latency = %d frames, %d msec\\n\", PaHost_GetTotalBufferFrames(past), msecLatency ));"; 3568 z[lc++]=" }"; 3569 z[lc++]=" InitializeCriticalSection( &pahsc->pahsc_StreamLock );"; 3570 z[lc++]=" pahsc->pahsc_StreamLockInited = 1;"; 3571 z[lc++]=" "; 3572 z[lc++]="#if (PA_USE_TIMER_CALLBACK == 0)"; 3573 z[lc++]=" pahsc->pahsc_BufferEventInited = 0;"; 3574 z[lc++]=" pahsc->pahsc_BufferEvent = CreateEvent( NULL, FALSE, FALSE, NULL );"; 3575 z[lc++]=" if( pahsc->pahsc_BufferEvent == NULL ){"; 3576 z[lc++]=" result = paHostError;"; 3577 z[lc++]=" sPaHostError = GetLastError();"; 3578 z[lc++]=" goto error;"; 3579 z[lc++]=" }"; 3580 z[lc++]=" pahsc->pahsc_BufferEventInited = 1;"; 3581 z[lc++]="#endif /* (PA_USE_TIMER_CALLBACK == 0) */"; 3582 z[lc++]="/* ------------------ OUTPUT */"; 3583 z[lc++]=" pahsc->pahsc_BytesPerUserOutputBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels * sizeof(short);"; 3584 z[lc++]=" pahsc->pahsc_BytesPerHostOutputBuffer = pahsc->pahsc_UserBuffersPerHostBuffer * pahsc->pahsc_BytesPerUserOutputBuffer;"; 3585 z[lc++]=" if( (past->past_OutputDeviceID != paNoDevice) && (past->past_NumOutputChannels > 0) )"; 3586 z[lc++]=" {"; 3587 z[lc++]=" result = PaHost_OpenOutputStream( past );"; 3588 z[lc++]=" if( result < 0 ) goto error;"; 3589 z[lc++]=" }"; 3590 z[lc++]="/* ------------------ INPUT */"; 3591 z[lc++]=" pahsc->pahsc_BytesPerUserInputBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels * sizeof(short);"; 3592 z[lc++]=" pahsc->pahsc_BytesPerHostInputBuffer = pahsc->pahsc_UserBuffersPerHostBuffer * pahsc->pahsc_BytesPerUserInputBuffer;"; 3593 z[lc++]=" if( (past->past_InputDeviceID != paNoDevice) && (past->past_NumInputChannels > 0) )"; 3594 z[lc++]=" {"; 3595 z[lc++]=" result = PaHost_OpenInputStream( past );"; 3596 z[lc++]=" if( result < 0 ) goto error;"; 3597 z[lc++]=" }"; 3598 z[lc++]="/* Calculate scalar used in CPULoad calculation. */ "; 3599 z[lc++]=" {"; 3600 z[lc++]=" LARGE_INTEGER frequency;"; 3601 z[lc++]=" if( QueryPerformanceFrequency( &frequency ) == 0 )"; 3602 z[lc++]=" {"; 3603 z[lc++]=" pahsc->pahsc_InverseTicksPerHostBuffer = 0.0;"; 3604 z[lc++]=" }"; 3605 z[lc++]=" else"; 3606 z[lc++]=" {"; 3607 z[lc++]=" pahsc->pahsc_InverseTicksPerHostBuffer = past->past_SampleRate /"; 3608 z[lc++]=" ( (double)frequency.QuadPart * past->past_FramesPerUserBuffer * pahsc->pahsc_UserBuffersPerHostBuffer );"; 3609 z[lc++]=" DBUG((\"pahsc_InverseTicksPerHostBuffer = %g\\n\", pahsc->pahsc_InverseTicksPerHostBuffer ));"; 3610 z[lc++]=" }"; 3611 z[lc++]=" }"; 3612 z[lc++]=" return result;"; 3613 z[lc++]="error:"; 3614 z[lc++]=" PaHost_CloseStream( past );"; 3615 z[lc++]=" return result;"; 3616 z[lc++]="}"; 3617 z[lc++]="/*************************************************************************/"; 3618 z[lc++]="PaError PaHost_StartOutput( internalPortAudioStream *past )"; 3619 z[lc++]="{"; 3620 z[lc++]=" MMRESULT mr;"; 3621 z[lc++]=" PaHostSoundControl *pahsc;"; 3622 z[lc++]=" PaError result = paNoError;"; 3623 z[lc++]=" int i;"; 3624 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3625 z[lc++]=" if( past->past_OutputDeviceID != paNoDevice )"; 3626 z[lc++]=" {"; 3627 z[lc++]=" if( (mr = waveOutPause( pahsc->pahsc_HWaveOut )) != MMSYSERR_NOERROR )"; 3628 z[lc++]=" {"; 3629 z[lc++]=" result = paHostError;"; 3630 z[lc++]=" sPaHostError = mr;"; 3631 z[lc++]=" goto error;"; 3632 z[lc++]=" }"; 3633 z[lc++]=" for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )"; 3634 z[lc++]=" {"; 3635 z[lc++]=" ZeroMemory( pahsc->pahsc_OutputBuffers[i].lpData, pahsc->pahsc_OutputBuffers[i].dwBufferLength );"; 3636 z[lc++]=" mr = waveOutWrite( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) );"; 3637 z[lc++]=" if( mr != MMSYSERR_NOERROR )"; 3638 z[lc++]=" {"; 3639 z[lc++]=" result = paHostError;"; 3640 z[lc++]=" sPaHostError = mr;"; 3641 z[lc++]=" goto error;"; 3642 z[lc++]=" }"; 3643 z[lc++]=" past->past_FrameCount += pahsc->pahsc_FramesPerHostBuffer;"; 3644 z[lc++]=" }"; 3645 z[lc++]=" pahsc->pahsc_CurrentOutputBuffer = 0;"; 3646 z[lc++]=" if( (mr = waveOutRestart( pahsc->pahsc_HWaveOut )) != MMSYSERR_NOERROR )"; 3647 z[lc++]=" {"; 3648 z[lc++]=" result = paHostError;"; 3649 z[lc++]=" sPaHostError = mr;"; 3650 z[lc++]=" goto error;"; 3651 z[lc++]=" }"; 3652 z[lc++]=" }"; 3653 z[lc++]=" DBUG((\"PaHost_StartOutput: DSW_StartOutput returned = 0x%X.\\n\", hr));"; 3654 z[lc++]="error:"; 3655 z[lc++]=" return result;"; 3656 z[lc++]="}"; 3657 z[lc++]="/*************************************************************************/"; 3658 z[lc++]="PaError PaHost_StartInput( internalPortAudioStream *past )"; 3659 z[lc++]="{"; 3660 z[lc++]=" PaError result = paNoError;"; 3661 z[lc++]=" MMRESULT mr;"; 3662 z[lc++]=" int i;"; 3663 z[lc++]=" PaHostSoundControl *pahsc;"; 3664 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3665 z[lc++]=" if( past->past_InputDeviceID != paNoDevice )"; 3666 z[lc++]=" {"; 3667 z[lc++]=" for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )"; 3668 z[lc++]=" {"; 3669 z[lc++]=" mr = waveInAddBuffer( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) );"; 3670 z[lc++]=" if( mr != MMSYSERR_NOERROR )"; 3671 z[lc++]=" {"; 3672 z[lc++]=" result = paHostError;"; 3673 z[lc++]=" sPaHostError = mr;"; 3674 z[lc++]=" goto error;"; 3675 z[lc++]=" }"; 3676 z[lc++]=" }"; 3677 z[lc++]=" pahsc->pahsc_CurrentInputBuffer = 0;"; 3678 z[lc++]=" mr = waveInStart( pahsc->pahsc_HWaveIn );"; 3679 z[lc++]=" DBUG((\"Pa_StartStream: waveInStart returned = 0x%X.\\n\", hr));"; 3680 z[lc++]=" if( mr != MMSYSERR_NOERROR )"; 3681 z[lc++]=" {"; 3682 z[lc++]=" result = paHostError;"; 3683 z[lc++]=" sPaHostError = mr;"; 3684 z[lc++]=" goto error;"; 3685 z[lc++]=" }"; 3686 z[lc++]=" }"; 3687 z[lc++]="error:"; 3688 z[lc++]=" return result;"; 3689 z[lc++]="}"; 3690 z[lc++]="/*************************************************************************/"; 3691 z[lc++]="PaError PaHost_StartEngine( internalPortAudioStream *past )"; 3692 z[lc++]="{"; 3693 z[lc++]=" PaError result = paNoError;"; 3694 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3695 z[lc++]="#if PA_USE_TIMER_CALLBACK"; 3696 z[lc++]=" int resolution;"; 3697 z[lc++]=" int bufsPerTimerCallback;"; 3698 z[lc++]=" int msecPerBuffer;"; 3699 z[lc++]="#endif /* PA_USE_TIMER_CALLBACK */"; 3700 z[lc++]=" "; 3701 z[lc++]=" past->past_StopSoon = 0;"; 3702 z[lc++]=" past->past_StopNow = 0;"; 3703 z[lc++]=" past->past_IsActive = 1;"; 3704 z[lc++]=" pahsc->pahsc_FramesPlayed = 0.0;"; 3705 z[lc++]=" pahsc->pahsc_LastPosition = 0;"; 3706 z[lc++]="#if PA_TRACE_START_STOP"; 3707 z[lc++]=" AddTraceMessage( \"PaHost_StartEngine: TimeSlice() returned \", result );"; 3708 z[lc++]="#endif"; 3709 z[lc++]="#if PA_USE_TIMER_CALLBACK"; 3710 z[lc++]="/* Create timer that will wake us up so we can fill the DSound buffer. */"; 3711 z[lc++]=" bufsPerTimerCallback = pahsc->pahsc_NumHostBuffers/4;"; 3712 z[lc++]=" if( bufsPerTimerCallback < 1 ) bufsPerTimerCallback = 1;"; 3713 z[lc++]=" if( bufsPerTimerCallback < 1 ) bufsPerTimerCallback = 1;"; 3714 z[lc++]=" msecPerBuffer = (1000 * bufsPerTimerCallback *"; 3715 z[lc++]=" pahsc->pahsc_UserBuffersPerHostBuffer *"; 3716 z[lc++]=" past->past_FramesPerUserBuffer ) / (int) past->past_SampleRate;"; 3717 z[lc++]=" if( msecPerBuffer < 10 ) msecPerBuffer = 10;"; 3718 z[lc++]=" else if( msecPerBuffer > 100 ) msecPerBuffer = 100;"; 3719 z[lc++]=" resolution = msecPerBuffer/4;"; 3720 z[lc++]=" pahsc->pahsc_TimerID = timeSetEvent( msecPerBuffer, resolution,"; 3721 z[lc++]=" (LPTIMECALLBACK) Pa_TimerCallback,"; 3722 z[lc++]=" (DWORD) past, TIME_PERIODIC );"; 3723 z[lc++]=" if( pahsc->pahsc_TimerID == 0 )"; 3724 z[lc++]=" {"; 3725 z[lc++]=" result = paHostError;"; 3726 z[lc++]=" sPaHostError = GetLastError();;"; 3727 z[lc++]=" goto error;"; 3728 z[lc++]=" }"; 3729 z[lc++]="#else /* PA_USE_TIMER_CALLBACK */"; 3730 z[lc++]=" ResetEvent( pahsc->pahsc_AbortEvent );"; 3731 z[lc++]="/* Create thread that waits for audio buffers to be ready for processing. */"; 3732 z[lc++]=" pahsc->pahsc_EngineThread = CreateThread( 0, 0, WinMMPa_OutputThreadProc, past, 0, &pahsc->pahsc_EngineThreadID );"; 3733 z[lc++]=" if( pahsc->pahsc_EngineThread == NULL )"; 3734 z[lc++]=" {"; 3735 z[lc++]=" result = paHostError;"; 3736 z[lc++]=" sPaHostError = GetLastError();;"; 3737 z[lc++]=" goto error;"; 3738 z[lc++]=" }"; 3739 z[lc++]="#if PA_TRACE_START_STOP"; 3740 z[lc++]=" AddTraceMessage( \"PaHost_StartEngine: thread \", (int) pahsc->pahsc_EngineThread );"; 3741 z[lc++]="#endif"; 3742 z[lc++]="/* I used to pass the thread which was failing. I now pass GetCurrentProcess()."; 3743 z[lc++]="** This fix could improve latency for some applications. It could also result in CPU"; 3744 z[lc++]="** starvation if the callback did too much processing."; 3745 z[lc++]="** I also added result checks, so we might see more failures at initialization."; 3746 z[lc++]="** Thanks to Alberto di Bene for spotting this."; 3747 z[lc++]="*/"; 3748 z[lc++]=" if( !SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) ) /* PLB20010816 */"; 3749 z[lc++]=" {"; 3750 z[lc++]=" result = paHostError;"; 3751 z[lc++]=" sPaHostError = GetLastError();;"; 3752 z[lc++]=" goto error;"; 3753 z[lc++]=" }"; 3754 z[lc++]=" if( !SetThreadPriority( pahsc->pahsc_EngineThread, THREAD_PRIORITY_HIGHEST ) )"; 3755 z[lc++]=" {"; 3756 z[lc++]=" result = paHostError;"; 3757 z[lc++]=" sPaHostError = GetLastError();;"; 3758 z[lc++]=" goto error;"; 3759 z[lc++]=" }"; 3760 z[lc++]="#endif"; 3761 z[lc++]="error:"; 3762 z[lc++]=" return result;"; 3763 z[lc++]="}"; 3764 z[lc++]="/*************************************************************************/"; 3765 z[lc++]="PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )"; 3766 z[lc++]="{"; 3767 z[lc++]=" int timeOut;"; 3768 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3769 z[lc++]=" if( pahsc == NULL ) return paNoError;"; 3770 z[lc++]="/* Tell background thread to stop generating more data and to let current data play out. */"; 3771 z[lc++]=" past->past_StopSoon = 1;"; 3772 z[lc++]="/* If aborting, tell background thread to stop NOW! */"; 3773 z[lc++]=" if( abort ) past->past_StopNow = 1;"; 3774 z[lc++]="/* Calculate timeOut longer than longest time it could take to play all buffers. */"; 3775 z[lc++]=" timeOut = (DWORD) (1500.0 * PaHost_GetTotalBufferFrames( past ) / past->past_SampleRate);"; 3776 z[lc++]=" if( timeOut < MIN_TIMEOUT_MSEC ) timeOut = MIN_TIMEOUT_MSEC;"; 3777 z[lc++]="#if PA_USE_TIMER_CALLBACK"; 3778 z[lc++]=" if( (past->past_OutputDeviceID != paNoDevice) &&"; 3779 z[lc++]=" past->past_IsActive &&"; 3780 z[lc++]=" (pahsc->pahsc_TimerID != 0) )"; 3781 z[lc++]=" {"; 3782 z[lc++]=" /* Wait for IsActive to drop. */"; 3783 z[lc++]=" while( (past->past_IsActive) && (timeOut > 0) )"; 3784 z[lc++]=" {"; 3785 z[lc++]=" Sleep(10);"; 3786 z[lc++]=" timeOut -= 10;"; 3787 z[lc++]=" }"; 3788 z[lc++]=" timeKillEvent(pahsc->pahsc_TimerID); /* Stop callback timer. */"; 3789 z[lc++]=" pahsc->pahsc_TimerID = 0;"; 3790 z[lc++]=" }"; 3791 z[lc++]="#else /* PA_USE_TIMER_CALLBACK */"; 3792 z[lc++]="#if PA_TRACE_START_STOP"; 3793 z[lc++]=" AddTraceMessage( \"PaHost_StopEngine: thread \", (int) pahsc->pahsc_EngineThread );"; 3794 z[lc++]="#endif"; 3795 z[lc++]=" if( (past->past_OutputDeviceID != paNoDevice) &&"; 3796 z[lc++]=" (past->past_IsActive) &&"; 3797 z[lc++]=" (pahsc->pahsc_EngineThread != NULL) )"; 3798 z[lc++]=" {"; 3799 z[lc++]=" DWORD got;"; 3800 z[lc++]="/* Tell background thread to stop generating more data and to let current data play out. */"; 3801 z[lc++]=" DBUG((\"PaHost_StopEngine: waiting for background thread.\\n\"));"; 3802 z[lc++]=" got = WaitForSingleObject( pahsc->pahsc_EngineThread, timeOut );"; 3803 z[lc++]=" if( got == WAIT_TIMEOUT )"; 3804 z[lc++]=" {"; 3805 z[lc++]=" ERR_RPT((\"PaHost_StopEngine: timed out while waiting for background thread.\\n\"));"; 3806 z[lc++]=" return paTimedOut;"; 3807 z[lc++]=" }"; 3808 z[lc++]=" CloseHandle( pahsc->pahsc_EngineThread );"; 3809 z[lc++]=" pahsc->pahsc_EngineThread = NULL;"; 3810 z[lc++]=" }"; 3811 z[lc++]="#endif /* PA_USE_TIMER_CALLBACK */"; 3812 z[lc++]=" past->past_IsActive = 0;"; 3813 z[lc++]=" return paNoError;"; 3814 z[lc++]="}"; 3815 z[lc++]="/*************************************************************************/"; 3816 z[lc++]="PaError PaHost_StopInput( internalPortAudioStream *past, int abort )"; 3817 z[lc++]="{"; 3818 z[lc++]=" MMRESULT mr;"; 3819 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3820 z[lc++]=" if( pahsc == NULL ) return paNoError;"; 3821 z[lc++]=" (void) abort;"; 3822 z[lc++]=" if( pahsc->pahsc_HWaveIn != NULL )"; 3823 z[lc++]=" {"; 3824 z[lc++]=" mr = waveInReset( pahsc->pahsc_HWaveIn );"; 3825 z[lc++]=" if( mr != MMSYSERR_NOERROR )"; 3826 z[lc++]=" {"; 3827 z[lc++]=" sPaHostError = mr;"; 3828 z[lc++]=" return paHostError;"; 3829 z[lc++]=" }"; 3830 z[lc++]=" }"; 3831 z[lc++]=" return paNoError;"; 3832 z[lc++]="}"; 3833 z[lc++]="/*************************************************************************/"; 3834 z[lc++]="PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )"; 3835 z[lc++]="{"; 3836 z[lc++]=" MMRESULT mr;"; 3837 z[lc++]=" PaHostSoundControl *pahsc;"; 3838 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3839 z[lc++]=" if( pahsc == NULL ) return paNoError;"; 3840 z[lc++]=" (void) abort;"; 3841 z[lc++]="#if PA_TRACE_START_STOP"; 3842 z[lc++]=" AddTraceMessage( \"PaHost_StopOutput: pahsc_HWaveOut \", (int) pahsc->pahsc_HWaveOut );"; 3843 z[lc++]="#endif"; 3844 z[lc++]=" if( pahsc->pahsc_HWaveOut != NULL )"; 3845 z[lc++]=" {"; 3846 z[lc++]=" mr = waveOutReset( pahsc->pahsc_HWaveOut );"; 3847 z[lc++]=" if( mr != MMSYSERR_NOERROR )"; 3848 z[lc++]=" {"; 3849 z[lc++]=" sPaHostError = mr;"; 3850 z[lc++]=" return paHostError;"; 3851 z[lc++]=" }"; 3852 z[lc++]=" }"; 3853 z[lc++]=" return paNoError;"; 3854 z[lc++]="}"; 3855 z[lc++]="/*******************************************************************/"; 3856 z[lc++]="PaError PaHost_CloseStream( internalPortAudioStream *past )"; 3857 z[lc++]="{"; 3858 z[lc++]=" int i;"; 3859 z[lc++]=" PaHostSoundControl *pahsc;"; 3860 z[lc++]=" if( past == NULL ) return paBadStreamPtr;"; 3861 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 3862 z[lc++]=" if( pahsc == NULL ) return paNoError;"; 3863 z[lc++]="#if PA_TRACE_START_STOP"; 3864 z[lc++]=" AddTraceMessage( \"PaHost_CloseStream: pahsc_HWaveOut \", (int) pahsc->pahsc_HWaveOut );"; 3865 z[lc++]="#endif"; 3866 z[lc++]="/* Free data and device for output. */"; 3867 z[lc++]=" if( pahsc->pahsc_HWaveOut )"; 3868 z[lc++]=" {"; 3869 z[lc++]=" if( pahsc->pahsc_OutputBuffers )"; 3870 z[lc++]=" {"; 3871 z[lc++]=" for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )"; 3872 z[lc++]=" {"; 3873 z[lc++]=" waveOutUnprepareHeader( pahsc->pahsc_HWaveOut, &pahsc->pahsc_OutputBuffers[i], sizeof(WAVEHDR) );"; 3874 z[lc++]=" GlobalFree( pahsc->pahsc_OutputBuffers[i].lpData ); /* MEM */"; 3875 z[lc++]=" }"; 3876 z[lc++]=" GlobalFree( pahsc->pahsc_OutputBuffers ); /* MEM */"; 3877 z[lc++]=" }"; 3878 z[lc++]=" waveOutClose( pahsc->pahsc_HWaveOut );"; 3879 z[lc++]=" }"; 3880 z[lc++]=" /* Free data and device for input. */"; 3881 z[lc++]=" if( pahsc->pahsc_HWaveIn )"; 3882 z[lc++]=" {"; 3883 z[lc++]=" if( pahsc->pahsc_InputBuffers )"; 3884 z[lc++]=" {"; 3885 z[lc++]=" for( i=0; i<pahsc->pahsc_NumHostBuffers; i++ )"; 3886 z[lc++]=" {"; 3887 z[lc++]=" waveInUnprepareHeader( pahsc->pahsc_HWaveIn, &pahsc->pahsc_InputBuffers[i], sizeof(WAVEHDR) );"; 3888 z[lc++]=" GlobalFree( pahsc->pahsc_InputBuffers[i].lpData ); /* MEM */"; 3889 z[lc++]=" }"; 3890 z[lc++]=" GlobalFree( pahsc->pahsc_InputBuffers ); /* MEM */"; 3891 z[lc++]=" }"; 3892 z[lc++]=" waveInClose( pahsc->pahsc_HWaveIn );"; 3893 z[lc++]=" }"; 3894 z[lc++]="#if (PA_USE_TIMER_CALLBACK == 0)"; 3895 z[lc++]=" if( pahsc->pahsc_AbortEventInited ) CloseHandle( pahsc->pahsc_AbortEvent );"; 3896 z[lc++]=" if( pahsc->pahsc_BufferEventInited ) CloseHandle( pahsc->pahsc_BufferEvent );"; 3897 z[lc++]="#endif"; 3898 z[lc++]=" if( pahsc->pahsc_StreamLockInited )"; 3899 z[lc++]=" DeleteCriticalSection( &pahsc->pahsc_StreamLock );"; 3900 z[lc++]=" PaHost_FreeFastMemory( pahsc, sizeof(PaHostSoundControl) ); /* MEM */"; 3901 z[lc++]=" past->past_DeviceData = NULL;"; 3902 z[lc++]=" return paNoError;"; 3903 z[lc++]="}"; 3904 z[lc++]="/*************************************************************************"; 3905 z[lc++]="** Determine minimum number of buffers required for this host based"; 3906 z[lc++]="** on minimum latency. Latency can be optionally set by user by setting"; 3907 z[lc++]="** an environment variable. For example, to set latency to 200 msec, put:"; 3908 z[lc++]="**"; 3909 z[lc++]="** set PA_MIN_LATENCY_MSEC=200"; 3910 z[lc++]="**"; 3911 z[lc++]="** in the AUTOEXEC.BAT file and reboot."; 3912 z[lc++]="** If the environment variable is not set, then the latency will be determined"; 3913 z[lc++]="** based on the OS. Windows NT has higher latency than Win95."; 3914 z[lc++]="*/"; 3915 z[lc++]="#define PA_LATENCY_ENV_NAME (\"PA_MIN_LATENCY_MSEC\")"; 3916 z[lc++]="int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )"; 3917 z[lc++]="{"; 3918 z[lc++]=" char envbuf[PA_ENV_BUF_SIZE];"; 3919 z[lc++]=" DWORD hostVersion;"; 3920 z[lc++]=" DWORD hresult;"; 3921 z[lc++]=" int minLatencyMsec = 0;"; 3922 z[lc++]=" double msecPerBuffer = (1000.0 * framesPerBuffer) / sampleRate;"; 3923 z[lc++]=" int minBuffers;"; 3924 z[lc++]="/* Let user determine minimal latency by setting environment variable. */"; 3925 z[lc++]=" hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );"; 3926 z[lc++]=" if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )"; 3927 z[lc++]=" {"; 3928 z[lc++]=" minLatencyMsec = atoi( envbuf );"; 3929 z[lc++]=" }"; 3930 z[lc++]=" else"; 3931 z[lc++]=" {"; 3932 z[lc++]="/* Set minimal latency based on whether NT or Win95."; 3933 z[lc++]=" * NT has higher latency."; 3934 z[lc++]=" */"; 3935 z[lc++]=" hostVersion = GetVersion();"; 3936 z[lc++]="/* High bit clear if NT */"; 3937 z[lc++]=" minLatencyMsec = ( (hostVersion & 0x80000000) == 0 ) ? PA_WIN_NT_LATENCY : PA_WIN_9X_LATENCY ;"; 3938 z[lc++]="#if PA_USE_HIGH_LATENCY"; 3939 z[lc++]=" PRINT((\"PA - Minimum Latency set to %d msec!\\n\", minLatencyMsec ));"; 3940 z[lc++]="#endif"; 3941 z[lc++]=" }"; 3942 z[lc++]=" DBUG((\"PA - Minimum Latency set to %d msec!\\n\", minLatencyMsec ));"; 3943 z[lc++]=" minBuffers = (int) (1.0 + ((double)minLatencyMsec / msecPerBuffer));"; 3944 z[lc++]=" if( minBuffers < 2 ) minBuffers = 2;"; 3945 z[lc++]=" return minBuffers;"; 3946 z[lc++]="}"; 3947 z[lc++]="/*************************************************************************"; 3948 z[lc++]="** Cleanup device info."; 3949 z[lc++]="*/"; 3950 z[lc++]="PaError PaHost_Term( void )"; 3951 z[lc++]="{"; 3952 z[lc++]=" int i;"; 3953 z[lc++]=" if( sNumDevices > 0 ){"; 3954 z[lc++]=" if( sDevicePtrs != NULL ){"; 3955 z[lc++]=" for( i=0; i<sNumDevices; i++ )"; 3956 z[lc++]=" {"; 3957 z[lc++]=" if( sDevicePtrs[i] != NULL )"; 3958 z[lc++]=" {"; 3959 z[lc++]=" GlobalFree( (char*)sDevicePtrs[i]->name ); /* MEM */"; 3960 z[lc++]=" GlobalFree( (void*)sDevicePtrs[i]->sampleRates ); /* MEM */"; 3961 z[lc++]=" GlobalFree( sDevicePtrs[i] ); /* MEM */"; 3962 z[lc++]=" }"; 3963 z[lc++]=" }"; 3964 z[lc++]=" GlobalFree( sDevicePtrs ); /* MEM */"; 3965 z[lc++]=" sDevicePtrs = NULL;"; 3966 z[lc++]=" }"; 3967 z[lc++]=" sNumDevices = 0;"; 3968 z[lc++]=" }"; 3969 z[lc++]=" return paNoError;"; 3970 z[lc++]="}"; 3971 z[lc++]="/*************************************************************************/"; 3972 z[lc++]="void Pa_Sleep( long msec )"; 3973 z[lc++]="{"; 3974 z[lc++]=" Sleep( msec );"; 3975 z[lc++]="}"; 3976 z[lc++]="/*************************************************************************"; 3977 z[lc++]=" * Allocate memory that can be accessed in real-time."; 3978 z[lc++]=" * This may need to be held in physical memory so that it is not"; 3979 z[lc++]=" * paged to virtual memory."; 3980 z[lc++]=" * This call MUST be balanced with a call to PaHost_FreeFastMemory()."; 3981 z[lc++]=" * Memory will be set to zero."; 3982 z[lc++]=" */"; 3983 z[lc++]="void *PaHost_AllocateFastMemory( long numBytes )"; 3984 z[lc++]="{"; 3985 z[lc++]=" void *addr = GlobalAlloc( GPTR, numBytes ); /* FIXME - do we need physical memory? Use VirtualLock() */ /* MEM */"; 3986 z[lc++]=" return addr;"; 3987 z[lc++]="}"; 3988 z[lc++]="/*************************************************************************"; 3989 z[lc++]=" * Free memory that could be accessed in real-time."; 3990 z[lc++]=" * This call MUST be balanced with a call to PaHost_AllocateFastMemory()."; 3991 z[lc++]=" */"; 3992 z[lc++]="void PaHost_FreeFastMemory( void *addr, long numBytes )"; 3993 z[lc++]="{"; 3994 z[lc++]=" if( addr != NULL ) GlobalFree( addr ); /* MEM */"; 3995 z[lc++]="}"; 3996 z[lc++]="/***********************************************************************/"; 3997 z[lc++]="PaError PaHost_StreamActive( internalPortAudioStream *past )"; 3998 z[lc++]="{"; 3999 z[lc++]=" PaHostSoundControl *pahsc;"; 4000 z[lc++]=" if( past == NULL ) return paBadStreamPtr;"; 4001 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 4002 z[lc++]=" if( pahsc == NULL ) return paInternalError;"; 4003 z[lc++]=" return (PaError) past->past_IsActive;"; 4004 z[lc++]="}"; 4005 z[lc++]="/*************************************************************************"; 4006 z[lc++]=" * This must be called periodically because mmtime.u.sample"; 4007 z[lc++]=" * is a DWORD and can wrap and lose sync after a few hours."; 4008 z[lc++]=" */"; 4009 z[lc++]="static PaError PaHost_UpdateStreamTime( PaHostSoundControl *pahsc )"; 4010 z[lc++]="{"; 4011 z[lc++]=" MMRESULT mr;"; 4012 z[lc++]=" MMTIME mmtime;"; 4013 z[lc++]=" mmtime.wType = TIME_SAMPLES;"; 4014 z[lc++]=" if( pahsc->pahsc_HWaveOut != NULL )"; 4015 z[lc++]=" {"; 4016 z[lc++]=" mr = waveOutGetPosition( pahsc->pahsc_HWaveOut, &mmtime, sizeof(mmtime) );"; 4017 z[lc++]=" }"; 4018 z[lc++]=" else"; 4019 z[lc++]=" {"; 4020 z[lc++]=" mr = waveInGetPosition( pahsc->pahsc_HWaveIn, &mmtime, sizeof(mmtime) );"; 4021 z[lc++]=" }"; 4022 z[lc++]=" if( mr != MMSYSERR_NOERROR )"; 4023 z[lc++]=" {"; 4024 z[lc++]=" sPaHostError = mr;"; 4025 z[lc++]=" return paHostError;"; 4026 z[lc++]=" }"; 4027 z[lc++]="/* This data has two variables and is shared by foreground and background. */"; 4028 z[lc++]="/* So we need to make it thread safe. */"; 4029 z[lc++]=" EnterCriticalSection( &pahsc->pahsc_StreamLock );"; 4030 z[lc++]=" pahsc->pahsc_FramesPlayed += ((long)mmtime.u.sample) - pahsc->pahsc_LastPosition;"; 4031 z[lc++]=" pahsc->pahsc_LastPosition = (long)mmtime.u.sample;"; 4032 z[lc++]=" LeaveCriticalSection( &pahsc->pahsc_StreamLock );"; 4033 z[lc++]=" return paNoError;"; 4034 z[lc++]="}"; 4035 z[lc++]="/*************************************************************************/"; 4036 z[lc++]="PaTimestamp Pa_StreamTime( PortAudioStream *stream )"; 4037 z[lc++]="{"; 4038 z[lc++]=" PaHostSoundControl *pahsc;"; 4039 z[lc++]=" internalPortAudioStream *past = (internalPortAudioStream *) stream;"; 4040 z[lc++]=" if( past == NULL ) return paBadStreamPtr;"; 4041 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 4042 z[lc++]=" PaHost_UpdateStreamTime( pahsc );"; 4043 z[lc++]=" return pahsc->pahsc_FramesPlayed;"; 4044 z[lc++]="}"; 4045 printlib(lc); 4046 } 4047 4048 4049 void makepa_dshdr(void) 4050 { 4051 int lc = 0; 4052 4053 z[lc++]="#ifndef __DSOUND_WRAPPER_H"; 4054 z[lc++]="#define __DSOUND_WRAPPER_H"; 4055 z[lc++]="/*"; 4056 z[lc++]=" * Simplified DirectSound interface."; 4057 z[lc++]=" *"; 4058 z[lc++]=" * Author: Phil Burk & Robert Marsanyi"; 4059 z[lc++]=" *"; 4060 z[lc++]=" * For PortAudio Portable Real-Time Audio Library"; 4061 z[lc++]=" * For more information see: http://www.softsynth.com/portaudio/"; 4062 z[lc++]=" * DirectSound Implementation"; 4063 z[lc++]=" * Copyright (c) 1999-2000 Phil Burk & Robert Marsanyi"; 4064 z[lc++]=" *"; 4065 z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining"; 4066 z[lc++]=" * a copy of this software and associated documentation files"; 4067 z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,"; 4068 z[lc++]=" * including without limitation the rights to use, copy, modify, merge,"; 4069 z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,"; 4070 z[lc++]=" * and to permit persons to whom the Software is furnished to do so,"; 4071 z[lc++]=" * subject to the following conditions:"; 4072 z[lc++]=" *"; 4073 z[lc++]=" * The above copyright notice and this permission notice shall be"; 4074 z[lc++]=" * included in all copies or substantial portions of the Software."; 4075 z[lc++]=" *"; 4076 z[lc++]=" * Any person wishing to distribute modifications to the Software is"; 4077 z[lc++]=" * requested to send the modifications to the original developer so that"; 4078 z[lc++]=" * they can be incorporated into the canonical version."; 4079 z[lc++]=" *"; 4080 z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,"; 4081 z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF"; 4082 z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT."; 4083 z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR"; 4084 z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF"; 4085 z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION"; 4086 z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."; 4087 z[lc++]=" *"; 4088 z[lc++]=" */"; 4089 z[lc++]="#include <DSound.h>"; 4090 z[lc++]="#if !defined(BOOL)"; 4091 z[lc++]="#define BOOL short"; 4092 z[lc++]="#endif"; 4093 z[lc++]="#ifndef SUPPORT_AUDIO_CAPTURE"; 4094 z[lc++]="#define SUPPORT_AUDIO_CAPTURE (1)"; 4095 z[lc++]="#endif"; 4096 z[lc++]="#ifdef __cplusplus"; 4097 z[lc++]="extern \"C\" {"; 4098 z[lc++]="#endif /* __cplusplus */ "; 4099 z[lc++]="#define DSW_NUM_POSITIONS (4)"; 4100 z[lc++]="#define DSW_NUM_EVENTS (5)"; 4101 z[lc++]="#define DSW_TERMINATION_EVENT (DSW_NUM_POSITIONS)"; 4102 z[lc++]="typedef struct"; 4103 z[lc++]="{"; 4104 z[lc++]="/* Output */"; 4105 z[lc++]=" LPDIRECTSOUND dsw_pDirectSound;"; 4106 z[lc++]=" LPDIRECTSOUNDBUFFER dsw_OutputBuffer;"; 4107 z[lc++]=" DWORD dsw_WriteOffset; /* last write position */"; 4108 z[lc++]=" INT dsw_OutputSize;"; 4109 z[lc++]=" INT dsw_BytesPerFrame;"; 4110 z[lc++]="/* Try to detect play buffer underflows. */"; 4111 z[lc++]=" LARGE_INTEGER dsw_CounterTicksPerBuffer; /* counter ticks it should take to play a full buffer */"; 4112 z[lc++]=" LARGE_INTEGER dsw_LastPlayTime;"; 4113 z[lc++]=" UINT dsw_LastPlayCursor;"; 4114 z[lc++]=" UINT dsw_OutputUnderflows;"; 4115 z[lc++]=" BOOL dsw_OutputRunning;"; 4116 z[lc++]="/* use double which lets us can play for several thousand years with enough precision */"; 4117 z[lc++]=" double dsw_FramesWritten;"; 4118 z[lc++]=" double dsw_FramesPlayed;"; 4119 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 4120 z[lc++]=" /* Input */"; 4121 z[lc++]=" LPDIRECTSOUNDCAPTURE dsw_pDirectSoundCapture;"; 4122 z[lc++]=" LPDIRECTSOUNDCAPTUREBUFFER dsw_InputBuffer;"; 4123 z[lc++]=" UINT dsw_ReadOffset; /* last read position */"; 4124 z[lc++]=" UINT dsw_InputSize;"; 4125 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 4126 z[lc++]="} DSoundWrapper;"; 4127 z[lc++]="HRESULT DSW_Init( DSoundWrapper *dsw );"; 4128 z[lc++]="void DSW_Term( DSoundWrapper *dsw );"; 4129 z[lc++]="HRESULT DSW_InitOutputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate,"; 4130 z[lc++]=" int nChannels, int bufSize );"; 4131 z[lc++]="HRESULT DSW_StartOutput( DSoundWrapper *dsw );"; 4132 z[lc++]="HRESULT DSW_StopOutput( DSoundWrapper *dsw );"; 4133 z[lc++]="DWORD DSW_GetOutputStatus( DSoundWrapper *dsw );"; 4134 z[lc++]="HRESULT DSW_WriteBlock( DSoundWrapper *dsw, char *buf, long numBytes );"; 4135 z[lc++]="HRESULT DSW_ZeroEmptySpace( DSoundWrapper *dsw );"; 4136 z[lc++]="HRESULT DSW_QueryOutputSpace( DSoundWrapper *dsw, long *bytesEmpty );"; 4137 z[lc++]="HRESULT DSW_Enumerate( DSoundWrapper *dsw );"; 4138 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 4139 z[lc++]="HRESULT DSW_InitInputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate,"; 4140 z[lc++]=" int nChannels, int bufSize );"; 4141 z[lc++]="HRESULT DSW_StartInput( DSoundWrapper *dsw );"; 4142 z[lc++]="HRESULT DSW_StopInput( DSoundWrapper *dsw );"; 4143 z[lc++]="HRESULT DSW_ReadBlock( DSoundWrapper *dsw, char *buf, long numBytes );"; 4144 z[lc++]="HRESULT DSW_QueryInputFilled( DSoundWrapper *dsw, long *bytesFilled );"; 4145 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 4146 z[lc++]="#ifdef __cplusplus"; 4147 z[lc++]="}"; 4148 z[lc++]="#endif /* __cplusplus */"; 4149 z[lc++]="#endif /* __DSOUND_WRAPPER_H */"; 4150 printlib(lc); 4151 } 4152 4153 4154 void makepa_dswrap(void) 4155 { 4156 int lc = 0; 4157 4158 z[lc++]="/*"; 4159 z[lc++]=" * Simplified DirectSound interface."; 4160 z[lc++]=" *"; 4161 z[lc++]=" * Author: Phil Burk & Robert Marsanyi"; 4162 z[lc++]=" *"; 4163 z[lc++]=" * PortAudio Portable Real-Time Audio Library"; 4164 z[lc++]=" * For more information see: http://www.softsynth.com/portaudio/"; 4165 z[lc++]=" * DirectSound Implementation"; 4166 z[lc++]=" * Copyright (c) 1999-2000 Phil Burk & Robert Marsanyi"; 4167 z[lc++]=" *"; 4168 z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining"; 4169 z[lc++]=" * a copy of this software and associated documentation files"; 4170 z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,"; 4171 z[lc++]=" * including without limitation the rights to use, copy, modify, merge,"; 4172 z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,"; 4173 z[lc++]=" * and to permit persons to whom the Software is furnished to do so,"; 4174 z[lc++]=" * subject to the following conditions:"; 4175 z[lc++]=" *"; 4176 z[lc++]=" * The above copyright notice and this permission notice shall be"; 4177 z[lc++]=" * included in all copies or substantial portions of the Software."; 4178 z[lc++]=" *"; 4179 z[lc++]=" * Any person wishing to distribute modifications to the Software is"; 4180 z[lc++]=" * requested to send the modifications to the original developer so that"; 4181 z[lc++]=" * they can be incorporated into the canonical version."; 4182 z[lc++]=" *"; 4183 z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,"; 4184 z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF"; 4185 z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT."; 4186 z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR"; 4187 z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF"; 4188 z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION"; 4189 z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."; 4190 z[lc++]=" *"; 4191 z[lc++]=" */"; 4192 z[lc++]="#include <stdio.h>"; 4193 z[lc++]="#include <stdlib.h>"; 4194 z[lc++]="#include <math.h>"; 4195 z[lc++]="#define INITGUID // Needed to build IID_IDirectSoundNotify. See objbase.h for info."; 4196 z[lc++]="#include <objbase.h>"; 4197 z[lc++]="#include <unknwn.h>"; 4198 z[lc++]="#if 0"; 4199 z[lc++]="#include \"dsound_wrapper.h\""; 4200 z[lc++]="#include \"pa_trace.h\""; 4201 z[lc++]="#endif"; 4202 z[lc++]="/************************************************************************************/"; 4203 z[lc++]="void DSW_Term( DSoundWrapper *dsw )"; 4204 z[lc++]="{"; 4205 z[lc++]="// Cleanup the sound buffers"; 4206 z[lc++]=" if (dsw->dsw_OutputBuffer)"; 4207 z[lc++]=" {"; 4208 z[lc++]=" IDirectSoundBuffer_Stop( dsw->dsw_OutputBuffer );"; 4209 z[lc++]=" IDirectSoundBuffer_Release( dsw->dsw_OutputBuffer );"; 4210 z[lc++]=" dsw->dsw_OutputBuffer = NULL;"; 4211 z[lc++]=" }"; 4212 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 4213 z[lc++]=" if (dsw->dsw_InputBuffer)"; 4214 z[lc++]=" {"; 4215 z[lc++]=" IDirectSoundCaptureBuffer_Stop( dsw->dsw_InputBuffer );"; 4216 z[lc++]=" IDirectSoundCaptureBuffer_Release( dsw->dsw_InputBuffer );"; 4217 z[lc++]=" dsw->dsw_InputBuffer = NULL;"; 4218 z[lc++]=" }"; 4219 z[lc++]=" if (dsw->dsw_pDirectSoundCapture)"; 4220 z[lc++]=" {"; 4221 z[lc++]=" IDirectSoundCapture_Release( dsw->dsw_pDirectSoundCapture );"; 4222 z[lc++]=" dsw->dsw_pDirectSoundCapture = NULL;"; 4223 z[lc++]=" }"; 4224 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 4225 z[lc++]=" if (dsw->dsw_pDirectSound)"; 4226 z[lc++]=" {"; 4227 z[lc++]=" IDirectSound_Release( dsw->dsw_pDirectSound );"; 4228 z[lc++]=" dsw->dsw_pDirectSound = NULL;"; 4229 z[lc++]=" }"; 4230 z[lc++]="}"; 4231 z[lc++]="/************************************************************************************/"; 4232 z[lc++]="HRESULT DSW_Init( DSoundWrapper *dsw )"; 4233 z[lc++]="{"; 4234 z[lc++]=" memset( dsw, 0, sizeof(DSoundWrapper) );"; 4235 z[lc++]=" return 0;"; 4236 z[lc++]="}"; 4237 z[lc++]="/************************************************************************************/"; 4238 z[lc++]="HRESULT DSW_InitOutputDevice( DSoundWrapper *dsw, LPGUID lpGUID )"; 4239 z[lc++]="{"; 4240 z[lc++]="// Create the DS object"; 4241 z[lc++]=" HRESULT hr = DirectSoundCreate( lpGUID, &dsw->dsw_pDirectSound, NULL );"; 4242 z[lc++]=" if( hr != DS_OK ) return hr;"; 4243 z[lc++]=" return hr;"; 4244 z[lc++]="}"; 4245 z[lc++]="/************************************************************************************/"; 4246 z[lc++]="HRESULT DSW_InitOutputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate, int nChannels, int bytesPerBuffer )"; 4247 z[lc++]="{"; 4248 z[lc++]=" DWORD dwDataLen;"; 4249 z[lc++]=" DWORD playCursor;"; 4250 z[lc++]=" HRESULT result;"; 4251 z[lc++]=" LPDIRECTSOUNDBUFFER pPrimaryBuffer;"; 4252 z[lc++]=" HWND hWnd;"; 4253 z[lc++]=" HRESULT hr;"; 4254 z[lc++]=" WAVEFORMATEX wfFormat;"; 4255 z[lc++]=" DSBUFFERDESC primaryDesc;"; 4256 z[lc++]=" DSBUFFERDESC secondaryDesc;"; 4257 z[lc++]=" unsigned char* pDSBuffData;"; 4258 z[lc++]=" LARGE_INTEGER counterFrequency;"; 4259 z[lc++]=" dsw->dsw_OutputSize = bytesPerBuffer;"; 4260 z[lc++]=" dsw->dsw_OutputRunning = FALSE;"; 4261 z[lc++]=" dsw->dsw_OutputUnderflows = 0;"; 4262 z[lc++]=" dsw->dsw_FramesWritten = 0;"; 4263 z[lc++]=" dsw->dsw_BytesPerFrame = nChannels * sizeof(short);"; 4264 z[lc++]="// We were using getForegroundWindow() but sometimes the ForegroundWindow may not be the"; 4265 z[lc++]="// applications's window. Also if that window is closed before the Buffer is closed"; 4266 z[lc++]="// then DirectSound can crash. (Thanks for Scott Patterson for reporting this.)"; 4267 z[lc++]="// So we will use GetDesktopWindow() which was suggested by Miller Puckette."; 4268 z[lc++]="// hWnd = GetForegroundWindow();"; 4269 z[lc++]=" hWnd = GetDesktopWindow();"; 4270 z[lc++]="// Set cooperative level to DSSCL_EXCLUSIVE so that we can get 16 bit output, 44.1 KHz."; 4271 z[lc++]="// Exclusize also prevents unexpected sounds from other apps during a performance."; 4272 z[lc++]=" if ((hr = IDirectSound_SetCooperativeLevel( dsw->dsw_pDirectSound,"; 4273 z[lc++]=" hWnd, DSSCL_EXCLUSIVE)) != DS_OK)"; 4274 z[lc++]=" {"; 4275 z[lc++]=" return hr;"; 4276 z[lc++]=" }"; 4277 z[lc++]="// -----------------------------------------------------------------------"; 4278 z[lc++]="// Create primary buffer and set format just so we can specify our custom format."; 4279 z[lc++]="// Otherwise we would be stuck with the default which might be 8 bit or 22050 Hz."; 4280 z[lc++]="// Setup the primary buffer description"; 4281 z[lc++]=" ZeroMemory(&primaryDesc, sizeof(DSBUFFERDESC));"; 4282 z[lc++]=" primaryDesc.dwSize = sizeof(DSBUFFERDESC);"; 4283 z[lc++]=" primaryDesc.dwFlags = DSBCAPS_PRIMARYBUFFER; // all panning, mixing, etc done by synth"; 4284 z[lc++]=" primaryDesc.dwBufferBytes = 0;"; 4285 z[lc++]=" primaryDesc.lpwfxFormat = NULL;"; 4286 z[lc++]="// Create the buffer"; 4287 z[lc++]=" if ((result = IDirectSound_CreateSoundBuffer( dsw->dsw_pDirectSound,"; 4288 z[lc++]=" &primaryDesc, &pPrimaryBuffer, NULL)) != DS_OK) return result;"; 4289 z[lc++]="// Define the buffer format"; 4290 z[lc++]=" wfFormat.wFormatTag = WAVE_FORMAT_PCM;"; 4291 z[lc++]=" wfFormat.nChannels = nChannels;"; 4292 z[lc++]=" wfFormat.nSamplesPerSec = nFrameRate;"; 4293 z[lc++]=" wfFormat.wBitsPerSample = 8 * sizeof(short);"; 4294 z[lc++]=" wfFormat.nBlockAlign = wfFormat.nChannels * wfFormat.wBitsPerSample / 8;"; 4295 z[lc++]=" wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;"; 4296 z[lc++]=" wfFormat.cbSize = 0; /* No extended format info. */"; 4297 z[lc++]="// Set the primary buffer's format"; 4298 z[lc++]=" if((result = IDirectSoundBuffer_SetFormat( pPrimaryBuffer, &wfFormat)) != DS_OK) return result;"; 4299 z[lc++]="// ----------------------------------------------------------------------"; 4300 z[lc++]="// Setup the secondary buffer description"; 4301 z[lc++]=" ZeroMemory(&secondaryDesc, sizeof(DSBUFFERDESC));"; 4302 z[lc++]=" secondaryDesc.dwSize = sizeof(DSBUFFERDESC);"; 4303 z[lc++]=" secondaryDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;"; 4304 z[lc++]=" secondaryDesc.dwBufferBytes = bytesPerBuffer;"; 4305 z[lc++]=" secondaryDesc.lpwfxFormat = &wfFormat;"; 4306 z[lc++]="// Create the secondary buffer"; 4307 z[lc++]=" if ((result = IDirectSound_CreateSoundBuffer( dsw->dsw_pDirectSound,"; 4308 z[lc++]=" &secondaryDesc, &dsw->dsw_OutputBuffer, NULL)) != DS_OK) return result;"; 4309 z[lc++]="// Lock the DS buffer"; 4310 z[lc++]=" if ((result = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, 0, dsw->dsw_OutputSize, (LPVOID*)&pDSBuffData,"; 4311 z[lc++]=" &dwDataLen, NULL, 0, 0)) != DS_OK) return result;"; 4312 z[lc++]="// Zero the DS buffer"; 4313 z[lc++]=" ZeroMemory(pDSBuffData, dwDataLen);"; 4314 z[lc++]="// Unlock the DS buffer"; 4315 z[lc++]=" if ((result = IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) return result;"; 4316 z[lc++]=" if( QueryPerformanceFrequency( &counterFrequency ) )"; 4317 z[lc++]=" {"; 4318 z[lc++]=" int framesInBuffer = bytesPerBuffer / (nChannels * sizeof(short));"; 4319 z[lc++]=" dsw->dsw_CounterTicksPerBuffer.QuadPart = (counterFrequency.QuadPart * framesInBuffer) / nFrameRate;"; 4320 z[lc++]=" AddTraceMessage(\"dsw_CounterTicksPerBuffer = %d\\n\", dsw->dsw_CounterTicksPerBuffer.LowPart );"; 4321 z[lc++]=" }"; 4322 z[lc++]=" else"; 4323 z[lc++]=" {"; 4324 z[lc++]=" dsw->dsw_CounterTicksPerBuffer.QuadPart = 0;"; 4325 z[lc++]=" }"; 4326 z[lc++]="// Let DSound set the starting write position because if we set it to zero, it looks like the"; 4327 z[lc++]="// buffer is full to begin with. This causes a long pause before sound starts when using large buffers."; 4328 z[lc++]=" hr = IDirectSoundBuffer_GetCurrentPosition( dsw->dsw_OutputBuffer, &playCursor, &dsw->dsw_WriteOffset );"; 4329 z[lc++]=" if( hr != DS_OK )"; 4330 z[lc++]=" {"; 4331 z[lc++]=" return hr;"; 4332 z[lc++]=" }"; 4333 z[lc++]=" dsw->dsw_FramesWritten = dsw->dsw_WriteOffset / dsw->dsw_BytesPerFrame;"; 4334 z[lc++]=" /* printf(\"DSW_InitOutputBuffer: playCursor = %d, writeCursor = %d\\n\", playCursor, dsw->dsw_WriteOffset ); */"; 4335 z[lc++]=" return DS_OK;"; 4336 z[lc++]="}"; 4337 z[lc++]="/************************************************************************************/"; 4338 z[lc++]="HRESULT DSW_StartOutput( DSoundWrapper *dsw )"; 4339 z[lc++]="{"; 4340 z[lc++]=" HRESULT hr;"; 4341 z[lc++]=" QueryPerformanceCounter( &dsw->dsw_LastPlayTime );"; 4342 z[lc++]=" dsw->dsw_LastPlayCursor = 0;"; 4343 z[lc++]=" dsw->dsw_FramesPlayed = 0;"; 4344 z[lc++]=" hr = IDirectSoundBuffer_SetCurrentPosition( dsw->dsw_OutputBuffer, 0 );"; 4345 z[lc++]=" if( hr != DS_OK )"; 4346 z[lc++]=" {"; 4347 z[lc++]=" return hr;"; 4348 z[lc++]=" }"; 4349 z[lc++]="// Start the buffer playback in a loop."; 4350 z[lc++]=" if( dsw->dsw_OutputBuffer != NULL )"; 4351 z[lc++]=" {"; 4352 z[lc++]=" hr = IDirectSoundBuffer_Play( dsw->dsw_OutputBuffer, 0, 0, DSBPLAY_LOOPING );"; 4353 z[lc++]=" if( hr != DS_OK )"; 4354 z[lc++]=" {"; 4355 z[lc++]=" return hr;"; 4356 z[lc++]=" }"; 4357 z[lc++]=" dsw->dsw_OutputRunning = TRUE;"; 4358 z[lc++]=" }"; 4359 z[lc++]=" "; 4360 z[lc++]=" return 0;"; 4361 z[lc++]="}"; 4362 z[lc++]="/************************************************************************************/"; 4363 z[lc++]="HRESULT DSW_StopOutput( DSoundWrapper *dsw )"; 4364 z[lc++]="{"; 4365 z[lc++]="// Stop the buffer playback"; 4366 z[lc++]=" if( dsw->dsw_OutputBuffer != NULL )"; 4367 z[lc++]=" {"; 4368 z[lc++]=" dsw->dsw_OutputRunning = FALSE;"; 4369 z[lc++]=" return IDirectSoundBuffer_Stop( dsw->dsw_OutputBuffer );"; 4370 z[lc++]=" }"; 4371 z[lc++]=" else return 0;"; 4372 z[lc++]="}"; 4373 z[lc++]="/************************************************************************************/"; 4374 z[lc++]="HRESULT DSW_QueryOutputSpace( DSoundWrapper *dsw, long *bytesEmpty )"; 4375 z[lc++]="{"; 4376 z[lc++]=" HRESULT hr;"; 4377 z[lc++]=" DWORD playCursor;"; 4378 z[lc++]=" DWORD writeCursor;"; 4379 z[lc++]=" long numBytesEmpty;"; 4380 z[lc++]=" long playWriteGap;"; 4381 z[lc++]="// Query to see how much room is in buffer."; 4382 z[lc++]="// Note: Even though writeCursor is not used, it must be passed to prevent DirectSound from dieing"; 4383 z[lc++]="// under WinNT. The Microsoft documentation says we can pass NULL but apparently not."; 4384 z[lc++]="// Thanks to Max Rheiner for the fix."; 4385 z[lc++]=" hr = IDirectSoundBuffer_GetCurrentPosition( dsw->dsw_OutputBuffer, &playCursor, &writeCursor );"; 4386 z[lc++]=" if( hr != DS_OK )"; 4387 z[lc++]=" {"; 4388 z[lc++]=" return hr;"; 4389 z[lc++]=" }"; 4390 z[lc++]=" AddTraceMessage(\"playCursor\", playCursor);"; 4391 z[lc++]=" AddTraceMessage(\"dsw_WriteOffset\", dsw->dsw_WriteOffset);"; 4392 z[lc++]="// Determine size of gap between playIndex and WriteIndex that we cannot write into."; 4393 z[lc++]=" playWriteGap = writeCursor - playCursor;"; 4394 z[lc++]=" if( playWriteGap < 0 ) playWriteGap += dsw->dsw_OutputSize; // unwrap"; 4395 z[lc++]="/* DirectSound doesn't have a large enough playCursor so we cannot detect wrap-around. */"; 4396 z[lc++]="/* Attempt to detect playCursor wrap-around and correct it. */"; 4397 z[lc++]=" if( dsw->dsw_OutputRunning && (dsw->dsw_CounterTicksPerBuffer.QuadPart != 0) )"; 4398 z[lc++]=" {"; 4399 z[lc++]="/* How much time has elapsed since last check. */"; 4400 z[lc++]=" LARGE_INTEGER currentTime;"; 4401 z[lc++]=" LARGE_INTEGER elapsedTime;"; 4402 z[lc++]=" long bytesPlayed;"; 4403 z[lc++]=" long bytesExpected;"; 4404 z[lc++]=" long buffersWrapped;"; 4405 z[lc++]=" QueryPerformanceCounter( ¤tTime );"; 4406 z[lc++]=" elapsedTime.QuadPart = currentTime.QuadPart - dsw->dsw_LastPlayTime.QuadPart;"; 4407 z[lc++]=" dsw->dsw_LastPlayTime = currentTime;"; 4408 z[lc++]="/* How many bytes does DirectSound say have been played. */"; 4409 z[lc++]=" bytesPlayed = playCursor - dsw->dsw_LastPlayCursor;"; 4410 z[lc++]=" if( bytesPlayed < 0 ) bytesPlayed += dsw->dsw_OutputSize; // unwrap"; 4411 z[lc++]=" dsw->dsw_LastPlayCursor = playCursor;"; 4412 z[lc++]="/* Calculate how many bytes we would have expected to been played by now. */"; 4413 z[lc++]=" bytesExpected = (long) ((elapsedTime.QuadPart * dsw->dsw_OutputSize) / dsw->dsw_CounterTicksPerBuffer.QuadPart);"; 4414 z[lc++]=" buffersWrapped = (bytesExpected - bytesPlayed) / dsw->dsw_OutputSize;"; 4415 z[lc++]=" if( buffersWrapped > 0 )"; 4416 z[lc++]=" {"; 4417 z[lc++]=" AddTraceMessage(\"playCursor wrapped! bytesPlayed\", bytesPlayed );"; 4418 z[lc++]=" AddTraceMessage(\"playCursor wrapped! bytesExpected\", bytesExpected );"; 4419 z[lc++]=" playCursor += (buffersWrapped * dsw->dsw_OutputSize);"; 4420 z[lc++]=" bytesPlayed += (buffersWrapped * dsw->dsw_OutputSize);"; 4421 z[lc++]=" }"; 4422 z[lc++]=" /* Maintain frame output cursor. */"; 4423 z[lc++]=" dsw->dsw_FramesPlayed += (bytesPlayed / dsw->dsw_BytesPerFrame);"; 4424 z[lc++]=" }"; 4425 z[lc++]=" numBytesEmpty = playCursor - dsw->dsw_WriteOffset;"; 4426 z[lc++]=" if( numBytesEmpty < 0 ) numBytesEmpty += dsw->dsw_OutputSize; // unwrap offset"; 4427 z[lc++]="/* Have we underflowed? */"; 4428 z[lc++]=" if( numBytesEmpty > (dsw->dsw_OutputSize - playWriteGap) )"; 4429 z[lc++]=" {"; 4430 z[lc++]=" if( dsw->dsw_OutputRunning )"; 4431 z[lc++]=" {"; 4432 z[lc++]=" dsw->dsw_OutputUnderflows += 1;"; 4433 z[lc++]=" AddTraceMessage(\"underflow detected! numBytesEmpty\", numBytesEmpty );"; 4434 z[lc++]=" }"; 4435 z[lc++]=" dsw->dsw_WriteOffset = writeCursor;"; 4436 z[lc++]=" numBytesEmpty = dsw->dsw_OutputSize - playWriteGap;"; 4437 z[lc++]=" }"; 4438 z[lc++]=" *bytesEmpty = numBytesEmpty;"; 4439 z[lc++]=" return hr;"; 4440 z[lc++]="}"; 4441 z[lc++]="/************************************************************************************/"; 4442 z[lc++]="HRESULT DSW_ZeroEmptySpace( DSoundWrapper *dsw )"; 4443 z[lc++]="{"; 4444 z[lc++]=" HRESULT hr;"; 4445 z[lc++]=" LPBYTE lpbuf1 = NULL;"; 4446 z[lc++]=" LPBYTE lpbuf2 = NULL;"; 4447 z[lc++]=" DWORD dwsize1 = 0;"; 4448 z[lc++]=" DWORD dwsize2 = 0;"; 4449 z[lc++]=" long bytesEmpty;"; 4450 z[lc++]=" hr = DSW_QueryOutputSpace( dsw, &bytesEmpty ); // updates dsw_FramesPlayed"; 4451 z[lc++]=" if (hr != DS_OK) return hr;"; 4452 z[lc++]=" if( bytesEmpty == 0 ) return DS_OK;"; 4453 z[lc++]=" // Lock free space in the DS"; 4454 z[lc++]=" hr = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, dsw->dsw_WriteOffset, bytesEmpty, (void **) &lpbuf1, &dwsize1,"; 4455 z[lc++]=" (void **) &lpbuf2, &dwsize2, 0);"; 4456 z[lc++]=" if (hr == DS_OK)"; 4457 z[lc++]=" {"; 4458 z[lc++]=" // Copy the buffer into the DS"; 4459 z[lc++]=" ZeroMemory(lpbuf1, dwsize1);"; 4460 z[lc++]=" if(lpbuf2 != NULL)"; 4461 z[lc++]=" {"; 4462 z[lc++]=" ZeroMemory(lpbuf2, dwsize2);"; 4463 z[lc++]=" }"; 4464 z[lc++]=" // Update our buffer offset and unlock sound buffer"; 4465 z[lc++]=" dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + dwsize1 + dwsize2) % dsw->dsw_OutputSize;"; 4466 z[lc++]=" IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);"; 4467 z[lc++]=" dsw->dsw_FramesWritten += bytesEmpty / dsw->dsw_BytesPerFrame;"; 4468 z[lc++]=" }"; 4469 z[lc++]=" return hr;"; 4470 z[lc++]="}"; 4471 z[lc++]="/************************************************************************************/"; 4472 z[lc++]="HRESULT DSW_WriteBlock( DSoundWrapper *dsw, char *buf, long numBytes )"; 4473 z[lc++]="{"; 4474 z[lc++]=" HRESULT hr;"; 4475 z[lc++]=" LPBYTE lpbuf1 = NULL;"; 4476 z[lc++]=" LPBYTE lpbuf2 = NULL;"; 4477 z[lc++]=" DWORD dwsize1 = 0;"; 4478 z[lc++]=" DWORD dwsize2 = 0;"; 4479 z[lc++]=" // Lock free space in the DS"; 4480 z[lc++]=" hr = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, dsw->dsw_WriteOffset, numBytes, (void **) &lpbuf1, &dwsize1,"; 4481 z[lc++]=" (void **) &lpbuf2, &dwsize2, 0);"; 4482 z[lc++]=" if (hr == DS_OK)"; 4483 z[lc++]=" {"; 4484 z[lc++]=" // Copy the buffer into the DS"; 4485 z[lc++]=" CopyMemory(lpbuf1, buf, dwsize1);"; 4486 z[lc++]=" if(lpbuf2 != NULL)"; 4487 z[lc++]=" {"; 4488 z[lc++]=" CopyMemory(lpbuf2, buf+dwsize1, dwsize2);"; 4489 z[lc++]=" }"; 4490 z[lc++]=" // Update our buffer offset and unlock sound buffer"; 4491 z[lc++]=" dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + dwsize1 + dwsize2) % dsw->dsw_OutputSize;"; 4492 z[lc++]=" IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);"; 4493 z[lc++]=" dsw->dsw_FramesWritten += numBytes / dsw->dsw_BytesPerFrame;"; 4494 z[lc++]=" }"; 4495 z[lc++]=" return hr;"; 4496 z[lc++]="}"; 4497 z[lc++]="/************************************************************************************/"; 4498 z[lc++]="DWORD DSW_GetOutputStatus( DSoundWrapper *dsw )"; 4499 z[lc++]="{"; 4500 z[lc++]=" DWORD status;"; 4501 z[lc++]=" if (IDirectSoundBuffer_GetStatus( dsw->dsw_OutputBuffer, &status ) != DS_OK)"; 4502 z[lc++]=" return( DSERR_INVALIDPARAM );"; 4503 z[lc++]=" else"; 4504 z[lc++]=" return( status );"; 4505 z[lc++]="}"; 4506 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 4507 z[lc++]="/* These routines are used to support audio input."; 4508 z[lc++]=" * Do NOT compile these calls when using NT4 because it does"; 4509 z[lc++]=" * not support the entry points."; 4510 z[lc++]=" */"; 4511 z[lc++]="/************************************************************************************/"; 4512 z[lc++]="HRESULT DSW_InitInputDevice( DSoundWrapper *dsw, LPGUID lpGUID )"; 4513 z[lc++]="{"; 4514 z[lc++]=" HRESULT hr = DirectSoundCaptureCreate( lpGUID, &dsw->dsw_pDirectSoundCapture, NULL );"; 4515 z[lc++]=" if( hr != DS_OK ) return hr;"; 4516 z[lc++]=" return hr;"; 4517 z[lc++]="}"; 4518 z[lc++]="/************************************************************************************/"; 4519 z[lc++]="HRESULT DSW_InitInputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate, int nChannels, int bytesPerBuffer )"; 4520 z[lc++]="{"; 4521 z[lc++]=" DSCBUFFERDESC captureDesc;"; 4522 z[lc++]=" WAVEFORMATEX wfFormat;"; 4523 z[lc++]=" HRESULT result;"; 4524 z[lc++]="// Define the buffer format"; 4525 z[lc++]=" wfFormat.wFormatTag = WAVE_FORMAT_PCM;"; 4526 z[lc++]=" wfFormat.nChannels = nChannels;"; 4527 z[lc++]=" wfFormat.nSamplesPerSec = nFrameRate;"; 4528 z[lc++]=" wfFormat.wBitsPerSample = 8 * sizeof(short);"; 4529 z[lc++]=" wfFormat.nBlockAlign = wfFormat.nChannels * (wfFormat.wBitsPerSample / 8);"; 4530 z[lc++]=" wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;"; 4531 z[lc++]=" wfFormat.cbSize = 0; /* No extended format info. */"; 4532 z[lc++]=" dsw->dsw_InputSize = bytesPerBuffer;"; 4533 z[lc++]="// ----------------------------------------------------------------------"; 4534 z[lc++]="// Setup the secondary buffer description"; 4535 z[lc++]=" ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC));"; 4536 z[lc++]=" captureDesc.dwSize = sizeof(DSCBUFFERDESC);"; 4537 z[lc++]=" captureDesc.dwFlags = 0;"; 4538 z[lc++]=" captureDesc.dwBufferBytes = bytesPerBuffer;"; 4539 z[lc++]=" captureDesc.lpwfxFormat = &wfFormat;"; 4540 z[lc++]=" // Create the capture buffer"; 4541 z[lc++]=" if ((result = IDirectSoundCapture_CreateCaptureBuffer( dsw->dsw_pDirectSoundCapture,"; 4542 z[lc++]=" &captureDesc, &dsw->dsw_InputBuffer, NULL)) != DS_OK) return result;"; 4543 z[lc++]=" dsw->dsw_ReadOffset = 0; // reset last read position to start of buffer"; 4544 z[lc++]=" return DS_OK;"; 4545 z[lc++]="}"; 4546 z[lc++]="/************************************************************************************/"; 4547 z[lc++]="HRESULT DSW_StartInput( DSoundWrapper *dsw )"; 4548 z[lc++]="{"; 4549 z[lc++]="// Start the buffer playback"; 4550 z[lc++]=" if( dsw->dsw_InputBuffer != NULL )"; 4551 z[lc++]=" {"; 4552 z[lc++]=" return IDirectSoundCaptureBuffer_Start( dsw->dsw_InputBuffer, DSCBSTART_LOOPING );"; 4553 z[lc++]=" }"; 4554 z[lc++]=" else return 0;"; 4555 z[lc++]="}"; 4556 z[lc++]="/************************************************************************************/"; 4557 z[lc++]="HRESULT DSW_StopInput( DSoundWrapper *dsw )"; 4558 z[lc++]="{"; 4559 z[lc++]="// Stop the buffer playback"; 4560 z[lc++]=" if( dsw->dsw_InputBuffer != NULL )"; 4561 z[lc++]=" {"; 4562 z[lc++]=" return IDirectSoundCaptureBuffer_Stop( dsw->dsw_InputBuffer );"; 4563 z[lc++]=" }"; 4564 z[lc++]=" else return 0;"; 4565 z[lc++]="}"; 4566 z[lc++]="/************************************************************************************/"; 4567 z[lc++]="HRESULT DSW_QueryInputFilled( DSoundWrapper *dsw, long *bytesFilled )"; 4568 z[lc++]="{"; 4569 z[lc++]=" HRESULT hr;"; 4570 z[lc++]=" DWORD capturePos;"; 4571 z[lc++]=" DWORD readPos;"; 4572 z[lc++]=" long filled;"; 4573 z[lc++]="// Query to see how much data is in buffer."; 4574 z[lc++]="// We don't need the capture position but sometimes DirectSound doesn't handle NULLS correctly"; 4575 z[lc++]="// so let's pass a pointer just to be safe."; 4576 z[lc++]=" hr = IDirectSoundCaptureBuffer_GetCurrentPosition( dsw->dsw_InputBuffer, &capturePos, &readPos );"; 4577 z[lc++]=" if( hr != DS_OK )"; 4578 z[lc++]=" {"; 4579 z[lc++]=" return hr;"; 4580 z[lc++]=" }"; 4581 z[lc++]=" filled = readPos - dsw->dsw_ReadOffset;"; 4582 z[lc++]=" if( filled < 0 ) filled += dsw->dsw_InputSize; // unwrap offset"; 4583 z[lc++]=" *bytesFilled = filled;"; 4584 z[lc++]=" return hr;"; 4585 z[lc++]="}"; 4586 z[lc++]="/************************************************************************************/"; 4587 z[lc++]="HRESULT DSW_ReadBlock( DSoundWrapper *dsw, char *buf, long numBytes )"; 4588 z[lc++]="{"; 4589 z[lc++]=" HRESULT hr;"; 4590 z[lc++]=" LPBYTE lpbuf1 = NULL;"; 4591 z[lc++]=" LPBYTE lpbuf2 = NULL;"; 4592 z[lc++]=" DWORD dwsize1 = 0;"; 4593 z[lc++]=" DWORD dwsize2 = 0;"; 4594 z[lc++]=" // Lock free space in the DS"; 4595 z[lc++]=" hr = IDirectSoundCaptureBuffer_Lock ( dsw->dsw_InputBuffer, dsw->dsw_ReadOffset, numBytes, (void **) &lpbuf1, &dwsize1,"; 4596 z[lc++]=" (void **) &lpbuf2, &dwsize2, 0);"; 4597 z[lc++]=" if (hr == DS_OK)"; 4598 z[lc++]=" {"; 4599 z[lc++]=" // Copy from DS to the buffer"; 4600 z[lc++]=" CopyMemory( buf, lpbuf1, dwsize1);"; 4601 z[lc++]=" if(lpbuf2 != NULL)"; 4602 z[lc++]=" {"; 4603 z[lc++]=" CopyMemory( buf+dwsize1, lpbuf2, dwsize2);"; 4604 z[lc++]=" }"; 4605 z[lc++]=" // Update our buffer offset and unlock sound buffer"; 4606 z[lc++]=" dsw->dsw_ReadOffset = (dsw->dsw_ReadOffset + dwsize1 + dwsize2) % dsw->dsw_InputSize;"; 4607 z[lc++]=" IDirectSoundCaptureBuffer_Unlock ( dsw->dsw_InputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);"; 4608 z[lc++]=" }"; 4609 z[lc++]=" return hr;"; 4610 z[lc++]="}"; 4611 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 4612 printlib(lc); 4613 } 4614 4615 4616 void makepa_dsound(void) 4617 { 4618 int lc = 0; 4619 4620 z[lc++]="/*"; 4621 z[lc++]=" * PortAudio Portable Real-Time Audio Library"; 4622 z[lc++]=" * Latest Version at: http://www.softsynth.com/portaudio/"; 4623 z[lc++]=" * DirectSound Implementation"; 4624 z[lc++]=" *"; 4625 z[lc++]=" * Copyright (c) 1999-2000 Phil Burk"; 4626 z[lc++]=" *"; 4627 z[lc++]=" * Permission is hereby granted, free of charge, to any person obtaining"; 4628 z[lc++]=" * a copy of this software and associated documentation files"; 4629 z[lc++]=" * (the \"Software\"), to deal in the Software without restriction,"; 4630 z[lc++]=" * including without limitation the rights to use, copy, modify, merge,"; 4631 z[lc++]=" * publish, distribute, sublicense, and/or sell copies of the Software,"; 4632 z[lc++]=" * and to permit persons to whom the Software is furnished to do so,"; 4633 z[lc++]=" * subject to the following conditions:"; 4634 z[lc++]=" *"; 4635 z[lc++]=" * The above copyright notice and this permission notice shall be"; 4636 z[lc++]=" * included in all copies or substantial portions of the Software."; 4637 z[lc++]=" *"; 4638 z[lc++]=" * Any person wishing to distribute modifications to the Software is"; 4639 z[lc++]=" * requested to send the modifications to the original developer so that"; 4640 z[lc++]=" * they can be incorporated into the canonical version."; 4641 z[lc++]=" *"; 4642 z[lc++]=" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,"; 4643 z[lc++]=" * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF"; 4644 z[lc++]=" * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT."; 4645 z[lc++]=" * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR"; 4646 z[lc++]=" * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF"; 4647 z[lc++]=" * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION"; 4648 z[lc++]=" * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."; 4649 z[lc++]=" *"; 4650 z[lc++]=" */"; 4651 z[lc++]="/* Modifications"; 4652 z[lc++]=" * 7/19/01 Mike Berry - casts for compiling with __MWERKS__ CodeWarrior"; 4653 z[lc++]=" * 9/27/01 Phil Burk - use number of frames instead of real-time for CPULoad calculation."; 4654 z[lc++]=" */"; 4655 z[lc++]="/* Compiler flags:"; 4656 z[lc++]=" SUPPORT_AUDIO_CAPTURE - define this flag if you want to SUPPORT_AUDIO_CAPTURE"; 4657 z[lc++]=" */"; 4658 z[lc++]="#include <stdio.h>"; 4659 z[lc++]="#include <stdlib.h>"; 4660 z[lc++]="#ifndef __MWERKS__"; 4661 z[lc++]="#include <malloc.h>"; 4662 z[lc++]="#include <memory.h>"; 4663 z[lc++]="#endif //__MWERKS__"; 4664 z[lc++]="#include <math.h>"; 4665 z[lc++]="#if 0"; 4666 z[lc++]="#include \"portaudio.h\""; 4667 z[lc++]="#include \"pa_host.h\""; 4668 z[lc++]="#include \"pa_trace.h\""; 4669 z[lc++]="#include \"dsound_wrapper.h\""; 4670 z[lc++]="#endif"; 4671 z[lc++]="#define PRINT(x) { printf x; fflush(stdout); }"; 4672 z[lc++]="#define ERR_RPT(x) PRINT(x)"; 4673 z[lc++]="#define DBUG(x) /* PRINT(x) */"; 4674 z[lc++]="#define DBUGX(x) /* PRINT(x) */"; 4675 z[lc++]="#define PA_USE_HIGH_LATENCY (0)"; 4676 z[lc++]="#if PA_USE_HIGH_LATENCY"; 4677 z[lc++]="#define PA_WIN_9X_LATENCY (500)"; 4678 z[lc++]="#define PA_WIN_NT_LATENCY (600)"; 4679 z[lc++]="#else"; 4680 z[lc++]="#define PA_WIN_9X_LATENCY (140)"; 4681 z[lc++]="#define PA_WIN_NT_LATENCY (280)"; 4682 z[lc++]="#endif"; 4683 z[lc++]="/* Trigger an underflow for testing purposes. Should normally be (0). */"; 4684 z[lc++]="#define PA_SIMULATE_UNDERFLOW (0)"; 4685 z[lc++]="#if PA_SIMULATE_UNDERFLOW"; 4686 z[lc++]="static gUnderCallbackCounter = 0;"; 4687 z[lc++]="#define UNDER_START_GAP (10)"; 4688 z[lc++]="#define UNDER_STOP_GAP (UNDER_START_GAP + 4)"; 4689 z[lc++]="#endif"; 4690 z[lc++]="/************************************************* Definitions ********/"; 4691 z[lc++]="typedef struct internalPortAudioStream internalPortAudioStream;"; 4692 z[lc++]="typedef struct internalPortAudioDevice"; 4693 z[lc++]="{"; 4694 z[lc++]=" GUID pad_GUID;"; 4695 z[lc++]=" GUID *pad_lpGUID;"; 4696 z[lc++]=" double pad_SampleRates[10]; /* for pointing to from pad_Info FIXME?!*/"; 4697 z[lc++]=" PaDeviceInfo pad_Info;"; 4698 z[lc++]="} internalPortAudioDevice;"; 4699 z[lc++]="/* Define structure to contain all DirectSound and Windows specific data. */"; 4700 z[lc++]="typedef struct PaHostSoundControl"; 4701 z[lc++]="{"; 4702 z[lc++]=" DSoundWrapper pahsc_DSoundWrapper;"; 4703 z[lc++]=" MMRESULT pahsc_TimerID;"; 4704 z[lc++]=" BOOL pahsc_IfInsideCallback; /* Test for reentrancy. */"; 4705 z[lc++]=" short *pahsc_NativeBuffer;"; 4706 z[lc++]=" unsigned int pahsc_BytesPerBuffer; /* native buffer size in bytes */"; 4707 z[lc++]=" double pahsc_ValidFramesWritten;"; 4708 z[lc++]=" int pahsc_FramesPerDSBuffer;"; 4709 z[lc++]="/* For measuring CPU utilization. */"; 4710 z[lc++]=" LARGE_INTEGER pahsc_EntryCount;"; 4711 z[lc++]=" double pahsc_InverseTicksPerUserBuffer;"; 4712 z[lc++]="} PaHostSoundControl;"; 4713 z[lc++]="/************************************************* Shared Data ********/"; 4714 z[lc++]="/* FIXME - put Mutex around this shared data. */"; 4715 z[lc++]="static int sNumDevices = 0;"; 4716 z[lc++]="static int sDeviceIndex = 0;"; 4717 z[lc++]="static internalPortAudioDevice *sDevices = NULL;"; 4718 z[lc++]="static int sDefaultInputDeviceID = paNoDevice;"; 4719 z[lc++]="static int sDefaultOutputDeviceID = paNoDevice;"; 4720 z[lc++]="static int sEnumerationError;"; 4721 z[lc++]="static int sPaHostError = 0;"; 4722 z[lc++]="/************************************************* Prototypes **********/"; 4723 z[lc++]="static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id );"; 4724 z[lc++]="static BOOL CALLBACK Pa_EnumProc(LPGUID lpGUID, "; 4725 z[lc++]=" LPCTSTR lpszDesc,"; 4726 z[lc++]=" LPCTSTR lpszDrvName, "; 4727 z[lc++]=" LPVOID lpContext );"; 4728 z[lc++]="static BOOL CALLBACK Pa_CountDevProc(LPGUID lpGUID, "; 4729 z[lc++]=" LPCTSTR lpszDesc,"; 4730 z[lc++]=" LPCTSTR lpszDrvName, "; 4731 z[lc++]=" LPVOID lpContext );"; 4732 z[lc++]="static Pa_QueryDevices( void );"; 4733 z[lc++]="static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg,"; 4734 z[lc++]=" DWORD dwUser, DWORD dw1, DWORD dw2);"; 4735 z[lc++]="/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/"; 4736 z[lc++]="static void Pa_StartUsageCalculation( internalPortAudioStream *past )"; 4737 z[lc++]="{"; 4738 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 4739 z[lc++]=" if( pahsc == NULL ) return;"; 4740 z[lc++]="/* Query system timer for usage analysis and to prevent overuse of CPU. */"; 4741 z[lc++]=" QueryPerformanceCounter( &pahsc->pahsc_EntryCount );"; 4742 z[lc++]="}"; 4743 z[lc++]="static void Pa_EndUsageCalculation( internalPortAudioStream *past )"; 4744 z[lc++]="{"; 4745 z[lc++]=" LARGE_INTEGER CurrentCount = { 0, 0 };"; 4746 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 4747 z[lc++]=" if( pahsc == NULL ) return;"; 4748 z[lc++]="/*"; 4749 z[lc++]="** Measure CPU utilization during this callback. Note that this calculation"; 4750 z[lc++]="** assumes that we had the processor the whole time."; 4751 z[lc++]="*/"; 4752 z[lc++]="#define LOWPASS_COEFFICIENT_0 (0.9)"; 4753 z[lc++]="#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0)"; 4754 z[lc++]=" if( QueryPerformanceCounter( &CurrentCount ) )"; 4755 z[lc++]=" {"; 4756 z[lc++]=" LONGLONG InsideCount = CurrentCount.QuadPart - pahsc->pahsc_EntryCount.QuadPart; "; 4757 z[lc++]=" double newUsage = InsideCount * pahsc->pahsc_InverseTicksPerUserBuffer;"; 4758 z[lc++]=" past->past_Usage = (LOWPASS_COEFFICIENT_0 * past->past_Usage) +"; 4759 z[lc++]=" (LOWPASS_COEFFICIENT_1 * newUsage);"; 4760 z[lc++]=" }"; 4761 z[lc++]="}"; 4762 z[lc++]="/****************************************** END CPU UTILIZATION *******/"; 4763 z[lc++]="static PaError Pa_QueryDevices( void )"; 4764 z[lc++]="{"; 4765 z[lc++]=" int numBytes;"; 4766 z[lc++]=" sDefaultInputDeviceID = paNoDevice;"; 4767 z[lc++]=" sDefaultOutputDeviceID = paNoDevice;"; 4768 z[lc++]="/* Enumerate once just to count devices. */"; 4769 z[lc++]=" sNumDevices = 0; // for default device"; 4770 z[lc++]=" DirectSoundEnumerate( (LPDSENUMCALLBACK)Pa_CountDevProc, NULL );"; 4771 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 4772 z[lc++]=" DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)Pa_CountDevProc, NULL );"; 4773 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 4774 z[lc++]="/* Allocate structures to hold device info. */"; 4775 z[lc++]=" numBytes = sNumDevices * sizeof(internalPortAudioDevice);"; 4776 z[lc++]=" sDevices = (internalPortAudioDevice *)PaHost_AllocateFastMemory( numBytes ); /* MEM */"; 4777 z[lc++]=" if( sDevices == NULL ) return paInsufficientMemory;"; 4778 z[lc++]="/* Enumerate again to fill in structures. */"; 4779 z[lc++]=" sDeviceIndex = 0;"; 4780 z[lc++]=" sEnumerationError = 0;"; 4781 z[lc++]=" DirectSoundEnumerate( (LPDSENUMCALLBACK)Pa_EnumProc, (void *)0 );"; 4782 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 4783 z[lc++]=" if( sEnumerationError != paNoError ) return sEnumerationError;"; 4784 z[lc++]=" sEnumerationError = 0;"; 4785 z[lc++]=" DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)Pa_EnumProc, (void *)1 );"; 4786 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 4787 z[lc++]=" return sEnumerationError;"; 4788 z[lc++]="}"; 4789 z[lc++]="/************************************************************************************/"; 4790 z[lc++]="long Pa_GetHostError()"; 4791 z[lc++]="{"; 4792 z[lc++]=" return sPaHostError;"; 4793 z[lc++]="}"; 4794 z[lc++]="/************************************************************************************"; 4795 z[lc++]="** Just count devices so we know how much memory to allocate."; 4796 z[lc++]="*/"; 4797 z[lc++]="static BOOL CALLBACK Pa_CountDevProc(LPGUID lpGUID, "; 4798 z[lc++]=" LPCTSTR lpszDesc,"; 4799 z[lc++]=" LPCTSTR lpszDrvName, "; 4800 z[lc++]=" LPVOID lpContext )"; 4801 z[lc++]="{"; 4802 z[lc++]=" sNumDevices++;"; 4803 z[lc++]=" return TRUE;"; 4804 z[lc++]="}"; 4805 z[lc++]="/************************************************************************************"; 4806 z[lc++]="** Extract capabilities info from each device."; 4807 z[lc++]="*/"; 4808 z[lc++]="static BOOL CALLBACK Pa_EnumProc(LPGUID lpGUID, "; 4809 z[lc++]=" LPCTSTR lpszDesc,"; 4810 z[lc++]=" LPCTSTR lpszDrvName, "; 4811 z[lc++]=" LPVOID lpContext )"; 4812 z[lc++]="{"; 4813 z[lc++]=" HRESULT hr;"; 4814 z[lc++]=" LPDIRECTSOUND lpDirectSound;"; 4815 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 4816 z[lc++]=" LPDIRECTSOUNDCAPTURE lpDirectSoundCapture;"; 4817 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 4818 z[lc++]=" int isInput = (int) lpContext; /* Passed from Pa_CountDevices() */"; 4819 z[lc++]=" internalPortAudioDevice *pad;"; 4820 z[lc++]=" "; 4821 z[lc++]=" if( sDeviceIndex >= sNumDevices )"; 4822 z[lc++]=" {"; 4823 z[lc++]=" sEnumerationError = paInternalError;"; 4824 z[lc++]=" return FALSE;"; 4825 z[lc++]=" }"; 4826 z[lc++]=" pad = &sDevices[sDeviceIndex];"; 4827 z[lc++]="/* Copy GUID to static array. Set pointer. */"; 4828 z[lc++]=" if( lpGUID == NULL )"; 4829 z[lc++]=" {"; 4830 z[lc++]=" pad->pad_lpGUID = NULL;"; 4831 z[lc++]=" }"; 4832 z[lc++]=" else"; 4833 z[lc++]=" {"; 4834 z[lc++]=" memcpy( &pad->pad_GUID, lpGUID, sizeof(GUID) );"; 4835 z[lc++]=" pad->pad_lpGUID = &pad->pad_GUID;"; 4836 z[lc++]=" }"; 4837 z[lc++]=" pad->pad_Info.sampleRates = pad->pad_SampleRates; /* Point to array. */"; 4838 z[lc++]="/* Allocate room for descriptive name. */"; 4839 z[lc++]=" if( lpszDesc != NULL )"; 4840 z[lc++]=" {"; 4841 z[lc++]=" int len = strlen(lpszDesc);"; 4842 z[lc++]=" pad->pad_Info.name = (char *)malloc( len+1 );"; 4843 z[lc++]=" if( pad->pad_Info.name == NULL )"; 4844 z[lc++]=" {"; 4845 z[lc++]=" sEnumerationError = paInsufficientMemory;"; 4846 z[lc++]=" return FALSE;"; 4847 z[lc++]=" }"; 4848 z[lc++]=" memcpy( (void *) pad->pad_Info.name, lpszDesc, len+1 );"; 4849 z[lc++]=" }"; 4850 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 4851 z[lc++]=" if( isInput )"; 4852 z[lc++]=" {"; 4853 z[lc++]=" /********** Input ******************************/"; 4854 z[lc++]=" DSCCAPS caps;"; 4855 z[lc++]=" if( lpGUID == NULL ) sDefaultInputDeviceID = sDeviceIndex;"; 4856 z[lc++]=" hr = DirectSoundCaptureCreate( lpGUID, &lpDirectSoundCapture, NULL );"; 4857 z[lc++]=" if( hr != DS_OK )"; 4858 z[lc++]=" {"; 4859 z[lc++]=" pad->pad_Info.maxInputChannels = 0;"; 4860 z[lc++]=" DBUG((\"Cannot create Capture for %s. Result = 0x%x\\n\", lpszDesc, hr ));"; 4861 z[lc++]=" }"; 4862 z[lc++]=" else"; 4863 z[lc++]=" {"; 4864 z[lc++]=" /* Query device characteristics. */"; 4865 z[lc++]=" caps.dwSize = sizeof(caps);"; 4866 z[lc++]=" IDirectSoundCapture_GetCaps( lpDirectSoundCapture, &caps );"; 4867 z[lc++]=" /* printf(\"caps.dwFormats = 0x%x\\n\", caps.dwFormats ); */"; 4868 z[lc++]=" pad->pad_Info.maxInputChannels = caps.dwChannels;"; 4869 z[lc++]=" /* Determine sample rates from flags. */"; 4870 z[lc++]=" if( caps.dwChannels == 2 )"; 4871 z[lc++]=" {"; 4872 z[lc++]=" int index = 0;"; 4873 z[lc++]=" if( caps.dwFormats & WAVE_FORMAT_1S16) pad->pad_SampleRates[index++] = 11025.0;"; 4874 z[lc++]=" if( caps.dwFormats & WAVE_FORMAT_2S16) pad->pad_SampleRates[index++] = 22050.0;"; 4875 z[lc++]=" if( caps.dwFormats & WAVE_FORMAT_4S16) pad->pad_SampleRates[index++] = 44100.0;"; 4876 z[lc++]=" pad->pad_Info.numSampleRates = index;"; 4877 z[lc++]=" }"; 4878 z[lc++]=" else if( caps.dwChannels == 1 )"; 4879 z[lc++]=" {"; 4880 z[lc++]=" int index = 0;"; 4881 z[lc++]=" if( caps.dwFormats & WAVE_FORMAT_1M16) pad->pad_SampleRates[index++] = 11025.0;"; 4882 z[lc++]=" if( caps.dwFormats & WAVE_FORMAT_2M16) pad->pad_SampleRates[index++] = 22050.0;"; 4883 z[lc++]=" if( caps.dwFormats & WAVE_FORMAT_4M16) pad->pad_SampleRates[index++] = 44100.0;"; 4884 z[lc++]=" pad->pad_Info.numSampleRates = index;"; 4885 z[lc++]=" }"; 4886 z[lc++]=" else pad->pad_Info.numSampleRates = 0;"; 4887 z[lc++]=" IDirectSoundCapture_Release( lpDirectSoundCapture );"; 4888 z[lc++]=" }"; 4889 z[lc++]=" }"; 4890 z[lc++]=" else"; 4891 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 4892 z[lc++]=" {"; 4893 z[lc++]=" /********** Output ******************************/"; 4894 z[lc++]=" DSCAPS caps;"; 4895 z[lc++]=" if( lpGUID == NULL ) sDefaultOutputDeviceID = sDeviceIndex;"; 4896 z[lc++]=" /* Create interfaces for each object. */"; 4897 z[lc++]=" hr = DirectSoundCreate( lpGUID, &lpDirectSound, NULL );"; 4898 z[lc++]=" if( hr != DS_OK )"; 4899 z[lc++]=" {"; 4900 z[lc++]=" pad->pad_Info.maxOutputChannels = 0;"; 4901 z[lc++]=" DBUG((\"Cannot create dsound for %s. Result = 0x%x\\n\", lpszDesc, hr ));"; 4902 z[lc++]=" }"; 4903 z[lc++]=" else"; 4904 z[lc++]=" {"; 4905 z[lc++]=" /* Query device characteristics. */"; 4906 z[lc++]=" caps.dwSize = sizeof(caps);"; 4907 z[lc++]=" IDirectSound_GetCaps( lpDirectSound, &caps );"; 4908 z[lc++]=" pad->pad_Info.maxOutputChannels = ( caps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1;"; 4909 z[lc++]=" /* Get sample rates. */"; 4910 z[lc++]=" pad->pad_SampleRates[0] = (double) caps.dwMinSecondarySampleRate;"; 4911 z[lc++]=" pad->pad_SampleRates[1] = (double) caps.dwMaxSecondarySampleRate;"; 4912 z[lc++]=" if( caps.dwFlags & DSCAPS_CONTINUOUSRATE ) pad->pad_Info.numSampleRates = -1;"; 4913 z[lc++]=" else if( caps.dwMinSecondarySampleRate == caps.dwMaxSecondarySampleRate )"; 4914 z[lc++]=" {"; 4915 z[lc++]=" if( caps.dwMinSecondarySampleRate == 0 )"; 4916 z[lc++]=" {"; 4917 z[lc++]=" /*"; 4918 z[lc++]=" ** On my Thinkpad 380Z, DirectSoundV6 returns min-max=0 !!"; 4919 z[lc++]=" ** But it supports continuous sampling."; 4920 z[lc++]=" ** So fake range of rates, and hope it really supports it."; 4921 z[lc++]=" */"; 4922 z[lc++]=" pad->pad_SampleRates[0] = 11025.0f;"; 4923 z[lc++]=" pad->pad_SampleRates[1] = 48000.0f;"; 4924 z[lc++]=" pad->pad_Info.numSampleRates = -1; /* continuous range */"; 4925 z[lc++]=" "; 4926 z[lc++]=" DBUG((\"PA - Reported rates both zero. Setting to fake values for device #%d\\n\", sDeviceIndex ));"; 4927 z[lc++]=" }"; 4928 z[lc++]=" else"; 4929 z[lc++]=" {"; 4930 z[lc++]=" pad->pad_Info.numSampleRates = 1;"; 4931 z[lc++]=" }"; 4932 z[lc++]=" }"; 4933 z[lc++]=" else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) )"; 4934 z[lc++]=" {"; 4935 z[lc++]=" /* The EWS88MT drivers lie, lie, lie. The say they only support two rates, 100 & 100000."; 4936 z[lc++]=" ** But we know that they really support a range of rates!"; 4937 z[lc++]=" ** So when we see a ridiculous set of rates, assume it is a range."; 4938 z[lc++]=" */"; 4939 z[lc++]=" pad->pad_Info.numSampleRates = -1;"; 4940 z[lc++]=" DBUG((\"PA - Sample rate range used instead of two odd values for device #%d\\n\", sDeviceIndex ));"; 4941 z[lc++]=" }"; 4942 z[lc++]=" else pad->pad_Info.numSampleRates = 2;"; 4943 z[lc++]=" IDirectSound_Release( lpDirectSound );"; 4944 z[lc++]=" }"; 4945 z[lc++]=" }"; 4946 z[lc++]=" pad->pad_Info.nativeSampleFormats = paInt16;"; 4947 z[lc++]=" sDeviceIndex++;"; 4948 z[lc++]=" return( TRUE );"; 4949 z[lc++]="}"; 4950 z[lc++]="/*************************************************************************/"; 4951 z[lc++]="int Pa_CountDevices()"; 4952 z[lc++]="{"; 4953 z[lc++]=" if( sNumDevices <= 0 ) Pa_Initialize();"; 4954 z[lc++]=" return sNumDevices;"; 4955 z[lc++]="}"; 4956 z[lc++]="static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id )"; 4957 z[lc++]="{"; 4958 z[lc++]=" if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;"; 4959 z[lc++]=" return &sDevices[id];"; 4960 z[lc++]="}"; 4961 z[lc++]="/*************************************************************************/"; 4962 z[lc++]="const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id )"; 4963 z[lc++]="{"; 4964 z[lc++]=" internalPortAudioDevice *pad;"; 4965 z[lc++]=" if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;"; 4966 z[lc++]=" pad = Pa_GetInternalDevice( id );"; 4967 z[lc++]=" return &pad->pad_Info ;"; 4968 z[lc++]="}"; 4969 z[lc++]="static PaError Pa_MaybeQueryDevices( void )"; 4970 z[lc++]="{"; 4971 z[lc++]=" if( sNumDevices == 0 )"; 4972 z[lc++]=" {"; 4973 z[lc++]=" return Pa_QueryDevices();"; 4974 z[lc++]=" }"; 4975 z[lc++]=" return 0;"; 4976 z[lc++]="}"; 4977 z[lc++]="/*************************************************************************"; 4978 z[lc++]="** Returns recommended device ID."; 4979 z[lc++]="** On the PC, the recommended device can be specified by the user by"; 4980 z[lc++]="** setting an environment variable. For example, to use device #1."; 4981 z[lc++]="**"; 4982 z[lc++]="** set PA_RECOMMENDED_OUTPUT_DEVICE=1"; 4983 z[lc++]="**"; 4984 z[lc++]="** The user should first determine the available device ID by using"; 4985 z[lc++]="** the supplied application \"pa_devs\"."; 4986 z[lc++]="*/"; 4987 z[lc++]="#define PA_ENV_BUF_SIZE (32)"; 4988 z[lc++]="#define PA_REC_IN_DEV_ENV_NAME (\"PA_RECOMMENDED_INPUT_DEVICE\")"; 4989 z[lc++]="#define PA_REC_OUT_DEV_ENV_NAME (\"PA_RECOMMENDED_OUTPUT_DEVICE\")"; 4990 z[lc++]="static PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName )"; 4991 z[lc++]="{"; 4992 z[lc++]=" DWORD hresult;"; 4993 z[lc++]=" char envbuf[PA_ENV_BUF_SIZE];"; 4994 z[lc++]=" PaDeviceID recommendedID = paNoDevice;"; 4995 z[lc++]="/* Let user determine default device by setting environment variable. */"; 4996 z[lc++]=" hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE );"; 4997 z[lc++]=" if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )"; 4998 z[lc++]=" {"; 4999 z[lc++]=" recommendedID = atoi( envbuf );"; 5000 z[lc++]=" }"; 5001 z[lc++]=" return recommendedID;"; 5002 z[lc++]="}"; 5003 z[lc++]="PaDeviceID Pa_GetDefaultInputDeviceID( void )"; 5004 z[lc++]="{"; 5005 z[lc++]=" PaError result;"; 5006 z[lc++]=" result = PaHost_GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME );"; 5007 z[lc++]=" if( result < 0 )"; 5008 z[lc++]=" {"; 5009 z[lc++]=" result = Pa_MaybeQueryDevices();"; 5010 z[lc++]=" if( result < 0 ) return result;"; 5011 z[lc++]=" result = sDefaultInputDeviceID;"; 5012 z[lc++]=" }"; 5013 z[lc++]=" return result;"; 5014 z[lc++]="}"; 5015 z[lc++]="PaDeviceID Pa_GetDefaultOutputDeviceID( void )"; 5016 z[lc++]="{"; 5017 z[lc++]=" PaError result;"; 5018 z[lc++]=" result = PaHost_GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME );"; 5019 z[lc++]=" if( result < 0 )"; 5020 z[lc++]=" {"; 5021 z[lc++]=" result = Pa_MaybeQueryDevices();"; 5022 z[lc++]=" if( result < 0 ) return result;"; 5023 z[lc++]=" result = sDefaultOutputDeviceID;"; 5024 z[lc++]=" }"; 5025 z[lc++]=" return result;"; 5026 z[lc++]="}"; 5027 z[lc++]="/**********************************************************************"; 5028 z[lc++]="** Make sure that we have queried the device capabilities."; 5029 z[lc++]="*/"; 5030 z[lc++]="PaError PaHost_Init( void )"; 5031 z[lc++]="{"; 5032 z[lc++]="#if PA_SIMULATE_UNDERFLOW"; 5033 z[lc++]=" PRINT((\"WARNING - Underflow Simulation Enabled - Expect a Big Glitch!!!\\n\"));"; 5034 z[lc++]="#endif"; 5035 z[lc++]=" return Pa_MaybeQueryDevices();"; 5036 z[lc++]="}"; 5037 z[lc++]="static PaError Pa_TimeSlice( internalPortAudioStream *past )"; 5038 z[lc++]="{"; 5039 z[lc++]=" PaError result = 0;"; 5040 z[lc++]=" long bytesEmpty = 0;"; 5041 z[lc++]=" long bytesFilled = 0;"; 5042 z[lc++]=" long bytesToXfer = 0;"; 5043 z[lc++]=" long numChunks;"; 5044 z[lc++]=" HRESULT hresult;"; 5045 z[lc++]=" PaHostSoundControl *pahsc;"; 5046 z[lc++]=" short *nativeBufPtr;"; 5047 z[lc++]=" past->past_NumCallbacks += 1;"; 5048 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 5049 z[lc++]=" if( pahsc == NULL ) return paInternalError;"; 5050 z[lc++]="/* How much input data is available? */"; 5051 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 5052 z[lc++]=" if( past->past_NumInputChannels > 0 )"; 5053 z[lc++]=" {"; 5054 z[lc++]=" DSW_QueryInputFilled( &pahsc->pahsc_DSoundWrapper, &bytesFilled );"; 5055 z[lc++]=" bytesToXfer = bytesFilled;"; 5056 z[lc++]=" }"; 5057 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 5058 z[lc++]="/* How much output room is available? */"; 5059 z[lc++]=" if( past->past_NumOutputChannels > 0 )"; 5060 z[lc++]=" {"; 5061 z[lc++]=" DSW_QueryOutputSpace( &pahsc->pahsc_DSoundWrapper, &bytesEmpty );"; 5062 z[lc++]=" bytesToXfer = bytesEmpty;"; 5063 z[lc++]=" }"; 5064 z[lc++]=" AddTraceMessage( \"bytesEmpty \", bytesEmpty );"; 5065 z[lc++]="/* Choose smallest value if both are active. */"; 5066 z[lc++]=" if( (past->past_NumInputChannels > 0) && (past->past_NumOutputChannels > 0) )"; 5067 z[lc++]=" {"; 5068 z[lc++]=" bytesToXfer = ( bytesFilled < bytesEmpty ) ? bytesFilled : bytesEmpty;"; 5069 z[lc++]=" }"; 5070 z[lc++]="/* printf(\"bytesFilled = %d, bytesEmpty = %d, bytesToXfer = %d\\n\","; 5071 z[lc++]=" bytesFilled, bytesEmpty, bytesToXfer);"; 5072 z[lc++]="*/"; 5073 z[lc++]="/* Quantize to multiples of a buffer. */"; 5074 z[lc++]=" numChunks = bytesToXfer / pahsc->pahsc_BytesPerBuffer;"; 5075 z[lc++]=" if( numChunks > (long)(past->past_NumUserBuffers/2) )"; 5076 z[lc++]=" {"; 5077 z[lc++]=" numChunks = (long)past->past_NumUserBuffers/2;"; 5078 z[lc++]=" }"; 5079 z[lc++]=" else if( numChunks < 0 )"; 5080 z[lc++]=" {"; 5081 z[lc++]=" numChunks = 0;"; 5082 z[lc++]=" }"; 5083 z[lc++]=" AddTraceMessage( \"numChunks \", numChunks );"; 5084 z[lc++]=" nativeBufPtr = pahsc->pahsc_NativeBuffer;"; 5085 z[lc++]=" if( numChunks > 0 )"; 5086 z[lc++]=" {"; 5087 z[lc++]=" while( numChunks-- > 0 )"; 5088 z[lc++]=" {"; 5089 z[lc++]=" /* Measure usage based on time to process one user buffer. */"; 5090 z[lc++]=" Pa_StartUsageCalculation( past );"; 5091 z[lc++]=" #if SUPPORT_AUDIO_CAPTURE"; 5092 z[lc++]=" /* Get native data from DirectSound. */"; 5093 z[lc++]=" if( past->past_NumInputChannels > 0 )"; 5094 z[lc++]=" {"; 5095 z[lc++]=" hresult = DSW_ReadBlock( &pahsc->pahsc_DSoundWrapper, (char *) nativeBufPtr, pahsc->pahsc_BytesPerBuffer );"; 5096 z[lc++]=" if( hresult < 0 )"; 5097 z[lc++]=" {"; 5098 z[lc++]=" ERR_RPT((\"DirectSound ReadBlock failed, hresult = 0x%x\\n\",hresult));"; 5099 z[lc++]=" sPaHostError = hresult;"; 5100 z[lc++]=" break;"; 5101 z[lc++]=" }"; 5102 z[lc++]=" }"; 5103 z[lc++]=" #endif /* SUPPORT_AUDIO_CAPTURE */"; 5104 z[lc++]=" /* Convert 16 bit native data to user data and call user routine. */"; 5105 z[lc++]=" result = Pa_CallConvertInt16( past, nativeBufPtr, nativeBufPtr );"; 5106 z[lc++]=" if( result != 0) break;"; 5107 z[lc++]=" /* Pass native data to DirectSound. */"; 5108 z[lc++]=" if( past->past_NumOutputChannels > 0 )"; 5109 z[lc++]=" {"; 5110 z[lc++]=" /* static short DEBUGHACK = 0;"; 5111 z[lc++]=" DEBUGHACK += 0x0049;"; 5112 z[lc++]=" nativeBufPtr[0] = DEBUGHACK; /* Make buzz to see if DirectSound still running. */"; 5113 z[lc++]=" hresult = DSW_WriteBlock( &pahsc->pahsc_DSoundWrapper, (char *) nativeBufPtr, pahsc->pahsc_BytesPerBuffer );"; 5114 z[lc++]=" if( hresult < 0 )"; 5115 z[lc++]=" {"; 5116 z[lc++]=" ERR_RPT((\"DirectSound WriteBlock failed, result = 0x%x\\n\",hresult));"; 5117 z[lc++]=" sPaHostError = hresult;"; 5118 z[lc++]=" break;"; 5119 z[lc++]=" }"; 5120 z[lc++]=" }"; 5121 z[lc++]=" Pa_EndUsageCalculation( past );"; 5122 z[lc++]=" }"; 5123 z[lc++]=" }"; 5124 z[lc++]=" return result;"; 5125 z[lc++]="}"; 5126 z[lc++]="/*******************************************************************/"; 5127 z[lc++]="static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)"; 5128 z[lc++]="{"; 5129 z[lc++]=" internalPortAudioStream *past;"; 5130 z[lc++]=" PaHostSoundControl *pahsc;"; 5131 z[lc++]="#if PA_SIMULATE_UNDERFLOW"; 5132 z[lc++]=" gUnderCallbackCounter++;"; 5133 z[lc++]=" if( (gUnderCallbackCounter >= UNDER_START_GAP) &&"; 5134 z[lc++]=" (gUnderCallbackCounter <= UNDER_STOP_GAP) )"; 5135 z[lc++]=" {"; 5136 z[lc++]=" if( gUnderCallbackCounter == UNDER_START_GAP)"; 5137 z[lc++]=" {"; 5138 z[lc++]=" AddTraceMessage(\"Begin stall: gUnderCallbackCounter =======\", gUnderCallbackCounter );"; 5139 z[lc++]=" }"; 5140 z[lc++]=" if( gUnderCallbackCounter == UNDER_STOP_GAP)"; 5141 z[lc++]=" {"; 5142 z[lc++]=" AddTraceMessage(\"End stall: gUnderCallbackCounter =======\", gUnderCallbackCounter );"; 5143 z[lc++]=" }"; 5144 z[lc++]=" return;"; 5145 z[lc++]=" }"; 5146 z[lc++]="#endif"; 5147 z[lc++]=" past = (internalPortAudioStream *) dwUser;"; 5148 z[lc++]=" if( past == NULL ) return;"; 5149 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 5150 z[lc++]=" if( pahsc == NULL ) return;"; 5151 z[lc++]=" if( !pahsc->pahsc_IfInsideCallback && past->past_IsActive )"; 5152 z[lc++]=" {"; 5153 z[lc++]=" if( past->past_StopNow )"; 5154 z[lc++]=" {"; 5155 z[lc++]=" past->past_IsActive = 0;"; 5156 z[lc++]=" }"; 5157 z[lc++]=" else if( past->past_StopSoon )"; 5158 z[lc++]=" {"; 5159 z[lc++]=" DSoundWrapper *dsw = &pahsc->pahsc_DSoundWrapper;"; 5160 z[lc++]=" if( past->past_NumOutputChannels > 0 )"; 5161 z[lc++]=" {"; 5162 z[lc++]=" DSW_ZeroEmptySpace( dsw ); "; 5163 z[lc++]=" AddTraceMessage(\"Pa_TimerCallback: waiting - written \", (int) dsw->dsw_FramesWritten );"; 5164 z[lc++]=" AddTraceMessage(\"Pa_TimerCallback: waiting - played \", (int) dsw->dsw_FramesPlayed );"; 5165 z[lc++]=" /* clear past_IsActive when all sound played */"; 5166 z[lc++]=" if( dsw->dsw_FramesPlayed >= past->past_FrameCount )"; 5167 z[lc++]=" {"; 5168 z[lc++]=" past->past_IsActive = 0;"; 5169 z[lc++]=" }"; 5170 z[lc++]=" }"; 5171 z[lc++]=" else"; 5172 z[lc++]=" {"; 5173 z[lc++]=" past->past_IsActive = 0;"; 5174 z[lc++]=" }"; 5175 z[lc++]=" }"; 5176 z[lc++]=" else"; 5177 z[lc++]=" {"; 5178 z[lc++]=" pahsc->pahsc_IfInsideCallback = 1;"; 5179 z[lc++]=" if( Pa_TimeSlice( past ) != 0) /* Call time slice independant of timing method. */"; 5180 z[lc++]=" {"; 5181 z[lc++]=" past->past_StopSoon = 1;"; 5182 z[lc++]=" }"; 5183 z[lc++]=" pahsc->pahsc_IfInsideCallback = 0;"; 5184 z[lc++]=" }"; 5185 z[lc++]=" }"; 5186 z[lc++]="}"; 5187 z[lc++]="/*******************************************************************/"; 5188 z[lc++]="PaError PaHost_OpenStream( internalPortAudioStream *past )"; 5189 z[lc++]="{"; 5190 z[lc++]=" HRESULT hr;"; 5191 z[lc++]=" PaError result = paNoError;"; 5192 z[lc++]=" PaHostSoundControl *pahsc;"; 5193 z[lc++]=" int numBytes, maxChannels;"; 5194 z[lc++]=" unsigned int minNumBuffers;"; 5195 z[lc++]=" internalPortAudioDevice *pad;"; 5196 z[lc++]=" DSoundWrapper *dsw;"; 5197 z[lc++]="/* Allocate and initialize host data. */"; 5198 z[lc++]=" pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); /* MEM */"; 5199 z[lc++]=" if( pahsc == NULL )"; 5200 z[lc++]=" {"; 5201 z[lc++]=" result = paInsufficientMemory;"; 5202 z[lc++]=" goto error;"; 5203 z[lc++]=" }"; 5204 z[lc++]=" memset( pahsc, 0, sizeof(PaHostSoundControl) );"; 5205 z[lc++]=" past->past_DeviceData = (void *) pahsc;"; 5206 z[lc++]=" pahsc->pahsc_TimerID = 0;"; 5207 z[lc++]=" dsw = &pahsc->pahsc_DSoundWrapper;"; 5208 z[lc++]=" DSW_Init( dsw );"; 5209 z[lc++]="/* Allocate native buffer. */"; 5210 z[lc++]=" maxChannels = ( past->past_NumOutputChannels > past->past_NumInputChannels ) ?"; 5211 z[lc++]=" past->past_NumOutputChannels : past->past_NumInputChannels;"; 5212 z[lc++]=" pahsc->pahsc_BytesPerBuffer = past->past_FramesPerUserBuffer * maxChannels * sizeof(short);"; 5213 z[lc++]=" if( maxChannels > 0 )"; 5214 z[lc++]=" {"; 5215 z[lc++]=" pahsc->pahsc_NativeBuffer = (short *) PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerBuffer); /* MEM */"; 5216 z[lc++]=" if( pahsc->pahsc_NativeBuffer == NULL )"; 5217 z[lc++]=" {"; 5218 z[lc++]=" result = paInsufficientMemory;"; 5219 z[lc++]=" goto error;"; 5220 z[lc++]=" }"; 5221 z[lc++]=" }"; 5222 z[lc++]=" else"; 5223 z[lc++]=" {"; 5224 z[lc++]=" result = paInvalidChannelCount;"; 5225 z[lc++]=" goto error;"; 5226 z[lc++]=" }"; 5227 z[lc++]=" "; 5228 z[lc++]=" DBUG((\"PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\\n\", pahsc->pahsc_MinFramesPerHostBuffer ));"; 5229 z[lc++]=" minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );"; 5230 z[lc++]=" past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;"; 5231 z[lc++]=" numBytes = pahsc->pahsc_BytesPerBuffer * past->past_NumUserBuffers;"; 5232 z[lc++]=" if( numBytes < DSBSIZE_MIN )"; 5233 z[lc++]=" {"; 5234 z[lc++]=" result = paBufferTooSmall;"; 5235 z[lc++]=" goto error;"; 5236 z[lc++]=" }"; 5237 z[lc++]=" if( numBytes > DSBSIZE_MAX )"; 5238 z[lc++]=" {"; 5239 z[lc++]=" result = paBufferTooBig;"; 5240 z[lc++]=" goto error;"; 5241 z[lc++]=" }"; 5242 z[lc++]=" pahsc->pahsc_FramesPerDSBuffer = past->past_FramesPerUserBuffer * past->past_NumUserBuffers;"; 5243 z[lc++]=" {"; 5244 z[lc++]=" int msecLatency = (int) ((pahsc->pahsc_FramesPerDSBuffer * 1000) / past->past_SampleRate);"; 5245 z[lc++]=" PRINT((\"PortAudio on DirectSound - Latency = %d frames, %d msec\\n\", pahsc->pahsc_FramesPerDSBuffer, msecLatency ));"; 5246 z[lc++]=" }"; 5247 z[lc++]="/* ------------------ OUTPUT */"; 5248 z[lc++]=" if( (past->past_OutputDeviceID >= 0) && (past->past_NumOutputChannels > 0) )"; 5249 z[lc++]=" {"; 5250 z[lc++]=" DBUG((\"PaHost_OpenStream: deviceID = 0x%x\\n\", past->past_OutputDeviceID));"; 5251 z[lc++]=" pad = Pa_GetInternalDevice( past->past_OutputDeviceID );"; 5252 z[lc++]=" hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound, NULL );"; 5253 z[lc++]="/* If this fails, then try each output device until we find one that works. */"; 5254 z[lc++]=" if( hr != DS_OK )"; 5255 z[lc++]=" {"; 5256 z[lc++]=" int i;"; 5257 z[lc++]=" ERR_RPT((\"Creation of requested Audio Output device '%s' failed.\\n\","; 5258 z[lc++]=" ((pad->pad_lpGUID == NULL) ? \"Default\" : pad->pad_Info.name) ));"; 5259 z[lc++]=" for( i=0; i<Pa_CountDevices(); i++ )"; 5260 z[lc++]=" {"; 5261 z[lc++]=" pad = Pa_GetInternalDevice( i );"; 5262 z[lc++]=" if( pad->pad_Info.maxOutputChannels >= past->past_NumOutputChannels )"; 5263 z[lc++]=" {"; 5264 z[lc++]=" DBUG((\"Try device '%s' instead.\\n\", pad->pad_Info.name ));"; 5265 z[lc++]=" hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound, NULL );"; 5266 z[lc++]=" if( hr == DS_OK )"; 5267 z[lc++]=" {"; 5268 z[lc++]=" ERR_RPT((\"Using device '%s' instead.\\n\", pad->pad_Info.name ));"; 5269 z[lc++]=" break;"; 5270 z[lc++]=" }"; 5271 z[lc++]=" }"; 5272 z[lc++]=" }"; 5273 z[lc++]=" }"; 5274 z[lc++]=" if( hr != DS_OK )"; 5275 z[lc++]=" {"; 5276 z[lc++]=" ERR_RPT((\"PortAudio: DirectSoundCreate() failed!\\n\"));"; 5277 z[lc++]=" result = paHostError;"; 5278 z[lc++]=" sPaHostError = hr;"; 5279 z[lc++]=" goto error;"; 5280 z[lc++]=" }"; 5281 z[lc++]=" hr = DSW_InitOutputBuffer( dsw,"; 5282 z[lc++]=" (unsigned long) (past->past_SampleRate + 0.5),"; 5283 z[lc++]=" past->past_NumOutputChannels, numBytes );"; 5284 z[lc++]=" DBUG((\"DSW_InitOutputBuffer() returns %x\\n\", hr));"; 5285 z[lc++]=" if( hr != DS_OK )"; 5286 z[lc++]=" {"; 5287 z[lc++]=" result = paHostError;"; 5288 z[lc++]=" sPaHostError = hr;"; 5289 z[lc++]=" goto error;"; 5290 z[lc++]=" }"; 5291 z[lc++]=" past->past_FrameCount = pahsc->pahsc_DSoundWrapper.dsw_FramesWritten;"; 5292 z[lc++]=" }"; 5293 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 5294 z[lc++]="/* ------------------ INPUT */"; 5295 z[lc++]=" if( (past->past_InputDeviceID >= 0) && (past->past_NumInputChannels > 0) )"; 5296 z[lc++]=" {"; 5297 z[lc++]=" pad = Pa_GetInternalDevice( past->past_InputDeviceID );"; 5298 z[lc++]=" hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture, NULL );"; 5299 z[lc++]="/* If this fails, then try each input device until we find one that works. */"; 5300 z[lc++]=" if( hr != DS_OK )"; 5301 z[lc++]=" {"; 5302 z[lc++]=" int i;"; 5303 z[lc++]=" ERR_RPT((\"Creation of requested Audio Capture device '%s' failed.\\n\","; 5304 z[lc++]=" ((pad->pad_lpGUID == NULL) ? \"Default\" : pad->pad_Info.name) ));"; 5305 z[lc++]=" for( i=0; i<Pa_CountDevices(); i++ )"; 5306 z[lc++]=" {"; 5307 z[lc++]=" pad = Pa_GetInternalDevice( i );"; 5308 z[lc++]=" if( pad->pad_Info.maxInputChannels >= past->past_NumInputChannels )"; 5309 z[lc++]=" {"; 5310 z[lc++]=" PRINT((\"Try device '%s' instead.\\n\", pad->pad_Info.name ));"; 5311 z[lc++]=" hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture, NULL );"; 5312 z[lc++]=" if( hr == DS_OK ) break;"; 5313 z[lc++]=" }"; 5314 z[lc++]=" }"; 5315 z[lc++]=" }"; 5316 z[lc++]=" if( hr != DS_OK )"; 5317 z[lc++]=" {"; 5318 z[lc++]=" ERR_RPT((\"PortAudio: DirectSoundCaptureCreate() failed!\\n\"));"; 5319 z[lc++]=" result = paHostError;"; 5320 z[lc++]=" sPaHostError = hr;"; 5321 z[lc++]=" goto error;"; 5322 z[lc++]=" }"; 5323 z[lc++]=" hr = DSW_InitInputBuffer( dsw,"; 5324 z[lc++]=" (unsigned long) (past->past_SampleRate + 0.5),"; 5325 z[lc++]=" past->past_NumInputChannels, numBytes );"; 5326 z[lc++]=" DBUG((\"DSW_InitInputBuffer() returns %x\\n\", hr));"; 5327 z[lc++]=" if( hr != DS_OK )"; 5328 z[lc++]=" {"; 5329 z[lc++]=" ERR_RPT((\"PortAudio: DSW_InitInputBuffer() returns %x\\n\", hr));"; 5330 z[lc++]=" result = paHostError;"; 5331 z[lc++]=" sPaHostError = hr;"; 5332 z[lc++]=" goto error;"; 5333 z[lc++]=" }"; 5334 z[lc++]=" }"; 5335 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 5336 z[lc++]=" /* Calculate scalar used in CPULoad calculation. */ "; 5337 z[lc++]=" {"; 5338 z[lc++]=" LARGE_INTEGER frequency;"; 5339 z[lc++]=" if( QueryPerformanceFrequency( &frequency ) == 0 )"; 5340 z[lc++]=" {"; 5341 z[lc++]=" pahsc->pahsc_InverseTicksPerUserBuffer = 0.0;"; 5342 z[lc++]=" }"; 5343 z[lc++]=" else"; 5344 z[lc++]=" {"; 5345 z[lc++]=" pahsc->pahsc_InverseTicksPerUserBuffer = past->past_SampleRate /"; 5346 z[lc++]=" ( (double)frequency.QuadPart * past->past_FramesPerUserBuffer );"; 5347 z[lc++]=" DBUG((\"pahsc_InverseTicksPerUserBuffer = %g\\n\", pahsc->pahsc_InverseTicksPerUserBuffer ));"; 5348 z[lc++]=" }"; 5349 z[lc++]=" }"; 5350 z[lc++]=" return result;"; 5351 z[lc++]="error:"; 5352 z[lc++]=" PaHost_CloseStream( past );"; 5353 z[lc++]=" return result;"; 5354 z[lc++]="}"; 5355 z[lc++]="/*************************************************************************/"; 5356 z[lc++]="PaError PaHost_StartOutput( internalPortAudioStream *past )"; 5357 z[lc++]="{"; 5358 z[lc++]=" HRESULT hr;"; 5359 z[lc++]=" PaHostSoundControl *pahsc;"; 5360 z[lc++]=" PaError result = paNoError;"; 5361 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 5362 z[lc++]="/* Give user callback a chance to pre-fill buffer. */"; 5363 z[lc++]=" result = Pa_TimeSlice( past );"; 5364 z[lc++]=" if( result != paNoError ) return result; // FIXME - what if finished?"; 5365 z[lc++]=" hr = DSW_StartOutput( &pahsc->pahsc_DSoundWrapper );"; 5366 z[lc++]=" DBUG((\"PaHost_StartOutput: DSW_StartOutput returned = 0x%X.\\n\", hr));"; 5367 z[lc++]=" if( hr != DS_OK )"; 5368 z[lc++]=" {"; 5369 z[lc++]=" result = paHostError;"; 5370 z[lc++]=" sPaHostError = hr;"; 5371 z[lc++]=" goto error;"; 5372 z[lc++]=" }"; 5373 z[lc++]="error:"; 5374 z[lc++]=" return result;"; 5375 z[lc++]="}"; 5376 z[lc++]="/*************************************************************************/"; 5377 z[lc++]="PaError PaHost_StartInput( internalPortAudioStream *past )"; 5378 z[lc++]="{"; 5379 z[lc++]=" PaError result = paNoError;"; 5380 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 5381 z[lc++]=" HRESULT hr;"; 5382 z[lc++]=" PaHostSoundControl *pahsc;"; 5383 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 5384 z[lc++]=" hr = DSW_StartInput( &pahsc->pahsc_DSoundWrapper );"; 5385 z[lc++]=" DBUG((\"Pa_StartStream: DSW_StartInput returned = 0x%X.\\n\", hr));"; 5386 z[lc++]=" if( hr != DS_OK )"; 5387 z[lc++]=" {"; 5388 z[lc++]=" result = paHostError;"; 5389 z[lc++]=" sPaHostError = hr;"; 5390 z[lc++]=" goto error;"; 5391 z[lc++]=" }"; 5392 z[lc++]="error:"; 5393 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 5394 z[lc++]=" return result;"; 5395 z[lc++]="}"; 5396 z[lc++]="/*************************************************************************/"; 5397 z[lc++]="PaError PaHost_StartEngine( internalPortAudioStream *past )"; 5398 z[lc++]="{"; 5399 z[lc++]=" PaHostSoundControl *pahsc;"; 5400 z[lc++]=" PaError result = paNoError;"; 5401 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 5402 z[lc++]=" past->past_StopNow = 0;"; 5403 z[lc++]=" past->past_StopSoon = 0;"; 5404 z[lc++]=" past->past_IsActive = 1;"; 5405 z[lc++]="/* Create timer that will wake us up so we can fill the DSound buffer. */"; 5406 z[lc++]=" {"; 5407 z[lc++]=" int msecPerBuffer;"; 5408 z[lc++]=" int resolution;"; 5409 z[lc++]=" int bufsPerInterrupt = past->past_NumUserBuffers/4;"; 5410 z[lc++]=" if( bufsPerInterrupt < 1 ) bufsPerInterrupt = 1;"; 5411 z[lc++]=" msecPerBuffer = 1000 * (bufsPerInterrupt * past->past_FramesPerUserBuffer) / (int) past->past_SampleRate;"; 5412 z[lc++]=" if( msecPerBuffer < 10 ) msecPerBuffer = 10;"; 5413 z[lc++]=" else if( msecPerBuffer > 100 ) msecPerBuffer = 100;"; 5414 z[lc++]=" resolution = msecPerBuffer/4;"; 5415 z[lc++]=" pahsc->pahsc_TimerID = timeSetEvent( msecPerBuffer, resolution, (LPTIMECALLBACK) Pa_TimerCallback,"; 5416 z[lc++]=" (DWORD) past, TIME_PERIODIC );"; 5417 z[lc++]=" }"; 5418 z[lc++]=" if( pahsc->pahsc_TimerID == 0 )"; 5419 z[lc++]=" {"; 5420 z[lc++]=" past->past_IsActive = 0;"; 5421 z[lc++]=" result = paHostError;"; 5422 z[lc++]=" sPaHostError = 0;"; 5423 z[lc++]=" goto error;"; 5424 z[lc++]=" }"; 5425 z[lc++]="error:"; 5426 z[lc++]=" return result;"; 5427 z[lc++]="}"; 5428 z[lc++]="/*************************************************************************/"; 5429 z[lc++]="PaError PaHost_StopEngine( internalPortAudioStream *past, int abort )"; 5430 z[lc++]="{"; 5431 z[lc++]=" int timeoutMsec;"; 5432 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 5433 z[lc++]=" if( pahsc == NULL ) return paNoError;"; 5434 z[lc++]=" if( abort ) past->past_StopNow = 1;"; 5435 z[lc++]=" past->past_StopSoon = 1;"; 5436 z[lc++]="/* Set timeout at 20% beyond maximum time we might wait. */"; 5437 z[lc++]=" timeoutMsec = (int) (1200.0 * pahsc->pahsc_FramesPerDSBuffer / past->past_SampleRate);"; 5438 z[lc++]=" while( past->past_IsActive && (timeoutMsec > 0) )"; 5439 z[lc++]=" {"; 5440 z[lc++]=" Sleep(10);"; 5441 z[lc++]=" timeoutMsec -= 10;"; 5442 z[lc++]=" }"; 5443 z[lc++]=" if( pahsc->pahsc_TimerID != 0 )"; 5444 z[lc++]=" {"; 5445 z[lc++]=" timeKillEvent(pahsc->pahsc_TimerID); /* Stop callback timer. */"; 5446 z[lc++]=" pahsc->pahsc_TimerID = 0;"; 5447 z[lc++]=" }"; 5448 z[lc++]=" return paNoError;"; 5449 z[lc++]="}"; 5450 z[lc++]="/*************************************************************************/"; 5451 z[lc++]="PaError PaHost_StopInput( internalPortAudioStream *past, int abort )"; 5452 z[lc++]="{"; 5453 z[lc++]="#if SUPPORT_AUDIO_CAPTURE"; 5454 z[lc++]=" HRESULT hr;"; 5455 z[lc++]=" PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 5456 z[lc++]=" if( pahsc == NULL ) return paNoError;"; 5457 z[lc++]=" (void) abort;"; 5458 z[lc++]=" hr = DSW_StopInput( &pahsc->pahsc_DSoundWrapper );"; 5459 z[lc++]=" DBUG((\"DSW_StopInput() result is %x\\n\", hr));"; 5460 z[lc++]="#endif /* SUPPORT_AUDIO_CAPTURE */"; 5461 z[lc++]=" return paNoError;"; 5462 z[lc++]="}"; 5463 z[lc++]="/*************************************************************************/"; 5464 z[lc++]="PaError PaHost_StopOutput( internalPortAudioStream *past, int abort )"; 5465 z[lc++]="{"; 5466 z[lc++]=" HRESULT hr;"; 5467 z[lc++]=" PaHostSoundControl *pahsc;"; 5468 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 5469 z[lc++]=" if( pahsc == NULL ) return paNoError;"; 5470 z[lc++]=" (void) abort;"; 5471 z[lc++]=" hr = DSW_StopOutput( &pahsc->pahsc_DSoundWrapper );"; 5472 z[lc++]=" DBUG((\"DSW_StopOutput() result is %x\\n\", hr));"; 5473 z[lc++]=" return paNoError;"; 5474 z[lc++]="}"; 5475 z[lc++]="/*******************************************************************/"; 5476 z[lc++]="PaError PaHost_CloseStream( internalPortAudioStream *past )"; 5477 z[lc++]="{"; 5478 z[lc++]=" PaHostSoundControl *pahsc;"; 5479 z[lc++]=" if( past == NULL ) return paBadStreamPtr;"; 5480 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 5481 z[lc++]=" if( pahsc == NULL ) return paNoError;"; 5482 z[lc++]=" DSW_Term( &pahsc->pahsc_DSoundWrapper );"; 5483 z[lc++]=" if( pahsc->pahsc_NativeBuffer )"; 5484 z[lc++]=" {"; 5485 z[lc++]=" PaHost_FreeFastMemory( pahsc->pahsc_NativeBuffer, pahsc->pahsc_BytesPerBuffer ); /* MEM */"; 5486 z[lc++]=" pahsc->pahsc_NativeBuffer = NULL;"; 5487 z[lc++]=" }"; 5488 z[lc++]=" PaHost_FreeFastMemory( pahsc, sizeof(PaHostSoundControl) ); /* MEM */"; 5489 z[lc++]=" past->past_DeviceData = NULL;"; 5490 z[lc++]=" return paNoError;"; 5491 z[lc++]="}"; 5492 z[lc++]="/*************************************************************************"; 5493 z[lc++]="** Determine minimum number of buffers required for this host based"; 5494 z[lc++]="** on minimum latency. Latency can be optionally set by user by setting"; 5495 z[lc++]="** an environment variable. For example, to set latency to 200 msec, put:"; 5496 z[lc++]="**"; 5497 z[lc++]="** set PA_MIN_LATENCY_MSEC=200"; 5498 z[lc++]="**"; 5499 z[lc++]="** in the AUTOEXEC.BAT file and reboot."; 5500 z[lc++]="** If the environment variable is not set, then the latency will be determined"; 5501 z[lc++]="** based on the OS. Windows NT has higher latency than Win95."; 5502 z[lc++]="*/"; 5503 z[lc++]="#define PA_LATENCY_ENV_NAME (\"PA_MIN_LATENCY_MSEC\")"; 5504 z[lc++]="int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate )"; 5505 z[lc++]="{"; 5506 z[lc++]=" char envbuf[PA_ENV_BUF_SIZE];"; 5507 z[lc++]=" DWORD hostVersion;"; 5508 z[lc++]=" DWORD hresult;"; 5509 z[lc++]=" int minLatencyMsec = 0;"; 5510 z[lc++]=" double msecPerBuffer = (1000.0 * framesPerBuffer) / sampleRate;"; 5511 z[lc++]=" int minBuffers;"; 5512 z[lc++]="/* Let user determine minimal latency by setting environment variable. */"; 5513 z[lc++]=" hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );"; 5514 z[lc++]=" if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )"; 5515 z[lc++]=" {"; 5516 z[lc++]=" minLatencyMsec = atoi( envbuf );"; 5517 z[lc++]=" }"; 5518 z[lc++]=" else"; 5519 z[lc++]=" {"; 5520 z[lc++]="/* Set minimal latency based on whether NT or Win95."; 5521 z[lc++]=" * NT has higher latency."; 5522 z[lc++]=" */"; 5523 z[lc++]=" hostVersion = GetVersion();"; 5524 z[lc++]="/* High bit clear if NT */"; 5525 z[lc++]=" minLatencyMsec = ( (hostVersion & 0x80000000) == 0 ) ? PA_WIN_NT_LATENCY : PA_WIN_9X_LATENCY ;"; 5526 z[lc++]="#if PA_USE_HIGH_LATENCY"; 5527 z[lc++]=" PRINT((\"PA - Minimum Latency set to %d msec!\\n\", minLatencyMsec ));"; 5528 z[lc++]="#endif"; 5529 z[lc++]=" }"; 5530 z[lc++]=" minBuffers = (int) (1.0 + ((double)minLatencyMsec / msecPerBuffer));"; 5531 z[lc++]=" if( minBuffers < 2 ) minBuffers = 2;"; 5532 z[lc++]=" return minBuffers;"; 5533 z[lc++]="}"; 5534 z[lc++]="/*************************************************************************/"; 5535 z[lc++]="PaError PaHost_Term( void )"; 5536 z[lc++]="{"; 5537 z[lc++]=" int i;"; 5538 z[lc++]="/* Free names allocated during enumeration. */"; 5539 z[lc++]=" for( i=0; i<sNumDevices; i++ )"; 5540 z[lc++]=" {"; 5541 z[lc++]=" if( sDevices[i].pad_Info.name != NULL )"; 5542 z[lc++]=" {"; 5543 z[lc++]=" free( (void *) sDevices[i].pad_Info.name );"; 5544 z[lc++]=" sDevices[i].pad_Info.name = NULL;"; 5545 z[lc++]=" }"; 5546 z[lc++]=" }"; 5547 z[lc++]=" if( sDevices != NULL )"; 5548 z[lc++]=" {"; 5549 z[lc++]=" PaHost_FreeFastMemory( sDevices, sNumDevices * sizeof(internalPortAudioDevice) ); /* MEM */"; 5550 z[lc++]=" sDevices = NULL;"; 5551 z[lc++]=" sNumDevices = 0;"; 5552 z[lc++]=" }"; 5553 z[lc++]=" return 0;"; 5554 z[lc++]="}"; 5555 z[lc++]="void Pa_Sleep( long msec )"; 5556 z[lc++]="{"; 5557 z[lc++]=" Sleep( msec );"; 5558 z[lc++]="}"; 5559 z[lc++]="/*************************************************************************"; 5560 z[lc++]=" * Allocate memory that can be accessed in real-time."; 5561 z[lc++]=" * This may need to be held in physical memory so that it is not"; 5562 z[lc++]=" * paged to virtual memory."; 5563 z[lc++]=" * This call MUST be balanced with a call to PaHost_FreeFastMemory()."; 5564 z[lc++]=" * Memory will be set to zero."; 5565 z[lc++]=" */"; 5566 z[lc++]="void *PaHost_AllocateFastMemory( long numBytes )"; 5567 z[lc++]="{"; 5568 z[lc++]=" void *addr = GlobalAlloc( GPTR, numBytes ); /* FIXME - do we need physical memory? Use VirtualLock() */ /* MEM */"; 5569 z[lc++]=" return addr;"; 5570 z[lc++]="}"; 5571 z[lc++]="/*************************************************************************"; 5572 z[lc++]=" * Free memory that could be accessed in real-time."; 5573 z[lc++]=" * This call MUST be balanced with a call to PaHost_AllocateFastMemory()."; 5574 z[lc++]=" */"; 5575 z[lc++]="void PaHost_FreeFastMemory( void *addr, long numBytes )"; 5576 z[lc++]="{"; 5577 z[lc++]=" if( addr != NULL ) GlobalFree( addr ); /* MEM */"; 5578 z[lc++]="}"; 5579 z[lc++]="/***********************************************************************/"; 5580 z[lc++]="PaError PaHost_StreamActive( internalPortAudioStream *past )"; 5581 z[lc++]="{"; 5582 z[lc++]=" PaHostSoundControl *pahsc;"; 5583 z[lc++]=" if( past == NULL ) return paBadStreamPtr;"; 5584 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 5585 z[lc++]=" if( pahsc == NULL ) return paInternalError;"; 5586 z[lc++]=" return (PaError) (past->past_IsActive);"; 5587 z[lc++]="}"; 5588 z[lc++]="/*************************************************************************/"; 5589 z[lc++]="PaTimestamp Pa_StreamTime( PortAudioStream *stream )"; 5590 z[lc++]="{"; 5591 z[lc++]=" DSoundWrapper *dsw;"; 5592 z[lc++]=" internalPortAudioStream *past = (internalPortAudioStream *) stream;"; 5593 z[lc++]=" PaHostSoundControl *pahsc;"; 5594 z[lc++]=" if( past == NULL ) return paBadStreamPtr;"; 5595 z[lc++]=" pahsc = (PaHostSoundControl *) past->past_DeviceData;"; 5596 z[lc++]=" dsw = &pahsc->pahsc_DSoundWrapper;"; 5597 z[lc++]=" return dsw->dsw_FramesPlayed;"; 5598 z[lc++]="}"; 5599 printlib(lc); 5600 } 5601 5602 5603