kernel - disklabel64 - Increase partition start alignment to 1 megabyte.
[dragonfly.git] / sys / dev / sound / pcm / feeder_fmt.c
blob3e428a20f99eb8e7efbbc1d928b778938ada468b
1 /*-
2 * Copyright (c) 1999 Cameron Grant <cg@FreeBSD.org>
3 * Copyright (c) 2005 Ariff Abdullah <ariff@FreeBSD.org>
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
27 * $FreeBSD: src/sys/dev/sound/pcm/feeder_fmt.c,v 1.14.2.2 2006/01/29 02:27:28 ariff Exp $
28 * $DragonFly: src/sys/dev/sound/pcm/feeder_fmt.c,v 1.4 2007/01/04 21:47:03 corecode Exp $
31 * *New* and rewritten soft format converter, supporting 24/32bit pcm data,
32 * simplified and optimized.
34 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
35 * *
36 * This new implementation is fully dedicated in memory of Cameron Grant, *
37 * the creator of the magnificent, highly addictive feeder infrastructure. *
38 * *
39 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
43 #include <dev/sound/pcm/sound.h>
44 #include "feeder_if.h"
46 SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pcm/feeder_fmt.c,v 1.4 2007/01/04 21:47:03 corecode Exp $");
48 MALLOC_DEFINE(M_FMTFEEDER, "fmtfeed", "pcm format feeder");
50 #define FEEDBUFSZ 8192
51 #define FEEDBUF24SZ 8190
53 #define FMT_TRACE(x...) /* printf(x) */
54 #define FMT_TEST(x, y...) /* if (x) FMT_TRACE(y) */
55 #define FMT_ALIGNBYTE(x) /* x */
58 * Sign inverted ulaw/alaw -> 8 table
60 static uint8_t ulaw_to_s8_tbl[] = {
61 131, 135, 139, 143, 147, 151, 155, 159,
62 163, 167, 171, 175, 179, 183, 187, 191,
63 194, 196, 198, 200, 202, 204, 206, 208,
64 210, 212, 214, 216, 218, 220, 222, 224,
65 226, 227, 228, 229, 230, 231, 232, 233,
66 234, 235, 236, 237, 238, 239, 240, 241,
67 241, 242, 242, 243, 243, 244, 244, 245,
68 245, 246, 246, 247, 247, 248, 248, 249,
69 249, 249, 250, 250, 250, 250, 251, 251,
70 251, 251, 252, 252, 252, 252, 253, 253,
71 253, 253, 253, 253, 254, 254, 254, 254,
72 254, 254, 254, 254, 255, 255, 255, 255,
73 255, 255, 255, 255, 255, 255, 255, 255,
74 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0,
77 125, 121, 117, 113, 109, 105, 101, 97,
78 93, 89, 85, 81, 77, 73, 69, 65,
79 62, 60, 58, 56, 54, 52, 50, 48,
80 46, 44, 42, 40, 38, 36, 34, 32,
81 30, 29, 28, 27, 26, 25, 24, 23,
82 22, 21, 20, 19, 18, 17, 16, 15,
83 15, 14, 14, 13, 13, 12, 12, 11,
84 11, 10, 10, 9, 9, 8, 8, 7,
85 7, 7, 6, 6, 6, 6, 5, 5,
86 5, 5, 4, 4, 4, 4, 3, 3,
87 3, 3, 3, 3, 2, 2, 2, 2,
88 2, 2, 2, 2, 1, 1, 1, 1,
89 1, 1, 1, 1, 1, 1, 1, 1,
90 0, 0, 0, 0, 0, 0, 0, 0,
91 0, 0, 0, 0, 0, 0, 0, 0,
92 0, 0, 0, 0, 0, 0, 0, 0,
95 static uint8_t alaw_to_s8_tbl[] = {
96 236, 237, 234, 235, 240, 241, 238, 239,
97 228, 229, 226, 227, 232, 233, 230, 231,
98 246, 246, 245, 245, 248, 248, 247, 247,
99 242, 242, 241, 241, 244, 244, 243, 243,
100 171, 175, 163, 167, 187, 191, 179, 183,
101 139, 143, 131, 135, 155, 159, 147, 151,
102 214, 216, 210, 212, 222, 224, 218, 220,
103 198, 200, 194, 196, 206, 208, 202, 204,
104 255, 255, 255, 255, 255, 255, 255, 255,
105 255, 255, 255, 255, 255, 255, 255, 255,
106 0, 0, 0, 0, 0, 0, 0, 0,
107 0, 0, 0, 0, 0, 0, 0, 0,
108 251, 251, 251, 251, 252, 252, 252, 252,
109 249, 249, 249, 249, 250, 250, 250, 250,
110 254, 254, 254, 254, 254, 254, 254, 254,
111 253, 253, 253, 253, 253, 253, 253, 253,
112 20, 19, 22, 21, 16, 15, 18, 17,
113 28, 27, 30, 29, 24, 23, 26, 25,
114 10, 10, 11, 11, 8, 8, 9, 9,
115 14, 14, 15, 15, 12, 12, 13, 13,
116 85, 81, 93, 89, 69, 65, 77, 73,
117 117, 113, 125, 121, 101, 97, 109, 105,
118 42, 40, 46, 44, 34, 32, 38, 36,
119 58, 56, 62, 60, 50, 48, 54, 52,
120 1, 1, 1, 1, 1, 1, 1, 1,
121 1, 1, 1, 1, 1, 1, 1, 1,
122 0, 0, 0, 0, 0, 0, 0, 0,
123 0, 0, 0, 0, 0, 0, 0, 0,
124 5, 5, 5, 5, 4, 4, 4, 4,
125 7, 7, 7, 7, 6, 6, 6, 6,
126 2, 2, 2, 2, 2, 2, 2, 2,
127 3, 3, 3, 3, 3, 3, 3, 3,
130 static uint8_t u8_to_ulaw_tbl[] = {
131 0, 0, 0, 0, 0, 1, 1, 1,
132 1, 2, 2, 2, 2, 3, 3, 3,
133 3, 4, 4, 4, 4, 5, 5, 5,
134 5, 6, 6, 6, 6, 7, 7, 7,
135 7, 8, 8, 8, 8, 9, 9, 9,
136 9, 10, 10, 10, 10, 11, 11, 11,
137 11, 12, 12, 12, 12, 13, 13, 13,
138 13, 14, 14, 14, 14, 15, 15, 15,
139 15, 16, 16, 17, 17, 18, 18, 19,
140 19, 20, 20, 21, 21, 22, 22, 23,
141 23, 24, 24, 25, 25, 26, 26, 27,
142 27, 28, 28, 29, 29, 30, 30, 31,
143 31, 32, 33, 34, 35, 36, 37, 38,
144 39, 40, 41, 42, 43, 44, 45, 46,
145 47, 49, 51, 53, 55, 57, 59, 61,
146 63, 66, 70, 74, 78, 84, 92, 104,
147 254, 231, 219, 211, 205, 201, 197, 193,
148 190, 188, 186, 184, 182, 180, 178, 176,
149 175, 174, 173, 172, 171, 170, 169, 168,
150 167, 166, 165, 164, 163, 162, 161, 160,
151 159, 159, 158, 158, 157, 157, 156, 156,
152 155, 155, 154, 154, 153, 153, 152, 152,
153 151, 151, 150, 150, 149, 149, 148, 148,
154 147, 147, 146, 146, 145, 145, 144, 144,
155 143, 143, 143, 143, 142, 142, 142, 142,
156 141, 141, 141, 141, 140, 140, 140, 140,
157 139, 139, 139, 139, 138, 138, 138, 138,
158 137, 137, 137, 137, 136, 136, 136, 136,
159 135, 135, 135, 135, 134, 134, 134, 134,
160 133, 133, 133, 133, 132, 132, 132, 132,
161 131, 131, 131, 131, 130, 130, 130, 130,
162 129, 129, 129, 129, 128, 128, 128, 128,
165 static uint8_t u8_to_alaw_tbl[] = {
166 42, 42, 42, 42, 42, 43, 43, 43,
167 43, 40, 40, 40, 40, 41, 41, 41,
168 41, 46, 46, 46, 46, 47, 47, 47,
169 47, 44, 44, 44, 44, 45, 45, 45,
170 45, 34, 34, 34, 34, 35, 35, 35,
171 35, 32, 32, 32, 32, 33, 33, 33,
172 33, 38, 38, 38, 38, 39, 39, 39,
173 39, 36, 36, 36, 36, 37, 37, 37,
174 37, 58, 58, 59, 59, 56, 56, 57,
175 57, 62, 62, 63, 63, 60, 60, 61,
176 61, 50, 50, 51, 51, 48, 48, 49,
177 49, 54, 54, 55, 55, 52, 52, 53,
178 53, 10, 11, 8, 9, 14, 15, 12,
179 13, 2, 3, 0, 1, 6, 7, 4,
180 5, 24, 30, 28, 18, 16, 22, 20,
181 106, 110, 98, 102, 122, 114, 75, 90,
182 213, 197, 245, 253, 229, 225, 237, 233,
183 149, 151, 145, 147, 157, 159, 153, 155,
184 133, 132, 135, 134, 129, 128, 131, 130,
185 141, 140, 143, 142, 137, 136, 139, 138,
186 181, 181, 180, 180, 183, 183, 182, 182,
187 177, 177, 176, 176, 179, 179, 178, 178,
188 189, 189, 188, 188, 191, 191, 190, 190,
189 185, 185, 184, 184, 187, 187, 186, 186,
190 165, 165, 165, 165, 164, 164, 164, 164,
191 167, 167, 167, 167, 166, 166, 166, 166,
192 161, 161, 161, 161, 160, 160, 160, 160,
193 163, 163, 163, 163, 162, 162, 162, 162,
194 173, 173, 173, 173, 172, 172, 172, 172,
195 175, 175, 175, 175, 174, 174, 174, 174,
196 169, 169, 169, 169, 168, 168, 168, 168,
197 171, 171, 171, 171, 170, 170, 170, 170,
200 static int
201 feed_table_u8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
202 uint32_t count, void *source)
204 int j, k = FEEDER_FEED(f->source, c, b, count, source);
205 uint8_t *tbl = (uint8_t *)f->data;
207 j = k;
208 while (j > 0) {
209 j--;
210 b[j] = tbl[b[j]] ^ 0x80;
212 return k;
215 static int
216 feed_table_s16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
217 uint32_t count, void *source)
219 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
220 uint8_t *tbl = (uint8_t *)f->data;
222 i = k;
223 k <<= 1;
224 j = k;
225 while (i > 0) {
226 b[--j] = tbl[b[--i]];
227 b[--j] = 0;
229 return k;
232 static int
233 feed_table_xlaw(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
234 uint32_t count, void *source)
236 int j, k = FEEDER_FEED(f->source, c, b, count, source);
237 uint8_t *tbl = (uint8_t *)f->data;
239 j = k;
240 while (j > 0) {
241 j--;
242 b[j] = tbl[b[j]];
244 return k;
247 static struct pcm_feederdesc feeder_ulawtou8_desc[] = {
248 {FEEDER_FMT, AFMT_MU_LAW, AFMT_U8, 0},
249 {FEEDER_FMT, AFMT_MU_LAW|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
250 {0, 0, 0, 0},
252 static kobj_method_t feeder_ulawtou8_methods[] = {
253 KOBJMETHOD(feeder_feed, feed_table_u8),
254 {0, 0}
256 FEEDER_DECLARE(feeder_ulawtou8, 0, ulaw_to_s8_tbl);
258 static struct pcm_feederdesc feeder_alawtou8_desc[] = {
259 {FEEDER_FMT, AFMT_A_LAW, AFMT_U8, 0},
260 {FEEDER_FMT, AFMT_A_LAW|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
261 {0, 0, 0, 0},
263 static kobj_method_t feeder_alawtou8_methods[] = {
264 KOBJMETHOD(feeder_feed, feed_table_u8),
265 {0, 0}
267 FEEDER_DECLARE(feeder_alawtou8, 0, alaw_to_s8_tbl);
269 static struct pcm_feederdesc feeder_ulawtos16le_desc[] = {
270 {FEEDER_FMT, AFMT_MU_LAW, AFMT_S16_LE, 0},
271 {FEEDER_FMT, AFMT_MU_LAW|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
272 {0, 0, 0, 0},
274 static kobj_method_t feeder_ulawtos16le_methods[] = {
275 KOBJMETHOD(feeder_feed, feed_table_s16le),
276 {0, 0}
278 FEEDER_DECLARE(feeder_ulawtos16le, 0, ulaw_to_s8_tbl);
280 static struct pcm_feederdesc feeder_alawtos16le_desc[] = {
281 {FEEDER_FMT, AFMT_A_LAW, AFMT_S16_LE, 0},
282 {FEEDER_FMT, AFMT_A_LAW|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
283 {0, 0, 0, 0},
285 static kobj_method_t feeder_alawtos16le_methods[] = {
286 KOBJMETHOD(feeder_feed, feed_table_s16le),
287 {0, 0}
289 FEEDER_DECLARE(feeder_alawtos16le, 0, alaw_to_s8_tbl);
291 static struct pcm_feederdesc feeder_u8toulaw_desc[] = {
292 {FEEDER_FMT, AFMT_U8, AFMT_MU_LAW, 0},
293 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_MU_LAW|AFMT_STEREO, 0},
294 {0, 0, 0, 0},
296 static kobj_method_t feeder_u8toulaw_methods[] = {
297 KOBJMETHOD(feeder_feed, feed_table_xlaw),
298 {0, 0}
300 FEEDER_DECLARE(feeder_u8toulaw, 0, u8_to_ulaw_tbl);
302 static struct pcm_feederdesc feeder_u8toalaw_desc[] = {
303 {FEEDER_FMT, AFMT_U8, AFMT_A_LAW, 0},
304 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_A_LAW|AFMT_STEREO, 0},
305 {0, 0, 0, 0},
307 static kobj_method_t feeder_u8toalaw_methods[] = {
308 KOBJMETHOD(feeder_feed, feed_table_xlaw),
309 {0, 0}
311 FEEDER_DECLARE(feeder_u8toalaw, 0, u8_to_alaw_tbl);
314 * Conversion rules:-
315 * 1. BE -> LE
316 * 2. if fmt == u8 , u8 -> s8 (economical)
317 * 3. Xle -> 16le
318 * 4. if fmt != u8 && fmt == u16le , u16le -> s16le
319 * 4. s16le mono -> s16le stereo
321 * All conversion done in byte level to preserve endianess.
324 static int
325 feed_common_init(struct pcm_feeder *f)
327 f->data = kmalloc(FEEDBUFSZ, M_FMTFEEDER, M_NOWAIT|M_ZERO);
328 if (f->data == NULL)
329 return ENOMEM;
330 return 0;
333 static int
334 feed_common_free(struct pcm_feeder *f)
336 if (f->data)
337 kfree(f->data, M_FMTFEEDER);
338 f->data = NULL;
339 return 0;
343 * Bit conversion
345 static int
346 feed_8to16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
347 uint32_t count, void *source)
349 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
351 i = k;
352 k <<= 1;
353 j = k;
354 while (i > 0) {
355 b[--j] = b[--i];
356 b[--j] = 0;
358 return k;
360 static struct pcm_feederdesc feeder_8to16le_desc[] = {
361 {FEEDER_FMT, AFMT_U8, AFMT_U16_LE, 0},
362 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
363 {FEEDER_FMT, AFMT_S8, AFMT_S16_LE, 0},
364 {FEEDER_FMT, AFMT_S8|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
365 {0, 0, 0, 0},
367 static kobj_method_t feeder_8to16le_methods[] = {
368 KOBJMETHOD(feeder_feed, feed_8to16le),
369 {0, 0}
371 FEEDER_DECLARE(feeder_8to16le, 0, NULL);
373 static int
374 feed_16leto8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
375 uint32_t count, void *source)
377 int i, j, k;
378 uint8_t *src = (uint8_t *)f->data;
380 k = count << 1;
381 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
382 if (k < 2) {
383 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
384 __func__, k);
385 return 0;
387 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
388 FMT_ALIGNBYTE(k &= ~1);
389 i = k;
390 j = k >> 1;
391 while (i > 0) {
392 b[--j] = src[--i];
393 i--;
395 return k >> 1;
397 static struct pcm_feederdesc feeder_16leto8_desc[] = {
398 {FEEDER_FMT, AFMT_U16_LE, AFMT_U8, 0},
399 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
400 {FEEDER_FMT, AFMT_S16_LE, AFMT_S8, 0},
401 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S8|AFMT_STEREO, 0},
402 {0, 0, 0, 0},
404 static kobj_method_t feeder_16leto8_methods[] = {
405 KOBJMETHOD(feeder_init, feed_common_init),
406 KOBJMETHOD(feeder_free, feed_common_free),
407 KOBJMETHOD(feeder_feed, feed_16leto8),
408 {0, 0}
410 FEEDER_DECLARE(feeder_16leto8, 0, NULL);
412 static int
413 feed_16leto24le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
414 uint32_t count, void *source)
416 int i, j, k;
418 k = (count / 3) << 1;
419 k = FEEDER_FEED(f->source, c, b, k, source);
420 if (k < 2) {
421 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
422 __func__, k);
423 return 0;
425 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
426 FMT_ALIGNBYTE(k &= ~1);
427 i = k;
428 j = (k >> 1) * 3;
429 k = j;
430 while (i > 0) {
431 b[--j] = b[--i];
432 b[--j] = b[--i];
433 b[--j] = 0;
435 return k;
437 static struct pcm_feederdesc feeder_16leto24le_desc[] = {
438 {FEEDER_FMT, AFMT_U16_LE, AFMT_U24_LE, 0},
439 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U24_LE|AFMT_STEREO, 0},
440 {FEEDER_FMT, AFMT_S16_LE, AFMT_S24_LE, 0},
441 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0},
442 {0, 0, 0, 0},
444 static kobj_method_t feeder_16leto24le_methods[] = {
445 KOBJMETHOD(feeder_feed, feed_16leto24le),
446 {0, 0}
448 FEEDER_DECLARE(feeder_16leto24le, 0, NULL);
450 static int
451 feed_24leto16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
452 uint32_t count, void *source)
454 int i, j, k;
455 uint8_t *src = (uint8_t *)f->data;
457 k = (count * 3) >> 1;
458 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUF24SZ), source);
459 if (k < 3) {
460 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
461 __func__, k);
462 return 0;
464 FMT_TEST(k % 3, "%s: Bytes not 24bit aligned.\n", __func__);
465 FMT_ALIGNBYTE(k -= k % 3);
466 i = (k / 3) << 1;
467 j = i;
468 while (i > 0) {
469 b[--i] = src[--k];
470 b[--i] = src[--k];
471 k--;
473 return j;
475 static struct pcm_feederdesc feeder_24leto16le_desc[] = {
476 {FEEDER_FMT, AFMT_U24_LE, AFMT_U16_LE, 0},
477 {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
478 {FEEDER_FMT, AFMT_S24_LE, AFMT_S16_LE, 0},
479 {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
480 {0, 0, 0, 0},
482 static kobj_method_t feeder_24leto16le_methods[] = {
483 KOBJMETHOD(feeder_init, feed_common_init),
484 KOBJMETHOD(feeder_free, feed_common_free),
485 KOBJMETHOD(feeder_feed, feed_24leto16le),
486 {0, 0}
488 FEEDER_DECLARE(feeder_24leto16le, 1, NULL);
490 static int
491 feed_16leto32le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
492 uint32_t count, void *source)
494 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
495 if (k < 2) {
496 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
497 __func__, k);
498 return 0;
500 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
501 FMT_ALIGNBYTE(k &= ~1);
502 i = k;
503 j = k << 1;
504 k = j;
505 while (i > 0) {
506 b[--j] = b[--i];
507 b[--j] = b[--i];
508 b[--j] = 0;
509 b[--j] = 0;
511 return k;
513 static struct pcm_feederdesc feeder_16leto32le_desc[] = {
514 {FEEDER_FMT, AFMT_U16_LE, AFMT_U32_LE, 0},
515 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U32_LE|AFMT_STEREO, 0},
516 {FEEDER_FMT, AFMT_S16_LE, AFMT_S32_LE, 0},
517 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S32_LE|AFMT_STEREO, 0},
518 {0, 0, 0, 0},
520 static kobj_method_t feeder_16leto32le_methods[] = {
521 KOBJMETHOD(feeder_feed, feed_16leto32le),
522 {0, 0}
524 FEEDER_DECLARE(feeder_16leto32le, 0, NULL);
526 static int
527 feed_32leto16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
528 uint32_t count, void *source)
530 int i, j, k;
531 uint8_t *src = (uint8_t *)f->data;
533 k = count << 1;
534 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
535 if (k < 4) {
536 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
537 __func__, k);
538 return 0;
540 FMT_TEST(k & 3, "%s: Bytes not 32bit aligned.\n", __func__);
541 FMT_ALIGNBYTE(k &= ~3);
542 i = k;
543 k >>= 1;
544 j = k;
545 while (i > 0) {
546 b[--j] = src[--i];
547 b[--j] = src[--i];
548 i -= 2;
550 return k;
552 static struct pcm_feederdesc feeder_32leto16le_desc[] = {
553 {FEEDER_FMT, AFMT_U32_LE, AFMT_U16_LE, 0},
554 {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
555 {FEEDER_FMT, AFMT_S32_LE, AFMT_S16_LE, 0},
556 {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
557 {0, 0, 0, 0},
559 static kobj_method_t feeder_32leto16le_methods[] = {
560 KOBJMETHOD(feeder_init, feed_common_init),
561 KOBJMETHOD(feeder_free, feed_common_free),
562 KOBJMETHOD(feeder_feed, feed_32leto16le),
563 {0, 0}
565 FEEDER_DECLARE(feeder_32leto16le, 1, NULL);
567 * Bit conversion end
571 * Channel conversion (mono -> stereo)
573 static int
574 feed_monotostereo8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
575 uint32_t count, void *source)
577 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
579 i = k;
580 j = k << 1;
581 while (i > 0) {
582 b[--j] = b[--i];
583 b[--j] = b[i];
585 return k << 1;
587 static struct pcm_feederdesc feeder_monotostereo8_desc[] = {
588 {FEEDER_FMT, AFMT_U8, AFMT_U8|AFMT_STEREO, 0},
589 {FEEDER_FMT, AFMT_S8, AFMT_S8|AFMT_STEREO, 0},
590 {0, 0, 0, 0},
592 static kobj_method_t feeder_monotostereo8_methods[] = {
593 KOBJMETHOD(feeder_feed, feed_monotostereo8),
594 {0, 0}
596 FEEDER_DECLARE(feeder_monotostereo8, 0, NULL);
598 static int
599 feed_monotostereo16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
600 uint32_t count, void *source)
602 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
603 uint8_t l, m;
605 if (k < 2) {
606 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
607 __func__, k);
608 return 0;
610 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
611 FMT_ALIGNBYTE(k &= ~1);
612 i = k;
613 j = k << 1;
614 while (i > 0) {
615 l = b[--i];
616 m = b[--i];
617 b[--j] = l;
618 b[--j] = m;
619 b[--j] = l;
620 b[--j] = m;
622 return k << 1;
624 static struct pcm_feederdesc feeder_monotostereo16_desc[] = {
625 {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_LE|AFMT_STEREO, 0},
626 {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_LE|AFMT_STEREO, 0},
627 {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_BE|AFMT_STEREO, 0},
628 {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_BE|AFMT_STEREO, 0},
629 {0, 0, 0, 0},
631 static kobj_method_t feeder_monotostereo16_methods[] = {
632 KOBJMETHOD(feeder_feed, feed_monotostereo16),
633 {0, 0}
635 FEEDER_DECLARE(feeder_monotostereo16, 0, NULL);
637 static int
638 feed_monotostereo24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
639 uint32_t count, void *source)
641 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
642 uint8_t l, m, n;
644 if (k < 3) {
645 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
646 __func__, k);
647 return 0;
649 FMT_TEST(k % 3, "%s: Bytes not 24bit aligned.\n", __func__);
650 FMT_ALIGNBYTE(k -= k % 3);
651 i = k;
652 j = k << 1;
653 while (i > 0) {
654 l = b[--i];
655 m = b[--i];
656 n = b[--i];
657 b[--j] = l;
658 b[--j] = m;
659 b[--j] = n;
660 b[--j] = l;
661 b[--j] = m;
662 b[--j] = n;
664 return k << 1;
666 static struct pcm_feederdesc feeder_monotostereo24_desc[] = {
667 {FEEDER_FMT, AFMT_U24_LE, AFMT_U24_LE|AFMT_STEREO, 0},
668 {FEEDER_FMT, AFMT_S24_LE, AFMT_S24_LE|AFMT_STEREO, 0},
669 {FEEDER_FMT, AFMT_U24_BE, AFMT_U24_BE|AFMT_STEREO, 0},
670 {FEEDER_FMT, AFMT_S24_BE, AFMT_S24_BE|AFMT_STEREO, 0},
671 {0, 0, 0, 0},
673 static kobj_method_t feeder_monotostereo24_methods[] = {
674 KOBJMETHOD(feeder_feed, feed_monotostereo24),
675 {0, 0}
677 FEEDER_DECLARE(feeder_monotostereo24, 0, NULL);
679 static int
680 feed_monotostereo32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
681 uint32_t count, void *source)
683 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
684 uint8_t l, m, n, o;
686 if (k < 4) {
687 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
688 __func__, k);
689 return 0;
691 FMT_TEST(k & 3, "%s: Bytes not 32bit aligned.\n", __func__);
692 FMT_ALIGNBYTE(k &= ~3);
693 i = k;
694 j = k << 1;
695 while (i > 0) {
696 l = b[--i];
697 m = b[--i];
698 n = b[--i];
699 o = b[--i];
700 b[--j] = l;
701 b[--j] = m;
702 b[--j] = n;
703 b[--j] = o;
704 b[--j] = l;
705 b[--j] = m;
706 b[--j] = n;
707 b[--j] = o;
709 return k << 1;
711 static struct pcm_feederdesc feeder_monotostereo32_desc[] = {
712 {FEEDER_FMT, AFMT_U32_LE, AFMT_U32_LE|AFMT_STEREO, 0},
713 {FEEDER_FMT, AFMT_S32_LE, AFMT_S32_LE|AFMT_STEREO, 0},
714 {FEEDER_FMT, AFMT_U32_BE, AFMT_U32_BE|AFMT_STEREO, 0},
715 {FEEDER_FMT, AFMT_S32_BE, AFMT_S32_BE|AFMT_STEREO, 0},
716 {0, 0, 0, 0},
718 static kobj_method_t feeder_monotostereo32_methods[] = {
719 KOBJMETHOD(feeder_feed, feed_monotostereo32),
720 {0, 0}
722 FEEDER_DECLARE(feeder_monotostereo32, 0, NULL);
724 * Channel conversion (mono -> stereo) end
728 * Channel conversion (stereo -> mono)
730 static int
731 feed_stereotomono8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
732 uint32_t count, void *source)
734 int i, j, k;
735 uint8_t *src = (uint8_t *)f->data;
737 k = count << 1;
738 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
739 if (k < 2) {
740 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
741 __func__, k);
742 return 0;
744 FMT_TEST(k & 1, "%s: Bytes not 8bit (stereo) aligned.\n", __func__);
745 FMT_ALIGNBYTE(k &= ~1);
746 i = k >> 1;
747 j = i;
748 while (i > 0) {
749 k--;
750 b[--i] = src[--k];
752 return j;
754 static struct pcm_feederdesc feeder_stereotomono8_desc[] = {
755 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_U8, 0},
756 {FEEDER_FMT, AFMT_S8|AFMT_STEREO, AFMT_S8, 0},
757 {0, 0, 0, 0},
759 static kobj_method_t feeder_stereotomono8_methods[] = {
760 KOBJMETHOD(feeder_init, feed_common_init),
761 KOBJMETHOD(feeder_free, feed_common_free),
762 KOBJMETHOD(feeder_feed, feed_stereotomono8),
763 {0, 0}
765 FEEDER_DECLARE(feeder_stereotomono8, 0, NULL);
767 static int
768 feed_stereotomono16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
769 uint32_t count, void *source)
771 int i, j, k;
772 uint8_t *src = (uint8_t *)f->data;
774 k = count << 1;
775 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
776 if (k < 4) {
777 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
778 __func__, k);
779 return 0;
781 FMT_TEST(k & 3, "%s: Bytes not 16bit (stereo) aligned.\n", __func__);
782 FMT_ALIGNBYTE(k &= ~3);
783 i = k >> 1;
784 j = i;
785 while (i > 0) {
786 k -= 2;
787 b[--i] = src[--k];
788 b[--i] = src[--k];
790 return j;
792 static struct pcm_feederdesc feeder_stereotomono16_desc[] = {
793 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U16_LE, 0},
794 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S16_LE, 0},
795 {FEEDER_FMT, AFMT_U16_BE|AFMT_STEREO, AFMT_U16_BE, 0},
796 {FEEDER_FMT, AFMT_S16_BE|AFMT_STEREO, AFMT_S16_BE, 0},
797 {0, 0, 0, 0},
799 static kobj_method_t feeder_stereotomono16_methods[] = {
800 KOBJMETHOD(feeder_init, feed_common_init),
801 KOBJMETHOD(feeder_free, feed_common_free),
802 KOBJMETHOD(feeder_feed, feed_stereotomono16),
803 {0, 0}
805 FEEDER_DECLARE(feeder_stereotomono16, 0, NULL);
807 static int
808 feed_stereotomono24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
809 uint32_t count, void *source)
811 int i, j, k;
812 uint8_t *src = (uint8_t *)f->data;
814 k = count << 1;
815 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUF24SZ), source);
816 if (k < 6) {
817 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
818 __func__, k);
819 return 0;
821 FMT_TEST(k % 6, "%s: Bytes not 24bit (stereo) aligned.\n", __func__);
822 FMT_ALIGNBYTE(k -= k % 6);
823 i = k >> 1;
824 j = i;
825 while (i > 0) {
826 k -= 3;
827 b[--i] = src[--k];
828 b[--i] = src[--k];
829 b[--i] = src[--k];
831 return j;
833 static struct pcm_feederdesc feeder_stereotomono24_desc[] = {
834 {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_U24_LE, 0},
835 {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_S24_LE, 0},
836 {FEEDER_FMT, AFMT_U24_BE|AFMT_STEREO, AFMT_U24_BE, 0},
837 {FEEDER_FMT, AFMT_S24_BE|AFMT_STEREO, AFMT_S24_BE, 0},
838 {0, 0, 0, 0},
840 static kobj_method_t feeder_stereotomono24_methods[] = {
841 KOBJMETHOD(feeder_init, feed_common_init),
842 KOBJMETHOD(feeder_free, feed_common_free),
843 KOBJMETHOD(feeder_feed, feed_stereotomono24),
844 {0, 0}
846 FEEDER_DECLARE(feeder_stereotomono24, 0, NULL);
848 static int
849 feed_stereotomono32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
850 uint32_t count, void *source)
852 int i, j, k;
853 uint8_t *src = (uint8_t *)f->data;
855 k = count << 1;
856 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
857 if (k < 8) {
858 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
859 __func__, k);
860 return 0;
862 FMT_TEST(k & 7, "%s: Bytes not 32bit (stereo) aligned.\n", __func__);
863 FMT_ALIGNBYTE(k &= ~7);
864 i = k >> 1;
865 j = i;
866 while (i > 0) {
867 k -= 4;
868 b[--i] = src[--k];
869 b[--i] = src[--k];
870 b[--i] = src[--k];
871 b[--i] = src[--k];
873 return j;
875 static struct pcm_feederdesc feeder_stereotomono32_desc[] = {
876 {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_U32_LE, 0},
877 {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_S32_LE, 0},
878 {FEEDER_FMT, AFMT_U32_BE|AFMT_STEREO, AFMT_U32_BE, 0},
879 {FEEDER_FMT, AFMT_S32_BE|AFMT_STEREO, AFMT_S32_BE, 0},
880 {0, 0, 0, 0},
882 static kobj_method_t feeder_stereotomono32_methods[] = {
883 KOBJMETHOD(feeder_init, feed_common_init),
884 KOBJMETHOD(feeder_free, feed_common_free),
885 KOBJMETHOD(feeder_feed, feed_stereotomono32),
886 {0, 0}
888 FEEDER_DECLARE(feeder_stereotomono32, 0, NULL);
890 * Channel conversion (stereo -> mono) end
894 * Sign conversion
896 static int
897 feed_sign8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
898 uint32_t count, void *source)
900 int i, j = FEEDER_FEED(f->source, c, b, count, source);
902 i = j;
903 while (i > 0)
904 b[--i] ^= 0x80;
905 return j;
907 static struct pcm_feederdesc feeder_sign8_desc[] = {
908 {FEEDER_FMT, AFMT_U8, AFMT_S8, 0},
909 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_S8|AFMT_STEREO, 0},
910 {FEEDER_FMT, AFMT_S8, AFMT_U8, 0},
911 {FEEDER_FMT, AFMT_S8|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
912 {0, 0, 0, 0},
914 static kobj_method_t feeder_sign8_methods[] = {
915 KOBJMETHOD(feeder_feed, feed_sign8),
916 {0, 0}
918 FEEDER_DECLARE(feeder_sign8, 0, NULL);
920 static int
921 feed_sign16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
922 uint32_t count, void *source)
924 int i, j = FEEDER_FEED(f->source, c, b, count, source);
926 if (j < 2) {
927 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
928 __func__, j);
929 return 0;
931 FMT_TEST(j & 1, "%s: Bytes not 16bit aligned.\n", __func__);
932 FMT_ALIGNBYTE(j &= ~1);
933 i = j;
934 while (i > 0) {
935 b[--i] ^= 0x80;
936 i--;
938 return j;
940 static struct pcm_feederdesc feeder_sign16le_desc[] = {
941 {FEEDER_FMT, AFMT_U16_LE, AFMT_S16_LE, 0},
942 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
943 {FEEDER_FMT, AFMT_S16_LE, AFMT_U16_LE, 0},
944 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
945 {0, 0, 0, 0},
947 static kobj_method_t feeder_sign16le_methods[] = {
948 KOBJMETHOD(feeder_feed, feed_sign16le),
949 {0, 0}
951 FEEDER_DECLARE(feeder_sign16le, 0, NULL);
953 static int
954 feed_sign24le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
955 uint32_t count, void *source)
957 int i, j = FEEDER_FEED(f->source, c, b, count, source);
959 if (j < 3) {
960 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
961 __func__, j);
962 return 0;
964 FMT_TEST(j % 3, "%s: Bytes not 24bit aligned.\n", __func__);
965 FMT_ALIGNBYTE(j -= j % 3);
966 i = j;
967 while (i > 0) {
968 b[--i] ^= 0x80;
969 i -= 2;
971 return j;
973 static struct pcm_feederdesc feeder_sign24le_desc[] = {
974 {FEEDER_FMT, AFMT_U24_LE, AFMT_S24_LE, 0},
975 {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0},
976 {FEEDER_FMT, AFMT_S24_LE, AFMT_U24_LE, 0},
977 {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_U24_LE|AFMT_STEREO, 0},
978 {0, 0, 0, 0},
980 static kobj_method_t feeder_sign24le_methods[] = {
981 KOBJMETHOD(feeder_feed, feed_sign24le),
982 {0, 0}
984 FEEDER_DECLARE(feeder_sign24le, 0, NULL);
986 static int
987 feed_sign32le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
988 uint32_t count, void *source)
990 int i, j = FEEDER_FEED(f->source, c, b, count, source);
992 if (j < 4) {
993 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
994 __func__, j);
995 return 0;
997 FMT_TEST(j & 3, "%s: Bytes not 32bit aligned.\n", __func__);
998 FMT_ALIGNBYTE(j &= ~3);
999 i = j;
1000 while (i > 0) {
1001 b[--i] ^= 0x80;
1002 i -= 3;
1004 return j;
1006 static struct pcm_feederdesc feeder_sign32le_desc[] = {
1007 {FEEDER_FMT, AFMT_U32_LE, AFMT_S32_LE, 0},
1008 {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_S32_LE|AFMT_STEREO, 0},
1009 {FEEDER_FMT, AFMT_S32_LE, AFMT_U32_LE, 0},
1010 {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_U32_LE|AFMT_STEREO, 0},
1011 {0, 0, 0, 0},
1013 static kobj_method_t feeder_sign32le_methods[] = {
1014 KOBJMETHOD(feeder_feed, feed_sign32le),
1015 {0, 0}
1017 FEEDER_DECLARE(feeder_sign32le, 0, NULL);
1019 * Sign conversion end.
1023 * Endian conversion.
1025 static int
1026 feed_endian16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
1027 uint32_t count, void *source)
1029 int i, j = FEEDER_FEED(f->source, c, b, count, source);
1030 uint8_t v;
1032 if (j < 2) {
1033 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
1034 __func__, j);
1035 return 0;
1037 FMT_TEST(j & 1, "%s: Bytes not 16bit aligned.\n", __func__);
1038 FMT_ALIGNBYTE(j &= ~1);
1039 i = j;
1040 while (i > 0) {
1041 v = b[--i];
1042 b[i] = b[i - 1];
1043 b[--i] = v;
1045 return j;
1047 static struct pcm_feederdesc feeder_endian16_desc[] = {
1048 {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_BE, 0},
1049 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U16_BE|AFMT_STEREO, 0},
1050 {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_BE, 0},
1051 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S16_BE|AFMT_STEREO, 0},
1052 {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_LE, 0},
1053 {FEEDER_FMT, AFMT_U16_BE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
1054 {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_LE, 0},
1055 {FEEDER_FMT, AFMT_S16_BE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
1056 {0, 0, 0, 0},
1058 static kobj_method_t feeder_endian16_methods[] = {
1059 KOBJMETHOD(feeder_feed, feed_endian16),
1060 {0, 0}
1062 FEEDER_DECLARE(feeder_endian16, 0, NULL);
1064 static int
1065 feed_endian24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
1066 uint32_t count, void *source)
1068 int i, j = FEEDER_FEED(f->source, c, b, count, source);
1069 uint8_t v;
1071 if (j < 3) {
1072 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
1073 __func__, j);
1074 return 0;
1076 FMT_TEST(j % 3, "%s: Bytes not 24bit aligned.\n", __func__);
1077 FMT_ALIGNBYTE(j -= j % 3);
1078 i = j;
1079 while (i > 0) {
1080 v = b[--i];
1081 b[i] = b[i - 2];
1082 b[i -= 2] = v;
1084 return j;
1086 static struct pcm_feederdesc feeder_endian24_desc[] = {
1087 {FEEDER_FMT, AFMT_U24_LE, AFMT_U24_BE, 0},
1088 {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_U24_BE|AFMT_STEREO, 0},
1089 {FEEDER_FMT, AFMT_S24_LE, AFMT_S24_BE, 0},
1090 {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_S24_BE|AFMT_STEREO, 0},
1091 {FEEDER_FMT, AFMT_U24_BE, AFMT_U24_LE, 0},
1092 {FEEDER_FMT, AFMT_U24_BE|AFMT_STEREO, AFMT_U24_LE|AFMT_STEREO, 0},
1093 {FEEDER_FMT, AFMT_S24_BE, AFMT_S24_LE, 0},
1094 {FEEDER_FMT, AFMT_S24_BE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0},
1095 {0, 0, 0, 0},
1097 static kobj_method_t feeder_endian24_methods[] = {
1098 KOBJMETHOD(feeder_feed, feed_endian24),
1099 {0, 0}
1101 FEEDER_DECLARE(feeder_endian24, 0, NULL);
1103 static int
1104 feed_endian32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
1105 uint32_t count, void *source)
1107 int i, j = FEEDER_FEED(f->source, c, b, count, source);
1108 uint8_t l, m;
1110 if (j < 4) {
1111 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
1112 __func__, j);
1113 return 0;
1115 FMT_TEST(j & 3, "%s: Bytes not 32bit aligned.\n", __func__);
1116 FMT_ALIGNBYTE(j &= ~3);
1117 i = j;
1118 while (i > 0) {
1119 l = b[--i];
1120 m = b[--i];
1121 b[i] = b[i - 1];
1122 b[i + 1] = b[i - 2];
1123 b[--i] = m;
1124 b[--i] = l;
1126 return j;
1128 static struct pcm_feederdesc feeder_endian32_desc[] = {
1129 {FEEDER_FMT, AFMT_U32_LE, AFMT_U32_BE, 0},
1130 {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_U32_BE|AFMT_STEREO, 0},
1131 {FEEDER_FMT, AFMT_S32_LE, AFMT_S32_BE, 0},
1132 {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_S32_BE|AFMT_STEREO, 0},
1133 {FEEDER_FMT, AFMT_U32_BE, AFMT_U32_LE, 0},
1134 {FEEDER_FMT, AFMT_U32_BE|AFMT_STEREO, AFMT_U32_LE|AFMT_STEREO, 0},
1135 {FEEDER_FMT, AFMT_S32_BE, AFMT_S32_LE, 0},
1136 {FEEDER_FMT, AFMT_S32_BE|AFMT_STEREO, AFMT_S32_LE|AFMT_STEREO, 0},
1137 {0, 0, 0, 0},
1139 static kobj_method_t feeder_endian32_methods[] = {
1140 KOBJMETHOD(feeder_feed, feed_endian32),
1141 {0, 0}
1143 FEEDER_DECLARE(feeder_endian32, 0, NULL);
1145 * Endian conversion end