No empty .Rs/.Re
[netbsd-mini2440.git] / sys / dev / mulaw.c
blob95f4be4f725e2b6d56ae09a2b6826c864b20153a
1 /* $NetBSD: mulaw.c,v 1.26 2006/11/16 01:32:45 christos Exp $ */
3 /*
4 * Copyright (c) 1991-1993 Regents of the University of California.
5 * All rights reserved.
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.
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.
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: mulaw.c,v 1.26 2006/11/16 01:32:45 christos Exp $");
40 #include <sys/types.h>
41 #include <sys/systm.h>
42 #include <sys/device.h>
43 #include <dev/auconv.h>
44 #include <dev/mulaw.h>
46 /* #define MULAW_DEBUG */
47 #ifdef MULAW_DEBUG
48 # define DPRINTF(x) printf x
49 #else
50 # define DPRINTF(x)
51 #endif
54 * This table converts a (8 bit) mu-law value to a 16 bit value.
55 * The 16 bits are represented as an array of two bytes for easier access
56 * to the individual bytes.
58 static const uint8_t mulawtolin16[256][2] = {
59 {0x02,0x84}, {0x06,0x84}, {0x0a,0x84}, {0x0e,0x84},
60 {0x12,0x84}, {0x16,0x84}, {0x1a,0x84}, {0x1e,0x84},
61 {0x22,0x84}, {0x26,0x84}, {0x2a,0x84}, {0x2e,0x84},
62 {0x32,0x84}, {0x36,0x84}, {0x3a,0x84}, {0x3e,0x84},
63 {0x41,0x84}, {0x43,0x84}, {0x45,0x84}, {0x47,0x84},
64 {0x49,0x84}, {0x4b,0x84}, {0x4d,0x84}, {0x4f,0x84},
65 {0x51,0x84}, {0x53,0x84}, {0x55,0x84}, {0x57,0x84},
66 {0x59,0x84}, {0x5b,0x84}, {0x5d,0x84}, {0x5f,0x84},
67 {0x61,0x04}, {0x62,0x04}, {0x63,0x04}, {0x64,0x04},
68 {0x65,0x04}, {0x66,0x04}, {0x67,0x04}, {0x68,0x04},
69 {0x69,0x04}, {0x6a,0x04}, {0x6b,0x04}, {0x6c,0x04},
70 {0x6d,0x04}, {0x6e,0x04}, {0x6f,0x04}, {0x70,0x04},
71 {0x70,0xc4}, {0x71,0x44}, {0x71,0xc4}, {0x72,0x44},
72 {0x72,0xc4}, {0x73,0x44}, {0x73,0xc4}, {0x74,0x44},
73 {0x74,0xc4}, {0x75,0x44}, {0x75,0xc4}, {0x76,0x44},
74 {0x76,0xc4}, {0x77,0x44}, {0x77,0xc4}, {0x78,0x44},
75 {0x78,0xa4}, {0x78,0xe4}, {0x79,0x24}, {0x79,0x64},
76 {0x79,0xa4}, {0x79,0xe4}, {0x7a,0x24}, {0x7a,0x64},
77 {0x7a,0xa4}, {0x7a,0xe4}, {0x7b,0x24}, {0x7b,0x64},
78 {0x7b,0xa4}, {0x7b,0xe4}, {0x7c,0x24}, {0x7c,0x64},
79 {0x7c,0x94}, {0x7c,0xb4}, {0x7c,0xd4}, {0x7c,0xf4},
80 {0x7d,0x14}, {0x7d,0x34}, {0x7d,0x54}, {0x7d,0x74},
81 {0x7d,0x94}, {0x7d,0xb4}, {0x7d,0xd4}, {0x7d,0xf4},
82 {0x7e,0x14}, {0x7e,0x34}, {0x7e,0x54}, {0x7e,0x74},
83 {0x7e,0x8c}, {0x7e,0x9c}, {0x7e,0xac}, {0x7e,0xbc},
84 {0x7e,0xcc}, {0x7e,0xdc}, {0x7e,0xec}, {0x7e,0xfc},
85 {0x7f,0x0c}, {0x7f,0x1c}, {0x7f,0x2c}, {0x7f,0x3c},
86 {0x7f,0x4c}, {0x7f,0x5c}, {0x7f,0x6c}, {0x7f,0x7c},
87 {0x7f,0x88}, {0x7f,0x90}, {0x7f,0x98}, {0x7f,0xa0},
88 {0x7f,0xa8}, {0x7f,0xb0}, {0x7f,0xb8}, {0x7f,0xc0},
89 {0x7f,0xc8}, {0x7f,0xd0}, {0x7f,0xd8}, {0x7f,0xe0},
90 {0x7f,0xe8}, {0x7f,0xf0}, {0x7f,0xf8}, {0x80,0x00},
91 {0xfd,0x7c}, {0xf9,0x7c}, {0xf5,0x7c}, {0xf1,0x7c},
92 {0xed,0x7c}, {0xe9,0x7c}, {0xe5,0x7c}, {0xe1,0x7c},
93 {0xdd,0x7c}, {0xd9,0x7c}, {0xd5,0x7c}, {0xd1,0x7c},
94 {0xcd,0x7c}, {0xc9,0x7c}, {0xc5,0x7c}, {0xc1,0x7c},
95 {0xbe,0x7c}, {0xbc,0x7c}, {0xba,0x7c}, {0xb8,0x7c},
96 {0xb6,0x7c}, {0xb4,0x7c}, {0xb2,0x7c}, {0xb0,0x7c},
97 {0xae,0x7c}, {0xac,0x7c}, {0xaa,0x7c}, {0xa8,0x7c},
98 {0xa6,0x7c}, {0xa4,0x7c}, {0xa2,0x7c}, {0xa0,0x7c},
99 {0x9e,0xfc}, {0x9d,0xfc}, {0x9c,0xfc}, {0x9b,0xfc},
100 {0x9a,0xfc}, {0x99,0xfc}, {0x98,0xfc}, {0x97,0xfc},
101 {0x96,0xfc}, {0x95,0xfc}, {0x94,0xfc}, {0x93,0xfc},
102 {0x92,0xfc}, {0x91,0xfc}, {0x90,0xfc}, {0x8f,0xfc},
103 {0x8f,0x3c}, {0x8e,0xbc}, {0x8e,0x3c}, {0x8d,0xbc},
104 {0x8d,0x3c}, {0x8c,0xbc}, {0x8c,0x3c}, {0x8b,0xbc},
105 {0x8b,0x3c}, {0x8a,0xbc}, {0x8a,0x3c}, {0x89,0xbc},
106 {0x89,0x3c}, {0x88,0xbc}, {0x88,0x3c}, {0x87,0xbc},
107 {0x87,0x5c}, {0x87,0x1c}, {0x86,0xdc}, {0x86,0x9c},
108 {0x86,0x5c}, {0x86,0x1c}, {0x85,0xdc}, {0x85,0x9c},
109 {0x85,0x5c}, {0x85,0x1c}, {0x84,0xdc}, {0x84,0x9c},
110 {0x84,0x5c}, {0x84,0x1c}, {0x83,0xdc}, {0x83,0x9c},
111 {0x83,0x6c}, {0x83,0x4c}, {0x83,0x2c}, {0x83,0x0c},
112 {0x82,0xec}, {0x82,0xcc}, {0x82,0xac}, {0x82,0x8c},
113 {0x82,0x6c}, {0x82,0x4c}, {0x82,0x2c}, {0x82,0x0c},
114 {0x81,0xec}, {0x81,0xcc}, {0x81,0xac}, {0x81,0x8c},
115 {0x81,0x74}, {0x81,0x64}, {0x81,0x54}, {0x81,0x44},
116 {0x81,0x34}, {0x81,0x24}, {0x81,0x14}, {0x81,0x04},
117 {0x80,0xf4}, {0x80,0xe4}, {0x80,0xd4}, {0x80,0xc4},
118 {0x80,0xb4}, {0x80,0xa4}, {0x80,0x94}, {0x80,0x84},
119 {0x80,0x78}, {0x80,0x70}, {0x80,0x68}, {0x80,0x60},
120 {0x80,0x58}, {0x80,0x50}, {0x80,0x48}, {0x80,0x40},
121 {0x80,0x38}, {0x80,0x30}, {0x80,0x28}, {0x80,0x20},
122 {0x80,0x18}, {0x80,0x10}, {0x80,0x08}, {0x80,0x00},
125 static const uint8_t lintomulaw[256] = {
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
127 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
128 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05,
129 0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07,
130 0x07, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
131 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b,
132 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d,
133 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f,
134 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13,
135 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17,
136 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, 0x1b,
137 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f,
138 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
139 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
140 0x2f, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c,
141 0x3e, 0x41, 0x45, 0x49, 0x4d, 0x53, 0x5b, 0x67,
142 0xff, 0xe7, 0xdb, 0xd3, 0xcd, 0xc9, 0xc5, 0xc1,
143 0xbe, 0xbc, 0xba, 0xb8, 0xb6, 0xb4, 0xb2, 0xb0,
144 0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8,
145 0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
146 0x9f, 0x9f, 0x9e, 0x9e, 0x9d, 0x9d, 0x9c, 0x9c,
147 0x9b, 0x9b, 0x9a, 0x9a, 0x99, 0x99, 0x98, 0x98,
148 0x97, 0x97, 0x96, 0x96, 0x95, 0x95, 0x94, 0x94,
149 0x93, 0x93, 0x92, 0x92, 0x91, 0x91, 0x90, 0x90,
150 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e,
151 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c,
152 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a,
153 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88,
154 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86,
155 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84,
156 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
157 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80,
160 static const uint8_t alawtolin16[256][2] = {
161 {0x6a,0x80}, {0x6b,0x80}, {0x68,0x80}, {0x69,0x80},
162 {0x6e,0x80}, {0x6f,0x80}, {0x6c,0x80}, {0x6d,0x80},
163 {0x62,0x80}, {0x63,0x80}, {0x60,0x80}, {0x61,0x80},
164 {0x66,0x80}, {0x67,0x80}, {0x64,0x80}, {0x65,0x80},
165 {0x75,0x40}, {0x75,0xc0}, {0x74,0x40}, {0x74,0xc0},
166 {0x77,0x40}, {0x77,0xc0}, {0x76,0x40}, {0x76,0xc0},
167 {0x71,0x40}, {0x71,0xc0}, {0x70,0x40}, {0x70,0xc0},
168 {0x73,0x40}, {0x73,0xc0}, {0x72,0x40}, {0x72,0xc0},
169 {0x2a,0x00}, {0x2e,0x00}, {0x22,0x00}, {0x26,0x00},
170 {0x3a,0x00}, {0x3e,0x00}, {0x32,0x00}, {0x36,0x00},
171 {0x0a,0x00}, {0x0e,0x00}, {0x02,0x00}, {0x06,0x00},
172 {0x1a,0x00}, {0x1e,0x00}, {0x12,0x00}, {0x16,0x00},
173 {0x55,0x00}, {0x57,0x00}, {0x51,0x00}, {0x53,0x00},
174 {0x5d,0x00}, {0x5f,0x00}, {0x59,0x00}, {0x5b,0x00},
175 {0x45,0x00}, {0x47,0x00}, {0x41,0x00}, {0x43,0x00},
176 {0x4d,0x00}, {0x4f,0x00}, {0x49,0x00}, {0x4b,0x00},
177 {0x7e,0xa8}, {0x7e,0xb8}, {0x7e,0x88}, {0x7e,0x98},
178 {0x7e,0xe8}, {0x7e,0xf8}, {0x7e,0xc8}, {0x7e,0xd8},
179 {0x7e,0x28}, {0x7e,0x38}, {0x7e,0x08}, {0x7e,0x18},
180 {0x7e,0x68}, {0x7e,0x78}, {0x7e,0x48}, {0x7e,0x58},
181 {0x7f,0xa8}, {0x7f,0xb8}, {0x7f,0x88}, {0x7f,0x98},
182 {0x7f,0xe8}, {0x7f,0xf8}, {0x7f,0xc8}, {0x7f,0xd8},
183 {0x7f,0x28}, {0x7f,0x38}, {0x7f,0x08}, {0x7f,0x18},
184 {0x7f,0x68}, {0x7f,0x78}, {0x7f,0x48}, {0x7f,0x58},
185 {0x7a,0xa0}, {0x7a,0xe0}, {0x7a,0x20}, {0x7a,0x60},
186 {0x7b,0xa0}, {0x7b,0xe0}, {0x7b,0x20}, {0x7b,0x60},
187 {0x78,0xa0}, {0x78,0xe0}, {0x78,0x20}, {0x78,0x60},
188 {0x79,0xa0}, {0x79,0xe0}, {0x79,0x20}, {0x79,0x60},
189 {0x7d,0x50}, {0x7d,0x70}, {0x7d,0x10}, {0x7d,0x30},
190 {0x7d,0xd0}, {0x7d,0xf0}, {0x7d,0x90}, {0x7d,0xb0},
191 {0x7c,0x50}, {0x7c,0x70}, {0x7c,0x10}, {0x7c,0x30},
192 {0x7c,0xd0}, {0x7c,0xf0}, {0x7c,0x90}, {0x7c,0xb0},
193 {0x95,0x80}, {0x94,0x80}, {0x97,0x80}, {0x96,0x80},
194 {0x91,0x80}, {0x90,0x80}, {0x93,0x80}, {0x92,0x80},
195 {0x9d,0x80}, {0x9c,0x80}, {0x9f,0x80}, {0x9e,0x80},
196 {0x99,0x80}, {0x98,0x80}, {0x9b,0x80}, {0x9a,0x80},
197 {0x8a,0xc0}, {0x8a,0x40}, {0x8b,0xc0}, {0x8b,0x40},
198 {0x88,0xc0}, {0x88,0x40}, {0x89,0xc0}, {0x89,0x40},
199 {0x8e,0xc0}, {0x8e,0x40}, {0x8f,0xc0}, {0x8f,0x40},
200 {0x8c,0xc0}, {0x8c,0x40}, {0x8d,0xc0}, {0x8d,0x40},
201 {0xd6,0x00}, {0xd2,0x00}, {0xde,0x00}, {0xda,0x00},
202 {0xc6,0x00}, {0xc2,0x00}, {0xce,0x00}, {0xca,0x00},
203 {0xf6,0x00}, {0xf2,0x00}, {0xfe,0x00}, {0xfa,0x00},
204 {0xe6,0x00}, {0xe2,0x00}, {0xee,0x00}, {0xea,0x00},
205 {0xab,0x00}, {0xa9,0x00}, {0xaf,0x00}, {0xad,0x00},
206 {0xa3,0x00}, {0xa1,0x00}, {0xa7,0x00}, {0xa5,0x00},
207 {0xbb,0x00}, {0xb9,0x00}, {0xbf,0x00}, {0xbd,0x00},
208 {0xb3,0x00}, {0xb1,0x00}, {0xb7,0x00}, {0xb5,0x00},
209 {0x81,0x58}, {0x81,0x48}, {0x81,0x78}, {0x81,0x68},
210 {0x81,0x18}, {0x81,0x08}, {0x81,0x38}, {0x81,0x28},
211 {0x81,0xd8}, {0x81,0xc8}, {0x81,0xf8}, {0x81,0xe8},
212 {0x81,0x98}, {0x81,0x88}, {0x81,0xb8}, {0x81,0xa8},
213 {0x80,0x58}, {0x80,0x48}, {0x80,0x78}, {0x80,0x68},
214 {0x80,0x18}, {0x80,0x08}, {0x80,0x38}, {0x80,0x28},
215 {0x80,0xd8}, {0x80,0xc8}, {0x80,0xf8}, {0x80,0xe8},
216 {0x80,0x98}, {0x80,0x88}, {0x80,0xb8}, {0x80,0xa8},
217 {0x85,0x60}, {0x85,0x20}, {0x85,0xe0}, {0x85,0xa0},
218 {0x84,0x60}, {0x84,0x20}, {0x84,0xe0}, {0x84,0xa0},
219 {0x87,0x60}, {0x87,0x20}, {0x87,0xe0}, {0x87,0xa0},
220 {0x86,0x60}, {0x86,0x20}, {0x86,0xe0}, {0x86,0xa0},
221 {0x82,0xb0}, {0x82,0x90}, {0x82,0xf0}, {0x82,0xd0},
222 {0x82,0x30}, {0x82,0x10}, {0x82,0x70}, {0x82,0x50},
223 {0x83,0xb0}, {0x83,0x90}, {0x83,0xf0}, {0x83,0xd0},
224 {0x83,0x30}, {0x83,0x10}, {0x83,0x70}, {0x83,0x50},
227 static const uint8_t lintoalaw[256] = {
228 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b,
229 0x28, 0x28, 0x28, 0x28, 0x29, 0x29, 0x29, 0x29,
230 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f,
231 0x2c, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d,
232 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x23,
233 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21,
234 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27,
235 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25,
236 0x3a, 0x3a, 0x3b, 0x3b, 0x38, 0x38, 0x39, 0x39,
237 0x3e, 0x3e, 0x3f, 0x3f, 0x3c, 0x3c, 0x3d, 0x3d,
238 0x32, 0x32, 0x33, 0x33, 0x30, 0x30, 0x31, 0x31,
239 0x36, 0x36, 0x37, 0x37, 0x34, 0x34, 0x35, 0x35,
240 0x0a, 0x0b, 0x08, 0x09, 0x0e, 0x0f, 0x0c, 0x0d,
241 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05,
242 0x1a, 0x18, 0x1e, 0x1c, 0x12, 0x10, 0x16, 0x14,
243 0x6a, 0x6e, 0x62, 0x66, 0x7a, 0x72, 0x4a, 0x5a,
244 0xd5, 0xc5, 0xf5, 0xfd, 0xe5, 0xe1, 0xed, 0xe9,
245 0x95, 0x97, 0x91, 0x93, 0x9d, 0x9f, 0x99, 0x9b,
246 0x85, 0x84, 0x87, 0x86, 0x81, 0x80, 0x83, 0x82,
247 0x8d, 0x8c, 0x8f, 0x8e, 0x89, 0x88, 0x8b, 0x8a,
248 0xb5, 0xb5, 0xb4, 0xb4, 0xb7, 0xb7, 0xb6, 0xb6,
249 0xb1, 0xb1, 0xb0, 0xb0, 0xb3, 0xb3, 0xb2, 0xb2,
250 0xbd, 0xbd, 0xbc, 0xbc, 0xbf, 0xbf, 0xbe, 0xbe,
251 0xb9, 0xb9, 0xb8, 0xb8, 0xbb, 0xbb, 0xba, 0xba,
252 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4,
253 0xa7, 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6,
254 0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0,
255 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2,
256 0xad, 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac,
257 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae,
258 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8,
259 0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, 0xaa,
262 #define DEFINE_FILTER(name) \
263 static int \
264 name##_fetch_to(stream_fetcher_t *, audio_stream_t *, int); \
265 stream_filter_t * \
266 name(struct audio_softc *sc, const audio_params_t *from, \
267 const audio_params_t *to) \
269 DPRINTF(("Construct '%s' filter.\n", __func__)); \
270 return auconv_nocontext_filter_factory(name##_fetch_to); \
272 static int \
273 name##_fetch_to(stream_fetcher_t *self, audio_stream_t *dst, int max_used)
275 DEFINE_FILTER(mulaw_to_linear8)
277 stream_filter_t *this;
278 int m, err;
280 this = (stream_filter_t *)self;
281 if ((err = this->prev->fetch_to(this->prev, this->src, max_used)))
282 return err;
283 m = dst->end - dst->start;
284 m = min(m, max_used);
285 if (dst->param.encoding == AUDIO_ENCODING_ULINEAR_LE) {
286 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
287 *d = mulawtolin16[*s][0];
288 } FILTER_LOOP_EPILOGUE(this->src, dst);
289 } else {
290 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
291 *d = mulawtolin16[*s][0] ^ 0x80;
292 } FILTER_LOOP_EPILOGUE(this->src, dst);
294 return 0;
297 DEFINE_FILTER(mulaw_to_linear16)
299 stream_filter_t *this;
300 int m, err;
302 this = (stream_filter_t *)self;
303 max_used = (max_used + 1) & ~1; /* round up to even */
304 if ((err = this->prev->fetch_to(this->prev, this->src, max_used / 2)))
305 return err;
306 m = (dst->end - dst->start) & ~1;
307 m = min(m, max_used);
308 switch (dst->param.encoding) {
309 case AUDIO_ENCODING_ULINEAR_LE:
310 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
311 d[0] = mulawtolin16[s[0]][1];
312 d[1] = mulawtolin16[s[0]][0];
313 } FILTER_LOOP_EPILOGUE(this->src, dst);
314 break;
315 case AUDIO_ENCODING_ULINEAR_BE:
316 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
317 d[0] = mulawtolin16[s[0]][0];
318 d[1] = mulawtolin16[s[0]][1];
319 } FILTER_LOOP_EPILOGUE(this->src, dst);
320 break;
321 case AUDIO_ENCODING_SLINEAR_LE:
322 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
323 d[0] = mulawtolin16[s[0]][1];
324 d[1] = mulawtolin16[s[0]][0] ^ 0x80;
325 } FILTER_LOOP_EPILOGUE(this->src, dst);
326 break;
327 case AUDIO_ENCODING_SLINEAR_BE:
328 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
329 d[0] = mulawtolin16[s[0]][0] ^ 0x80;
330 d[1] = mulawtolin16[s[0]][1];
331 } FILTER_LOOP_EPILOGUE(this->src, dst);
332 break;
334 return 0;
337 DEFINE_FILTER(linear16_to_mulaw)
339 stream_filter_t *this;
340 int m, err;
342 this = (stream_filter_t *)self;
343 if ((err = this->prev->fetch_to(this->prev, this->src, max_used * 2)))
344 return err;
345 m = dst->end - dst->start;
346 m = min(m, max_used);
347 switch (this->src->param.encoding) {
348 case AUDIO_ENCODING_SLINEAR_LE:
349 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
350 d[0] = lintomulaw[s[1] ^ 0x80];
351 } FILTER_LOOP_EPILOGUE(this->src, dst);
352 break;
353 case AUDIO_ENCODING_SLINEAR_BE:
354 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
355 d[0] = lintomulaw[s[0] ^ 0x80];
356 } FILTER_LOOP_EPILOGUE(this->src, dst);
357 break;
358 case AUDIO_ENCODING_ULINEAR_LE:
359 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
360 d[0] = lintomulaw[s[1]];
361 } FILTER_LOOP_EPILOGUE(this->src, dst);
362 break;
363 case AUDIO_ENCODING_ULINEAR_BE:
364 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
365 d[0] = lintomulaw[s[0]];
366 } FILTER_LOOP_EPILOGUE(this->src, dst);
367 break;
369 return 0;
372 DEFINE_FILTER(linear8_to_mulaw)
374 stream_filter_t *this;
375 int m, err;
377 this = (stream_filter_t *)self;
378 if ((err = this->prev->fetch_to(this->prev, this->src, max_used)))
379 return err;
380 m = dst->end - dst->start;
381 m = min(m, max_used);
382 if (this->src->param.encoding == AUDIO_ENCODING_ULINEAR_LE) {
383 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
384 *d = lintomulaw[*s];
385 } FILTER_LOOP_EPILOGUE(this->src, dst);
386 } else { /* SLINEAR_LE */
387 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
388 *d = lintomulaw[*s ^ 0x80];
389 } FILTER_LOOP_EPILOGUE(this->src, dst);
391 return 0;
394 DEFINE_FILTER(alaw_to_linear8)
396 stream_filter_t *this;
397 int m, err;
399 this = (stream_filter_t *)self;
400 if ((err = this->prev->fetch_to(this->prev, this->src, max_used)))
401 return err;
402 m = dst->end - dst->start;
403 m = min(m, max_used);
404 if (dst->param.encoding == AUDIO_ENCODING_ULINEAR_LE) {
405 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
406 *d = alawtolin16[*s][0];
407 } FILTER_LOOP_EPILOGUE(this->src, dst);
408 } else { /* SLINEAR */
409 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
410 *d = alawtolin16[*s][0] ^ 0x80;
411 } FILTER_LOOP_EPILOGUE(this->src, dst);
413 return 0;
416 DEFINE_FILTER(alaw_to_linear16)
418 stream_filter_t *this;
419 int m, err;
421 this = (stream_filter_t *)self;
422 max_used = (max_used + 1) & ~1; /* round up to even */
423 if ((err = this->prev->fetch_to(this->prev, this->src, max_used / 2)))
424 return err;
425 m = (dst->end - dst->start) & ~1;
426 m = min(m, max_used);
427 switch (dst->param.encoding) {
428 case AUDIO_ENCODING_ULINEAR_LE:
429 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
430 d[0] = alawtolin16[s[0]][1];
431 d[1] = alawtolin16[s[0]][0];
432 } FILTER_LOOP_EPILOGUE(this->src, dst);
433 break;
434 case AUDIO_ENCODING_ULINEAR_BE:
435 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
436 d[0] = alawtolin16[s[0]][0];
437 d[1] = alawtolin16[s[0]][1];
438 } FILTER_LOOP_EPILOGUE(this->src, dst);
439 break;
440 case AUDIO_ENCODING_SLINEAR_LE:
441 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
442 d[0] = alawtolin16[s[0]][1];
443 d[1] = alawtolin16[s[0]][0] ^ 0x80;
444 } FILTER_LOOP_EPILOGUE(this->src, dst);
445 break;
446 case AUDIO_ENCODING_SLINEAR_BE:
447 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
448 d[0] = alawtolin16[s[0]][0] ^ 0x80;
449 d[1] = alawtolin16[s[0]][1];
450 } FILTER_LOOP_EPILOGUE(this->src, dst);
451 break;
453 return 0;
456 DEFINE_FILTER(linear8_to_alaw)
458 stream_filter_t *this;
459 int m, err;
461 this = (stream_filter_t *)self;
462 if ((err = this->prev->fetch_to(this->prev, this->src, max_used)))
463 return err;
464 m = dst->end - dst->start;
465 m = min(m, max_used);
466 if (this->src->param.encoding == AUDIO_ENCODING_ULINEAR_LE) {
467 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
468 *d = lintoalaw[*s];
469 } FILTER_LOOP_EPILOGUE(this->src, dst);
470 } else { /* SLINEAR_LE */
471 FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) {
472 *d = lintoalaw[*s ^ 0x80];
473 } FILTER_LOOP_EPILOGUE(this->src, dst);
475 return 0;
478 DEFINE_FILTER(linear16_to_alaw)
480 stream_filter_t *this;
481 int m, err;
483 this = (stream_filter_t *)self;
484 if ((err = this->prev->fetch_to(this->prev, this->src, max_used * 2)))
485 return err;
486 m = dst->end - dst->start;
487 m = min(m, max_used);
488 switch (this->src->param.encoding) {
489 case AUDIO_ENCODING_SLINEAR_LE:
490 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
491 d[0] = lintoalaw[s[1] ^ 0x80];
492 } FILTER_LOOP_EPILOGUE(this->src, dst);
493 break;
494 case AUDIO_ENCODING_SLINEAR_BE:
495 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
496 d[0] = lintoalaw[s[0] ^ 0x80];
497 } FILTER_LOOP_EPILOGUE(this->src, dst);
498 break;
499 case AUDIO_ENCODING_ULINEAR_LE:
500 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
501 d[0] = lintoalaw[s[1]];
502 } FILTER_LOOP_EPILOGUE(this->src, dst);
503 break;
504 case AUDIO_ENCODING_ULINEAR_BE:
505 FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
506 d[0] = lintoalaw[s[0]];
507 } FILTER_LOOP_EPILOGUE(this->src, dst);
508 break;
510 return 0;