annotate src/portaudio_20161030_catalina_patch/qa/paqa_latency.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 4edcd14160a5
children
rev   line source
Chris@4 1 /** @file paqa_latency.c
Chris@4 2 @ingroup qa_src
Chris@4 3 @brief Test latency estimates.
Chris@4 4 @author Ross Bencina <rossb@audiomulch.com>
Chris@4 5 @author Phil Burk <philburk@softsynth.com>
Chris@4 6 */
Chris@4 7 /*
Chris@4 8 * $Id: patest_sine.c 1368 2008-03-01 00:38:27Z rossb $
Chris@4 9 *
Chris@4 10 * This program uses the PortAudio Portable Audio Library.
Chris@4 11 * For more information see: http://www.portaudio.com/
Chris@4 12 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
Chris@4 13 *
Chris@4 14 * Permission is hereby granted, free of charge, to any person obtaining
Chris@4 15 * a copy of this software and associated documentation files
Chris@4 16 * (the "Software"), to deal in the Software without restriction,
Chris@4 17 * including without limitation the rights to use, copy, modify, merge,
Chris@4 18 * publish, distribute, sublicense, and/or sell copies of the Software,
Chris@4 19 * and to permit persons to whom the Software is furnished to do so,
Chris@4 20 * subject to the following conditions:
Chris@4 21 *
Chris@4 22 * The above copyright notice and this permission notice shall be
Chris@4 23 * included in all copies or substantial portions of the Software.
Chris@4 24 *
Chris@4 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@4 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@4 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Chris@4 28 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
Chris@4 29 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@4 30 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@4 31 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@4 32 */
Chris@4 33
Chris@4 34 /*
Chris@4 35 * The text above constitutes the entire PortAudio license; however,
Chris@4 36 * the PortAudio community also makes the following non-binding requests:
Chris@4 37 *
Chris@4 38 * Any person wishing to distribute modifications to the Software is
Chris@4 39 * requested to send the modifications to the original developer so that
Chris@4 40 * they can be incorporated into the canonical version. It is also
Chris@4 41 * requested that these non-binding requests be included along with the
Chris@4 42 * license above.
Chris@4 43 */
Chris@4 44 #include <stdio.h>
Chris@4 45 #include <math.h>
Chris@4 46 #include "portaudio.h"
Chris@4 47 #include "loopback/src/qa_tools.h"
Chris@4 48
Chris@4 49 #define NUM_SECONDS (5)
Chris@4 50 #define SAMPLE_RATE (44100)
Chris@4 51 #define FRAMES_PER_BUFFER (64)
Chris@4 52
Chris@4 53 #ifndef M_PI
Chris@4 54 #define M_PI (3.14159265)
Chris@4 55 #endif
Chris@4 56
Chris@4 57 #define TABLE_SIZE (200)
Chris@4 58 typedef struct
Chris@4 59 {
Chris@4 60 float sine[TABLE_SIZE];
Chris@4 61 int left_phase;
Chris@4 62 int right_phase;
Chris@4 63 char message[20];
Chris@4 64 int minFramesPerBuffer;
Chris@4 65 int maxFramesPerBuffer;
Chris@4 66 int callbackCount;
Chris@4 67 PaTime minDeltaDacTime;
Chris@4 68 PaTime maxDeltaDacTime;
Chris@4 69 PaStreamCallbackTimeInfo previousTimeInfo;
Chris@4 70 }
Chris@4 71 paTestData;
Chris@4 72
Chris@4 73 /* Used to tally the results of the QA tests. */
Chris@4 74 int g_testsPassed = 0;
Chris@4 75 int g_testsFailed = 0;
Chris@4 76
Chris@4 77 /* This routine will be called by the PortAudio engine when audio is needed.
Chris@4 78 ** It may called at interrupt level on some machines so don't do anything
Chris@4 79 ** that could mess up the system like calling malloc() or free().
Chris@4 80 */
Chris@4 81 static int patestCallback( const void *inputBuffer, void *outputBuffer,
Chris@4 82 unsigned long framesPerBuffer,
Chris@4 83 const PaStreamCallbackTimeInfo* timeInfo,
Chris@4 84 PaStreamCallbackFlags statusFlags,
Chris@4 85 void *userData )
Chris@4 86 {
Chris@4 87 paTestData *data = (paTestData*)userData;
Chris@4 88 float *out = (float*)outputBuffer;
Chris@4 89 unsigned long i;
Chris@4 90
Chris@4 91 (void) timeInfo; /* Prevent unused variable warnings. */
Chris@4 92 (void) statusFlags;
Chris@4 93 (void) inputBuffer;
Chris@4 94
Chris@4 95 if( data->minFramesPerBuffer > framesPerBuffer )
Chris@4 96 {
Chris@4 97 data->minFramesPerBuffer = framesPerBuffer;
Chris@4 98 }
Chris@4 99 if( data->maxFramesPerBuffer < framesPerBuffer )
Chris@4 100 {
Chris@4 101 data->maxFramesPerBuffer = framesPerBuffer;
Chris@4 102 }
Chris@4 103
Chris@4 104 /* Measure min and max output time stamp delta. */
Chris@4 105 if( data->callbackCount > 0 )
Chris@4 106 {
Chris@4 107 PaTime delta = timeInfo->outputBufferDacTime - data->previousTimeInfo.outputBufferDacTime;
Chris@4 108 if( data->minDeltaDacTime > delta )
Chris@4 109 {
Chris@4 110 data->minDeltaDacTime = delta;
Chris@4 111 }
Chris@4 112 if( data->maxDeltaDacTime < delta )
Chris@4 113 {
Chris@4 114 data->maxDeltaDacTime = delta;
Chris@4 115 }
Chris@4 116 }
Chris@4 117 data->previousTimeInfo = *timeInfo;
Chris@4 118
Chris@4 119 for( i=0; i<framesPerBuffer; i++ )
Chris@4 120 {
Chris@4 121 *out++ = data->sine[data->left_phase]; /* left */
Chris@4 122 *out++ = data->sine[data->right_phase]; /* right */
Chris@4 123 data->left_phase += 1;
Chris@4 124 if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
Chris@4 125 data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
Chris@4 126 if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
Chris@4 127 }
Chris@4 128
Chris@4 129 data->callbackCount += 1;
Chris@4 130 return paContinue;
Chris@4 131 }
Chris@4 132
Chris@4 133 PaError paqaCheckLatency( PaStreamParameters *outputParamsPtr,
Chris@4 134 paTestData *dataPtr, double sampleRate, unsigned long framesPerBuffer )
Chris@4 135 {
Chris@4 136 PaError err;
Chris@4 137 PaStream *stream;
Chris@4 138 const PaStreamInfo* streamInfo;
Chris@4 139
Chris@4 140 dataPtr->minFramesPerBuffer = 9999999;
Chris@4 141 dataPtr->maxFramesPerBuffer = 0;
Chris@4 142 dataPtr->minDeltaDacTime = 9999999.0;
Chris@4 143 dataPtr->maxDeltaDacTime = 0.0;
Chris@4 144 dataPtr->callbackCount = 0;
Chris@4 145
Chris@4 146 printf("Stream parameter: suggestedOutputLatency = %g\n", outputParamsPtr->suggestedLatency );
Chris@4 147 if( framesPerBuffer == paFramesPerBufferUnspecified ){
Chris@4 148 printf("Stream parameter: user framesPerBuffer = paFramesPerBufferUnspecified\n" );
Chris@4 149 }else{
Chris@4 150 printf("Stream parameter: user framesPerBuffer = %lu\n", framesPerBuffer );
Chris@4 151 }
Chris@4 152 err = Pa_OpenStream(
Chris@4 153 &stream,
Chris@4 154 NULL, /* no input */
Chris@4 155 outputParamsPtr,
Chris@4 156 sampleRate,
Chris@4 157 framesPerBuffer,
Chris@4 158 paClipOff, /* we won't output out of range samples so don't bother clipping them */
Chris@4 159 patestCallback,
Chris@4 160 dataPtr );
Chris@4 161 if( err != paNoError ) goto error1;
Chris@4 162
Chris@4 163 streamInfo = Pa_GetStreamInfo( stream );
Chris@4 164 printf("Stream info: inputLatency = %g\n", streamInfo->inputLatency );
Chris@4 165 printf("Stream info: outputLatency = %g\n", streamInfo->outputLatency );
Chris@4 166
Chris@4 167 err = Pa_StartStream( stream );
Chris@4 168 if( err != paNoError ) goto error2;
Chris@4 169
Chris@4 170 printf("Play for %d seconds.\n", NUM_SECONDS );
Chris@4 171 Pa_Sleep( NUM_SECONDS * 1000 );
Chris@4 172
Chris@4 173 printf(" minFramesPerBuffer = %4d\n", dataPtr->minFramesPerBuffer );
Chris@4 174 printf(" maxFramesPerBuffer = %4d\n", dataPtr->maxFramesPerBuffer );
Chris@4 175 printf(" minDeltaDacTime = %f\n", dataPtr->minDeltaDacTime );
Chris@4 176 printf(" maxDeltaDacTime = %f\n", dataPtr->maxDeltaDacTime );
Chris@4 177
Chris@4 178 err = Pa_StopStream( stream );
Chris@4 179 if( err != paNoError ) goto error2;
Chris@4 180
Chris@4 181 err = Pa_CloseStream( stream );
Chris@4 182 Pa_Sleep( 1 * 1000 );
Chris@4 183
Chris@4 184
Chris@4 185 printf("-------------------------------------\n");
Chris@4 186 return err;
Chris@4 187 error2:
Chris@4 188 Pa_CloseStream( stream );
Chris@4 189 error1:
Chris@4 190 printf("-------------------------------------\n");
Chris@4 191 return err;
Chris@4 192 }
Chris@4 193
Chris@4 194
Chris@4 195 /*******************************************************************/
Chris@4 196 static int paqaNoopCallback( const void *inputBuffer, void *outputBuffer,
Chris@4 197 unsigned long framesPerBuffer,
Chris@4 198 const PaStreamCallbackTimeInfo* timeInfo,
Chris@4 199 PaStreamCallbackFlags statusFlags,
Chris@4 200 void *userData )
Chris@4 201 {
Chris@4 202 (void)inputBuffer;
Chris@4 203 (void)outputBuffer;
Chris@4 204 (void)framesPerBuffer;
Chris@4 205 (void)timeInfo;
Chris@4 206 (void)statusFlags;
Chris@4 207 (void)userData;
Chris@4 208 return paContinue;
Chris@4 209 }
Chris@4 210
Chris@4 211 /*******************************************************************/
Chris@4 212 static int paqaCheckMultipleSuggested( PaDeviceIndex deviceIndex, int isInput )
Chris@4 213 {
Chris@4 214 int i;
Chris@4 215 int numLoops = 10;
Chris@4 216 PaError err;
Chris@4 217 PaStream *stream;
Chris@4 218 PaStreamParameters streamParameters;
Chris@4 219 const PaStreamInfo* streamInfo;
Chris@4 220 double lowLatency;
Chris@4 221 double highLatency;
Chris@4 222 double finalLatency;
Chris@55 223 double sampleRate = SAMPLE_RATE;
Chris@4 224 const PaDeviceInfo *pdi = Pa_GetDeviceInfo( deviceIndex );
Chris@4 225 double previousLatency = 0.0;
Chris@4 226 int numChannels = 1;
Chris@55 227 float toleranceRatio = 1.0;
Chris@55 228
Chris@4 229 printf("------------------------ paqaCheckMultipleSuggested - %s\n",
Chris@4 230 (isInput ? "INPUT" : "OUTPUT") );
Chris@4 231 if( isInput )
Chris@4 232 {
Chris@4 233 lowLatency = pdi->defaultLowInputLatency;
Chris@4 234 highLatency = pdi->defaultHighInputLatency;
Chris@4 235 numChannels = (pdi->maxInputChannels < 2) ? 1 : 2;
Chris@4 236 }
Chris@4 237 else
Chris@4 238 {
Chris@4 239 lowLatency = pdi->defaultLowOutputLatency;
Chris@4 240 highLatency = pdi->defaultHighOutputLatency;
Chris@4 241 numChannels = (pdi->maxOutputChannels < 2) ? 1 : 2;
Chris@4 242 }
Chris@4 243 streamParameters.channelCount = numChannels;
Chris@4 244 streamParameters.device = deviceIndex;
Chris@4 245 streamParameters.hostApiSpecificStreamInfo = NULL;
Chris@4 246 streamParameters.sampleFormat = paFloat32;
Chris@55 247 sampleRate = pdi->defaultSampleRate;
Chris@4 248
Chris@4 249 printf(" lowLatency = %g\n", lowLatency );
Chris@4 250 printf(" highLatency = %g\n", highLatency );
Chris@4 251 printf(" numChannels = %d\n", numChannels );
Chris@55 252 printf(" sampleRate = %g\n", sampleRate );
Chris@4 253
Chris@4 254 if( (highLatency - lowLatency) < 0.001 )
Chris@4 255 {
Chris@55 256 numLoops = 1;
Chris@55 257 }
Chris@55 258
Chris@4 259 for( i=0; i<numLoops; i++ )
Chris@4 260 {
Chris@55 261 if( numLoops == 1 )
Chris@55 262 streamParameters.suggestedLatency = lowLatency;
Chris@55 263 else
Chris@55 264 streamParameters.suggestedLatency = lowLatency + ((highLatency - lowLatency) * i /(numLoops - 1));
Chris@4 265
Chris@4 266 printf(" suggestedLatency[%d] = %6.4f\n", i, streamParameters.suggestedLatency );
Chris@4 267
Chris@4 268 err = Pa_OpenStream(
Chris@4 269 &stream,
Chris@4 270 (isInput ? &streamParameters : NULL),
Chris@4 271 (isInput ? NULL : &streamParameters),
Chris@4 272 sampleRate,
Chris@4 273 paFramesPerBufferUnspecified,
Chris@4 274 paClipOff, /* we won't output out of range samples so don't bother clipping them */
Chris@4 275 paqaNoopCallback,
Chris@4 276 NULL );
Chris@4 277 if( err != paNoError ) goto error;
Chris@4 278
Chris@4 279 streamInfo = Pa_GetStreamInfo( stream );
Chris@4 280
Chris@4 281 err = Pa_CloseStream( stream );
Chris@4 282
Chris@4 283 if( isInput )
Chris@4 284 {
Chris@4 285 finalLatency = streamInfo->inputLatency;
Chris@4 286 }
Chris@4 287 else
Chris@4 288 {
Chris@4 289 finalLatency = streamInfo->outputLatency;
Chris@4 290 }
Chris@4 291 printf(" finalLatency = %6.4f\n", finalLatency );
Chris@55 292 /* For the default low & high latency values, expect quite close; for other requested
Chris@55 293 * values, at worst the next power-of-2 may result (eg 513 -> 1024) */
Chris@55 294 toleranceRatio = ( (i == 0) || (i == ( numLoops - 1 )) ) ? 0.1 : 1.0;
Chris@55 295 QA_ASSERT_CLOSE( "final latency should be close to suggested latency",
Chris@55 296 streamParameters.suggestedLatency, finalLatency, (streamParameters.suggestedLatency * toleranceRatio) );
Chris@55 297 if( i == 0 )
Chris@55 298 {
Chris@55 299 previousLatency = finalLatency;
Chris@55 300 }
Chris@55 301 }
Chris@55 302
Chris@55 303 if( numLoops > 1 )
Chris@55 304 {
Chris@4 305 QA_ASSERT_TRUE( " final latency should increase with suggested latency", (finalLatency > previousLatency) );
Chris@4 306 }
Chris@55 307
Chris@4 308 return 0;
Chris@4 309 error:
Chris@4 310 return -1;
Chris@4 311 }
Chris@4 312
Chris@4 313 /*******************************************************************/
Chris@4 314 static int paqaVerifySuggestedLatency( void )
Chris@4 315 {
Chris@4 316 PaDeviceIndex id;
Chris@4 317 int result = 0;
Chris@4 318 const PaDeviceInfo *pdi;
Chris@4 319 int numDevices = Pa_GetDeviceCount();
Chris@4 320
Chris@4 321 printf("\n ------------------------ paqaVerifySuggestedLatency\n");
Chris@4 322 for( id=0; id<numDevices; id++ ) /* Iterate through all devices. */
Chris@4 323 {
Chris@4 324 pdi = Pa_GetDeviceInfo( id );
Chris@55 325 printf("\nUsing device #%d: '%s' (%s)\n", id, pdi->name, Pa_GetHostApiInfo(pdi->hostApi)->name);
Chris@4 326 if( pdi->maxOutputChannels > 0 )
Chris@4 327 {
Chris@55 328 if( paqaCheckMultipleSuggested( id, 0 ) < 0 )
Chris@55 329 {
Chris@55 330 printf("OUTPUT CHECK FAILED !!! #%d: '%s'\n", id, pdi->name);
Chris@55 331 result -= 1;
Chris@55 332 }
Chris@4 333 }
Chris@4 334 if( pdi->maxInputChannels > 0 )
Chris@4 335 {
Chris@55 336 if( paqaCheckMultipleSuggested( id, 1 ) < 0 )
Chris@55 337 {
Chris@55 338 printf("INPUT CHECK FAILED !!! #%d: '%s'\n", id, pdi->name);
Chris@55 339 result -= 1;
Chris@55 340 }
Chris@4 341 }
Chris@4 342 }
Chris@55 343 return result;
Chris@4 344 }
Chris@4 345
Chris@4 346 /*******************************************************************/
Chris@4 347 static int paqaVerifyDeviceInfoLatency( void )
Chris@4 348 {
Chris@4 349 PaDeviceIndex id;
Chris@4 350 const PaDeviceInfo *pdi;
Chris@4 351 int numDevices = Pa_GetDeviceCount();
Chris@4 352
Chris@4 353 printf("\n ------------------------ paqaVerifyDeviceInfoLatency\n");
Chris@4 354 for( id=0; id<numDevices; id++ ) /* Iterate through all devices. */
Chris@4 355 {
Chris@4 356 pdi = Pa_GetDeviceInfo( id );
Chris@4 357 printf("Using device #%d: '%s' (%s)\n", id, pdi->name, Pa_GetHostApiInfo(pdi->hostApi)->name);
Chris@4 358 if( pdi->maxOutputChannels > 0 )
Chris@4 359 {
Chris@4 360 printf(" Output defaultLowOutputLatency = %f seconds\n", pdi->defaultLowOutputLatency);
Chris@55 361 printf(" Output defaultHighOutputLatency = %f seconds\n", pdi->defaultHighOutputLatency);
Chris@4 362 QA_ASSERT_TRUE( "defaultLowOutputLatency should be > 0", (pdi->defaultLowOutputLatency > 0.0) );
Chris@4 363 QA_ASSERT_TRUE( "defaultHighOutputLatency should be > 0", (pdi->defaultHighOutputLatency > 0.0) );
Chris@55 364 QA_ASSERT_TRUE( "defaultHighOutputLatency should be >= Low", (pdi->defaultHighOutputLatency >= pdi->defaultLowOutputLatency) );
Chris@4 365 }
Chris@4 366 if( pdi->maxInputChannels > 0 )
Chris@4 367 {
Chris@55 368 printf(" Input defaultLowInputLatency = %f seconds\n", pdi->defaultLowInputLatency);
Chris@55 369 printf(" Input defaultHighInputLatency = %f seconds\n", pdi->defaultHighInputLatency);
Chris@55 370 QA_ASSERT_TRUE( "defaultLowInputLatency should be > 0", (pdi->defaultLowInputLatency > 0.0) );
Chris@55 371 QA_ASSERT_TRUE( "defaultHighInputLatency should be > 0", (pdi->defaultHighInputLatency > 0.0) );
Chris@55 372 QA_ASSERT_TRUE( "defaultHighInputLatency should be >= Low", (pdi->defaultHighInputLatency >= pdi->defaultLowInputLatency) );
Chris@4 373 }
Chris@4 374 }
Chris@4 375 return 0;
Chris@4 376 error:
Chris@4 377 return -1;
Chris@4 378 }
Chris@4 379
Chris@4 380
Chris@4 381
Chris@4 382 /*******************************************************************/
Chris@4 383 int main(void);
Chris@4 384 int main(void)
Chris@4 385 {
Chris@4 386 PaStreamParameters outputParameters;
Chris@4 387 PaError err;
Chris@4 388 paTestData data;
Chris@4 389 const PaDeviceInfo *deviceInfo;
Chris@4 390 int i;
Chris@4 391 int framesPerBuffer;
Chris@55 392 double sampleRate = SAMPLE_RATE;
Chris@4 393
Chris@55 394 printf("\nPortAudio QA: investigate output latency.\n");
Chris@55 395
Chris@4 396 /* initialise sinusoidal wavetable */
Chris@4 397 for( i=0; i<TABLE_SIZE; i++ )
Chris@4 398 {
Chris@4 399 data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
Chris@4 400 }
Chris@4 401 data.left_phase = data.right_phase = 0;
Chris@4 402
Chris@4 403 err = Pa_Initialize();
Chris@4 404 if( err != paNoError ) goto error;
Chris@4 405
Chris@4 406 /* Run self tests. */
Chris@4 407 if( paqaVerifyDeviceInfoLatency() < 0 ) goto error;
Chris@4 408
Chris@4 409 if( paqaVerifySuggestedLatency() < 0 ) goto error;
Chris@4 410
Chris@4 411 outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
Chris@4 412 if (outputParameters.device == paNoDevice) {
Chris@4 413 fprintf(stderr,"Error: No default output device.\n");
Chris@4 414 goto error;
Chris@4 415 }
Chris@4 416
Chris@55 417 printf("\n\nNow running Audio Output Tests...\n");
Chris@55 418 printf("-------------------------------------\n");
Chris@55 419
Chris@4 420 outputParameters.channelCount = 2; /* stereo output */
Chris@4 421 outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
Chris@4 422 deviceInfo = Pa_GetDeviceInfo( outputParameters.device );
Chris@4 423 printf("Using device #%d: '%s' (%s)\n", outputParameters.device, deviceInfo->name, Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
Chris@4 424 printf("Device info: defaultLowOutputLatency = %f seconds\n", deviceInfo->defaultLowOutputLatency);
Chris@4 425 printf("Device info: defaultHighOutputLatency = %f seconds\n", deviceInfo->defaultHighOutputLatency);
Chris@55 426 sampleRate = deviceInfo->defaultSampleRate;
Chris@55 427 printf("Sample Rate for following tests: %g\n", sampleRate);
Chris@4 428 outputParameters.hostApiSpecificStreamInfo = NULL;
Chris@55 429 printf("-------------------------------------\n");
Chris@55 430
Chris@4 431 // Try to use a small buffer that is smaller than we think the device can handle.
Chris@4 432 // Try to force combining multiple user buffers into a host buffer.
Chris@4 433 printf("------------- Try a very small buffer.\n");
Chris@4 434 framesPerBuffer = 9;
Chris@4 435 outputParameters.suggestedLatency = deviceInfo->defaultLowOutputLatency;
Chris@4 436 err = paqaCheckLatency( &outputParameters, &data, sampleRate, framesPerBuffer );
Chris@4 437 if( err != paNoError ) goto error;
Chris@4 438
Chris@4 439 printf("------------- 64 frame buffer with 1.1 * defaultLow latency.\n");
Chris@4 440 framesPerBuffer = 64;
Chris@4 441 outputParameters.suggestedLatency = deviceInfo->defaultLowOutputLatency * 1.1;
Chris@4 442 err = paqaCheckLatency( &outputParameters, &data, sampleRate, framesPerBuffer );
Chris@4 443 if( err != paNoError ) goto error;
Chris@4 444
Chris@4 445 // Try to create a huge buffer that is bigger than the allowed device maximum.
Chris@4 446 printf("------------- Try a huge buffer.\n");
Chris@4 447 framesPerBuffer = 16*1024;
Chris@4 448 outputParameters.suggestedLatency = ((double)framesPerBuffer) / sampleRate; // approximate
Chris@4 449 err = paqaCheckLatency( &outputParameters, &data, sampleRate, framesPerBuffer );
Chris@4 450 if( err != paNoError ) goto error;
Chris@4 451
Chris@4 452 printf("------------- Try suggestedLatency = 0.0\n");
Chris@4 453 outputParameters.suggestedLatency = 0.0;
Chris@4 454 err = paqaCheckLatency( &outputParameters, &data, sampleRate, paFramesPerBufferUnspecified );
Chris@4 455 if( err != paNoError ) goto error;
Chris@4 456
Chris@4 457 printf("------------- Try suggestedLatency = defaultLowOutputLatency\n");
Chris@4 458 outputParameters.suggestedLatency = deviceInfo->defaultLowOutputLatency;
Chris@4 459 err = paqaCheckLatency( &outputParameters, &data, sampleRate, paFramesPerBufferUnspecified );
Chris@4 460 if( err != paNoError ) goto error;
Chris@4 461
Chris@4 462 printf("------------- Try suggestedLatency = defaultHighOutputLatency\n");
Chris@4 463 outputParameters.suggestedLatency = deviceInfo->defaultHighOutputLatency;
Chris@4 464 err = paqaCheckLatency( &outputParameters, &data, sampleRate, paFramesPerBufferUnspecified );
Chris@4 465 if( err != paNoError ) goto error;
Chris@4 466
Chris@4 467 printf("------------- Try suggestedLatency = defaultHighOutputLatency * 4\n");
Chris@4 468 outputParameters.suggestedLatency = deviceInfo->defaultHighOutputLatency * 4;
Chris@4 469 err = paqaCheckLatency( &outputParameters, &data, sampleRate, paFramesPerBufferUnspecified );
Chris@4 470 if( err != paNoError ) goto error;
Chris@4 471
Chris@55 472 Pa_Terminate();
Chris@55 473 printf("SUCCESS - test finished.\n");
Chris@55 474 return err;
Chris@4 475
Chris@4 476 error:
Chris@4 477 Pa_Terminate();
Chris@55 478 fprintf( stderr, "ERROR - test failed.\n" );
Chris@4 479 fprintf( stderr, "Error number: %d\n", err );
Chris@4 480 fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
Chris@4 481 return err;
Chris@4 482 }