From 5db3f8fb7c05e0ca29cc910e5caa6b306f56e9a6 Mon Sep 17 00:00:00 2001 From: philburk Date: Mon, 7 Mar 2011 00:52:47 +0000 Subject: [PATCH] Convert patest_two_rates.c to V19. Make paloopback over/underflow report easier to understand. --- qa/loopback/src/paqa.c | 47 +++++++++++++-------- test/patest_two_rates.c | 92 ++++++++++++++++++++--------------------- 2 files changed, 75 insertions(+), 64 deletions(-) diff --git a/qa/loopback/src/paqa.c b/qa/loopback/src/paqa.c index 21970ca..e21f47d 100644 --- a/qa/loopback/src/paqa.c +++ b/qa/loopback/src/paqa.c @@ -100,12 +100,17 @@ typedef struct LoopbackContext_s PaQaSineGenerator generators[MAX_NUM_GENERATORS]; // Record each channel individually. PaQaRecording recordings[MAX_NUM_RECORDINGS]; + // Measured at runtime. - int callbackCount; + int callbackCount; // incremented for each callback + int inputBufferCount; // incremented if input buffer not NULL int inputUnderflowCount; - int outputUnderflowCount; int inputOverflowCount; + + int outputBufferCount; // incremented if output buffer not NULL int outputOverflowCount; + int outputUnderflowCount; + int minFramesPerBuffer; int maxFramesPerBuffer; int primingCount; @@ -144,7 +149,7 @@ static int RecordAndPlaySinesCallback( const void *inputBuffer, void *outputBuff int i; LoopbackContext *loopbackContext = (LoopbackContext *) userData; - + loopbackContext->callbackCount += 1; if( statusFlags & paInputUnderflow ) loopbackContext->inputUnderflowCount += 1; if( statusFlags & paInputOverflow ) loopbackContext->inputOverflowCount += 1; @@ -167,8 +172,10 @@ static int RecordAndPlaySinesCallback( const void *inputBuffer, void *outputBuff { int channelsPerFrame = loopbackContext->test->inputParameters.channelCount; float *in = (float *)inputBuffer; - PaSampleFormat inFormat = loopbackContext->test->inputParameters.sampleFormat; + + loopbackContext->inputBufferCount += 1; + if( inFormat != paFloat32 ) { int samplesToConvert = framesPerBuffer * channelsPerFrame; @@ -197,8 +204,10 @@ static int RecordAndPlaySinesCallback( const void *inputBuffer, void *outputBuff { int channelsPerFrame = loopbackContext->test->outputParameters.channelCount; float *out = (float *)outputBuffer; - PaSampleFormat outFormat = loopbackContext->test->outputParameters.sampleFormat; + + loopbackContext->outputBufferCount += 1; + if( outFormat != paFloat32 ) { // If we need to convert then mix to the g_ConversionBuffer and then convert into the PA outputBuffer. @@ -772,6 +781,15 @@ static int PaQa_SingleLoopBackTest( UserOptions *userOptions, TestParameters *te err = PaQa_RunLoopback( &loopbackContext ); QA_ASSERT_TRUE("loopback did not run", (loopbackContext.callbackCount > 1) ); + printf( "%4d/%4d/%4d, %4d/%4d/%4d | ", + loopbackContext.inputOverflowCount, + loopbackContext.inputUnderflowCount, + loopbackContext.inputBufferCount, + loopbackContext.outputOverflowCount, + loopbackContext.outputUnderflowCount, + loopbackContext.outputBufferCount + ); + // Analyse recording to detect glitches. for( i=0; isamplesPerFrame; i++ ) { @@ -825,14 +843,7 @@ static int PaQa_SingleLoopBackTest( UserOptions *userOptions, TestParameters *te { printf( "OK" ); } - - printf( ", %d/%d,%d/%d ", - loopbackContext.inputOverflowCount, - loopbackContext.inputUnderflowCount, - loopbackContext.outputOverflowCount, - loopbackContext.outputUnderflowCount - ); - + printf( "\n" ); PaQa_TeardownLoopbackContext( &loopbackContext ); @@ -894,7 +905,7 @@ static void PaQa_OverrideTestParameters( TestParameters *testParamsPtr, UserOpt { testParamsPtr->outputParameters.suggestedLatency = userOptions->outputLatency * 0.001; } - printf( " running with suggested latency (msec): input = %5.2f, out = %5.2f\n", + printf( " Running with suggested latency (msec): input = %5.2f, out = %5.2f\n", (testParamsPtr->inputParameters.suggestedLatency * 1000.0), (testParamsPtr->outputParameters.suggestedLatency * 1000.0) ); } @@ -932,7 +943,7 @@ static int PaQa_AnalyzeLoopbackConnection( UserOptions *userOptions, PaDeviceInd int numSampleFormats = (sizeof(sampleFormats)/sizeof(PaSampleFormat)); printf( "=============== Analysing Loopback %d to %d =====================\n", outputDevice, inputDevice ); - printf( " Devices: %s => %s\n", outputDeviceInfo->name, inputDeviceInfo->name); + printf( " Devices: %s => %s\n", outputDeviceInfo->name, inputDeviceInfo->name); PaQa_SetDefaultTestParameters( &testParams, inputDevice, outputDevice ); @@ -947,7 +958,7 @@ static int PaQa_AnalyzeLoopbackConnection( UserOptions *userOptions, PaDeviceInd printf( "\n************ Mode = %s ************\n", (( testParams.flags & 1 ) ? s_FlagOnNames[0] : s_FlagOffNames[0]) ); printf("|- requested -|- measured ------------------------------\n"); - printf("|-sRate-|-fr/buf-|- frm/buf -|-latency-|- channel results -\n"); + printf("|-sRate-|-fr/buf-|- over/under/calls for in, out -|- frm/buf -|-latency-|- channel results -\n"); // Loop though various sample rates. if( userOptions->sampleRate < 0 ) @@ -1106,10 +1117,10 @@ int PaQa_CheckForLoopBack( UserOptions *userOptions, PaDeviceIndex inputDevice, printf( "Look for loopback cable between \"%s\" => \"%s\"\n", outputDeviceInfo->name, inputDeviceInfo->name); - printf( " default suggested input latency (msec): low = %5.2f, high = %5.2f\n", + printf( " Default suggested input latency (msec): low = %5.2f, high = %5.2f\n", (inputDeviceInfo->defaultLowInputLatency * 1000.0), (inputDeviceInfo->defaultHighInputLatency * 1000.0) ); - printf( " default suggested output latency (msec): low = %5.2f, high = %5.2f\n", + printf( " Default suggested output latency (msec): low = %5.2f, high = %5.2f\n", (outputDeviceInfo->defaultLowOutputLatency * 1000.0), (outputDeviceInfo->defaultHighOutputLatency * 1000.0) ); diff --git a/test/patest_two_rates.c b/test/patest_two_rates.c index 3b3b7a9..5a2b178 100644 --- a/test/patest_two_rates.c +++ b/test/patest_two_rates.c @@ -49,7 +49,7 @@ #define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) #define SAMPLE_RATE_1 (44100) -#define SAMPLE_RATE_2 (44100) +#define SAMPLE_RATE_2 (48000) #define FRAMES_PER_BUFFER (256) #define FREQ_INCR (0.1) @@ -60,22 +60,23 @@ typedef struct { double phase; - double numFrames; + int numFrames; } paTestData; /* 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(). -*/ -static int patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) + ** 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(). + */ +static int patestCallback( const void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void *userData ) { paTestData *data = (paTestData*)userData; float *out = (float*)outputBuffer; - int frameIndex, channelIndex; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ + int frameIndex; + (void) timeInfo; /* Prevent unused variable warnings. */ (void) inputBuffer; for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ ) @@ -89,7 +90,7 @@ static int patestCallback( void *inputBuffer, void *outputBuffer, data->phase += FREQ_INCR; if( data->phase >= (2.0 * M_PI) ) data->phase -= (2.0 * M_PI); } - + data->numFrames += 1; return 0; } @@ -98,8 +99,9 @@ int main(void); int main(void) { PaError err; - PortAudioStream *stream1; - PortAudioStream *stream2; + PaStreamParameters outputParameters; + PaStream *stream1; + PaStream *stream2; paTestData data1 = {0}; paTestData data2 = {0}; printf("PortAudio Test: two rates.\n" ); @@ -107,24 +109,27 @@ int main(void) err = Pa_Initialize(); if( err != paNoError ) goto error; - /* Start first stream. **********************/ + outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ + if (outputParameters.device == paNoDevice) { + fprintf(stderr,"Error: No default output device.\n"); + goto error; + } + outputParameters.channelCount = 2; /* stereo output */ + outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */ + outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; + outputParameters.hostApiSpecificStreamInfo = NULL; + + /* Start first stream. **********************/ err = Pa_OpenStream( - &stream1, - paNoDevice, /* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - OUTPUT_DEVICE, - 2, /* Stereo */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE_1, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data1 ); - if( err != paNoError ) goto error; + &stream1, + NULL, /* no input */ + &outputParameters, + SAMPLE_RATE_1, + FRAMES_PER_BUFFER, + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + patestCallback, + &data1 ); + if( err != paNoError ) goto error; err = Pa_StartStream( stream1 ); if( err != paNoError ) goto error; @@ -133,21 +138,14 @@ int main(void) /* Start second stream. **********************/ err = Pa_OpenStream( - &stream2, - paNoDevice, /* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - OUTPUT_DEVICE, - 2, /* Stereo */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE_2, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data2 ); + &stream2, + NULL, /* no input */ + &outputParameters, + SAMPLE_RATE_2, + FRAMES_PER_BUFFER, + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + patestCallback, + &data2 ); if( err != paNoError ) goto error; err = Pa_StartStream( stream2 ); @@ -167,6 +165,8 @@ int main(void) Pa_CloseStream( stream1 ); Pa_Terminate(); + + printf("NumFrames = %d on stream1, %d on stream2.\n", data1.numFrames, data2.numFrames ); printf("Test finished.\n"); return err; error: -- 2.43.0