| cannam@89 | 1 /** @file patest_converters.c | 
| cannam@89 | 2 	@ingroup test_src | 
| cannam@89 | 3 	@brief Tests the converter functions in pa_converters.c | 
| cannam@89 | 4 	@author Ross Bencina <rossb@audiomulch.com> | 
| cannam@89 | 5 | 
| cannam@89 | 6     Link with pa_dither.c and pa_converters.c | 
| cannam@89 | 7 | 
| cannam@89 | 8     see http://www.portaudio.com/trac/wiki/V19ConvertersStatus for a discussion of this. | 
| cannam@89 | 9 */ | 
| cannam@89 | 10 /* | 
| cannam@89 | 11  * $Id: $ | 
| cannam@89 | 12  * | 
| cannam@89 | 13  * This program uses the PortAudio Portable Audio Library. | 
| cannam@89 | 14  * For more information see: http://www.portaudio.com/ | 
| cannam@89 | 15  * Copyright (c) 1999-2008 Ross Bencina and Phil Burk | 
| cannam@89 | 16  * | 
| cannam@89 | 17  * Permission is hereby granted, free of charge, to any person obtaining | 
| cannam@89 | 18  * a copy of this software and associated documentation files | 
| cannam@89 | 19  * (the "Software"), to deal in the Software without restriction, | 
| cannam@89 | 20  * including without limitation the rights to use, copy, modify, merge, | 
| cannam@89 | 21  * publish, distribute, sublicense, and/or sell copies of the Software, | 
| cannam@89 | 22  * and to permit persons to whom the Software is furnished to do so, | 
| cannam@89 | 23  * subject to the following conditions: | 
| cannam@89 | 24  * | 
| cannam@89 | 25  * The above copyright notice and this permission notice shall be | 
| cannam@89 | 26  * included in all copies or substantial portions of the Software. | 
| cannam@89 | 27  * | 
| cannam@89 | 28  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
| cannam@89 | 29  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 
| cannam@89 | 30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | 
| cannam@89 | 31  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR | 
| cannam@89 | 32  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | 
| cannam@89 | 33  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | 
| cannam@89 | 34  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 
| cannam@89 | 35  */ | 
| cannam@89 | 36 | 
| cannam@89 | 37 /* | 
| cannam@89 | 38  * The text above constitutes the entire PortAudio license; however, | 
| cannam@89 | 39  * the PortAudio community also makes the following non-binding requests: | 
| cannam@89 | 40  * | 
| cannam@89 | 41  * Any person wishing to distribute modifications to the Software is | 
| cannam@89 | 42  * requested to send the modifications to the original developer so that | 
| cannam@89 | 43  * they can be incorporated into the canonical version. It is also | 
| cannam@89 | 44  * requested that these non-binding requests be included along with the | 
| cannam@89 | 45  * license above. | 
| cannam@89 | 46  */ | 
| cannam@89 | 47 #include <stdio.h> | 
| cannam@89 | 48 #include <stdlib.h> | 
| cannam@89 | 49 #include <string.h> | 
| cannam@89 | 50 #include <math.h> | 
| cannam@89 | 51 | 
| cannam@89 | 52 #include "portaudio.h" | 
| cannam@89 | 53 #include "pa_converters.h" | 
| cannam@89 | 54 #include "pa_dither.h" | 
| cannam@89 | 55 #include "pa_types.h" | 
| cannam@89 | 56 #include "pa_endianness.h" | 
| cannam@89 | 57 | 
| cannam@89 | 58 #ifndef M_PI | 
| cannam@89 | 59 #define M_PI  (3.14159265) | 
| cannam@89 | 60 #endif | 
| cannam@89 | 61 | 
| cannam@89 | 62 #define MAX_PER_CHANNEL_FRAME_COUNT     (2048) | 
| cannam@89 | 63 #define MAX_CHANNEL_COUNT               (8) | 
| cannam@89 | 64 | 
| cannam@89 | 65 | 
| cannam@89 | 66 #define SAMPLE_FORMAT_COUNT (6) | 
| cannam@89 | 67 | 
| cannam@89 | 68 static PaSampleFormat sampleFormats_[ SAMPLE_FORMAT_COUNT ] = | 
| cannam@89 | 69     { paFloat32, paInt32, paInt24, paInt16, paInt8, paUInt8 }; /* all standard PA sample formats */ | 
| cannam@89 | 70 | 
| cannam@89 | 71 static const char* sampleFormatNames_[SAMPLE_FORMAT_COUNT] = | 
| cannam@89 | 72     { "paFloat32", "paInt32", "paInt24", "paInt16", "paInt8", "paUInt8" }; | 
| cannam@89 | 73 | 
| cannam@89 | 74 | 
| cannam@89 | 75 static const char* abbreviatedSampleFormatNames_[SAMPLE_FORMAT_COUNT] = | 
| cannam@89 | 76     { "f32", "i32", "i24", "i16", " i8", "ui8" }; | 
| cannam@89 | 77 | 
| cannam@89 | 78 | 
| cannam@89 | 79 PaError My_Pa_GetSampleSize( PaSampleFormat format ); | 
| cannam@89 | 80 | 
| cannam@89 | 81 /* | 
| cannam@89 | 82     available flags are paClipOff and paDitherOff | 
| cannam@89 | 83     clipping is usually applied for float -> int conversions | 
| cannam@89 | 84     dither is usually applied for all downconversions (ie anything but 8bit->8bit conversions | 
| cannam@89 | 85 */ | 
| cannam@89 | 86 | 
| cannam@89 | 87 static int CanClip( PaSampleFormat sourceFormat, PaSampleFormat destinationFormat ) | 
| cannam@89 | 88 { | 
| cannam@89 | 89     if( sourceFormat == paFloat32 && destinationFormat != sourceFormat ) | 
| cannam@89 | 90         return 1; | 
| cannam@89 | 91     else | 
| cannam@89 | 92         return 0; | 
| cannam@89 | 93 } | 
| cannam@89 | 94 | 
| cannam@89 | 95 static int CanDither( PaSampleFormat sourceFormat, PaSampleFormat destinationFormat ) | 
| cannam@89 | 96 { | 
| cannam@89 | 97     if( sourceFormat < destinationFormat && sourceFormat != paInt8 ) | 
| cannam@89 | 98         return 1; | 
| cannam@89 | 99     else | 
| cannam@89 | 100         return 0; | 
| cannam@89 | 101 } | 
| cannam@89 | 102 | 
| cannam@89 | 103 static void GenerateOneCycleSineReference( double *out, int frameCount, int strideFrames ) | 
| cannam@89 | 104 { | 
| cannam@89 | 105     int i; | 
| cannam@89 | 106     for( i=0; i < frameCount; ++i ){ | 
| cannam@89 | 107         *out = sin( ((double)i/(double)frameCount) * 2. * M_PI ); | 
| cannam@89 | 108         out += strideFrames; | 
| cannam@89 | 109     } | 
| cannam@89 | 110 } | 
| cannam@89 | 111 | 
| cannam@89 | 112 | 
| cannam@89 | 113 static void GenerateOneCycleSine( PaSampleFormat format, void *buffer, int frameCount, int strideFrames ) | 
| cannam@89 | 114 { | 
| cannam@89 | 115     switch( format ){ | 
| cannam@89 | 116 | 
| cannam@89 | 117         case paFloat32: | 
| cannam@89 | 118             { | 
| cannam@89 | 119                 int i; | 
| cannam@89 | 120                 float *out = (float*)buffer; | 
| cannam@89 | 121                 for( i=0; i < frameCount; ++i ){ | 
| cannam@89 | 122                     *out = (float).9 * sin( ((double)i/(double)frameCount) * 2. * M_PI ); | 
| cannam@89 | 123                     out += strideFrames; | 
| cannam@89 | 124                 } | 
| cannam@89 | 125             } | 
| cannam@89 | 126             break; | 
| cannam@89 | 127         case paInt32: | 
| cannam@89 | 128             { | 
| cannam@89 | 129                 int i; | 
| cannam@89 | 130                 PaInt32 *out = (PaInt32*)buffer; | 
| cannam@89 | 131                 for( i=0; i < frameCount; ++i ){ | 
| cannam@89 | 132                     *out = (PaInt32)(.9 * sin( ((double)i/(double)frameCount) * 2. * M_PI ) * 0x7FFFFFFF); | 
| cannam@89 | 133                     out += strideFrames; | 
| cannam@89 | 134                 } | 
| cannam@89 | 135             } | 
| cannam@89 | 136             break; | 
| cannam@89 | 137         case paInt24: | 
| cannam@89 | 138             { | 
| cannam@89 | 139                 int i; | 
| cannam@89 | 140                 unsigned char *out = (unsigned char*)buffer; | 
| cannam@89 | 141                 for( i=0; i < frameCount; ++i ){ | 
| cannam@89 | 142                     signed long temp = (PaInt32)(.9 * sin( ((double)i/(double)frameCount) * 2. * M_PI ) * 0x7FFFFFFF); | 
| cannam@89 | 143 | 
| cannam@89 | 144                     #if defined(PA_LITTLE_ENDIAN) | 
| cannam@89 | 145                             out[0] = (unsigned char)(temp >> 8) & 0xFF; | 
| cannam@89 | 146                             out[1] = (unsigned char)(temp >> 16) & 0xFF; | 
| cannam@89 | 147                             out[2] = (unsigned char)(temp >> 24) & 0xFF; | 
| cannam@89 | 148                     #elif defined(PA_BIG_ENDIAN) | 
| cannam@89 | 149                             out[0] = (unsigned char)(temp >> 24) & 0xFF; | 
| cannam@89 | 150                             out[1] = (unsigned char)(temp >> 16) & 0xFF; | 
| cannam@89 | 151                             out[2] = (unsigned char)(temp >> 8) & 0xFF; | 
| cannam@89 | 152                     #endif | 
| cannam@89 | 153                     out += 3; | 
| cannam@89 | 154                 } | 
| cannam@89 | 155             } | 
| cannam@89 | 156             break; | 
| cannam@89 | 157         case paInt16: | 
| cannam@89 | 158             { | 
| cannam@89 | 159                 int i; | 
| cannam@89 | 160                 PaInt16 *out = (PaInt16*)buffer; | 
| cannam@89 | 161                 for( i=0; i < frameCount; ++i ){ | 
| cannam@89 | 162                     *out = (PaInt16)(.9 * sin( ((double)i/(double)frameCount) * 2. * M_PI ) * 0x7FFF ); | 
| cannam@89 | 163                     out += strideFrames; | 
| cannam@89 | 164                 } | 
| cannam@89 | 165             } | 
| cannam@89 | 166             break; | 
| cannam@89 | 167         case paInt8: | 
| cannam@89 | 168             { | 
| cannam@89 | 169                 int i; | 
| cannam@89 | 170                 signed char *out = (signed char*)buffer; | 
| cannam@89 | 171                 for( i=0; i < frameCount; ++i ){ | 
| cannam@89 | 172                     *out = (signed char)(.9 * sin( ((double)i/(double)frameCount) * 2. * M_PI ) * 0x7F ); | 
| cannam@89 | 173                     out += strideFrames; | 
| cannam@89 | 174                 } | 
| cannam@89 | 175             } | 
| cannam@89 | 176             break; | 
| cannam@89 | 177         case paUInt8: | 
| cannam@89 | 178             { | 
| cannam@89 | 179                 int i; | 
| cannam@89 | 180                 unsigned char *out = (unsigned char*)buffer; | 
| cannam@89 | 181                 for( i=0; i < frameCount; ++i ){ | 
| cannam@89 | 182                     *out = (unsigned char)( .5 * (1. + (.9 * sin( ((double)i/(double)frameCount) * 2. * M_PI ))) * 0xFF  ); | 
| cannam@89 | 183                     out += strideFrames; | 
| cannam@89 | 184                 } | 
| cannam@89 | 185             } | 
| cannam@89 | 186             break; | 
| cannam@89 | 187     } | 
| cannam@89 | 188 } | 
| cannam@89 | 189 | 
| cannam@89 | 190 int TestNonZeroPresent( void *buffer, int size ) | 
| cannam@89 | 191 { | 
| cannam@89 | 192     char *p = (char*)buffer; | 
| cannam@89 | 193     int i; | 
| cannam@89 | 194 | 
| cannam@89 | 195     for( i=0; i < size; ++i ){ | 
| cannam@89 | 196 | 
| cannam@89 | 197         if( *p != 0 ) | 
| cannam@89 | 198             return 1; | 
| cannam@89 | 199         ++p; | 
| cannam@89 | 200     } | 
| cannam@89 | 201 | 
| cannam@89 | 202     return 0; | 
| cannam@89 | 203 } | 
| cannam@89 | 204 | 
| cannam@89 | 205 float MaximumAbsDifference( float* sourceBuffer, float* referenceBuffer, int count ) | 
| cannam@89 | 206 { | 
| cannam@89 | 207     float result = 0; | 
| cannam@89 | 208     float difference; | 
| cannam@89 | 209     while( count-- ){ | 
| cannam@89 | 210         difference = fabs( *sourceBuffer++ - *referenceBuffer++ ); | 
| cannam@89 | 211         if( difference > result ) | 
| cannam@89 | 212             result = difference; | 
| cannam@89 | 213     } | 
| cannam@89 | 214 | 
| cannam@89 | 215     return result; | 
| cannam@89 | 216 } | 
| cannam@89 | 217 | 
| cannam@89 | 218 int main( const char **argv, int argc ) | 
| cannam@89 | 219 { | 
| cannam@89 | 220     PaUtilTriangularDitherGenerator ditherState; | 
| cannam@89 | 221     PaUtilConverter *converter; | 
| cannam@89 | 222     void *destinationBuffer, *sourceBuffer; | 
| cannam@89 | 223     double *referenceBuffer; | 
| cannam@89 | 224     int sourceFormatIndex, destinationFormatIndex; | 
| cannam@89 | 225     PaSampleFormat sourceFormat, destinationFormat; | 
| cannam@89 | 226     PaStreamFlags flags; | 
| cannam@89 | 227     int passFailMatrix[SAMPLE_FORMAT_COUNT][SAMPLE_FORMAT_COUNT]; // [source][destination] | 
| cannam@89 | 228     float noiseAmplitudeMatrix[SAMPLE_FORMAT_COUNT][SAMPLE_FORMAT_COUNT]; // [source][destination] | 
| cannam@89 | 229     float amp; | 
| cannam@89 | 230 | 
| cannam@89 | 231 #define FLAG_COMBINATION_COUNT (4) | 
| cannam@89 | 232     PaStreamFlags flagCombinations[FLAG_COMBINATION_COUNT] = { paNoFlag, paClipOff, paDitherOff, paClipOff | paDitherOff }; | 
| cannam@89 | 233     const char *flagCombinationNames[FLAG_COMBINATION_COUNT] = { "paNoFlag", "paClipOff", "paDitherOff", "paClipOff | paDitherOff" }; | 
| cannam@89 | 234     int flagCombinationIndex; | 
| cannam@89 | 235 | 
| cannam@89 | 236     PaUtil_InitializeTriangularDitherState( &ditherState ); | 
| cannam@89 | 237 | 
| cannam@89 | 238     /* allocate more than enough space, we use sizeof(float) but we need to fit any 32 bit datum */ | 
| cannam@89 | 239 | 
| cannam@89 | 240     destinationBuffer = (void*)malloc( MAX_PER_CHANNEL_FRAME_COUNT * MAX_CHANNEL_COUNT * sizeof(float) ); | 
| cannam@89 | 241     sourceBuffer = (void*)malloc( MAX_PER_CHANNEL_FRAME_COUNT * MAX_CHANNEL_COUNT * sizeof(float) ); | 
| cannam@89 | 242     referenceBuffer = (void*)malloc( MAX_PER_CHANNEL_FRAME_COUNT * MAX_CHANNEL_COUNT * sizeof(float) ); | 
| cannam@89 | 243 | 
| cannam@89 | 244 | 
| cannam@89 | 245     /* the first round of tests simply iterates through the buffer combinations testing | 
| cannam@89 | 246         that putting something in gives something out */ | 
| cannam@89 | 247 | 
| cannam@89 | 248     printf( "= Sine wave in, something out =\n" ); | 
| cannam@89 | 249 | 
| cannam@89 | 250     printf( "\n" ); | 
| cannam@89 | 251 | 
| cannam@89 | 252     GenerateOneCycleSine( paFloat32, referenceBuffer, MAX_PER_CHANNEL_FRAME_COUNT, 1 ); | 
| cannam@89 | 253 | 
| cannam@89 | 254     for( flagCombinationIndex = 0; flagCombinationIndex < FLAG_COMBINATION_COUNT; ++flagCombinationIndex ){ | 
| cannam@89 | 255         flags = flagCombinations[flagCombinationIndex]; | 
| cannam@89 | 256 | 
| cannam@89 | 257         printf( "\n" ); | 
| cannam@89 | 258         printf( "== flags = %s ==\n", flagCombinationNames[flagCombinationIndex] ); | 
| cannam@89 | 259 | 
| cannam@89 | 260         for( sourceFormatIndex = 0; sourceFormatIndex < SAMPLE_FORMAT_COUNT; ++sourceFormatIndex ){ | 
| cannam@89 | 261             for( destinationFormatIndex = 0; destinationFormatIndex < SAMPLE_FORMAT_COUNT; ++destinationFormatIndex ){ | 
| cannam@89 | 262                 sourceFormat = sampleFormats_[sourceFormatIndex]; | 
| cannam@89 | 263                 destinationFormat = sampleFormats_[destinationFormatIndex]; | 
| cannam@89 | 264                 //printf( "%s -> %s ", sampleFormatNames_[ sourceFormatIndex ], sampleFormatNames_[ destinationFormatIndex ] ); | 
| cannam@89 | 265 | 
| cannam@89 | 266                 converter = PaUtil_SelectConverter( sourceFormat, destinationFormat, flags ); | 
| cannam@89 | 267 | 
| cannam@89 | 268                 /* source is a sinewave */ | 
| cannam@89 | 269                 GenerateOneCycleSine( sourceFormat, sourceBuffer, MAX_PER_CHANNEL_FRAME_COUNT, 1 ); | 
| cannam@89 | 270 | 
| cannam@89 | 271                 /* zero destination */ | 
| cannam@89 | 272                 memset( destinationBuffer, 0, MAX_PER_CHANNEL_FRAME_COUNT * My_Pa_GetSampleSize( destinationFormat ) ); | 
| cannam@89 | 273 | 
| cannam@89 | 274                 (*converter)( destinationBuffer, 1, sourceBuffer, 1, MAX_PER_CHANNEL_FRAME_COUNT, &ditherState ); | 
| cannam@89 | 275 | 
| cannam@89 | 276     /* | 
| cannam@89 | 277     Other ways we could test this would be: | 
| cannam@89 | 278         - pass a constant, check for a constant (wouldn't work with dither) | 
| cannam@89 | 279         - pass alternating +/-, check for the same... | 
| cannam@89 | 280     */ | 
| cannam@89 | 281                 if( TestNonZeroPresent( destinationBuffer, MAX_PER_CHANNEL_FRAME_COUNT * My_Pa_GetSampleSize( destinationFormat ) ) ){ | 
| cannam@89 | 282                     //printf( "PASSED\n" ); | 
| cannam@89 | 283                     passFailMatrix[sourceFormatIndex][destinationFormatIndex] = 1; | 
| cannam@89 | 284                 }else{ | 
| cannam@89 | 285                     //printf( "FAILED\n" ); | 
| cannam@89 | 286                     passFailMatrix[sourceFormatIndex][destinationFormatIndex] = 0; | 
| cannam@89 | 287                 } | 
| cannam@89 | 288 | 
| cannam@89 | 289 | 
| cannam@89 | 290                 /* try to measure the noise floor (comparing output signal to a float32 sine wave) */ | 
| cannam@89 | 291 | 
| cannam@89 | 292                 if( passFailMatrix[sourceFormatIndex][destinationFormatIndex] ){ | 
| cannam@89 | 293 | 
| cannam@89 | 294                     /* convert destination back to paFloat32 into source */ | 
| cannam@89 | 295                     converter = PaUtil_SelectConverter( destinationFormat, paFloat32, paNoFlag ); | 
| cannam@89 | 296 | 
| cannam@89 | 297                     memset( sourceBuffer, 0, MAX_PER_CHANNEL_FRAME_COUNT * My_Pa_GetSampleSize( paFloat32 ) ); | 
| cannam@89 | 298                     (*converter)( sourceBuffer, 1, destinationBuffer, 1, MAX_PER_CHANNEL_FRAME_COUNT, &ditherState ); | 
| cannam@89 | 299 | 
| cannam@89 | 300                     if( TestNonZeroPresent( sourceBuffer, MAX_PER_CHANNEL_FRAME_COUNT * My_Pa_GetSampleSize( paFloat32 ) ) ){ | 
| cannam@89 | 301 | 
| cannam@89 | 302                         noiseAmplitudeMatrix[sourceFormatIndex][destinationFormatIndex] = MaximumAbsDifference( (float*)sourceBuffer, (float*)referenceBuffer, MAX_PER_CHANNEL_FRAME_COUNT ); | 
| cannam@89 | 303 | 
| cannam@89 | 304                     }else{ | 
| cannam@89 | 305                         /* can't test noise floor because there is no conversion from dest format to float available */ | 
| cannam@89 | 306                         noiseAmplitudeMatrix[sourceFormatIndex][destinationFormatIndex] = -1; // mark as failed | 
| cannam@89 | 307                     } | 
| cannam@89 | 308                 }else{ | 
| cannam@89 | 309                     noiseAmplitudeMatrix[sourceFormatIndex][destinationFormatIndex] = -1; // mark as failed | 
| cannam@89 | 310                 } | 
| cannam@89 | 311             } | 
| cannam@89 | 312         } | 
| cannam@89 | 313 | 
| cannam@89 | 314         printf( "\n" ); | 
| cannam@89 | 315         printf( "=== Output contains non-zero data ===\n" ); | 
| cannam@89 | 316         printf( "Key: . - pass, X - fail\n" ); | 
| cannam@89 | 317         printf( "{{{\n" ); // trac preformated text tag | 
| cannam@89 | 318         printf( "in|  out:    " ); | 
| cannam@89 | 319         for( destinationFormatIndex = 0; destinationFormatIndex < SAMPLE_FORMAT_COUNT; ++destinationFormatIndex ){ | 
| cannam@89 | 320             printf( "  %s   ", abbreviatedSampleFormatNames_[destinationFormatIndex] ); | 
| cannam@89 | 321         } | 
| cannam@89 | 322         printf( "\n" ); | 
| cannam@89 | 323 | 
| cannam@89 | 324         for( sourceFormatIndex = 0; sourceFormatIndex < SAMPLE_FORMAT_COUNT; ++sourceFormatIndex ){ | 
| cannam@89 | 325             printf( "%s         ", abbreviatedSampleFormatNames_[sourceFormatIndex] ); | 
| cannam@89 | 326             for( destinationFormatIndex = 0; destinationFormatIndex < SAMPLE_FORMAT_COUNT; ++destinationFormatIndex ){ | 
| cannam@89 | 327                 printf( "   %s   ", (passFailMatrix[sourceFormatIndex][destinationFormatIndex])? " ." : " X" ); | 
| cannam@89 | 328             } | 
| cannam@89 | 329             printf( "\n" ); | 
| cannam@89 | 330         } | 
| cannam@89 | 331         printf( "}}}\n" ); // trac preformated text tag | 
| cannam@89 | 332 | 
| cannam@89 | 333         printf( "\n" ); | 
| cannam@89 | 334         printf( "=== Combined dynamic range (src->dest->float32) ===\n" ); | 
| cannam@89 | 335         printf( "Key: Noise amplitude in dBfs, X - fail (either above failed or dest->float32 failed)\n" ); | 
| cannam@89 | 336         printf( "{{{\n" ); // trac preformated text tag | 
| cannam@89 | 337         printf( "in|  out:    " ); | 
| cannam@89 | 338         for( destinationFormatIndex = 0; destinationFormatIndex < SAMPLE_FORMAT_COUNT; ++destinationFormatIndex ){ | 
| cannam@89 | 339             printf( "  %s   ", abbreviatedSampleFormatNames_[destinationFormatIndex] ); | 
| cannam@89 | 340         } | 
| cannam@89 | 341         printf( "\n" ); | 
| cannam@89 | 342 | 
| cannam@89 | 343         for( sourceFormatIndex = 0; sourceFormatIndex < SAMPLE_FORMAT_COUNT; ++sourceFormatIndex ){ | 
| cannam@89 | 344             printf( " %s       ", abbreviatedSampleFormatNames_[sourceFormatIndex] ); | 
| cannam@89 | 345             for( destinationFormatIndex = 0; destinationFormatIndex < SAMPLE_FORMAT_COUNT; ++destinationFormatIndex ){ | 
| cannam@89 | 346                 amp = noiseAmplitudeMatrix[sourceFormatIndex][destinationFormatIndex]; | 
| cannam@89 | 347                 if( amp < 0. ) | 
| cannam@89 | 348                     printf( "    X   " ); | 
| cannam@89 | 349                 else | 
| cannam@89 | 350                     printf( " % 6.1f ", 20.*log10(amp) ); | 
| cannam@89 | 351             } | 
| cannam@89 | 352             printf( "\n" ); | 
| cannam@89 | 353         } | 
| cannam@89 | 354         printf( "}}}\n" ); // trac preformated text tag | 
| cannam@89 | 355     } | 
| cannam@89 | 356 | 
| cannam@89 | 357 | 
| cannam@89 | 358     free( destinationBuffer ); | 
| cannam@89 | 359     free( sourceBuffer ); | 
| cannam@89 | 360     free( referenceBuffer ); | 
| cannam@89 | 361 } | 
| cannam@89 | 362 | 
| cannam@89 | 363 // copied here for now otherwise we need to include the world just for this function. | 
| cannam@89 | 364 PaError My_Pa_GetSampleSize( PaSampleFormat format ) | 
| cannam@89 | 365 { | 
| cannam@89 | 366     int result; | 
| cannam@89 | 367 | 
| cannam@89 | 368     switch( format & ~paNonInterleaved ) | 
| cannam@89 | 369     { | 
| cannam@89 | 370 | 
| cannam@89 | 371     case paUInt8: | 
| cannam@89 | 372     case paInt8: | 
| cannam@89 | 373         result = 1; | 
| cannam@89 | 374         break; | 
| cannam@89 | 375 | 
| cannam@89 | 376     case paInt16: | 
| cannam@89 | 377         result = 2; | 
| cannam@89 | 378         break; | 
| cannam@89 | 379 | 
| cannam@89 | 380     case paInt24: | 
| cannam@89 | 381         result = 3; | 
| cannam@89 | 382         break; | 
| cannam@89 | 383 | 
| cannam@89 | 384     case paFloat32: | 
| cannam@89 | 385     case paInt32: | 
| cannam@89 | 386         result = 4; | 
| cannam@89 | 387         break; | 
| cannam@89 | 388 | 
| cannam@89 | 389     default: | 
| cannam@89 | 390         result = paSampleFormatNotSupported; | 
| cannam@89 | 391         break; | 
| cannam@89 | 392     } | 
| cannam@89 | 393 | 
| cannam@89 | 394     return (PaError) result; | 
| cannam@89 | 395 } |