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;
int i;
LoopbackContext *loopbackContext = (LoopbackContext *) userData;
-
+
loopbackContext->callbackCount += 1;
if( statusFlags & paInputUnderflow ) loopbackContext->inputUnderflowCount += 1;
if( statusFlags & paInputOverflow ) loopbackContext->inputOverflowCount += 1;
{
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;
{
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.
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++ )
{
{
printf( "OK" );
}
-
- printf( ", %d/%d,%d/%d ",
- loopbackContext.inputOverflowCount,
- loopbackContext.inputUnderflowCount,
- loopbackContext.outputOverflowCount,
- loopbackContext.outputUnderflowCount
- );
-
+
printf( "\n" );
PaQa_TeardownLoopbackContext( &loopbackContext );
{
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) );
}
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 );
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 )
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) );
#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)
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++ )
data->phase += FREQ_INCR;
if( data->phase >= (2.0 * M_PI) ) data->phase -= (2.0 * M_PI);
}
-
+ data->numFrames += 1;
return 0;
}
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" );
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;
/* 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 );
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: