1 /*-------------- Telecommunications & Signal Processing Lab ---------------
2                              McGill University
3 
4 Routine:
5   int AFfRdMulaw (AFILE *AFp, long int offs, float Dbuff[], int Nreq)
6 
7 Purpose:
8   Read 8-bit mu-law data from an audio file (return float values)
9 
10 Description:
11   This routine reads a specified number of 8-bit mu-law samples from an audio
12   file.  The data in the file is converted to float format on output.
13 
14 Parameters:
15   <-  int AFfRdMulaw
16       Number of data values transferred from the file.  On reaching the end of
17       the file, this value may be less than Nreq.
18    -> AFILE *AFp
19       Audio file pointer for an audio file opened by AFopnRead
20   <-  float Dbuff[]
21       Array of floats to receive the samples
22    -> int Nreq
23       Number of samples requested.  Nreq may be zero.
24 
25 Author / revision:
26   P. Kabal  Copyright (C) 2003
27   $Revision: 1.2 $  $Date: 2003/05/09 01:11:34 $
28 
29 -------------------------------------------------------------------------*/
30 
31 #include <libtsp/AFdataio.h>
32 #include <libtsp/AFpar.h>
33 #include <libtsp/UTtypes.h>
34 
35 #define LW		FDL_MULAW8
36 #define MINV(a, b)	(((a) < (b)) ? (a) : (b))
37 #define NBBUF		8192
38 
39 #define FREAD(buf,size,nv,fp)	(int) fread ((char *) buf, (size_t) size, \
40 					     (size_t) nv, fp)
41 
42 /* ITU-T Recommendation G.711
43    Mu-law data is stored in sign-magnitude bit-complemented format.  The sign
44    bit is 0 for positive data.  After complementing the bits, the byte is in
45    sign-segment-mantissa format.
46    mu-law data  complement  segment step-size       value
47    0 000 xxxx   1 111 yyyy     7      256     -8031, ... , -4191
48    0 001 xxxx   1 110 yyyy     6      128     -3999, ... , -2079
49    0 010 xxxx   1 101 yyyy     5       64     -1983, ... , -1023
50    0 011 xxxx   1 100 yyyy     4       32      -975, ... , -495
51    0 100 xxxx   1 011 yyyy     3       16      -471, ... , -231
52    0 101 xxxx   1 010 yyyy     2        8      -219, ... , -99
53    0 110 xxxx   1 001 yyyy     1        4       -93, ... , -33
54    0 111 xxxx   1 000 yyyy     0        2       -30, ... ,  0
55    1 000 xxxx   0 111 yyyy     7      256      8031, ... , 4191
56    1 001 xxxx   0 110 yyyy     6      128      3999, ... , 2079
57    1 010 xxxx   0 101 yyyy     5       64      1983, ... , 1023
58    1 011 xxxx   0 100 yyyy     4       32       975, ... , 495
59    1 100 xxxx   0 011 yyyy     3       16       471, ... , 231
60    1 101 xxxx   0 010 yyyy     2        8       219, ... , 99
61    1 110 xxxx   0 001 yyyy     1        4        93, ... , 33
62    1 111 xxxx   0 000 yyyy     0        2        30, ... , 0
63 
64   The following table implements the conversion, with the output data scaled
65   by 4, and includes the complementing operation.  This corresponds to output
66   values from -32124 to +32124 (for AFp->ScaleF = 1).
67 */
68 
69 static const double Mutab[256] = {
70   -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
71   -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
72   -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
73   -11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
74    -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
75    -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
76    -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
77    -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
78    -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
79    -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
80     -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
81     -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
82     -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
83     -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
84     -120,   -112,   -104,    -96,    -88,    -80,    -72,    -64,
85      -56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
86    32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
87    23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
88    15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
89    11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
90     7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
91     5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
92     3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
93     2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
94     1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
95     1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
96      876,    844,    812,    780,    748,    716,    684,    652,
97      620,    588,    556,    524,    492,    460,    428,    396,
98      372,    356,    340,    324,    308,    292,    276,    260,
99      244,    228,    212,    196,    180,    164,    148,    132,
100      120,    112,    104,     96,     88,     80,     72,     64,
101       56,     48,     40,     32,     24,     16,      8,      0
102 };
103 
104 
105 int
AFfRdMulaw(AFILE * AFp,float Dbuff[],int Nreq)106 AFfRdMulaw (AFILE *AFp, float Dbuff[], int Nreq)
107 
108 {
109   int is, N, i, Nr;
110   uint1_t Buf[NBBUF/LW];
111   double g;
112 
113   for (is = 0; is < Nreq; ) {
114 
115     /* Read data from the audio file */
116     N = MINV (NBBUF / LW, Nreq - is);
117     Nr = FREAD (Buf, LW, N, AFp->fp);
118 
119     /* Convert to float */
120     g = AFp->ScaleF;
121     for (i = 0; i < Nr; ++i) {
122       Dbuff[is] = (float) (g * Mutab[Buf[i]]);
123       ++is;
124     }
125 
126     if (Nr < N)
127       break;
128   }
129 
130   return is;
131 }
132