FreeBSD/Linux Kernel Cross Reference
sys/dev/mulaw.c
1 /* $NetBSD: mulaw.c,v 1.23 2005/01/10 22:01:37 kent Exp $ */
2
3 /*
4 * Copyright (c) 1991-1993 Regents of the University of California.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the Computer Systems
18 * Engineering Group at Lawrence Berkeley Laboratory.
19 * 4. Neither the name of the University nor of the Laboratory may be used
20 * to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 */
36
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: mulaw.c,v 1.23 2005/01/10 22:01:37 kent Exp $");
39
40 #include <sys/types.h>
41 #include <sys/systm.h>
42 #include <dev/auconv.h>
43 #include <dev/mulaw.h>
44
45 /* #define MULAW_DEBUG */
46 #ifdef MULAW_DEBUG
47 # define DPRINTF(x) printf x
48 #else
49 # define DPRINTF(x)
50 #endif
51
52 /*
53 * This table converts a (8 bit) mu-law value to a 16 bit value.
54 * The 16 bits are represented as an array of two bytes for easier access
55 * to the individual bytes.
56 */
57 static const uint8_t mulawtolin16[256][2] = {
58 {0x02,0x84}, {0x06,0x84}, {0x0a,0x84}, {0x0e,0x84},
59 {0x12,0x84}, {0x16,0x84}, {0x1a,0x84}, {0x1e,0x84},
60 {0x22,0x84}, {0x26,0x84}, {0x2a,0x84}, {0x2e,0x84},
61 {0x32,0x84}, {0x36,0x84}, {0x3a,0x84}, {0x3e,0x84},
62 {0x41,0x84}, {0x43,0x84}, {0x45,0x84}, {0x47,0x84},
63 {0x49,0x84}, {0x4b,0x84}, {0x4d,0x84}, {0x4f,0x84},
64 {0x51,0x84}, {0x53,0x84}, {0x55,0x84}, {0x57,0x84},
65 {0x59,0x84}, {0x5b,0x84}, {0x5d,0x84}, {0x5f,0x84},
66 {0x61,0x04}, {0x62,0x04}, {0x63,0x04}, {0x64,0x04},
67 {0x65,0x04}, {0x66,0x04}, {0x67,0x04}, {0x68,0x04},
68 {0x69,0x04}, {0x6a,0x04}, {0x6b,0x04}, {0x6c,0x04},
69 {0x6d,0x04}, {0x6e,0x04}, {0x6f,0x04}, {0x70,0x04},
70 {0x70,0xc4}, {0x71,0x44}, {0x71,0xc4}, {0x72,0x44},
71 {0x72,0xc4}, {0x73,0x44}, {0x73,0xc4}, {0x74,0x44},
72 {0x74,0xc4}, {0x75,0x44}, {0x75,0xc4}, {0x76,0x44},
73 {0x76,0xc4}, {0x77,0x44}, {0x77,0xc4}, {0x78,0x44},
74 {0x78,0xa4}, {0x78,0xe4}, {0x79,0x24}, {0x79,0x64},
75 {0x79,0xa4}, {0x79,0xe4}, {0x7a,0x24}, {0x7a,0x64},
76 {0x7a,0xa4}, {0x7a,0xe4}, {0x7b,0x24}, {0x7b,0x64},
77 {0x7b,0xa4}, {0x7b,0xe4}, {0x7c,0x24}, {0x7c,0x64},
78 {0x7c,0x94}, {0x7c,0xb4}, {0x7c,0xd4}, {0x7c,0xf4},
79 {0x7d,0x14}, {0x7d,0x34}, {0x7d,0x54}, {0x7d,0x74},
80 {0x7d,0x94}, {0x7d,0xb4}, {0x7d,0xd4}, {0x7d,0xf4},
81 {0x7e,0x14}, {0x7e,0x34}, {0x7e,0x54}, {0x7e,0x74},
82 {0x7e,0x8c}, {0x7e,0x9c}, {0x7e,0xac}, {0x7e,0xbc},
83 {0x7e,0xcc}, {0x7e,0xdc}, {0x7e,0xec}, {0x7e,0xfc},
84 {0x7f,0x0c}, {0x7f,0x1c}, {0x7f,0x2c}, {0x7f,0x3c},
85 {0x7f,0x4c}, {0x7f,0x5c}, {0x7f,0x6c}, {0x7f,0x7c},
86 {0x7f,0x88}, {0x7f,0x90}, {0x7f,0x98}, {0x7f,0xa0},
87 {0x7f,0xa8}, {0x7f,0xb0}, {0x7f,0xb8}, {0x7f,0xc0},
88 {0x7f,0xc8}, {0x7f,0xd0}, {0x7f,0xd8}, {0x7f,0xe0},
89 {0x7f,0xe8}, {0x7f,0xf0}, {0x7f,0xf8}, {0x80,0x00},
90 {0xfd,0x7c}, {0xf9,0x7c}, {0xf5,0x7c}, {0xf1,0x7c},
91 {0xed,0x7c}, {0xe9,0x7c}, {0xe5,0x7c}, {0xe1,0x7c},
92 {0xdd,0x7c}, {0xd9,0x7c}, {0xd5,0x7c}, {0xd1,0x7c},
93 {0xcd,0x7c}, {0xc9,0x7c}, {0xc5,0x7c}, {0xc1,0x7c},
94 {0xbe,0x7c}, {0xbc,0x7c}, {0xba,0x7c}, {0xb8,0x7c},
95 {0xb6,0x7c}, {0xb4,0x7c}, {0xb2,0x7c}, {0xb0,0x7c},
96 {0xae,0x7c}, {0xac,0x7c}, {0xaa,0x7c}, {0xa8,0x7c},
97 {0xa6,0x7c}, {0xa4,0x7c}, {0xa2,0x7c}, {0xa0,0x7c},
98 {0x9e,0xfc}, {0x9d,0xfc}, {0x9c,0xfc}, {0x9b,0xfc},
99 {0x9a,0xfc}, {0x99,0xfc}, {0x98,0xfc}, {0x97,0xfc},
100 {0x96,0xfc}, {0x95,0xfc}, {0x94,0xfc}, {0x93,0xfc},
101 {0x92,0xfc}, {0x91,0xfc}, {0x90,0xfc}, {0x8f,0xfc},
102 {0x8f,0x3c}, {0x8e,0xbc}, {0x8e,0x3c}, {0x8d,0xbc},
103 {0x8d,0x3c}, {0x8c,0xbc}, {0x8c,0x3c}, {0x8b,0xbc},
104 {0x8b,0x3c}, {0x8a,0xbc}, {0x8a,0x3c}, {0x89,0xbc},
105 {0x89,0x3c}, {0x88,0xbc}, {0x88,0x3c}, {0x87,0xbc},
106 {0x87,0x5c}, {0x87,0x1c}, {0x86,0xdc}, {0x86,0x9c},
107 {0x86,0x5c}, {0x86,0x1c}, {0x85,0xdc}, {0x85,0x9c},
108 {0x85,0x5c}, {0x85,0x1c}, {0x84,0xdc}, {0x84,0x9c},
109 {0x84,0x5c}, {0x84,0x1c}, {0x83,0xdc}, {0x83,0x9c},
110 {0x83,0x6c}, {0x83,0x4c}, {0x83,0x2c}, {0x83,0x0c},
111 {0x82,0xec}, {0x82,0xcc}, {0x82,0xac}, {0x82,0x8c},
112 {0x82,0x6c}, {0x82,0x4c}, {0x82,0x2c}, {0x82,0x0c},
113 {0x81,0xec}, {0x81,0xcc}, {0x81,0xac}, {0x81,0x8c},
114 {0x81,0x74}, {0x81,0x64}, {0x81,0x54}, {0x81,0x44},
115 {0x81,0x34}, {0x81,0x24}, {0x81,0x14}, {0x81,0x04},
116 {0x80,0xf4}, {0x80,0xe4}, {0x80,0xd4}, {0x80,0xc4},
117 {0x80,0xb4}, {0x80,0xa4}, {0x80,0x94}, {0x80,0x84},
118 {0x80,0x78}, {0x80,0x70}, {0x80,0x68}, {0x80,0x60},
119 {0x80,0x58}, {0x80,0x50}, {0x80,0x48}, {0x80,0x40},
120 {0x80,0x38}, {0x80,0x30}, {0x80,0x28}, {0x80,0x20},
121 {0x80,0x18}, {0x80,0x10}, {0x80,0x08}, {0x80,0x00},
122 };
123
124 static const uint8_t lintomulaw[256] = {
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
126 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
127 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05,
128 0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07,
129 0x07, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
130 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b,
131 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d,
132 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f,
133 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13,
134 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17,
135 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, 0x1b,
136 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f,
137 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
138 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
139 0x2f, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c,
140 0x3e, 0x41, 0x45, 0x49, 0x4d, 0x53, 0x5b, 0x67,
141 0xff, 0xe7, 0xdb, 0xd3, 0xcd, 0xc9, 0xc5, 0xc1,
142 0xbe, 0xbc, 0xba, 0xb8, 0xb6, 0xb4, 0xb2, 0xb0,
143 0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8,
144 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
145 0x9f, 0x9f, 0x9e, 0x9e, 0x9d, 0x9d, 0x9c, 0x9c,
146 0x9b, 0x9b, 0x9a, 0x9a, 0x99, 0x99, 0x98, 0x98,
147 0x97, 0x97, 0x96, 0x96, 0x95, 0x95, 0x94, 0x94,
148 0x93, 0x93, 0x92, 0x92, 0x91, 0x91, 0x90, 0x90,
149 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e,
150 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c,
151 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a,
152 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88,
153 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86,
154 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84,
155 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
156 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80,
157 };
158
159 static const uint8_t alawtolin16[256][2] = {
160 {0x6a,0x80}, {0x6b,0x80}, {0x68,0x80}, {0x69,0x80},
161 {0x6e,0x80}, {0x6f,0x80}, {0x6c,0x80}, {0x6d,0x80},
162 {0x62,0x80}, {0x63,0x80}, {0x60,0x80}, {0x61,0x80},
163 {0x66,0x80}, {0x67,0x80}, {0x64,0x80}, {0x65,0x80},
164 {0x75,0x40}, {0x75,0xc0}, {0x74,0x40}, {0x74,0xc0},
165 {0x77,0x40}, {0x77,0xc0}, {0x76,0x40}, {0x76,0xc0},
166 {0x71,0x40}, {0x71,0xc0}, {0x70,0x40}, {0x70,0xc0},
167 {0x73,0x40}, {0x73,0xc0}, {0x72,0x40}, {0x72,0xc0},
168 {0x2a,0x00}, {0x2e,0x00}, {0x22,0x00}, {0x26,0x00},
169 {0x3a,0x00}, {0x3e,0x00}, {0x32,0x00}, {0x36,0x00},
170 {0x0a,0x00}, {0x0e,0x00}, {0x02,0x00}, {0x06,0x00},
171 {0x1a,0x00}, {0x1e,0x00}, {0x12,0x00}, {0x16,0x00},
172 {0x55,0x00}, {0x57,0x00}, {0x51,0x00}, {0x53,0x00},
173 {0x5d,0x00}, {0x5f,0x00}, {0x59,0x00}, {0x5b,0x00},
174 {0x45,0x00}, {0x47,0x00}, {0x41,0x00}, {0x43,0x00},
175 {0x4d,0x00}, {0x4f,0x00}, {0x49,0x00}, {0x4b,0x00},
176 {0x7e,0xa8}, {0x7e,0xb8}, {0x7e,0x88}, {0x7e,0x98},
177 {0x7e,0xe8}, {0x7e,0xf8}, {0x7e,0xc8}, {0x7e,0xd8},
178 {0x7e,0x28}, {0x7e,0x38}, {0x7e,0x08}, {0x7e,0x18},
179 {0x7e,0x68}, {0x7e,0x78}, {0x7e,0x48}, {0x7e,0x58},
180 {0x7f,0xa8}, {0x7f,0xb8}, {0x7f,0x88}, {0x7f,0x98},
181 {0x7f,0xe8}, {0x7f,0xf8}, {0x7f,0xc8}, {0x7f,0xd8},
182 {0x7f,0x28}, {0x7f,0x38}, {0x7f,0x08}, {0x7f,0x18},
183 {0x7f,0x68}, {0x7f,0x78}, {0x7f,0x48}, {0x7f,0x58},
184 {0x7a,0xa0}, {0x7a,0xe0}, {0x7a,0x20}, {0x7a,0x60},
185 {0x7b,0xa0}, {0x7b,0xe0}, {0x7b,0x20}, {0x7b,0x60},
186 {0x78,0xa0}, {0x78,0xe0}, {0x78,0x20}, {0x78,0x60},
187 {0x79,0xa0}, {0x79,0xe0}, {0x79,0x20}, {0x79,0x60},
188 {0x7d,0x50}, {0x7d,0x70}, {0x7d,0x10}, {0x7d,0x30},
189 {0x7d,0xd0}, {0x7d,0xf0}, {0x7d,0x90}, {0x7d,0xb0},
190 {0x7c,0x50}, {0x7c,0x70}, {0x7c,0x10}, {0x7c,0x30},
191 {0x7c,0xd0}, {0x7c,0xf0}, {0x7c,0x90}, {0x7c,0xb0},
192 {0x95,0x80}, {0x94,0x80}, {0x97,0x80}, {0x96,0x80},
193 {0x91,0x80}, {0x90,0x80}, {0x93,0x80}, {0x92,0x80},
194 {0x9d,0x80}, {0x9c,0x80}, {0x9f,0x80}, {0x9e,0x80},
195 {0x99,0x80}, {0x98,0x80}, {0x9b,0x80}, {0x9a,0x80},
196 {0x8a,0xc0}, {0x8a,0x40}, {0x8b,0xc0}, {0x8b,0x40},
197 {0x88,0xc0}, {0x88,0x40}, {0x89,0xc0}, {0x89,0x40},
198 {0x8e,0xc0}, {0x8e,0x40}, {0x8f,0xc0}, {0x8f,0x40},
199 {0x8c,0xc0}, {0x8c,0x40}, {0x8d,0xc0}, {0x8d,0x40},
200 {0xd6,0x00}, {0xd2,0x00}, {0xde,0x00}, {0xda,0x00},
201 {0xc6,0x00}, {0xc2,0x00}, {0xce,0x00}, {0xca,0x00},
202 {0xf6,0x00}, {0xf2,0x00}, {0xfe,0x00}, {0xfa,0x00},
203 {0xe6,0x00}, {0xe2,0x00}, {0xee,0x00}, {0xea,0x00},
204 {0xab,0x00}, {0xa9,0x00}, {0xaf,0x00}, {0xad,0x00},
205 {0xa3,0x00}, {0xa1,0x00}, {0xa7,0x00}, {0xa5,0x00},
206 {0xbb,0x00}, {0xb9,0x00}, {0xbf,0x00}, {0xbd,0x00},
207 {0xb3,0x00}, {0xb1,0x00}, {0xb7,0x00}, {0xb5,0x00},
208 {0x81,0x58}, {0x81,0x48}, {0x81,0x78}, {0x81,0x68},
209 {0x81,0x18}, {0x81,0x08}, {0x81,0x38}, {0x81,0x28},
210 {0x81,0xd8}, {0x81,0xc8}, {0x81,0xf8}, {0x81,0xe8},
211 {0x81,0x98}, {0x81,0x88}, {0x81,0xb8}, {0x81,0xa8},
212 {0x80,0x58}, {0x80,0x48}, {0x80,0x78}, {0x80,0x68},
213 {0x80,0x18}, {0x80,0x08}, {0x80,0x38}, {0x80,0x28},
214 {0x80,0xd8}, {0x80,0xc8}, {0x80,0xf8}, {0x80,0xe8},
215 {0x80,0x98}, {0x80,0x88}, {0x80,0xb8}, {0x80,0xa8},
216 {0x85,0x60}, {0x85,0x20}, {0x85,0xe0}, {0x85,0xa0},
217 {0x84,0x60}, {0x84,0x20}, {0x84,0xe0}, {0x84,0xa0},
218 {0x87,0x60}, {0x87,0x20}, {0x87,0xe0}, {0x87,0xa0},
219 {0x86,0x60}, {0x86,0x20}, {0x86,0xe0}, {0x86,0xa0},
220 {0x82,0xb0}, {0x82,0x90}, {0x82,0xf0}, {0x82,0xd0},
221 {0x82,0x30}, {0x82,0x10}, {0x82,0x70}, {0x82,0x50},
222 {0x83,0xb0}, {0x83,0x90}, {0x83,0xf0}, {0x83,0xd0},
223 {0x83,0x30}, {0x83,0x10}, {0x83,0x70}, {0x83,0x50},
224 };
225
226 static const uint8_t lintoalaw[256] = {
227 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b,
228 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29,
229 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f,
230 0x2c, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d,
231 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x23,
232 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21,
233 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27,
234 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25,
235 0x3a, 0x3a, 0x3b, 0x3b, 0x38, 0x38, 0x39, 0x39,
236 0x3e, 0x3e, 0x3f, 0x3f, 0x3c, 0x3c, 0x3d, 0x3d,
237 0x32, 0x32, 0x33, 0x33, 0x30, 0x30, 0x31, 0x31,
238 0x36, 0x36, 0x37, 0x37, 0x34, 0x34, 0x35, 0x35,
239 0x0a, 0x0b, 0x08, 0x09, 0x0e, 0x0f, 0x0c, 0x0d,
240 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05,
241 0x1a, 0x18, 0x1e, 0x1c, 0x12, 0x10, 0x16, 0x14,
242 0x6a, 0x6e, 0x62, 0x66, 0x7a, 0x72, 0x4a, 0x5a,
243 0xd5, 0xc5, 0xf5, 0xfd, 0xe5, 0xe1, 0xed, 0xe9,
244 0x95, 0x97, 0x91, 0x93, 0x9d, 0x9f, 0x99, 0x9b,
245 0x85, 0x84, 0x87, 0x86, 0x81, 0x80, 0x83, 0x82,
246 0x8d, 0x8c, 0x8f, 0x8e, 0x89, 0x88, 0x8b, 0x8a,
247 0xb5, 0xb5, 0xb4, 0xb4, 0xb7, 0xb7, 0xb6, 0xb6,
248 0xb1, 0xb1, 0xb0, 0xb0, 0xb3, 0xb3, 0xb2, 0xb2,
249 0xbd, 0xbd, 0xbc, 0xbc, 0xbf, 0xbf, 0xbe, 0xbe,
250 0xb9, 0xb9, 0xb8, 0xb8, 0xbb, 0xbb, 0xba, 0xba,
251 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4,
252 0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6,
253 0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0,
254 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2,
255 0xad, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac,
256 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae,
257 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8,
258 0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa,
259 };
260
261 #define DEFINE_FILTER(name) \
262 static int \
263 name##_fetch_to(stream_fetcher_t *, audio_stream_t *, int); \
264 stream_filter_t * \
265 name(struct audio_softc *sc, const audio_params_t *from, \
266 const audio_params_t *to) \
267 { \
268 DPRINTF(("Construct '%s' filter.\n", __func__)); \
269 return auconv_nocontext_filter_factory(name##_fetch_to); \
270 } \
271 static int \
272 name##_fetch_to(stream_fetcher_t *self, audio_stream_t *dst, int max_used)
273
274 DEFINE_FILTER(mulaw_to_linear8)
275 {
276 stream_filter_t *this;
277 int m, err;
278
279 this = (stream_filter_t *)self;
280 if ((err = this->prev->fetch_to(this->prev, this->src, max_used)))
281 return err;
282 m = dst->end - dst->start;
283 m = min(m, max_used);
284 if (dst->param.encoding == AUDIO_ENCODING_ULINEAR_LE) {
285 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
286 *d = mulawtolin16[*s][0];
287 } FILTER_LOOP_EPILOGUE(this->src, dst);
288 } else {
289 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
290 *d = mulawtolin16[*s][0] ^ 0x80;
291 } FILTER_LOOP_EPILOGUE(this->src, dst);
292 }
293 return 0;
294 }
295
296 DEFINE_FILTER(mulaw_to_linear16)
297 {
298 stream_filter_t *this;
299 int m, err;
300
301 this = (stream_filter_t *)self;
302 max_used = (max_used + 1) & ~1; /* round up to even */
303 if ((err = this->prev->fetch_to(this->prev, this->src, max_used / 2)))
304 return err;
305 m = (dst->end - dst->start) & ~1;
306 m = min(m, max_used);
307 switch (dst->param.encoding) {
308 case AUDIO_ENCODING_ULINEAR_LE:
309 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
310 d[0] = mulawtolin16[s[0]][1];
311 d[1] = mulawtolin16[s[0]][0];
312 } FILTER_LOOP_EPILOGUE(this->src, dst);
313 break;
314 case AUDIO_ENCODING_ULINEAR_BE:
315 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
316 d[0] = mulawtolin16[s[0]][0];
317 d[1] = mulawtolin16[s[0]][1];
318 } FILTER_LOOP_EPILOGUE(this->src, dst);
319 break;
320 case AUDIO_ENCODING_SLINEAR_LE:
321 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
322 d[0] = mulawtolin16[s[0]][1];
323 d[1] = mulawtolin16[s[0]][0] ^ 0x80;
324 } FILTER_LOOP_EPILOGUE(this->src, dst);
325 break;
326 case AUDIO_ENCODING_SLINEAR_BE:
327 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
328 d[0] = mulawtolin16[s[0]][0] ^ 0x80;
329 d[1] = mulawtolin16[s[0]][1];
330 } FILTER_LOOP_EPILOGUE(this->src, dst);
331 break;
332 }
333 return 0;
334 }
335
336 DEFINE_FILTER(linear16_to_mulaw)
337 {
338 stream_filter_t *this;
339 int m, err;
340
341 this = (stream_filter_t *)self;
342 if ((err = this->prev->fetch_to(this->prev, this->src, max_used * 2)))
343 return err;
344 m = dst->end - dst->start;
345 m = min(m, max_used);
346 switch (this->src->param.encoding) {
347 case AUDIO_ENCODING_SLINEAR_LE:
348 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
349 d[0] = lintomulaw[s[1] ^ 0x80];
350 } FILTER_LOOP_EPILOGUE(this->src, dst);
351 break;
352 case AUDIO_ENCODING_SLINEAR_BE:
353 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
354 d[0] = lintomulaw[s[0] ^ 0x80];
355 } FILTER_LOOP_EPILOGUE(this->src, dst);
356 break;
357 case AUDIO_ENCODING_ULINEAR_LE:
358 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
359 d[0] = lintomulaw[s[1]];
360 } FILTER_LOOP_EPILOGUE(this->src, dst);
361 break;
362 case AUDIO_ENCODING_ULINEAR_BE:
363 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
364 d[0] = lintomulaw[s[0]];
365 } FILTER_LOOP_EPILOGUE(this->src, dst);
366 break;
367 }
368 return 0;
369 }
370
371 DEFINE_FILTER(linear8_to_mulaw)
372 {
373 stream_filter_t *this;
374 int m, err;
375
376 this = (stream_filter_t *)self;
377 if ((err = this->prev->fetch_to(this->prev, this->src, max_used)))
378 return err;
379 m = dst->end - dst->start;
380 m = min(m, max_used);
381 if (this->src->param.encoding == AUDIO_ENCODING_ULINEAR_LE) {
382 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
383 *d = lintomulaw[*s];
384 } FILTER_LOOP_EPILOGUE(this->src, dst);
385 } else { /* SLINEAR_LE */
386 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
387 *d = lintomulaw[*s ^ 0x80];
388 } FILTER_LOOP_EPILOGUE(this->src, dst);
389 }
390 return 0;
391 }
392
393 DEFINE_FILTER(alaw_to_linear8)
394 {
395 stream_filter_t *this;
396 int m, err;
397
398 this = (stream_filter_t *)self;
399 if ((err = this->prev->fetch_to(this->prev, this->src, max_used)))
400 return err;
401 m = dst->end - dst->start;
402 m = min(m, max_used);
403 if (dst->param.encoding == AUDIO_ENCODING_ULINEAR_LE) {
404 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
405 *d = alawtolin16[*s][0];
406 } FILTER_LOOP_EPILOGUE(this->src, dst);
407 } else { /* SLINEAR */
408 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
409 *d = alawtolin16[*s][0] ^ 0x80;
410 } FILTER_LOOP_EPILOGUE(this->src, dst);
411 }
412 return 0;
413 }
414
415 DEFINE_FILTER(alaw_to_linear16)
416 {
417 stream_filter_t *this;
418 int m, err;
419
420 this = (stream_filter_t *)self;
421 max_used = (max_used + 1) & ~1; /* round up to even */
422 if ((err = this->prev->fetch_to(this->prev, this->src, max_used / 2)))
423 return err;
424 m = (dst->end - dst->start) & ~1;
425 m = min(m, max_used);
426 switch (dst->param.encoding) {
427 case AUDIO_ENCODING_ULINEAR_LE:
428 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
429 d[0] = alawtolin16[s[0]][1];
430 d[1] = alawtolin16[s[0]][0];
431 } FILTER_LOOP_EPILOGUE(this->src, dst);
432 break;
433 case AUDIO_ENCODING_ULINEAR_BE:
434 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
435 d[0] = alawtolin16[s[0]][0];
436 d[1] = alawtolin16[s[0]][1];
437 } FILTER_LOOP_EPILOGUE(this->src, dst);
438 break;
439 case AUDIO_ENCODING_SLINEAR_LE:
440 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
441 d[0] = alawtolin16[s[0]][1];
442 d[1] = alawtolin16[s[0]][0] ^ 0x80;
443 } FILTER_LOOP_EPILOGUE(this->src, dst);
444 break;
445 case AUDIO_ENCODING_SLINEAR_BE:
446 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
447 d[0] = alawtolin16[s[0]][0] ^ 0x80;
448 d[1] = alawtolin16[s[0]][1];
449 } FILTER_LOOP_EPILOGUE(this->src, dst);
450 break;
451 }
452 return 0;
453 }
454
455 DEFINE_FILTER(linear8_to_alaw)
456 {
457 stream_filter_t *this;
458 int m, err;
459
460 this = (stream_filter_t *)self;
461 if ((err = this->prev->fetch_to(this->prev, this->src, max_used)))
462 return err;
463 m = dst->end - dst->start;
464 m = min(m, max_used);
465 if (this->src->param.encoding == AUDIO_ENCODING_ULINEAR_LE) {
466 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
467 *d = lintoalaw[*s];
468 } FILTER_LOOP_EPILOGUE(this->src, dst);
469 } else { /* SLINEAR_LE */
470 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
471 *d = lintoalaw[*s ^ 0x80];
472 } FILTER_LOOP_EPILOGUE(this->src, dst);
473 }
474 return 0;
475 }
476
477 DEFINE_FILTER(linear16_to_alaw)
478 {
479 stream_filter_t *this;
480 int m, err;
481
482 this = (stream_filter_t *)self;
483 if ((err = this->prev->fetch_to(this->prev, this->src, max_used * 2)))
484 return err;
485 m = dst->end - dst->start;
486 m = min(m, max_used);
487 switch (this->src->param.encoding) {
488 case AUDIO_ENCODING_SLINEAR_LE:
489 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
490 d[0] = lintoalaw[s[1] ^ 0x80];
491 } FILTER_LOOP_EPILOGUE(this->src, dst);
492 break;
493 case AUDIO_ENCODING_SLINEAR_BE:
494 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
495 d[0] = lintoalaw[s[0] ^ 0x80];
496 } FILTER_LOOP_EPILOGUE(this->src, dst);
497 break;
498 case AUDIO_ENCODING_ULINEAR_LE:
499 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
500 d[0] = lintoalaw[s[1]];
501 } FILTER_LOOP_EPILOGUE(this->src, dst);
502 break;
503 case AUDIO_ENCODING_ULINEAR_BE:
504 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
505 d[0] = lintoalaw[s[0]];
506 } FILTER_LOOP_EPILOGUE(this->src, dst);
507 break;
508 }
509 return 0;
510 }
Cache object: 2d1a5ecc081412e82032fea64896b615
|