From 35073f0c653c8c2fe92e0817c9b2e67e767b3d0e Mon Sep 17 00:00:00 2001 From: rossb Date: Thu, 4 Aug 2011 13:56:52 +0000 Subject: [PATCH] updated patest_suggested_vs_streaminfo_latency to support running multiple test iterations from the python script --- test/patest_suggested_vs_streaminfo_latency.c | 95 ++++++++++++++++--- .../patest_suggested_vs_streaminfo_latency.py | 29 ++++-- 2 files changed, 102 insertions(+), 22 deletions(-) diff --git a/test/patest_suggested_vs_streaminfo_latency.c b/test/patest_suggested_vs_streaminfo_latency.c index 41c5c7c..473f9a1 100644 --- a/test/patest_suggested_vs_streaminfo_latency.c +++ b/test/patest_suggested_vs_streaminfo_latency.c @@ -81,11 +81,37 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer, + + */ /*******************************************************************/ -int main(void); -int main(void) +static void usage() +{ + int i; + const PaDeviceInfo *deviceInfo; + const char *channelString; + + fprintf( stderr, "PortAudio suggested (requested) vs. resulting (reported) stream latency test\n" ); + fprintf( stderr, "Usage: x.exe input-device-index output-device-index frames-per-buffer\n" ); + fprintf( stderr, "Use -1 for default device index, or use one of these:\n" ); + for( i=0; i < Pa_GetDeviceCount(); ++i ){ + deviceInfo = Pa_GetDeviceInfo(i); + if( deviceInfo->maxInputChannels > 0 && deviceInfo->maxOutputChannels > 0 ) + channelString = "full-duplex"; + else if( deviceInfo->maxInputChannels > 0 ) + channelString = "input only"; + else + channelString = "output only"; + + fprintf( stderr, "%d (%s, %s, %s)\n", i, deviceInfo->name, Pa_GetHostApiInfo(deviceInfo->hostApi)->name, channelString ); + } + Pa_Terminate(); + exit(-1); +} + +int main( int argc, const char* argv[] ); +int main( int argc, const char* argv[] ) { PaStreamParameters outputParameters, inputParameters; PaStream *stream; @@ -94,16 +120,39 @@ int main(void) PaTime suggestedLatency; PaStreamInfo *streamInfo; PaDeviceInfo *deviceInfo; - + int deviceCount; + int framesPerBuffer = FRAMES_PER_BUFFER; err = Pa_Initialize(); if( err != paNoError ) goto error; - printf("# sample rate=%f, frames per buffer=%d\n", (float)SAMPLE_RATE, FRAMES_PER_BUFFER ); + if( argc > 1 && strcmp(argv[1],"-h") == 0 ) + usage(); - outputParameters.device = Pa_GetDefaultOutputDevice(); - if (outputParameters.device == paNoDevice) { - fprintf(stderr,"Error: No default output device.\n"); - goto error; + if( argc > 3 ){ + framesPerBuffer = atoi(argv[3]); + } + + printf("# sample rate=%f, frames per buffer=%d\n", (float)SAMPLE_RATE, framesPerBuffer ); + + outputParameters.device = -1; + if( argc > 1 ) + outputParameters.device = atoi(argv[1]); + if( outputParameters.device == -1 ){ + outputParameters.device = Pa_GetDefaultOutputDevice(); + if (outputParameters.device == paNoDevice) { + fprintf(stderr,"Error: No default output device available.\n"); + goto error; + } + }else{ + deviceInfo = Pa_GetDeviceInfo(outputParameters.device); + if( !deviceInfo ){ + fprintf(stderr,"Error: Invalid output device index.\n"); + usage(); + } + if( deviceInfo->maxOutputChannels == 0 ){ + fprintf(stderr,"Error: Specified output device has no output channels (an input only device?).\n"); + usage(); + } } outputParameters.channelCount = NUM_CHANNELS; @@ -114,11 +163,27 @@ int main(void) printf( "# using output device id %d (%s, %s)\n", outputParameters.device, deviceInfo->name, Pa_GetHostApiInfo(deviceInfo->hostApi)->name ); - inputParameters.device = Pa_GetDefaultInputDevice(); - if (inputParameters.device == paNoDevice) { - fprintf(stderr,"Error: No default input device.\n"); - goto error; + inputParameters.device = -1; + if( argc > 2 ) + inputParameters.device = atoi(argv[1]); + if( inputParameters.device == -1 ){ + inputParameters.device = Pa_GetDefaultInputDevice(); + if (inputParameters.device == paNoDevice) { + fprintf(stderr,"Error: No default input device available.\n"); + goto error; + } + }else{ + deviceInfo = Pa_GetDeviceInfo(inputParameters.device); + if( !deviceInfo ){ + fprintf(stderr,"Error: Invalid input device index.\n"); + usage(); + } + if( deviceInfo->maxInputChannels == 0 ){ + fprintf(stderr,"Error: Specified input device has no input channels (an output only device?).\n"); + usage(); + } } + inputParameters.channelCount = NUM_CHANNELS; inputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */ @@ -144,7 +209,7 @@ int main(void) NULL, /* no input */ &outputParameters, SAMPLE_RATE, - FRAMES_PER_BUFFER, + framesPerBuffer, paClipOff, /* we won't output out of range samples so don't bother clipping them */ patestCallback, 0 ); @@ -164,7 +229,7 @@ int main(void) &inputParameters, NULL, /* no output */ SAMPLE_RATE, - FRAMES_PER_BUFFER, + framesPerBuffer, paClipOff, /* we won't output out of range samples so don't bother clipping them */ patestCallback, 0 ); @@ -184,7 +249,7 @@ int main(void) &inputParameters, &outputParameters, SAMPLE_RATE, - FRAMES_PER_BUFFER, + framesPerBuffer, paClipOff, /* we won't output out of range samples so don't bother clipping them */ patestCallback, 0 ); diff --git a/test/patest_suggested_vs_streaminfo_latency.py b/test/patest_suggested_vs_streaminfo_latency.py index a7a8d55..c993e85 100644 --- a/test/patest_suggested_vs_streaminfo_latency.py +++ b/test/patest_suggested_vs_streaminfo_latency.py @@ -13,6 +13,9 @@ import numpy testExeName = "PATest.exe" # rename to whatever the compiled patest_suggested_vs_streaminfo_latency.c binary is dataFileName = 'patest_suggested_vs_streaminfo_latency.csv' # code below calls the exe to generate this file +inputDeviceIndex = -1 # -1 means default +inputDeviceIndex = -1 # -1 means default + def loadCsvData( dataFileName ): params= "" @@ -39,16 +42,28 @@ def loadCsvData( dataFileName ): result.fullDuplexInputLatency = data[4] return result; +# run the test with different frames per buffer values: + +framesPerBufferValues = [0] +# powers of two +#for i in range (1,11): +# framesPerBufferValues.append( 2 ^ i ) + +# could also test: multiples of 10, random numbers, powers of primes, etc + + + +for framesPerBuffer in framesPerBufferValues: -os.system(testExeName + ' > ' + dataFileName) + os.system(testExeName + " -1 -1 " + str(framesPerBuffer) + ' > ' + dataFileName) -d = loadCsvData(dataFileName) + d = loadCsvData(dataFileName) -plot( d.suggestedLatency, d.suggestedLatency ) -plot( d.suggestedLatency, d.halfDuplexOutputLatency ) -plot( d.suggestedLatency, d.halfDuplexInputLatency ) -plot( d.suggestedLatency, d.fullDuplexOutputLatency ) -plot( d.suggestedLatency, d.fullDuplexInputLatency ) + plot( d.suggestedLatency, d.suggestedLatency ) + plot( d.suggestedLatency, d.halfDuplexOutputLatency ) + plot( d.suggestedLatency, d.halfDuplexInputLatency ) + plot( d.suggestedLatency, d.fullDuplexOutputLatency ) + plot( d.suggestedLatency, d.fullDuplexInputLatency ) title('PortAudio suggested (requested) vs. resulting (reported) stream latency\n%s'%d.titleInfo) ylabel('PaStreamInfo::{input,output}Latency (s)') -- 2.43.0