linear.c revision 1.2 1 1.2 isaki /* $NetBSD: linear.c,v 1.2 2019/05/08 13:40:17 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 #if defined(_KERNEL)
30 1.2 isaki #include <sys/cdefs.h>
31 1.2 isaki __KERNEL_RCSID(0, "$NetBSD: linear.c,v 1.2 2019/05/08 13:40:17 isaki Exp $");
32 1.2 isaki
33 1.2 isaki #include <sys/types.h>
34 1.2 isaki #include <sys/systm.h>
35 1.2 isaki #include <sys/device.h>
36 1.2 isaki #include <dev/audio/audiovar.h>
37 1.2 isaki #include <dev/audio/linear.h>
38 1.2 isaki #else
39 1.2 isaki #include <stdint.h>
40 1.2 isaki #include <stdbool.h>
41 1.2 isaki #include "compat.h"
42 1.2 isaki #include "audiovar.h"
43 1.2 isaki #endif /* _KERNEL */
44 1.2 isaki
45 1.2 isaki /*
46 1.2 isaki * audio_linear8_to_internal:
47 1.2 isaki * This filter performs conversion from [US]LINEAR8 to internal format.
48 1.2 isaki */
49 1.2 isaki void
50 1.2 isaki audio_linear8_to_internal(audio_filter_arg_t *arg)
51 1.2 isaki {
52 1.2 isaki const uint8_t *s;
53 1.2 isaki aint_t *d;
54 1.2 isaki uint8_t xor;
55 1.2 isaki u_int sample_count;
56 1.2 isaki u_int i;
57 1.2 isaki
58 1.2 isaki DIAGNOSTIC_filter_arg(arg);
59 1.2 isaki KASSERT(audio_format2_is_linear(arg->srcfmt));
60 1.2 isaki KASSERT(arg->srcfmt->precision == 8);
61 1.2 isaki KASSERT(arg->srcfmt->stride == 8);
62 1.2 isaki KASSERT(audio_format2_is_internal(arg->dstfmt));
63 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
64 1.2 isaki
65 1.2 isaki s = arg->src;
66 1.2 isaki d = arg->dst;
67 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
68 1.2 isaki xor = audio_format2_is_signed(arg->srcfmt) ? 0 : 0x80;
69 1.2 isaki
70 1.2 isaki for (i = 0; i < sample_count; i++) {
71 1.2 isaki uint8_t val;
72 1.2 isaki val = *s++;
73 1.2 isaki val ^= xor;
74 1.2 isaki *d++ = (auint_t)val << (AUDIO_INTERNAL_BITS - 8);
75 1.2 isaki }
76 1.2 isaki }
77 1.2 isaki
78 1.2 isaki /*
79 1.2 isaki * audio_internal_to_linear8:
80 1.2 isaki * This filter performs conversion from internal format to [US]LINEAR8.
81 1.2 isaki */
82 1.2 isaki void
83 1.2 isaki audio_internal_to_linear8(audio_filter_arg_t *arg)
84 1.2 isaki {
85 1.2 isaki const aint_t *s;
86 1.2 isaki uint8_t *d;
87 1.2 isaki uint8_t xor;
88 1.2 isaki u_int sample_count;
89 1.2 isaki u_int i;
90 1.2 isaki
91 1.2 isaki DIAGNOSTIC_filter_arg(arg);
92 1.2 isaki KASSERT(audio_format2_is_linear(arg->dstfmt));
93 1.2 isaki KASSERT(arg->dstfmt->precision == 8);
94 1.2 isaki KASSERT(arg->dstfmt->stride == 8);
95 1.2 isaki KASSERT(audio_format2_is_internal(arg->srcfmt));
96 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
97 1.2 isaki
98 1.2 isaki s = arg->src;
99 1.2 isaki d = arg->dst;
100 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
101 1.2 isaki xor = audio_format2_is_signed(arg->dstfmt) ? 0 : 0x80;
102 1.2 isaki
103 1.2 isaki for (i = 0; i < sample_count; i++) {
104 1.2 isaki uint8_t val;
105 1.2 isaki val = (*s++) >> (AUDIO_INTERNAL_BITS - 8);
106 1.2 isaki val ^= xor;
107 1.2 isaki *d++ = val;
108 1.2 isaki }
109 1.2 isaki }
110 1.2 isaki
111 1.2 isaki /*
112 1.2 isaki * audio_linear16_to_internal:
113 1.2 isaki * This filter performs conversion from [US]LINEAR16{LE,BE} to internal
114 1.2 isaki * format.
115 1.2 isaki */
116 1.2 isaki void
117 1.2 isaki audio_linear16_to_internal(audio_filter_arg_t *arg)
118 1.2 isaki {
119 1.2 isaki const uint16_t *s;
120 1.2 isaki aint_t *d;
121 1.2 isaki uint16_t xor;
122 1.2 isaki u_int sample_count;
123 1.2 isaki u_int shift;
124 1.2 isaki u_int i;
125 1.2 isaki bool is_src_NE;
126 1.2 isaki
127 1.2 isaki DIAGNOSTIC_filter_arg(arg);
128 1.2 isaki KASSERT(audio_format2_is_linear(arg->srcfmt));
129 1.2 isaki KASSERT(arg->srcfmt->precision == 16);
130 1.2 isaki KASSERT(arg->srcfmt->stride == 16);
131 1.2 isaki KASSERT(audio_format2_is_internal(arg->dstfmt));
132 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
133 1.2 isaki
134 1.2 isaki s = arg->src;
135 1.2 isaki d = arg->dst;
136 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
137 1.2 isaki
138 1.2 isaki shift = AUDIO_INTERNAL_BITS - 16;
139 1.2 isaki xor = audio_format2_is_signed(arg->srcfmt) ? 0 : 0x8000;
140 1.2 isaki is_src_NE = (audio_format2_endian(arg->srcfmt) == BYTE_ORDER);
141 1.2 isaki
142 1.2 isaki /*
143 1.2 isaki * Since slinear16_OppositeEndian to slinear_NativeEndian is used
144 1.2 isaki * so much especially on big endian machines, so it's expanded.
145 1.2 isaki * Other conversions are rarely used, so they are compressed.
146 1.2 isaki */
147 1.2 isaki if (__predict_true(xor == 0) && is_src_NE == false) {
148 1.2 isaki /* slinear16_OE to slinear<AI>_NE */
149 1.2 isaki for (i = 0; i < sample_count; i++) {
150 1.2 isaki uint16_t val;
151 1.2 isaki val = *s++;
152 1.2 isaki val = bswap16(val);
153 1.2 isaki *d++ = (auint_t)val << shift;
154 1.2 isaki }
155 1.2 isaki } else {
156 1.2 isaki /* slinear16_NE to slinear<AI>_NE */
157 1.2 isaki /* ulinear16_{NE,OE} to slinear<AI>_NE */
158 1.2 isaki for (i = 0; i < sample_count; i++) {
159 1.2 isaki uint16_t val;
160 1.2 isaki val = *s++;
161 1.2 isaki if (!is_src_NE)
162 1.2 isaki val = bswap16(val);
163 1.2 isaki val ^= xor;
164 1.2 isaki *d++ = (auint_t)val << shift;
165 1.2 isaki }
166 1.2 isaki }
167 1.2 isaki }
168 1.2 isaki
169 1.2 isaki /*
170 1.2 isaki * audio_internal_to_linear16:
171 1.2 isaki * This filter performs conversion from internal format to
172 1.2 isaki * [US]LINEAR16{LE,BE}.
173 1.2 isaki */
174 1.2 isaki void
175 1.2 isaki audio_internal_to_linear16(audio_filter_arg_t *arg)
176 1.2 isaki {
177 1.2 isaki const aint_t *s;
178 1.2 isaki uint16_t *d;
179 1.2 isaki uint16_t xor;
180 1.2 isaki u_int sample_count;
181 1.2 isaki u_int shift;
182 1.2 isaki u_int i;
183 1.2 isaki bool is_dst_NE;
184 1.2 isaki
185 1.2 isaki DIAGNOSTIC_filter_arg(arg);
186 1.2 isaki KASSERT(audio_format2_is_linear(arg->dstfmt));
187 1.2 isaki KASSERT(arg->dstfmt->precision == 16);
188 1.2 isaki KASSERT(arg->dstfmt->stride == 16);
189 1.2 isaki KASSERT(audio_format2_is_internal(arg->srcfmt));
190 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
191 1.2 isaki
192 1.2 isaki s = arg->src;
193 1.2 isaki d = arg->dst;
194 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
195 1.2 isaki
196 1.2 isaki shift = AUDIO_INTERNAL_BITS - 16;
197 1.2 isaki xor = audio_format2_is_signed(arg->dstfmt) ? 0 : 0x8000;
198 1.2 isaki is_dst_NE = (audio_format2_endian(arg->dstfmt) == BYTE_ORDER);
199 1.2 isaki
200 1.2 isaki /*
201 1.2 isaki * Since slinear_NativeEndian to slinear16_OppositeEndian is used
202 1.2 isaki * so much especially on big endian machines, so it's expanded.
203 1.2 isaki * Other conversions are rarely used, so they are compressed.
204 1.2 isaki */
205 1.2 isaki if (__predict_true(xor == 0) && is_dst_NE == false) {
206 1.2 isaki /* slinear<AI>_NE -> slinear16_OE */
207 1.2 isaki for (i = 0; i < sample_count; i++) {
208 1.2 isaki uint16_t val;
209 1.2 isaki val = (*s++) >> shift;
210 1.2 isaki val = bswap16(val);
211 1.2 isaki *d++ = val;
212 1.2 isaki }
213 1.2 isaki } else {
214 1.2 isaki /* slinear<AI>_NE -> slinear16_NE */
215 1.2 isaki /* slinear<AI>_NE -> ulinear16_{NE,OE} */
216 1.2 isaki for (i = 0; i < sample_count; i++) {
217 1.2 isaki uint16_t val;
218 1.2 isaki val = (*s++) >> shift;
219 1.2 isaki val ^= xor;
220 1.2 isaki if (!is_dst_NE)
221 1.2 isaki val = bswap16(val);
222 1.2 isaki *d++ = val;
223 1.2 isaki }
224 1.2 isaki }
225 1.2 isaki }
226 1.2 isaki
227 1.2 isaki #if defined(AUDIO_SUPPORT_LINEAR24)
228 1.2 isaki /*
229 1.2 isaki * audio_linear24_to_internal:
230 1.2 isaki * This filter performs conversion from [US]LINEAR24/24{LE,BE} to
231 1.2 isaki * internal format. Since it's rerely used, it's size optimized.
232 1.2 isaki */
233 1.2 isaki void
234 1.2 isaki audio_linear24_to_internal(audio_filter_arg_t *arg)
235 1.2 isaki {
236 1.2 isaki const uint8_t *s;
237 1.2 isaki aint_t *d;
238 1.2 isaki auint_t xor;
239 1.2 isaki u_int sample_count;
240 1.2 isaki u_int i;
241 1.2 isaki bool is_src_LE;
242 1.2 isaki
243 1.2 isaki DIAGNOSTIC_filter_arg(arg);
244 1.2 isaki KASSERT(audio_format2_is_linear(arg->srcfmt));
245 1.2 isaki KASSERT(arg->srcfmt->precision == 24);
246 1.2 isaki KASSERT(arg->srcfmt->stride == 24);
247 1.2 isaki KASSERT(audio_format2_is_internal(arg->dstfmt));
248 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
249 1.2 isaki
250 1.2 isaki s = arg->src;
251 1.2 isaki d = arg->dst;
252 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
253 1.2 isaki xor = audio_format2_is_signed(arg->srcfmt)
254 1.2 isaki ? 0 : (1 << (AUDIO_INTERNAL_BITS - 1));
255 1.2 isaki is_src_LE = (audio_format2_endian(arg->srcfmt) == LITTLE_ENDIAN);
256 1.2 isaki
257 1.2 isaki for (i = 0; i < sample_count; i++) {
258 1.2 isaki uint32_t val;
259 1.2 isaki if (is_src_LE) {
260 1.2 isaki val = s[0] | (s[1] << 8) | (s[2] << 16);
261 1.2 isaki } else {
262 1.2 isaki val = (s[0] << 16) | (s[1] << 8) | s[2];
263 1.2 isaki }
264 1.2 isaki s += 3;
265 1.2 isaki
266 1.2 isaki #if AUDIO_INTERNAL_BITS < 24
267 1.2 isaki val >>= 24 - AUDIO_INTERNAL_BITS;
268 1.2 isaki #else
269 1.2 isaki val <<= AUDIO_INTERNAL_BITS - 24;
270 1.2 isaki #endif
271 1.2 isaki val ^= xor;
272 1.2 isaki *d++ = val;
273 1.2 isaki }
274 1.2 isaki }
275 1.2 isaki
276 1.2 isaki /*
277 1.2 isaki * audio_internal_to_linear24:
278 1.2 isaki * This filter performs conversion from internal format to
279 1.2 isaki * [US]LINEAR24/24{LE,BE}. Since it's rarely used, it's size optimized.
280 1.2 isaki */
281 1.2 isaki void
282 1.2 isaki audio_internal_to_linear24(audio_filter_arg_t *arg)
283 1.2 isaki {
284 1.2 isaki const aint_t *s;
285 1.2 isaki uint8_t *d;
286 1.2 isaki auint_t xor;
287 1.2 isaki u_int sample_count;
288 1.2 isaki u_int i;
289 1.2 isaki bool is_dst_LE;
290 1.2 isaki
291 1.2 isaki DIAGNOSTIC_filter_arg(arg);
292 1.2 isaki KASSERT(audio_format2_is_linear(arg->dstfmt));
293 1.2 isaki KASSERT(arg->dstfmt->precision == 24);
294 1.2 isaki KASSERT(arg->dstfmt->stride == 24);
295 1.2 isaki KASSERT(audio_format2_is_internal(arg->srcfmt));
296 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
297 1.2 isaki
298 1.2 isaki s = arg->src;
299 1.2 isaki d = arg->dst;
300 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
301 1.2 isaki xor = audio_format2_is_signed(arg->dstfmt)
302 1.2 isaki ? 0 : (1 << (AUDIO_INTERNAL_BITS - 1));
303 1.2 isaki is_dst_LE = (audio_format2_endian(arg->dstfmt) == LITTLE_ENDIAN);
304 1.2 isaki
305 1.2 isaki for (i = 0; i < sample_count; i++) {
306 1.2 isaki uint32_t val;
307 1.2 isaki val = *s++;
308 1.2 isaki val ^= xor;
309 1.2 isaki #if AUDIO_INTERNAL_BITS < 24
310 1.2 isaki val <<= 24 - AUDIO_INTERNAL_BITS;
311 1.2 isaki #else
312 1.2 isaki val >>= AUDIO_INTERNAL_BITS - 24;
313 1.2 isaki #endif
314 1.2 isaki if (is_dst_LE) {
315 1.2 isaki d[0] = val & 0xff;
316 1.2 isaki d[1] = (val >> 8) & 0xff;
317 1.2 isaki d[2] = (val >> 16) & 0xff;
318 1.2 isaki } else {
319 1.2 isaki d[0] = (val >> 16) & 0xff;
320 1.2 isaki d[1] = (val >> 8) & 0xff;
321 1.2 isaki d[2] = val & 0xff;
322 1.2 isaki }
323 1.2 isaki d += 3;
324 1.2 isaki }
325 1.2 isaki }
326 1.2 isaki #endif /* AUDIO_SUPPORT_LINEAR24 */
327 1.2 isaki
328 1.2 isaki /*
329 1.2 isaki * audio_linear32_to_internal:
330 1.2 isaki * This filter performs conversion from [US]LINEAR32{LE,BE} to internal
331 1.2 isaki * format. Since it's rarely used, it's size optimized.
332 1.2 isaki */
333 1.2 isaki void
334 1.2 isaki audio_linear32_to_internal(audio_filter_arg_t *arg)
335 1.2 isaki {
336 1.2 isaki const uint32_t *s;
337 1.2 isaki aint_t *d;
338 1.2 isaki auint_t xor;
339 1.2 isaki u_int sample_count;
340 1.2 isaki u_int i;
341 1.2 isaki bool is_src_NE;
342 1.2 isaki
343 1.2 isaki DIAGNOSTIC_filter_arg(arg);
344 1.2 isaki KASSERT(audio_format2_is_linear(arg->srcfmt));
345 1.2 isaki KASSERT(arg->srcfmt->precision == 32);
346 1.2 isaki KASSERT(arg->srcfmt->stride == 32);
347 1.2 isaki KASSERT(audio_format2_is_internal(arg->dstfmt));
348 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
349 1.2 isaki
350 1.2 isaki s = arg->src;
351 1.2 isaki d = arg->dst;
352 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
353 1.2 isaki xor = audio_format2_is_signed(arg->srcfmt)
354 1.2 isaki ? 0 : (1 << (AUDIO_INTERNAL_BITS - 1));
355 1.2 isaki is_src_NE = (audio_format2_endian(arg->srcfmt) == BYTE_ORDER);
356 1.2 isaki
357 1.2 isaki for (i = 0; i < sample_count; i++) {
358 1.2 isaki uint32_t val;
359 1.2 isaki val = *s++;
360 1.2 isaki if (!is_src_NE)
361 1.2 isaki val = bswap32(val);
362 1.2 isaki val >>= 32 - AUDIO_INTERNAL_BITS;
363 1.2 isaki val ^= xor;
364 1.2 isaki *d++ = val;
365 1.2 isaki }
366 1.2 isaki }
367 1.2 isaki
368 1.2 isaki /*
369 1.2 isaki * audio_internal_to_linear32:
370 1.2 isaki * This filter performs conversion from internal format to
371 1.2 isaki * [US]LINEAR32{LE,BE}. Since it's rarely used, it's size optimized.
372 1.2 isaki */
373 1.2 isaki void
374 1.2 isaki audio_internal_to_linear32(audio_filter_arg_t *arg)
375 1.2 isaki {
376 1.2 isaki const aint_t *s;
377 1.2 isaki uint32_t *d;
378 1.2 isaki auint_t xor;
379 1.2 isaki u_int sample_count;
380 1.2 isaki u_int i;
381 1.2 isaki bool is_dst_NE;
382 1.2 isaki
383 1.2 isaki DIAGNOSTIC_filter_arg(arg);
384 1.2 isaki KASSERT(audio_format2_is_linear(arg->dstfmt));
385 1.2 isaki KASSERT(arg->dstfmt->precision == 32);
386 1.2 isaki KASSERT(arg->dstfmt->stride == 32);
387 1.2 isaki KASSERT(audio_format2_is_internal(arg->srcfmt));
388 1.2 isaki KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
389 1.2 isaki
390 1.2 isaki s = arg->src;
391 1.2 isaki d = arg->dst;
392 1.2 isaki sample_count = arg->count * arg->srcfmt->channels;
393 1.2 isaki xor = audio_format2_is_signed(arg->dstfmt)
394 1.2 isaki ? 0 : (1 << (AUDIO_INTERNAL_BITS - 1));
395 1.2 isaki is_dst_NE = (audio_format2_endian(arg->dstfmt) == BYTE_ORDER);
396 1.2 isaki
397 1.2 isaki for (i = 0; i < sample_count; i++) {
398 1.2 isaki uint32_t val;
399 1.2 isaki val = *s++;
400 1.2 isaki val ^= xor;
401 1.2 isaki val <<= 32 - AUDIO_INTERNAL_BITS;
402 1.2 isaki if (!is_dst_NE)
403 1.2 isaki val = bswap32(val);
404 1.2 isaki *d++ = val;
405 1.2 isaki }
406 1.2 isaki }
407