From: philburk Date: Thu, 1 Sep 2011 22:08:32 +0000 (+0000) Subject: Implement the Float32 to UInt8 converters. X-Git-Tag: pa_stable_v19_20111121_r1788~28 X-Git-Url: https://andrewgundersen.net/repos?a=commitdiff_plain;h=9cdd56f5b4f2776ff8a62947b1eaf8fe1a2d9f6b;p=portaudio 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. --- diff --git a/qa/loopback/src/paqa.c b/qa/loopback/src/paqa.c index 3ac6599..ad993a9 100644 --- a/qa/loopback/src/paqa.c +++ b/qa/loopback/src/paqa.c @@ -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; iFormatstreamRepresentation.magic == PA_STREAM_MAGIC ); + OSStatus osErr = UpdateSampleRateFromDeviceProperty( stream, inDevice, isInput ); if( osErr == noErr ) { @@ -1034,6 +1038,10 @@ static OSStatus AudioDevicePropertyGenericListenerProc( AudioDeviceID inDevice, { OSStatus osErr = noErr; PaMacCoreStream *stream = (PaMacCoreStream*)inClientData; + + // Make sure the callback is operating on a stream that is still valid! + assert( stream->streamRepresentation.magic == PA_STREAM_MAGIC ); + PaMacCoreDeviceProperties *deviceProperties = isInput ? &stream->inputProperties : &stream->outputProperties; UInt32 *valuePtr = NULL; switch( inPropertyID ) @@ -2107,7 +2115,7 @@ static OSStatus AudioIOProc( void *inRefCon, PaMacCoreStream *stream = (PaMacCoreStream*)inRefCon; const bool isRender = inBusNumber == OUTPUT_ELEMENT; int callbackResult = paContinue ; - double hostTimeStampInPaTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime); + double hostTimeStampInPaTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime); VVDBUG(("AudioIOProc()\n")); diff --git a/test/patest_sine8.c b/test/patest_sine8.c index beeae9e..c00319a 100644 --- a/test/patest_sine8.c +++ b/test/patest_sine8.c @@ -52,8 +52,12 @@ #if TEST_UNSIGNED #define TEST_FORMAT paUInt8 +typedef unsigned char sample_t; +#define SILENCE ((sample_t)0x80) #else #define TEST_FORMAT paInt8 +typedef char sample_t; +#define SILENCE ((sample_t)0x00) #endif #ifndef M_PI @@ -62,11 +66,7 @@ typedef struct { -#if TEST_UNSIGNED - unsigned char sine[TABLE_SIZE]; -#else - char sine[TABLE_SIZE]; -#endif + sample_t sine[TABLE_SIZE]; int left_phase; int right_phase; unsigned int framesToGo; @@ -84,7 +84,7 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer, void *userData ) { paTestData *data = (paTestData*)userData; - char *out = (char*)outputBuffer; + sample_t *out = (sample_t*)outputBuffer; int i; int framesToCalc; int finished = 0; @@ -114,14 +114,8 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer, /* zero remainder of final buffer */ for( ; i<(int)framesPerBuffer; i++ ) { -#if TEST_UNSIGNED - *out++ = (unsigned char) 0x80; /* left */ - *out++ = (unsigned char) 0x80; /* right */ -#else - *out++ = 0; /* left */ - *out++ = 0; /* right */ -#endif - + *out++ = SILENCE; /* left */ + *out++ = SILENCE; /* right */ } return finished; } @@ -145,10 +139,7 @@ int main(void) /* initialise sinusoidal wavetable */ for( i=0; i