2 * Copyright (c) 1999 Cameron Grant <cg@FreeBSD.org>
3 * Copyright (c) 2005 Ariff Abdullah <ariff@FreeBSD.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
36 * This new implementation is fully dedicated in memory of Cameron Grant, *
37 * the creator of the magnificent, highly addictive feeder infrastructure. *
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,
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;
210 b[j] = tbl[b[j]] ^ 0x80;
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;
226 b[--j] = tbl[b[--i]];
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;
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},
252 static kobj_method_t feeder_ulawtou8_methods[] = {
253 KOBJMETHOD(feeder_feed, feed_table_u8),
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},
263 static kobj_method_t feeder_alawtou8_methods[] = {
264 KOBJMETHOD(feeder_feed, feed_table_u8),
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},
274 static kobj_method_t feeder_ulawtos16le_methods[] = {
275 KOBJMETHOD(feeder_feed, feed_table_s16le),
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},
285 static kobj_method_t feeder_alawtos16le_methods[] = {
286 KOBJMETHOD(feeder_feed, feed_table_s16le),
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},
296 static kobj_method_t feeder_u8toulaw_methods[] = {
297 KOBJMETHOD(feeder_feed, feed_table_xlaw),
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},
307 static kobj_method_t feeder_u8toalaw_methods[] = {
308 KOBJMETHOD(feeder_feed, feed_table_xlaw),
311 FEEDER_DECLARE(feeder_u8toalaw, 0, u8_to_alaw_tbl);
316 * 2. if fmt == u8 , u8 -> s8 (economical)
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.
325 feed_common_init(struct pcm_feeder *f)
327 f->data = kmalloc(FEEDBUFSZ, M_FMTFEEDER, M_NOWAIT|M_ZERO);
334 feed_common_free(struct pcm_feeder *f)
337 kfree(f->data, M_FMTFEEDER);
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);
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},
367 static kobj_method_t feeder_8to16le_methods[] = {
368 KOBJMETHOD(feeder_feed, feed_8to16le),
371 FEEDER_DECLARE(feeder_8to16le, 0, NULL);
374 feed_16leto8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
375 uint32_t count, void *source)
378 uint8_t *src = (uint8_t *)f->data;
381 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
383 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
387 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
388 FMT_ALIGNBYTE(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},
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),
410 FEEDER_DECLARE(feeder_16leto8, 0, NULL);
413 feed_16leto24le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
414 uint32_t count, void *source)
418 k = (count / 3) << 1;
419 k = FEEDER_FEED(f->source, c, b, k, source);
421 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
425 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
426 FMT_ALIGNBYTE(k &= ~1);
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},
444 static kobj_method_t feeder_16leto24le_methods[] = {
445 KOBJMETHOD(feeder_feed, feed_16leto24le),
448 FEEDER_DECLARE(feeder_16leto24le, 0, NULL);
451 feed_24leto16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
452 uint32_t count, void *source)
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);
460 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
464 FMT_TEST(k % 3, "%s: Bytes not 24bit aligned.\n", __func__);
465 FMT_ALIGNBYTE(k -= k % 3);
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},
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),
488 FEEDER_DECLARE(feeder_24leto16le, 1, NULL);
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);
496 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
500 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
501 FMT_ALIGNBYTE(k &= ~1);
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},
520 static kobj_method_t feeder_16leto32le_methods[] = {
521 KOBJMETHOD(feeder_feed, feed_16leto32le),
524 FEEDER_DECLARE(feeder_16leto32le, 0, NULL);
527 feed_32leto16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
528 uint32_t count, void *source)
531 uint8_t *src = (uint8_t *)f->data;
534 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
536 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
540 FMT_TEST(k & 3, "%s: Bytes not 32bit aligned.\n", __func__);
541 FMT_ALIGNBYTE(k &= ~3);
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},
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),
565 FEEDER_DECLARE(feeder_32leto16le, 1, NULL);
571 * Channel conversion (mono -> stereo)
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);
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},
592 static kobj_method_t feeder_monotostereo8_methods[] = {
593 KOBJMETHOD(feeder_feed, feed_monotostereo8),
596 FEEDER_DECLARE(feeder_monotostereo8, 0, NULL);
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);
606 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
610 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
611 FMT_ALIGNBYTE(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},
631 static kobj_method_t feeder_monotostereo16_methods[] = {
632 KOBJMETHOD(feeder_feed, feed_monotostereo16),
635 FEEDER_DECLARE(feeder_monotostereo16, 0, NULL);
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);
645 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
649 FMT_TEST(k % 3, "%s: Bytes not 24bit aligned.\n", __func__);
650 FMT_ALIGNBYTE(k -= k % 3);
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},
673 static kobj_method_t feeder_monotostereo24_methods[] = {
674 KOBJMETHOD(feeder_feed, feed_monotostereo24),
677 FEEDER_DECLARE(feeder_monotostereo24, 0, NULL);
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);
687 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
691 FMT_TEST(k & 3, "%s: Bytes not 32bit aligned.\n", __func__);
692 FMT_ALIGNBYTE(k &= ~3);
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},
718 static kobj_method_t feeder_monotostereo32_methods[] = {
719 KOBJMETHOD(feeder_feed, feed_monotostereo32),
722 FEEDER_DECLARE(feeder_monotostereo32, 0, NULL);
724 * Channel conversion (mono -> stereo) end
728 * Channel conversion (stereo -> mono)
731 feed_stereotomono8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
732 uint32_t count, void *source)
735 uint8_t *src = (uint8_t *)f->data;
738 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
740 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
744 FMT_TEST(k & 1, "%s: Bytes not 8bit (stereo) aligned.\n", __func__);
745 FMT_ALIGNBYTE(k &= ~1);
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},
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),
765 FEEDER_DECLARE(feeder_stereotomono8, 0, NULL);
768 feed_stereotomono16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
769 uint32_t count, void *source)
772 uint8_t *src = (uint8_t *)f->data;
775 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
777 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
781 FMT_TEST(k & 3, "%s: Bytes not 16bit (stereo) aligned.\n", __func__);
782 FMT_ALIGNBYTE(k &= ~3);
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},
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),
805 FEEDER_DECLARE(feeder_stereotomono16, 0, NULL);
808 feed_stereotomono24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
809 uint32_t count, void *source)
812 uint8_t *src = (uint8_t *)f->data;
815 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUF24SZ), source);
817 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
821 FMT_TEST(k % 6, "%s: Bytes not 24bit (stereo) aligned.\n", __func__);
822 FMT_ALIGNBYTE(k -= k % 6);
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},
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),
846 FEEDER_DECLARE(feeder_stereotomono24, 0, NULL);
849 feed_stereotomono32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
850 uint32_t count, void *source)
853 uint8_t *src = (uint8_t *)f->data;
856 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
858 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
862 FMT_TEST(k & 7, "%s: Bytes not 32bit (stereo) aligned.\n", __func__);
863 FMT_ALIGNBYTE(k &= ~7);
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},
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),
888 FEEDER_DECLARE(feeder_stereotomono32, 0, NULL);
890 * Channel conversion (stereo -> mono) end
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);
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},
914 static kobj_method_t feeder_sign8_methods[] = {
915 KOBJMETHOD(feeder_feed, feed_sign8),
918 FEEDER_DECLARE(feeder_sign8, 0, NULL);
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);
927 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
931 FMT_TEST(j & 1, "%s: Bytes not 16bit aligned.\n", __func__);
932 FMT_ALIGNBYTE(j &= ~1);
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},
947 static kobj_method_t feeder_sign16le_methods[] = {
948 KOBJMETHOD(feeder_feed, feed_sign16le),
951 FEEDER_DECLARE(feeder_sign16le, 0, NULL);
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);
960 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
964 FMT_TEST(j % 3, "%s: Bytes not 24bit aligned.\n", __func__);
965 FMT_ALIGNBYTE(j -= j % 3);
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},
980 static kobj_method_t feeder_sign24le_methods[] = {
981 KOBJMETHOD(feeder_feed, feed_sign24le),
984 FEEDER_DECLARE(feeder_sign24le, 0, NULL);
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);
993 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
997 FMT_TEST(j & 3, "%s: Bytes not 32bit aligned.\n", __func__);
998 FMT_ALIGNBYTE(j &= ~3);
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},
1013 static kobj_method_t feeder_sign32le_methods[] = {
1014 KOBJMETHOD(feeder_feed, feed_sign32le),
1017 FEEDER_DECLARE(feeder_sign32le, 0, NULL);
1019 * Sign conversion end.
1023 * Endian conversion.
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);
1033 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
1037 FMT_TEST(j & 1, "%s: Bytes not 16bit aligned.\n", __func__);
1038 FMT_ALIGNBYTE(j &= ~1);
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},
1058 static kobj_method_t feeder_endian16_methods[] = {
1059 KOBJMETHOD(feeder_feed, feed_endian16),
1062 FEEDER_DECLARE(feeder_endian16, 0, NULL);
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);
1072 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
1076 FMT_TEST(j % 3, "%s: Bytes not 24bit aligned.\n", __func__);
1077 FMT_ALIGNBYTE(j -= j % 3);
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},
1097 static kobj_method_t feeder_endian24_methods[] = {
1098 KOBJMETHOD(feeder_feed, feed_endian24),
1101 FEEDER_DECLARE(feeder_endian24, 0, NULL);
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);
1111 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
1115 FMT_TEST(j & 3, "%s: Bytes not 32bit aligned.\n", __func__);
1116 FMT_ALIGNBYTE(j &= ~3);
1122 b[i + 1] = b[i - 2];
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},
1139 static kobj_method_t feeder_endian32_methods[] = {
1140 KOBJMETHOD(feeder_feed, feed_endian32),
1143 FEEDER_DECLARE(feeder_endian32, 0, NULL);
1145 * Endian conversion end