Implement the Float32 to UInt8 converters.

The loopback test now passes cleanly for the first time on my PreSonus FireStudio.
Added tests for clip and dither flag combinations to loopback.
This commit is contained in:
philburk 2011-09-01 22:08:32 +00:00
commit 9cdd56f5b4
4 changed files with 88 additions and 50 deletions

View file

@ -91,7 +91,8 @@ typedef struct TestParameters_s
int maxFrames;
double baseFrequency;
double amplitude;
int flags;
PaStreamFlags streamFlags; // paClipOff, etc
int flags; // PAQA_FLAG_TWO_STREAMS, PAQA_FLAG_USE_BLOCKING_IO
} TestParameters;
typedef struct LoopbackContext_s
@ -106,15 +107,19 @@ typedef struct LoopbackContext_s
PaTime streamInfoOutputLatency;
// Measured at runtime.
int callbackCount; // incremented for each callback
int inputBufferCount; // incremented if input buffer not NULL
volatile int callbackCount; // incremented for each callback
volatile int inputBufferCount; // incremented if input buffer not NULL
int inputUnderflowCount;
int inputOverflowCount;
int outputBufferCount; // incremented if output buffer not NULL
volatile int outputBufferCount; // incremented if output buffer not NULL
int outputOverflowCount;
int outputUnderflowCount;
// Measure whether input or output is lagging behind.
volatile int minInputOutputDelta;
volatile int maxInputOutputDelta;
int minFramesPerBuffer;
int maxFramesPerBuffer;
int primingCount;
@ -239,7 +244,22 @@ static int RecordAndPlaySinesCallback( const void *inputBuffer, void *outputBuff
}
}
// Measure whether the input or output are lagging behind.
// Don't measure lag at end.
if( !loopbackContext->done )
{
int inputOutputDelta = loopbackContext->inputBufferCount - loopbackContext->outputBufferCount;
if( loopbackContext->maxInputOutputDelta < inputOutputDelta )
{
loopbackContext->maxInputOutputDelta = inputOutputDelta;
}
if( loopbackContext->minInputOutputDelta > inputOutputDelta )
{
loopbackContext->minInputOutputDelta = inputOutputDelta;
}
}
return loopbackContext->done ? paComplete : paContinue;
}
@ -350,7 +370,7 @@ int PaQa_RunLoopbackHalfDuplex( LoopbackContext *loopbackContext )
NULL,
test->sampleRate,
test->framesPerBuffer,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
test->streamFlags,
RecordAndPlaySinesCallback,
loopbackContext );
if( err != paNoError ) goto error;
@ -360,7 +380,7 @@ int PaQa_RunLoopbackHalfDuplex( LoopbackContext *loopbackContext )
&test->outputParameters,
test->sampleRate,
test->framesPerBuffer,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
test->streamFlags,
RecordAndPlaySinesCallback,
loopbackContext );
if( err != paNoError ) goto error;
@ -870,8 +890,9 @@ static int PaQa_SingleLoopBackTest( UserOptions *userOptions, TestParameters *te
{
printf( "OK" );
}
printf( "\n" );
PaQa_TeardownLoopbackContext( &loopbackContext );
if( numBadChannels > 0 )
@ -899,6 +920,7 @@ static void PaQa_SetDefaultTestParameters( TestParameters *testParamsPtr, PaDevi
testParamsPtr->framesPerBuffer = DEFAULT_FRAMES_PER_BUFFER;
testParamsPtr->baseFrequency = 200.0;
testParamsPtr->flags = PAQA_FLAG_TWO_STREAMS;
testParamsPtr->streamFlags = paClipOff; /* we won't output out of range samples so don't bother clipping them */
testParamsPtr->inputParameters.device = inputDevice;
testParamsPtr->inputParameters.sampleFormat = paFloat32;
@ -1038,18 +1060,27 @@ static int PaQa_AnalyzeLoopbackConnection( UserOptions *userOptions, PaDeviceInd
}
printf("\nTest Sample Formats using Half Duplex IO -----\n" );
testParams.flags = PAQA_FLAG_TWO_STREAMS;
for( iFormat=0; iFormat<numSampleFormats; iFormat++ )
{
int numBadChannels;
PaSampleFormat format = sampleFormats[ iFormat ];
testParams.inputParameters.sampleFormat = format;
testParams.outputParameters.sampleFormat = format;
printf("Sample format = %d = %s\n", (int) format, sampleFormatNames[iFormat] );
numBadChannels = PaQa_SingleLoopBackTest( userOptions, &testParams );
totalBadChannels += numBadChannels;
}
PaQa_SetDefaultTestParameters( &testParams, inputDevice, outputDevice );
testParams.flags = PAQA_FLAG_TWO_STREAMS;
for( int iFlags= 0; iFlags<4; iFlags++ )
{
// Cycle through combinations of flags.
testParams.streamFlags = 0;
if( iFlags & 1 ) testParams.streamFlags |= paClipOff;
if( iFlags & 2 ) testParams.streamFlags |= paDitherOff;
for( iFormat=0; iFormat<numSampleFormats; iFormat++ )
{
int numBadChannels;
PaSampleFormat format = sampleFormats[ iFormat ];
testParams.inputParameters.sampleFormat = format;
testParams.outputParameters.sampleFormat = format;
printf("Sample format = %d = %s, PaStreamFlags = 0x%02X\n", (int) format, sampleFormatNames[iFormat], (unsigned int) testParams.streamFlags );
numBadChannels = PaQa_SingleLoopBackTest( userOptions, &testParams );
totalBadChannels += numBadChannels;
}
}
printf( "\n" );
printf( "****************************************\n");
@ -1159,7 +1190,7 @@ int PaQa_CheckForLoopBack( UserOptions *userOptions, PaDeviceIndex inputDevice,
PaQa_OverrideTestParameters( &testParams, userOptions );
testParams.maxFrames = (int) (LOOPBACK_DETECTION_DURATION_SECONDS * testParams.sampleRate);
minAmplitude = testParams.amplitude / 2.0;
minAmplitude = testParams.amplitude / 4.0;
// Check to see if the selected formats are supported.
if( Pa_IsFormatSupported( &testParams.inputParameters, NULL, testParams.sampleRate ) != paFormatIsSupported )