windows-nt/Source/XPSP1/NT/multimedia/media/msacm/g711/gentable.c

318 lines
11 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
//==========================================================================;
//
// 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;
}