/*-------------- Telecommunications & Signal Processing Lab --------------- McGill University Routine: int AFreadAlaw (AFILE *AFp, long int offs, float Fbuff[], int Nreq) Purpose: Read 8-bit A-law data from an audio file (return float values) Description: This routine reads a specified number of 8-bit A-law samples from an audio file. The data in the file is converted to float format on output. The file must have been opened using subroutine AFopenRead. Parameters: <- int AFreadAlaw Number of data values transferred from the file. On reaching the end of the file, this value may be less than Nreq. -> AFILE *AFp Audio file pointer for an audio file opened by AFopenRead -> long int offs Offset into the file in samples. The parameter offs must be non- negative. <- float Fbuff[] Array of floats to receive the samples -> int Nreq Number of samples requested. Nreq may be zero. Author / revision: P. Kabal Copyright (C) 1996 $Revision: 1.4 $ $Date: 1996/08/14 18:01:06 $ -------------------------------------------------------------------------*/ static char rcsid [] = "$Id: AFreadAlaw.c 1.4 1996/08/14 AFsp-V2R1 $"; #include #include #include #include #define LW FDL_ALAW8 #define MINV(a, b) (((a) < (b)) ? (a) : (b)) #define NBBUF 8192 /* ITU-T Recommendation G.711 A-law data is stored in sign-magnitude alternate-bit-complemented format. The sign bit is 1 for positive data. After complementing the bits, the byte is in sign-segment-mantissa format. A-law data complement segment step-size value 0 000 xxxx 0 101 xyxy 5 32 -1008, ... , -528 0 001 xxxx 0 100 xyxy 4 16 -504, ... , -264 0 010 xxxx 0 111 xyxy 7 128 -4032, ... , -2112 0 011 xxxx 0 110 xyxy 6 64 -2016, ... , -1056 0 100 xxxx 0 001 xyxy 1 2 -63, ... , -33 0 101 xxxx 0 000 xyxy 1 2 -31, ... , -1 0 110 xxxx 0 011 xyxy 3 8 -252, ... , -132 0 111 xxxx 0 010 xyxy 2 4 -126, ... , -66 1 000 xxxx 1 101 xyxy 5 32 528, ... , 1008 1 001 xxxx 1 100 xyxy 4 16 264, ... , 504 1 010 xxxx 1 111 xyxy 7 128 2112, ... , 4032 1 011 xxxx 1 110 xyxy 6 64 1056, ... , 2016 1 100 xxxx 1 001 xyxy 1 2 33, ... , 63 1 101 xxxx 1 000 xyxy 1 2 1, ... , 31 1 110 xxxx 1 011 xyxy 3 8 132, ... , 252 1 111 xxxx 1 010 xyxy 2 4 66, ... , 126 The following table implements the conversion, with the output data scaled by 8, and includes the complementing operation. This corresponds to output values from -32256 to +32256 (for AFp->ScaleF = 1). */ static const float fAtab[256] = { -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, -344, -328, -376, -360, -280, -264, -312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72, -120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136, -184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656, -752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816, -784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848 }; int AFreadAlaw (AFp, offs, Fbuff, Nreq) AFILE *AFp; long int offs; float Fbuff[]; int Nreq; { long int offsb; int Nd, is, n, i, Nval; uint1_t Buf[NBBUF/LW]; uint1_t *B; offsb = AFp->Start + LW * offs; Nd = (int) MINV (Nreq, (AFp->End - offsb) / LW); /* Nd can be negative */ for (is = 0; is < Nd; ) { /* Read data from the audio file */ n = MINV (NBBUF / LW, Nd - is); Nval = FLreadFile (AFp->fp, (long int) (offsb + is * LW), (void *) Buf, (size_t) LW, (size_t) n); if (Nval != n) UThalt ("AFreadAlaw: Unexpected end-of-file"); /* Convert to float */ B = Buf; for (i = 0; i < Nval; ++i) { Fbuff[is] = AFp->ScaleF * fAtab[*B]; ++is; ++B; } } return is; }