File: mulaw.c

package info (click to toggle)
vpb-driver 4.2.55-1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 3,528 kB
  • sloc: cpp: 26,247; ansic: 19,041; sh: 3,210; perl: 1,132; makefile: 752; asm: 182
file content (237 lines) | stat: -rw-r--r-- 6,245 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/*---------------------------------------------------------------------------*\

    FILE....: MULAW.C
    TYPE....: C Functions
    AUTHOR..: David Rowe
    DATE....: 16/10/97

    Mu-law compression functions.

         Voicetronix Voice Processing Board (VPB) Software
         Copyright (C) 1999-2007 Voicetronix www.voicetronix.com.au

         This library is free software; you can redistribute it and/or
         modify it under the terms of the GNU Lesser General Public
         License as published by the Free Software Foundation; either
         version 2.1 of the License, or (at your option) any later version.

         This library is distributed in the hope that it will be useful,
         but WITHOUT ANY WARRANTY; without even the implied warranty of
         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
         Lesser General Public License for more details.

         You should have received a copy of the GNU Lesser General Public
         License along with this library; if not, write to the Free Software
         Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
         MA  02110-1301  USA

\*---------------------------------------------------------------------------*/

#include <assert.h>
#include <stdint.h>

#include "alawmulaw.h"

/* mu-law constants */

#define	LSIGN	0x8000		/* linear sign bit 15 = 1 if negative	   */
#define	MUSIGN	0x80		/* mu-law sign bit 7 = 1 if negative	   */
#define	MUMAX	0x1fff		/* max mu-law value in linear form	   */
#define	MUMAG	0x7f		/* mu-law magnitude bits 		   */
#define	BIAS	33		/* converts seg end points to powers of 2  */
#define	LINEAR	0xf		/* masks of linear portion of magnitude	   */

static short mulaw_to_linear_lut[256];
static char linear_to_mulaw_lut[65536];

static void init_mulaw_to_linear_lut(void);
static void init_linear_to_mulaw_lut(void);

/*--------------------------------------------------------------------------*\

	FUNCTION.: init_mulaw_luts
	AUTHORS..: Mark Mickan
	DATE.....: 29 Jan 2007

	Call the necessary lookup table initialisation functions.  This
	function should be called in initialisation code, before either
	mulaw_encode or mulaw_decode are called.

\*--------------------------------------------------------------------------*/

void init_mulaw_luts(void)
{
    init_mulaw_to_linear_lut();
    init_linear_to_mulaw_lut();
}

/*--------------------------------------------------------------------------*\

	FUNCTION.: init_mulaw_to_linear_lut
	AUTHORS..: Mark Mickan
	DATE.....: 29 Jan 2007

	Calculate the linear equivalent of all possible mu-law samples.
	Heavily based on David Rowe's original mulaw_decode function.
	The linear samples are in Q15 format.

	Reference: TI databook
		   "Theory, Alogorithms, and Implementations Vol 1", p171

\*--------------------------------------------------------------------------*/

static void init_mulaw_to_linear_lut(void)
{
    unsigned long  acc,p,s,q;
    int    i;

    for(i=0; i<256; i++) {
	acc = ~i & 0xff;

	/* extract sign */

	if (acc & MUSIGN)
	    p = LSIGN;
	else
	    p = 0;
	acc &= MUMAG;

	/* extract q and s */

	q = acc & 0xf;
	s = acc >> 4;

	/* remove bias and form linear sample */

	acc = 2*q+BIAS;
	acc <<= s;
	acc -= BIAS;
	acc <<= MULAW_SCALE;
	if (p)
	    mulaw_to_linear_lut[i] = -acc;
	else
	    mulaw_to_linear_lut[i] = acc;
    }
}

/*--------------------------------------------------------------------------*\

	FUNCTION.: init_linear_to_mulaw_lut
	AUTHOR...: Mark Mickan
	DATE.....: 29 Jan 2007

	Calculate the mu-law equivalent of all possible linear samples
	and store them in a lookup table.  The linear samples are
       	assumed to be in Q15 format.  Heavily based on David Rowe's
	original mulaw_encode function.

	Reference: TI databook
		   "Theory, Alogorithms, and Implementations Vol 1", p171

	Mu-law format: psssqqqq

		       p is the sign
		       s is the segment
		       q if the quantisation bin number

\*--------------------------------------------------------------------------*/

static void init_linear_to_mulaw_lut(void)
{
    unsigned short y,mag;
    unsigned short p,s,q,b;
    unsigned long  acc;
    int    i;

    for(i=-32768; i<32768; i++) {
	acc = i >> MULAW_SCALE;

	/* separate sign and bias */

	if (acc & LSIGN) {
	    p = MUSIGN;
	    mag = -acc;
	}
	else {
	    p = 0;
	    mag = acc;
	}
	mag += BIAS;

	/* encode magnitude */

	if (mag > MUMAX)
	    y = p + MUMAG;
	else {

	    /* determine left most bit and therefore segment */

	    b = 0;
	    acc = mag >> 1;
	    while(acc) {
		b++;
		acc >>= 1;
	    }
	    s = b - 5;

	    /* extract quantisation bin */

	    q = mag >> (b-4);
	    q &= LINEAR;
	    y = p + (s<<4) + q;
	}

	linear_to_mulaw_lut[i+32768] = ~y & 0xff;
    }
}


/*--------------------------------------------------------------------------*\

	FUNCTION.: mulaw_encode
	AUTHOR...: David Rowe
	DATE.....: 14/10/97

	Encodes a vector of linear samples to mu-law equivalents.  The linear
	samples are assumed to be in Q15 format.

\*--------------------------------------------------------------------------*/

void mulaw_encode(char mulaw[], const short linear[], unsigned short sz)
/*  char   mulaw[];	mulaw encoded samples                           */
/*  word   linear[];	16 bit input samples	                        */
/*  unsigned short sz;	number of sample in buffers			*/
{
    int    i;

    for(i=0; i<sz; ++i) {
	mulaw[i] = linear_to_mulaw_lut[linear[i]+32768];
    }
}

/*--------------------------------------------------------------------------*\

	FUNCTION.: mulaw_decode
	AUTHOR...: David Rowe
	DATE.....: 14/10/97
	AUTHOR...: Mark Mickan (modified to use lookup table)
	DATE.....: 29 Jan 2007

	Decodes a vector of mu-law samples to linear equivalents.  The linear
	samples are normalised to Q15.

\*--------------------------------------------------------------------------*/

void mulaw_decode(short linear[], const unsigned char mulaw[], unsigned short sz)
/*  word   linear[];	16 bit output samples           		*/
/*  char   mulaw[];	mulaw encoded samples                           */
/*  unsigned short sz;	number of sample in buffers			*/
{
    int    i;

    for(i=0; i<sz; ++i) {
	linear[i] = mulaw_to_linear_lut[mulaw[i]];
    }

}