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