updated patest_suggested_vs_streaminfo_latency to support running multiple test iterations from the python script

This commit is contained in:
rossb 2011-08-04 13:56:52 +00:00
commit 35073f0c65
2 changed files with 102 additions and 22 deletions

View file

@ -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 );

View file

@ -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:
os.system(testExeName + ' > ' + dataFileName)
framesPerBufferValues = [0]
# powers of two
#for i in range (1,11):
# framesPerBufferValues.append( 2 ^ i )
d = loadCsvData(dataFileName)
# could also test: multiples of 10, random numbers, powers of primes, etc
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 )
for framesPerBuffer in framesPerBufferValues:
os.system(testExeName + " -1 -1 " + str(framesPerBuffer) + ' > ' + 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 )
title('PortAudio suggested (requested) vs. resulting (reported) stream latency\n%s'%d.titleInfo)
ylabel('PaStreamInfo::{input,output}Latency (s)')