|
|
//==========================================================================;
//
// 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 <stdio.h>
//--------------------------------------------------------------------------;
//
// 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; }
|