Convert patest_two_rates.c to V19.
Make paloopback over/underflow report easier to understand.
This commit is contained in:
parent
8e5dda777a
commit
5db3f8fb7c
2 changed files with 75 additions and 64 deletions
|
|
@ -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; i<testParams->samplesPerFrame; 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) );
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue