16381639
127
    PaDeviceIndex outputDevice;
127
    PaDeviceIndex outputDevice;
128
} UserOptions;
128
} UserOptions;
129
 
129
 
130
#define BIG_BUFFER_SIZE  (sizeof(float) * 2 * 2048)
130
#define BIG_BUFFER_SIZE  (sizeof(float) * 2 * 2 * 1024)
131
static unsigned char g_ReadWriteBuffer[BIG_BUFFER_SIZE];
131
static unsigned char g_ReadWriteBuffer[BIG_BUFFER_SIZE];
132
static unsigned char g_ConversionBuffer[BIG_BUFFER_SIZE];
 
 
133
 
132
 
 
 
133
#define MAX_CONVERSION_SAMPLES   (2 * 32 * 1024)
 
 
134
#define CONVERSION_BUFFER_SIZE  (sizeof(float) * 2 * MAX_CONVERSION_SAMPLES)
 
 
135
static unsigned char g_ConversionBuffer[CONVERSION_BUFFER_SIZE];
 
 
136
 
134
/*******************************************************************/
137
/*******************************************************************/
135
static int RecordAndPlaySinesCallback( const void *inputBuffer, void *outputBuffer,
138
static int RecordAndPlaySinesCallback( const void *inputBuffer, void *outputBuffer,
136
                        unsigned long framesPerBuffer,
139
                        unsigned long framesPerBuffer,
...
 
...
 
164
    {
167
    {
165
        int channelsPerFrame = loopbackContext->test->inputParameters.channelCount;
168
        int channelsPerFrame = loopbackContext->test->inputParameters.channelCount;
166
        float *in = (float *)inputBuffer;
169
        float *in = (float *)inputBuffer;
167
        
170
 
168
        PaSampleFormat inFormat = loopbackContext->test->inputParameters.sampleFormat;
171
        PaSampleFormat inFormat = loopbackContext->test->inputParameters.sampleFormat;
169
        if( inFormat != paFloat32 )
172
        if( inFormat != paFloat32 )
170
        {
173
        {
 
 
174
            int samplesToConvert = framesPerBuffer * channelsPerFrame;
171
            in = (float *) g_ConversionBuffer;
175
            in = (float *) g_ConversionBuffer;
172
            PaQa_ConvertToFloat( inputBuffer, framesPerBuffer * channelsPerFrame, inFormat, (float *) g_ConversionBuffer );
176
            if( samplesToConvert > MAX_CONVERSION_SAMPLES )
 
 
177
            {
 
 
178
                // Hack to prevent buffer overflow.
 
 
179
                // @todo Loop with small buffer instead of failing.
 
 
180
                printf("Format conversion buffer too small!\n");
 
 
181
                return paComplete;
 
 
182
            }
 
 
183
            PaQa_ConvertToFloat( inputBuffer, samplesToConvert, inFormat, (float *) g_ConversionBuffer );
173
        }
184
        }
174
 
185
 
175
        // Read each channel from the buffer.
186
        // Read each channel from the buffer.
...
 
...
 
205
 
216
 
206
        if( outFormat != paFloat32 )
217
        if( outFormat != paFloat32 )
207
        {
218
        {
 
 
219
            int samplesToConvert = framesPerBuffer * channelsPerFrame;
 
 
220
            if( samplesToConvert > MAX_CONVERSION_SAMPLES )
 
 
221
            {
 
 
222
                printf("Format conversion buffer too small!\n");
 
 
223
                return paComplete;
 
 
224
            }            
208
            PaQa_ConvertFromFloat( out, framesPerBuffer * channelsPerFrame, outFormat, outputBuffer );
225
            PaQa_ConvertFromFloat( out, framesPerBuffer * channelsPerFrame, outFormat, outputBuffer );
209
        }
226
        }
210
 
227
 
...
 
...
 
809
        printf( "OK" );
826
        printf( "OK" );
810
    }
827
    }
811
 
828
 
812
    printf( ", %d/%d/%d/%d ",
829
    printf( ", %d/%d,%d/%d ",
813
           loopbackContext.inputOverflowCount,
830
           loopbackContext.inputOverflowCount,
814
           loopbackContext.inputUnderflowCount,
831
           loopbackContext.inputUnderflowCount,
815
           loopbackContext.outputOverflowCount,
832
           loopbackContext.outputOverflowCount,
...
 
...
 
914
    const char *sampleFormatNames[] = { "paUInt8", "paInt8", "paInt16", "paInt32" };
931
    const char *sampleFormatNames[] = { "paUInt8", "paInt8", "paInt16", "paInt32" };
915
    int numSampleFormats = (sizeof(sampleFormats)/sizeof(PaSampleFormat));
932
    int numSampleFormats = (sizeof(sampleFormats)/sizeof(PaSampleFormat));
916
 
933
 
917
    printf( "=============== Analysing Loopback %d to %d ====================\n", outputDevice, inputDevice  );
934
    printf( "=============== Analysing Loopback %d to %d =====================\n", outputDevice, inputDevice  );
918
    printf( "    Devices: %s => %s\n", outputDeviceInfo->name, inputDeviceInfo->name);
935
    printf( "    Devices: %s => %s\n", outputDeviceInfo->name, inputDeviceInfo->name);
919
 
936
 
920
    PaQa_SetDefaultTestParameters( &testParams, inputDevice, outputDevice );
937
    PaQa_SetDefaultTestParameters( &testParams, inputDevice, outputDevice );
...
 
...
 
929
        testParams.flags = flagSettings[iFlags];
946
        testParams.flags = flagSettings[iFlags];
930
        printf( "\n************ Mode = %s ************\n",
947
        printf( "\n************ Mode = %s ************\n",
931
               (( testParams.flags & 1 ) ? s_FlagOnNames[0] : s_FlagOffNames[0]) );
948
               (( testParams.flags & 1 ) ? s_FlagOnNames[0] : s_FlagOffNames[0]) );
932
        printf("|-   requested  -|- measured ----------------------------------------------->\n");
949
        printf("|-   requested  -|- measured ------------------------------\n");
933
        printf("|-sRate-|-fr/buf-|- frm/buf -|-latency-|-channel results-------------------->\n");
950
        printf("|-sRate-|-fr/buf-|- frm/buf -|-latency-|- channel results -\n");
934
 
951
 
935
        // Loop though various sample rates.
952
        // Loop though various sample rates.
936
        if( userOptions->sampleRate < 0 )
953
        if( userOptions->sampleRate < 0 )
...
 
...
 
1117
 
1134
 
1118
    PaQa_SetupLoopbackContext( &loopbackContext, &testParams );
1135
    PaQa_SetupLoopbackContext( &loopbackContext, &testParams );
1119
 
1136
 
1120
    testParams.flags = PAQA_FLAG_TWO_STREAMS;
1137
    if( inputDevice == outputDevice )
 
 
1138
    {
 
 
1139
        // Use full duplex if checking for loopback on one device.
 
 
1140
        testParams.flags &= ~PAQA_FLAG_TWO_STREAMS;
 
 
1141
    }
 
 
1142
    else
 
 
1143
    {
 
 
1144
        // Use half duplex if checking for loopback on two different device.
 
 
1145
        testParams.flags = PAQA_FLAG_TWO_STREAMS;
 
 
1146
    }
1121
    err = PaQa_RunLoopback( &loopbackContext );
1147
    err = PaQa_RunLoopback( &loopbackContext );
1122
    QA_ASSERT_TRUE("loopback detection callback did not run", (loopbackContext.callbackCount > 1) );
1148
    QA_ASSERT_TRUE("loopback detection callback did not run", (loopbackContext.callbackCount > 1) );
1123
 
1149