From a08b3b1856abc37322094a66b8ec2043c5fdb9f7 Mon Sep 17 00:00:00 2001 From: philburk Date: Thu, 8 Sep 2011 09:13:16 +0000 Subject: [PATCH] Add self tests to paqa_latency.c --- qa/paqa_latency.c | 179 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 174 insertions(+), 5 deletions(-) diff --git a/qa/paqa_latency.c b/qa/paqa_latency.c index 8fe08e7..3c0fc2e 100644 --- a/qa/paqa_latency.c +++ b/qa/paqa_latency.c @@ -44,6 +44,7 @@ #include #include #include "portaudio.h" +#include "loopback/src/qa_tools.h" #define NUM_SECONDS (5) #define SAMPLE_RATE (44100) @@ -69,6 +70,10 @@ typedef struct } paTestData; +/* Used to tally the results of the QA tests. */ +int g_testsPassed = 0; +int g_testsFailed = 0; + /* This routine will be called by the PortAudio engine when audio is needed. ** It may called at interrupt level on some machines so don't do anything ** that could mess up the system like calling malloc() or free(). @@ -96,7 +101,7 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer, data->maxFramesPerBuffer = framesPerBuffer; } - // Measure min and max output time stamp delta. + /* Measure min and max output time stamp delta. */ if( data->callbackCount > 0 ) { PaTime delta = timeInfo->outputBufferDacTime - data->previousTimeInfo.outputBufferDacTime; @@ -187,6 +192,167 @@ error1: } +/*******************************************************************/ +static int paqaNoopCallback( const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void *userData ) +{ + (void)inputBuffer; + (void)outputBuffer; + (void)framesPerBuffer; + (void)timeInfo; + (void)statusFlags; + (void)userData; + return paContinue; +} + +/*******************************************************************/ +static int paqaCheckMultipleSuggested( PaDeviceIndex deviceIndex, int isInput ) +{ + int i; + int numLoops = 10; + PaError err; + PaStream *stream; + PaStreamParameters streamParameters; + const PaStreamInfo* streamInfo; + double lowLatency; + double highLatency; + double finalLatency; + double sampleRate = 44100.0; + const PaDeviceInfo *pdi = Pa_GetDeviceInfo( deviceIndex ); + double previousLatency = 0.0; + int numChannels = 1; + + printf("------------------------ paqaCheckMultipleSuggested - %s\n", + (isInput ? "INPUT" : "OUTPUT") ); + if( isInput ) + { + lowLatency = pdi->defaultLowInputLatency; + highLatency = pdi->defaultHighInputLatency; + numChannels = (pdi->maxInputChannels < 2) ? 1 : 2; + } + else + { + lowLatency = pdi->defaultLowOutputLatency; + highLatency = pdi->defaultHighOutputLatency; + numChannels = (pdi->maxOutputChannels < 2) ? 1 : 2; + } + streamParameters.channelCount = numChannels; + streamParameters.device = deviceIndex; + streamParameters.hostApiSpecificStreamInfo = NULL; + streamParameters.sampleFormat = paFloat32; + + printf(" lowLatency = %g\n", lowLatency ); + printf(" highLatency = %g\n", highLatency ); + printf(" numChannels = %d\n", numChannels ); + + for( i=0; iinputLatency; + } + else + { + finalLatency = streamInfo->outputLatency; + } + printf(" finalLatency = %6.4f\n", finalLatency ); + QA_ASSERT_CLOSE( "final latency should be close to suggested latency", + streamParameters.suggestedLatency, finalLatency, (streamParameters.suggestedLatency * 0.3) ); + + QA_ASSERT_TRUE( " final latency should increase with suggested latency", (finalLatency > previousLatency) ); + previousLatency = finalLatency; + } + + return 0; +error: + return -1; +} + +/*******************************************************************/ +static int paqaVerifySuggestedLatency( void ) +{ + PaDeviceIndex id; + int result = 0; + const PaDeviceInfo *pdi; + int numDevices = Pa_GetDeviceCount(); + + printf("\n ------------------------ paqaVerifySuggestedLatency\n"); + for( id=0; idname, Pa_GetHostApiInfo(pdi->hostApi)->name); + if( pdi->maxOutputChannels > 0 ) + { + if( (result = paqaCheckMultipleSuggested( id, 0 )) != 0 ) goto error; + } + if( pdi->maxInputChannels > 0 ) + { + if( (result = paqaCheckMultipleSuggested( id, 1 )) != 0 ) goto error; + } + } + return 0; +error: + return -1; +} + +/*******************************************************************/ +static int paqaVerifyDeviceInfoLatency( void ) +{ + PaDeviceIndex id; + const PaDeviceInfo *pdi; + int numDevices = Pa_GetDeviceCount(); + + printf("\n ------------------------ paqaVerifyDeviceInfoLatency\n"); + for( id=0; idname, Pa_GetHostApiInfo(pdi->hostApi)->name); + if( pdi->maxOutputChannels > 0 ) + { + printf(" Output defaultLowOutputLatency = %f seconds\n", pdi->defaultLowOutputLatency); + printf(" Output info: defaultHighOutputLatency = %f seconds\n", pdi->defaultHighOutputLatency); + QA_ASSERT_TRUE( "defaultLowOutputLatency should be > 0", (pdi->defaultLowOutputLatency > 0.0) ); + QA_ASSERT_TRUE( "defaultHighOutputLatency should be > 0", (pdi->defaultHighOutputLatency > 0.0) ); + QA_ASSERT_TRUE( "defaultHighOutputLatency should be > Low", (pdi->defaultHighOutputLatency > pdi->defaultLowOutputLatency) ); + } + if( pdi->maxInputChannels > 0 ) + { + printf(" Input defaultLowOutputLatency = %f seconds\n", pdi->defaultLowInputLatency); + printf(" Input defaultHighOutputLatency = %f seconds\n", pdi->defaultHighInputLatency); + QA_ASSERT_TRUE( "defaultLowOutputLatency should be > 0", (pdi->defaultLowInputLatency > 0.0) ); + QA_ASSERT_TRUE( "defaultHighOutputLatency should be > 0", (pdi->defaultHighInputLatency > 0.0) ); + QA_ASSERT_TRUE( "defaultHighOutputLatency should be > Low", (pdi->defaultHighInputLatency > pdi->defaultLowInputLatency) ); + } + } + return 0; +error: + return -1; +} + + + /*******************************************************************/ int main(void); int main(void) @@ -198,7 +364,6 @@ int main(void) int i; int framesPerBuffer; double sampleRate = 44100; - printf("PortAudio QA: investigate output latency. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); @@ -211,7 +376,12 @@ int main(void) err = Pa_Initialize(); if( err != paNoError ) goto error; - + + /* Run self tests. */ + if( paqaVerifyDeviceInfoLatency() < 0 ) goto error; + + if( paqaVerifySuggestedLatency() < 0 ) goto error; + outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ if (outputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default output device.\n"); @@ -226,7 +396,6 @@ int main(void) printf("Device info: defaultHighOutputLatency = %f seconds\n", deviceInfo->defaultHighOutputLatency); outputParameters.hostApiSpecificStreamInfo = NULL; - // Try to use a small buffer that is smaller than we think the device can handle. // Try to force combining multiple user buffers into a host buffer. printf("------------- Try a very small buffer.\n"); @@ -240,7 +409,7 @@ int main(void) outputParameters.suggestedLatency = deviceInfo->defaultLowOutputLatency * 1.1; err = paqaCheckLatency( &outputParameters, &data, sampleRate, framesPerBuffer ); if( err != paNoError ) goto error; - + // Try to create a huge buffer that is bigger than the allowed device maximum. printf("------------- Try a huge buffer.\n"); framesPerBuffer = 16*1024; -- 2.43.0