1638 | 1639 | ||
---|---|---|---|
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 |