//==========================================================================; // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // Copyright (c) 1993-1996 Microsoft Corporation // //--------------------------------------------------------------------------; // // gentable.c // // Description: // This is a utility program to generate various tables in the // form of 'C' source code. Portions of some of these tables can // be pasted into codec source code. The output is to stdio // and can be redirected into a file. Portions of the file can // then be cut and pasted into another 'C' source file as necessary. // //==========================================================================; #include //--------------------------------------------------------------------------; // // Name: // UlawToAlawTable // // // Description: /* This table was copied directly from the G.711 specification. Using the G.711 spec terminology, this table converts u-law decoder output value numbers to A-law decoder output value numbers. */ // // Arguments: // // // Return: // // // Notes: // // // History: // 08/01/93 Created. // // //--------------------------------------------------------------------------; unsigned char UlawToAlawTable[128] = { 1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25, 27,29,31, 33,34,35,36,37,38,39,40,41,42,43,44, 46, 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62, 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, 81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99, 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119, 120,121,122,123,124,125,126,127,128 }; //--------------------------------------------------------------------------; // // Name: // AlawToUlawTable // // // Description: /* This table was copied directly from the G.711 specification. Using the G.711 spec terminology, this table converts A-law decoder output value numbers to u-law decoder output value numbers. A-law decoder output value numbers range from 1 to 128, so AlawToUlawTable[0] is unused. Note that u-law decoder output value numbers range from 0 to 127. */ // // Arguments: // // // Return: // // // Notes: // // // History: // 08/01/93 Created. // // //--------------------------------------------------------------------------; unsigned char AlawToUlawTable[129] = { 0, // this first entry not used 1,3,5,7,9,11,13, 15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, 32,32,33,33,34,34,35,35, 36,37,38,39,40,41,42,43,44,45,46,47, 48,48,49,49, 50,51,52,53,54,55,56,57,58,59,60,61,62,63,64, 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, 79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99, 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115, 116,117,118,119,120,121,122,123,124,125,126,127 }; short DecodeTable[256]; // // Our main procedure. // void main() { short i,j; short SegBase[16]; short IntervalStep[16]; short Sample; // // This generates a decode table for A-law. The resulting // table can be used to convert an A-law character to // a 16-bit PCM value. // // These seg base values and interval steps are based directly // on the G.711 A-law spec. They correspond to 13-bit PCM data. SegBase[ 0] = -1; IntervalStep[ 0] = -2; SegBase[ 1] = -33; IntervalStep[ 1] = -2; SegBase[ 2] = -66; IntervalStep[ 2] = -4; SegBase[ 3] = -132; IntervalStep[ 3] = -8; SegBase[ 4] = -264; IntervalStep[ 4] = -16; SegBase[ 5] = -528; IntervalStep[ 5] = -32; SegBase[ 6] = -1056; IntervalStep[ 6] = -64; SegBase[ 7] = -2112; IntervalStep[ 7] = -128; SegBase[ 8] = 1; IntervalStep[ 8] = 2; SegBase[ 9] = 33; IntervalStep[ 9] = 2; SegBase[10] = 66; IntervalStep[10] = 4; SegBase[11] = 132; IntervalStep[11] = 8; SegBase[12] = 264; IntervalStep[12] = 16; SegBase[13] = 528; IntervalStep[13] = 32; SegBase[14] = 1056; IntervalStep[14] = 64; SegBase[15] = 2112; IntervalStep[15] = 128; printf("\n\n\n\n\n// A-law decode table:\n\n"); for (i=0; i<16; i++) for (j=0; j<16; j++) { Sample = SegBase[i^0x05] + IntervalStep[i^0x05]*(j^0x05); // Sample is a 13-bit signed PCM value. // In our table, we'll convert it to 16-bit. The // generated comment will indicate the 13-bit value. printf( "\t%6d,\t\t// y[%02x]= %6d\n", Sample << 3, i*16 + j, Sample); } // // This generates a decode table for u-law. The resulting // table can be used to convert a u-law character to // a 16-bit PCM value. // // These seg base values and interval steps are based directly // on the G.711 A-law spec. They correspond to 14-bit PCM data. SegBase[ 0] = -8031; IntervalStep[ 0] = 256; SegBase[ 1] = -3999; IntervalStep[ 1] = 128; SegBase[ 2] = -1983; IntervalStep[ 2] = 64; SegBase[ 3] = -975; IntervalStep[ 3] = 32; SegBase[ 4] = -471; IntervalStep[ 4] = 16; SegBase[ 5] = -219; IntervalStep[ 5] = 8; SegBase[ 6] = -93; IntervalStep[ 6] = 4; SegBase[ 7] = -30; IntervalStep[ 7] = 2; SegBase[ 8] = 8031; IntervalStep[ 8] = -256; SegBase[ 9] = 3999; IntervalStep[ 9] = -128; SegBase[10] = 1983; IntervalStep[10] = -64; SegBase[11] = 975; IntervalStep[11] = -32; SegBase[12] = 471; IntervalStep[12] = -16; SegBase[13] = 219; IntervalStep[13] = -8; SegBase[14] = 93; IntervalStep[14] = -4; SegBase[15] = 30; IntervalStep[15] = -2; printf("\n\n\n\n\n// u-law decode table:\n\n"); for (i=0; i<16; i++) for (j=0; j<16; j++) { Sample = SegBase[i] + IntervalStep[i]*j; // Sample is a 14-bit signed PCM value. // In our table, we'll convert it to 16-bit. The // generated comment will indicate the 14-bit value. printf( "\t%6d,\t\t// y[%02x]= %6d\n", Sample << 2, i*16 + j, Sample); } // // This generates a conversion table from A-law chars // to u-law chars. The AlawToUlawTable above converts // decoder output value numbers, which is not quite what // we want. Using that table, this routine will generate // 'C' source code for a table that converts directly from // A-law chars to u-law chars. // printf("\n\n\n\n\n// A-law to u-law char conversion table:\n\n"); for (i=0; i<256; i++) // i counts thru all A-law chars { // Here is the process to go from an A-law char // to a u-law char. // 1. convert from A-law char to A-law decoder // output value number. from observing the tables // in the G.711 spec it can be seen that this is // done by inverting the even bits and dropping the // sign bit of the A-law char and then adding 1. // 2. using the AlawToUlawTable above, convert from // the A-law decoder output value number to the // corresponding u-law output value number. // 3. convert from u-law decoder output value // number to u-law char. from observing the tables // in the G.711 spec it can be seen that this is // done by inverting the 7 LSBs of the u-law // decoder output value number. // 4. apply polarity to the u-law char. that is, // set the sign bit of the u-law char the same // as the sign bit of the original A-law char. j = i; // j starts of as original A-law char // Step 1: j = ((i^0x55) & 0x7F) + 1; // Step 2: j = AlawToUlawTable[j]; // Step 3: j = (j ^ 0x7F); // Step 4: j = j | (i & 0x80); // j ends as corresponding u-law char // Now i is an A-law char and j is the corresponding u-law char printf( "\t0x%02x,\t\t// A-law[%02x] ==> u-law[%02x]\n", j, i, j); } // // This generates a conversion table from u-law chars // to A-law chars. The UlawToAlawTable above converts // decoder output value numbers, which is not quite what // we want. Using that table, this routine will generate // 'C' source code for a table that converts directly from // u-law chars to A-law chars. // printf("\n\n\n\n\n// u-law to A-law char conversion table:\n\n"); for (i=0; i<256; i++) // i counts thru all U-law chars { // Here is the process to go from a u-law char // to a A-law char. // 1. convert from u-law char to u-law decoder // output value number. from observing the tables // in the G.711 spec it can be seen that this is // done by dropping the sign bit of the u-law // char and then inverting the 7 LSBs. // 2. using the UlawToAlawTable above, convert from // the u-law decoder output value number to the // corresponding A-law output value number. // 3. convert from A-law decoder output value // number to A-law char. from observing the tables // in the G.711 spec it can be seen that this is // done by subtracting 1 from the A-law decoder output // value number and inverting the even bits. // 4. apply polarity to the A-law char. that is, // set the sign bit of the A-law char the same // as the sign bit of the original u-law char. j = i; // j starts of as original u-law char // Step 1: j = (i & 0x7F) ^ 0x7F; // Step 2: j = UlawToAlawTable[j]; // Step 3: j = (j - 1)^0x55; // Step 4: j = j | (i & 0x80); // j ends as corresponding A-law char // Now i is a u-law char and j is the corresponding A-law char printf( "\t0x%02x,\t\t// u-law[%02x] ==> A-law[%02x]\n", j, i, j); } return; }