linear.c revision 1.3 1 1.3 isaki /* $NetBSD: linear.c,v 1.3 2020/01/11 04:06:13 isaki Exp $ */
2 1.2 isaki
3 1.2 isaki /*
4 1.2 isaki * Copyright (C) 2017 Tetsuya Isaki. All rights reserved.
5 1.2 isaki * Copyright (C) 2017 Y.Sugahara (moveccr). All rights reserved.
6 1.2 isaki *
7 1.2 isaki * Redistribution and use in source and binary forms, with or without
8 1.2 isaki * modification, are permitted provided that the following conditions
9 1.2 isaki * are met:
10 1.2 isaki * 1. Redistributions of source code must retain the above copyright
11 1.2 isaki * notice, this list of conditions and the following disclaimer.
12 1.2 isaki * 2. Redistributions in binary form must reproduce the above copyright
13 1.2 isaki * notice, this list of conditions and the following disclaimer in the
14 1.2 isaki * documentation and/or other materials provided with the distribution.
15 1.2 isaki *
16 1.2 isaki * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 1.2 isaki * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 1.2 isaki * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 1.2 isaki * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 1.2 isaki * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 1.2 isaki * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 1.2 isaki * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 1.2 isaki * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 1.2 isaki * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 1.2 isaki * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 1.2 isaki * SUCH DAMAGE.
27 1.2 isaki */
28 1.2 isaki
29 1.2 isaki #include <sys/cdefs.h>
30 1.3 isaki __KERNEL_RCSID(0, "$NetBSD: linear.c,v 1.3 2020/01/11 04:06:13 isaki Exp $");
31 1.2 isaki
32 1.2 isaki #include <sys/types.h>
33 1.2 isaki #include <sys/systm.h>
34 1.2 isaki #include <sys/device.h>
35 1.2 isaki #include <dev/audio/audiovar.h>
36 1.2 isaki #include <dev/audio/linear.h>
37 1.2 isaki
38 1.2 isaki /*
39 1.2 isaki * audio_linear8_to_internal:
40 1.2 isaki * This filter performs conversion from [US]LINEAR8 to internal format.
41 1.2 isaki */
42 1.2 isaki void
43 1.2 isaki audio_linear8_to_internal(audio_filter_arg_t *arg)
44 1.2 isaki {
45 1.2 isaki const uint8_t *s;
46 1.2 isaki aint_t *d;
47 1.2 isaki uint8_t xor;
48 1.2 isaki u_int sample_count;
49 1.2 isaki u_int i;
50 1.2 isaki
51 1.2 isaki DIAGNOSTIC_filter_arg(arg);
52 1.2 isaki KASSERT(audio_format2_is_linear(arg->srcfmt));
53 1.2 isaki KASSERT(arg->srcfmt->precision == 8);
54 1.2 isaki KASSERT(arg->srcfmt->stride == 8);
55 1.2 isaki KASSERT(audio_format2_is_internal(arg->dstfmt));
56 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
57 1.2 isaki
58 1.2 isaki s = arg->src;
59 1.2 isaki d = arg->dst;
60 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
61 1.2 isaki xor = audio_format2_is_signed(arg->srcfmt) ? 0 : 0x80;
62 1.2 isaki
63 1.2 isaki for (i = 0; i < sample_count; i++) {
64 1.2 isaki uint8_t val;
65 1.2 isaki val = *s++;
66 1.2 isaki val ^= xor;
67 1.2 isaki *d++ = (auint_t)val << (AUDIO_INTERNAL_BITS - 8);
68 1.2 isaki }
69 1.2 isaki }
70 1.2 isaki
71 1.2 isaki /*
72 1.2 isaki * audio_internal_to_linear8:
73 1.2 isaki * This filter performs conversion from internal format to [US]LINEAR8.
74 1.2 isaki */
75 1.2 isaki void
76 1.2 isaki audio_internal_to_linear8(audio_filter_arg_t *arg)
77 1.2 isaki {
78 1.2 isaki const aint_t *s;
79 1.2 isaki uint8_t *d;
80 1.2 isaki uint8_t xor;
81 1.2 isaki u_int sample_count;
82 1.2 isaki u_int i;
83 1.2 isaki
84 1.2 isaki DIAGNOSTIC_filter_arg(arg);
85 1.2 isaki KASSERT(audio_format2_is_linear(arg->dstfmt));
86 1.2 isaki KASSERT(arg->dstfmt->precision == 8);
87 1.2 isaki KASSERT(arg->dstfmt->stride == 8);
88 1.2 isaki KASSERT(audio_format2_is_internal(arg->srcfmt));
89 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
90 1.2 isaki
91 1.2 isaki s = arg->src;
92 1.2 isaki d = arg->dst;
93 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
94 1.2 isaki xor = audio_format2_is_signed(arg->dstfmt) ? 0 : 0x80;
95 1.2 isaki
96 1.2 isaki for (i = 0; i < sample_count; i++) {
97 1.2 isaki uint8_t val;
98 1.2 isaki val = (*s++) >> (AUDIO_INTERNAL_BITS - 8);
99 1.2 isaki val ^= xor;
100 1.2 isaki *d++ = val;
101 1.2 isaki }
102 1.2 isaki }
103 1.2 isaki
104 1.2 isaki /*
105 1.2 isaki * audio_linear16_to_internal:
106 1.2 isaki * This filter performs conversion from [US]LINEAR16{LE,BE} to internal
107 1.2 isaki * format.
108 1.2 isaki */
109 1.2 isaki void
110 1.2 isaki audio_linear16_to_internal(audio_filter_arg_t *arg)
111 1.2 isaki {
112 1.2 isaki const uint16_t *s;
113 1.2 isaki aint_t *d;
114 1.2 isaki uint16_t xor;
115 1.2 isaki u_int sample_count;
116 1.2 isaki u_int shift;
117 1.2 isaki u_int i;
118 1.2 isaki bool is_src_NE;
119 1.2 isaki
120 1.2 isaki DIAGNOSTIC_filter_arg(arg);
121 1.2 isaki KASSERT(audio_format2_is_linear(arg->srcfmt));
122 1.2 isaki KASSERT(arg->srcfmt->precision == 16);
123 1.2 isaki KASSERT(arg->srcfmt->stride == 16);
124 1.2 isaki KASSERT(audio_format2_is_internal(arg->dstfmt));
125 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
126 1.2 isaki
127 1.2 isaki s = arg->src;
128 1.2 isaki d = arg->dst;
129 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
130 1.2 isaki
131 1.2 isaki shift = AUDIO_INTERNAL_BITS - 16;
132 1.2 isaki xor = audio_format2_is_signed(arg->srcfmt) ? 0 : 0x8000;
133 1.2 isaki is_src_NE = (audio_format2_endian(arg->srcfmt) == BYTE_ORDER);
134 1.2 isaki
135 1.2 isaki /*
136 1.2 isaki * Since slinear16_OppositeEndian to slinear_NativeEndian is used
137 1.2 isaki * so much especially on big endian machines, so it's expanded.
138 1.2 isaki * Other conversions are rarely used, so they are compressed.
139 1.2 isaki */
140 1.2 isaki if (__predict_true(xor == 0) && is_src_NE == false) {
141 1.2 isaki /* slinear16_OE to slinear<AI>_NE */
142 1.2 isaki for (i = 0; i < sample_count; i++) {
143 1.2 isaki uint16_t val;
144 1.2 isaki val = *s++;
145 1.2 isaki val = bswap16(val);
146 1.2 isaki *d++ = (auint_t)val << shift;
147 1.2 isaki }
148 1.2 isaki } else {
149 1.2 isaki /* slinear16_NE to slinear<AI>_NE */
150 1.2 isaki /* ulinear16_{NE,OE} to slinear<AI>_NE */
151 1.2 isaki for (i = 0; i < sample_count; i++) {
152 1.2 isaki uint16_t val;
153 1.2 isaki val = *s++;
154 1.2 isaki if (!is_src_NE)
155 1.2 isaki val = bswap16(val);
156 1.2 isaki val ^= xor;
157 1.2 isaki *d++ = (auint_t)val << shift;
158 1.2 isaki }
159 1.2 isaki }
160 1.2 isaki }
161 1.2 isaki
162 1.2 isaki /*
163 1.2 isaki * audio_internal_to_linear16:
164 1.2 isaki * This filter performs conversion from internal format to
165 1.2 isaki * [US]LINEAR16{LE,BE}.
166 1.2 isaki */
167 1.2 isaki void
168 1.2 isaki audio_internal_to_linear16(audio_filter_arg_t *arg)
169 1.2 isaki {
170 1.2 isaki const aint_t *s;
171 1.2 isaki uint16_t *d;
172 1.2 isaki uint16_t xor;
173 1.2 isaki u_int sample_count;
174 1.2 isaki u_int shift;
175 1.2 isaki u_int i;
176 1.2 isaki bool is_dst_NE;
177 1.2 isaki
178 1.2 isaki DIAGNOSTIC_filter_arg(arg);
179 1.2 isaki KASSERT(audio_format2_is_linear(arg->dstfmt));
180 1.2 isaki KASSERT(arg->dstfmt->precision == 16);
181 1.2 isaki KASSERT(arg->dstfmt->stride == 16);
182 1.2 isaki KASSERT(audio_format2_is_internal(arg->srcfmt));
183 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
184 1.2 isaki
185 1.2 isaki s = arg->src;
186 1.2 isaki d = arg->dst;
187 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
188 1.2 isaki
189 1.2 isaki shift = AUDIO_INTERNAL_BITS - 16;
190 1.2 isaki xor = audio_format2_is_signed(arg->dstfmt) ? 0 : 0x8000;
191 1.2 isaki is_dst_NE = (audio_format2_endian(arg->dstfmt) == BYTE_ORDER);
192 1.2 isaki
193 1.2 isaki /*
194 1.2 isaki * Since slinear_NativeEndian to slinear16_OppositeEndian is used
195 1.2 isaki * so much especially on big endian machines, so it's expanded.
196 1.2 isaki * Other conversions are rarely used, so they are compressed.
197 1.2 isaki */
198 1.2 isaki if (__predict_true(xor == 0) && is_dst_NE == false) {
199 1.2 isaki /* slinear<AI>_NE -> slinear16_OE */
200 1.2 isaki for (i = 0; i < sample_count; i++) {
201 1.2 isaki uint16_t val;
202 1.2 isaki val = (*s++) >> shift;
203 1.2 isaki val = bswap16(val);
204 1.2 isaki *d++ = val;
205 1.2 isaki }
206 1.2 isaki } else {
207 1.2 isaki /* slinear<AI>_NE -> slinear16_NE */
208 1.2 isaki /* slinear<AI>_NE -> ulinear16_{NE,OE} */
209 1.2 isaki for (i = 0; i < sample_count; i++) {
210 1.2 isaki uint16_t val;
211 1.2 isaki val = (*s++) >> shift;
212 1.2 isaki val ^= xor;
213 1.2 isaki if (!is_dst_NE)
214 1.2 isaki val = bswap16(val);
215 1.2 isaki *d++ = val;
216 1.2 isaki }
217 1.2 isaki }
218 1.2 isaki }
219 1.2 isaki
220 1.2 isaki #if defined(AUDIO_SUPPORT_LINEAR24)
221 1.2 isaki /*
222 1.2 isaki * audio_linear24_to_internal:
223 1.2 isaki * This filter performs conversion from [US]LINEAR24/24{LE,BE} to
224 1.2 isaki * internal format. Since it's rerely used, it's size optimized.
225 1.2 isaki */
226 1.2 isaki void
227 1.2 isaki audio_linear24_to_internal(audio_filter_arg_t *arg)
228 1.2 isaki {
229 1.2 isaki const uint8_t *s;
230 1.2 isaki aint_t *d;
231 1.2 isaki auint_t xor;
232 1.2 isaki u_int sample_count;
233 1.2 isaki u_int i;
234 1.2 isaki bool is_src_LE;
235 1.2 isaki
236 1.2 isaki DIAGNOSTIC_filter_arg(arg);
237 1.2 isaki KASSERT(audio_format2_is_linear(arg->srcfmt));
238 1.2 isaki KASSERT(arg->srcfmt->precision == 24);
239 1.2 isaki KASSERT(arg->srcfmt->stride == 24);
240 1.2 isaki KASSERT(audio_format2_is_internal(arg->dstfmt));
241 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
242 1.2 isaki
243 1.2 isaki s = arg->src;
244 1.2 isaki d = arg->dst;
245 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
246 1.2 isaki xor = audio_format2_is_signed(arg->srcfmt)
247 1.2 isaki ? 0 : (1 << (AUDIO_INTERNAL_BITS - 1));
248 1.2 isaki is_src_LE = (audio_format2_endian(arg->srcfmt) == LITTLE_ENDIAN);
249 1.2 isaki
250 1.2 isaki for (i = 0; i < sample_count; i++) {
251 1.2 isaki uint32_t val;
252 1.2 isaki if (is_src_LE) {
253 1.2 isaki val = s[0] | (s[1] << 8) | (s[2] << 16);
254 1.2 isaki } else {
255 1.2 isaki val = (s[0] << 16) | (s[1] << 8) | s[2];
256 1.2 isaki }
257 1.2 isaki s += 3;
258 1.2 isaki
259 1.2 isaki #if AUDIO_INTERNAL_BITS < 24
260 1.2 isaki val >>= 24 - AUDIO_INTERNAL_BITS;
261 1.2 isaki #else
262 1.2 isaki val <<= AUDIO_INTERNAL_BITS - 24;
263 1.2 isaki #endif
264 1.2 isaki val ^= xor;
265 1.2 isaki *d++ = val;
266 1.2 isaki }
267 1.2 isaki }
268 1.2 isaki
269 1.2 isaki /*
270 1.2 isaki * audio_internal_to_linear24:
271 1.2 isaki * This filter performs conversion from internal format to
272 1.2 isaki * [US]LINEAR24/24{LE,BE}. Since it's rarely used, it's size optimized.
273 1.2 isaki */
274 1.2 isaki void
275 1.2 isaki audio_internal_to_linear24(audio_filter_arg_t *arg)
276 1.2 isaki {
277 1.2 isaki const aint_t *s;
278 1.2 isaki uint8_t *d;
279 1.2 isaki auint_t xor;
280 1.2 isaki u_int sample_count;
281 1.2 isaki u_int i;
282 1.2 isaki bool is_dst_LE;
283 1.2 isaki
284 1.2 isaki DIAGNOSTIC_filter_arg(arg);
285 1.2 isaki KASSERT(audio_format2_is_linear(arg->dstfmt));
286 1.2 isaki KASSERT(arg->dstfmt->precision == 24);
287 1.2 isaki KASSERT(arg->dstfmt->stride == 24);
288 1.2 isaki KASSERT(audio_format2_is_internal(arg->srcfmt));
289 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
290 1.2 isaki
291 1.2 isaki s = arg->src;
292 1.2 isaki d = arg->dst;
293 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
294 1.2 isaki xor = audio_format2_is_signed(arg->dstfmt)
295 1.2 isaki ? 0 : (1 << (AUDIO_INTERNAL_BITS - 1));
296 1.2 isaki is_dst_LE = (audio_format2_endian(arg->dstfmt) == LITTLE_ENDIAN);
297 1.2 isaki
298 1.2 isaki for (i = 0; i < sample_count; i++) {
299 1.2 isaki uint32_t val;
300 1.2 isaki val = *s++;
301 1.2 isaki val ^= xor;
302 1.2 isaki #if AUDIO_INTERNAL_BITS < 24
303 1.2 isaki val <<= 24 - AUDIO_INTERNAL_BITS;
304 1.2 isaki #else
305 1.2 isaki val >>= AUDIO_INTERNAL_BITS - 24;
306 1.2 isaki #endif
307 1.2 isaki if (is_dst_LE) {
308 1.2 isaki d[0] = val & 0xff;
309 1.2 isaki d[1] = (val >> 8) & 0xff;
310 1.2 isaki d[2] = (val >> 16) & 0xff;
311 1.2 isaki } else {
312 1.2 isaki d[0] = (val >> 16) & 0xff;
313 1.2 isaki d[1] = (val >> 8) & 0xff;
314 1.2 isaki d[2] = val & 0xff;
315 1.2 isaki }
316 1.2 isaki d += 3;
317 1.2 isaki }
318 1.2 isaki }
319 1.2 isaki #endif /* AUDIO_SUPPORT_LINEAR24 */
320 1.2 isaki
321 1.2 isaki /*
322 1.2 isaki * audio_linear32_to_internal:
323 1.2 isaki * This filter performs conversion from [US]LINEAR32{LE,BE} to internal
324 1.2 isaki * format. Since it's rarely used, it's size optimized.
325 1.2 isaki */
326 1.2 isaki void
327 1.2 isaki audio_linear32_to_internal(audio_filter_arg_t *arg)
328 1.2 isaki {
329 1.2 isaki const uint32_t *s;
330 1.2 isaki aint_t *d;
331 1.2 isaki auint_t xor;
332 1.2 isaki u_int sample_count;
333 1.2 isaki u_int i;
334 1.2 isaki bool is_src_NE;
335 1.2 isaki
336 1.2 isaki DIAGNOSTIC_filter_arg(arg);
337 1.2 isaki KASSERT(audio_format2_is_linear(arg->srcfmt));
338 1.2 isaki KASSERT(arg->srcfmt->precision == 32);
339 1.2 isaki KASSERT(arg->srcfmt->stride == 32);
340 1.2 isaki KASSERT(audio_format2_is_internal(arg->dstfmt));
341 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
342 1.2 isaki
343 1.2 isaki s = arg->src;
344 1.2 isaki d = arg->dst;
345 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
346 1.2 isaki xor = audio_format2_is_signed(arg->srcfmt)
347 1.2 isaki ? 0 : (1 << (AUDIO_INTERNAL_BITS - 1));
348 1.2 isaki is_src_NE = (audio_format2_endian(arg->srcfmt) == BYTE_ORDER);
349 1.2 isaki
350 1.2 isaki for (i = 0; i < sample_count; i++) {
351 1.2 isaki uint32_t val;
352 1.2 isaki val = *s++;
353 1.2 isaki if (!is_src_NE)
354 1.2 isaki val = bswap32(val);
355 1.2 isaki val >>= 32 - AUDIO_INTERNAL_BITS;
356 1.2 isaki val ^= xor;
357 1.2 isaki *d++ = val;
358 1.2 isaki }
359 1.2 isaki }
360 1.2 isaki
361 1.2 isaki /*
362 1.2 isaki * audio_internal_to_linear32:
363 1.2 isaki * This filter performs conversion from internal format to
364 1.2 isaki * [US]LINEAR32{LE,BE}. Since it's rarely used, it's size optimized.
365 1.2 isaki */
366 1.2 isaki void
367 1.2 isaki audio_internal_to_linear32(audio_filter_arg_t *arg)
368 1.2 isaki {
369 1.2 isaki const aint_t *s;
370 1.2 isaki uint32_t *d;
371 1.2 isaki auint_t xor;
372 1.2 isaki u_int sample_count;
373 1.2 isaki u_int i;
374 1.2 isaki bool is_dst_NE;
375 1.2 isaki
376 1.2 isaki DIAGNOSTIC_filter_arg(arg);
377 1.2 isaki KASSERT(audio_format2_is_linear(arg->dstfmt));
378 1.2 isaki KASSERT(arg->dstfmt->precision == 32);
379 1.2 isaki KASSERT(arg->dstfmt->stride == 32);
380 1.2 isaki KASSERT(audio_format2_is_internal(arg->srcfmt));
381 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
382 1.2 isaki
383 1.2 isaki s = arg->src;
384 1.2 isaki d = arg->dst;
385 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
386 1.2 isaki xor = audio_format2_is_signed(arg->dstfmt)
387 1.2 isaki ? 0 : (1 << (AUDIO_INTERNAL_BITS - 1));
388 1.2 isaki is_dst_NE = (audio_format2_endian(arg->dstfmt) == BYTE_ORDER);
389 1.2 isaki
390 1.2 isaki for (i = 0; i < sample_count; i++) {
391 1.2 isaki uint32_t val;
392 1.2 isaki val = *s++;
393 1.2 isaki val ^= xor;
394 1.2 isaki val <<= 32 - AUDIO_INTERNAL_BITS;
395 1.2 isaki if (!is_dst_NE)
396 1.2 isaki val = bswap32(val);
397 1.2 isaki *d++ = val;
398 1.2 isaki }
399 1.2 isaki }
400