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 $
29 * *New* and rewritten soft format converter, supporting 24/32bit pcm data,
30 * simplified and optimized.
32 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
34 * This new implementation is fully dedicated in memory of Cameron Grant, *
35 * the creator of the magnificent, highly addictive feeder infrastructure. *
37 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
41 #include <dev/sound/pcm/sound.h>
42 #include "feeder_if.h"
44 SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pcm/feeder_fmt.c,v 1.4 2007/01/04 21:47:03 corecode Exp $");
46 MALLOC_DEFINE(M_FMTFEEDER, "fmtfeed", "pcm format feeder");
48 #define FEEDBUFSZ 8192
49 #define FEEDBUF24SZ 8190
51 #define FMT_TRACE(x...) /* printf(x) */
52 #define FMT_TEST(x, y...) /* if (x) FMT_TRACE(y) */
53 #define FMT_ALIGNBYTE(x) /* x */
56 * Sign inverted ulaw/alaw -> 8 table
58 static uint8_t ulaw_to_s8_tbl[] = {
59 131, 135, 139, 143, 147, 151, 155, 159,
60 163, 167, 171, 175, 179, 183, 187, 191,
61 194, 196, 198, 200, 202, 204, 206, 208,
62 210, 212, 214, 216, 218, 220, 222, 224,
63 226, 227, 228, 229, 230, 231, 232, 233,
64 234, 235, 236, 237, 238, 239, 240, 241,
65 241, 242, 242, 243, 243, 244, 244, 245,
66 245, 246, 246, 247, 247, 248, 248, 249,
67 249, 249, 250, 250, 250, 250, 251, 251,
68 251, 251, 252, 252, 252, 252, 253, 253,
69 253, 253, 253, 253, 254, 254, 254, 254,
70 254, 254, 254, 254, 255, 255, 255, 255,
71 255, 255, 255, 255, 255, 255, 255, 255,
72 0, 0, 0, 0, 0, 0, 0, 0,
73 0, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0,
75 125, 121, 117, 113, 109, 105, 101, 97,
76 93, 89, 85, 81, 77, 73, 69, 65,
77 62, 60, 58, 56, 54, 52, 50, 48,
78 46, 44, 42, 40, 38, 36, 34, 32,
79 30, 29, 28, 27, 26, 25, 24, 23,
80 22, 21, 20, 19, 18, 17, 16, 15,
81 15, 14, 14, 13, 13, 12, 12, 11,
82 11, 10, 10, 9, 9, 8, 8, 7,
83 7, 7, 6, 6, 6, 6, 5, 5,
84 5, 5, 4, 4, 4, 4, 3, 3,
85 3, 3, 3, 3, 2, 2, 2, 2,
86 2, 2, 2, 2, 1, 1, 1, 1,
87 1, 1, 1, 1, 1, 1, 1, 1,
88 0, 0, 0, 0, 0, 0, 0, 0,
89 0, 0, 0, 0, 0, 0, 0, 0,
90 0, 0, 0, 0, 0, 0, 0, 0,
93 static uint8_t alaw_to_s8_tbl[] = {
94 236, 237, 234, 235, 240, 241, 238, 239,
95 228, 229, 226, 227, 232, 233, 230, 231,
96 246, 246, 245, 245, 248, 248, 247, 247,
97 242, 242, 241, 241, 244, 244, 243, 243,
98 171, 175, 163, 167, 187, 191, 179, 183,
99 139, 143, 131, 135, 155, 159, 147, 151,
100 214, 216, 210, 212, 222, 224, 218, 220,
101 198, 200, 194, 196, 206, 208, 202, 204,
102 255, 255, 255, 255, 255, 255, 255, 255,
103 255, 255, 255, 255, 255, 255, 255, 255,
104 0, 0, 0, 0, 0, 0, 0, 0,
105 0, 0, 0, 0, 0, 0, 0, 0,
106 251, 251, 251, 251, 252, 252, 252, 252,
107 249, 249, 249, 249, 250, 250, 250, 250,
108 254, 254, 254, 254, 254, 254, 254, 254,
109 253, 253, 253, 253, 253, 253, 253, 253,
110 20, 19, 22, 21, 16, 15, 18, 17,
111 28, 27, 30, 29, 24, 23, 26, 25,
112 10, 10, 11, 11, 8, 8, 9, 9,
113 14, 14, 15, 15, 12, 12, 13, 13,
114 85, 81, 93, 89, 69, 65, 77, 73,
115 117, 113, 125, 121, 101, 97, 109, 105,
116 42, 40, 46, 44, 34, 32, 38, 36,
117 58, 56, 62, 60, 50, 48, 54, 52,
118 1, 1, 1, 1, 1, 1, 1, 1,
119 1, 1, 1, 1, 1, 1, 1, 1,
120 0, 0, 0, 0, 0, 0, 0, 0,
121 0, 0, 0, 0, 0, 0, 0, 0,
122 5, 5, 5, 5, 4, 4, 4, 4,
123 7, 7, 7, 7, 6, 6, 6, 6,
124 2, 2, 2, 2, 2, 2, 2, 2,
125 3, 3, 3, 3, 3, 3, 3, 3,
128 static uint8_t u8_to_ulaw_tbl[] = {
129 0, 0, 0, 0, 0, 1, 1, 1,
130 1, 2, 2, 2, 2, 3, 3, 3,
131 3, 4, 4, 4, 4, 5, 5, 5,
132 5, 6, 6, 6, 6, 7, 7, 7,
133 7, 8, 8, 8, 8, 9, 9, 9,
134 9, 10, 10, 10, 10, 11, 11, 11,
135 11, 12, 12, 12, 12, 13, 13, 13,
136 13, 14, 14, 14, 14, 15, 15, 15,
137 15, 16, 16, 17, 17, 18, 18, 19,
138 19, 20, 20, 21, 21, 22, 22, 23,
139 23, 24, 24, 25, 25, 26, 26, 27,
140 27, 28, 28, 29, 29, 30, 30, 31,
141 31, 32, 33, 34, 35, 36, 37, 38,
142 39, 40, 41, 42, 43, 44, 45, 46,
143 47, 49, 51, 53, 55, 57, 59, 61,
144 63, 66, 70, 74, 78, 84, 92, 104,
145 254, 231, 219, 211, 205, 201, 197, 193,
146 190, 188, 186, 184, 182, 180, 178, 176,
147 175, 174, 173, 172, 171, 170, 169, 168,
148 167, 166, 165, 164, 163, 162, 161, 160,
149 159, 159, 158, 158, 157, 157, 156, 156,
150 155, 155, 154, 154, 153, 153, 152, 152,
151 151, 151, 150, 150, 149, 149, 148, 148,
152 147, 147, 146, 146, 145, 145, 144, 144,
153 143, 143, 143, 143, 142, 142, 142, 142,
154 141, 141, 141, 141, 140, 140, 140, 140,
155 139, 139, 139, 139, 138, 138, 138, 138,
156 137, 137, 137, 137, 136, 136, 136, 136,
157 135, 135, 135, 135, 134, 134, 134, 134,
158 133, 133, 133, 133, 132, 132, 132, 132,
159 131, 131, 131, 131, 130, 130, 130, 130,
160 129, 129, 129, 129, 128, 128, 128, 128,
163 static uint8_t u8_to_alaw_tbl[] = {
164 42, 42, 42, 42, 42, 43, 43, 43,
165 43, 40, 40, 40, 40, 41, 41, 41,
166 41, 46, 46, 46, 46, 47, 47, 47,
167 47, 44, 44, 44, 44, 45, 45, 45,
168 45, 34, 34, 34, 34, 35, 35, 35,
169 35, 32, 32, 32, 32, 33, 33, 33,
170 33, 38, 38, 38, 38, 39, 39, 39,
171 39, 36, 36, 36, 36, 37, 37, 37,
172 37, 58, 58, 59, 59, 56, 56, 57,
173 57, 62, 62, 63, 63, 60, 60, 61,
174 61, 50, 50, 51, 51, 48, 48, 49,
175 49, 54, 54, 55, 55, 52, 52, 53,
176 53, 10, 11, 8, 9, 14, 15, 12,
177 13, 2, 3, 0, 1, 6, 7, 4,
178 5, 24, 30, 28, 18, 16, 22, 20,
179 106, 110, 98, 102, 122, 114, 75, 90,
180 213, 197, 245, 253, 229, 225, 237, 233,
181 149, 151, 145, 147, 157, 159, 153, 155,
182 133, 132, 135, 134, 129, 128, 131, 130,
183 141, 140, 143, 142, 137, 136, 139, 138,
184 181, 181, 180, 180, 183, 183, 182, 182,
185 177, 177, 176, 176, 179, 179, 178, 178,
186 189, 189, 188, 188, 191, 191, 190, 190,
187 185, 185, 184, 184, 187, 187, 186, 186,
188 165, 165, 165, 165, 164, 164, 164, 164,
189 167, 167, 167, 167, 166, 166, 166, 166,
190 161, 161, 161, 161, 160, 160, 160, 160,
191 163, 163, 163, 163, 162, 162, 162, 162,
192 173, 173, 173, 173, 172, 172, 172, 172,
193 175, 175, 175, 175, 174, 174, 174, 174,
194 169, 169, 169, 169, 168, 168, 168, 168,
195 171, 171, 171, 171, 170, 170, 170, 170,
199 feed_table_u8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
200 uint32_t count, void *source)
202 int j, k = FEEDER_FEED(f->source, c, b, count, source);
203 uint8_t *tbl = (uint8_t *)f->data;
208 b[j] = tbl[b[j]] ^ 0x80;
214 feed_table_s16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
215 uint32_t count, void *source)
217 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
218 uint8_t *tbl = (uint8_t *)f->data;
224 b[--j] = tbl[b[--i]];
231 feed_table_xlaw(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
232 uint32_t count, void *source)
234 int j, k = FEEDER_FEED(f->source, c, b, count, source);
235 uint8_t *tbl = (uint8_t *)f->data;
245 static struct pcm_feederdesc feeder_ulawtou8_desc[] = {
246 {FEEDER_FMT, AFMT_MU_LAW, AFMT_U8, 0},
247 {FEEDER_FMT, AFMT_MU_LAW|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
250 static kobj_method_t feeder_ulawtou8_methods[] = {
251 KOBJMETHOD(feeder_feed, feed_table_u8),
254 FEEDER_DECLARE(feeder_ulawtou8, 0, ulaw_to_s8_tbl);
256 static struct pcm_feederdesc feeder_alawtou8_desc[] = {
257 {FEEDER_FMT, AFMT_A_LAW, AFMT_U8, 0},
258 {FEEDER_FMT, AFMT_A_LAW|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
261 static kobj_method_t feeder_alawtou8_methods[] = {
262 KOBJMETHOD(feeder_feed, feed_table_u8),
265 FEEDER_DECLARE(feeder_alawtou8, 0, alaw_to_s8_tbl);
267 static struct pcm_feederdesc feeder_ulawtos16le_desc[] = {
268 {FEEDER_FMT, AFMT_MU_LAW, AFMT_S16_LE, 0},
269 {FEEDER_FMT, AFMT_MU_LAW|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
272 static kobj_method_t feeder_ulawtos16le_methods[] = {
273 KOBJMETHOD(feeder_feed, feed_table_s16le),
276 FEEDER_DECLARE(feeder_ulawtos16le, 0, ulaw_to_s8_tbl);
278 static struct pcm_feederdesc feeder_alawtos16le_desc[] = {
279 {FEEDER_FMT, AFMT_A_LAW, AFMT_S16_LE, 0},
280 {FEEDER_FMT, AFMT_A_LAW|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
283 static kobj_method_t feeder_alawtos16le_methods[] = {
284 KOBJMETHOD(feeder_feed, feed_table_s16le),
287 FEEDER_DECLARE(feeder_alawtos16le, 0, alaw_to_s8_tbl);
289 static struct pcm_feederdesc feeder_u8toulaw_desc[] = {
290 {FEEDER_FMT, AFMT_U8, AFMT_MU_LAW, 0},
291 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_MU_LAW|AFMT_STEREO, 0},
294 static kobj_method_t feeder_u8toulaw_methods[] = {
295 KOBJMETHOD(feeder_feed, feed_table_xlaw),
298 FEEDER_DECLARE(feeder_u8toulaw, 0, u8_to_ulaw_tbl);
300 static struct pcm_feederdesc feeder_u8toalaw_desc[] = {
301 {FEEDER_FMT, AFMT_U8, AFMT_A_LAW, 0},
302 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_A_LAW|AFMT_STEREO, 0},
305 static kobj_method_t feeder_u8toalaw_methods[] = {
306 KOBJMETHOD(feeder_feed, feed_table_xlaw),
309 FEEDER_DECLARE(feeder_u8toalaw, 0, u8_to_alaw_tbl);
314 * 2. if fmt == u8 , u8 -> s8 (economical)
316 * 4. if fmt != u8 && fmt == u16le , u16le -> s16le
317 * 4. s16le mono -> s16le stereo
319 * All conversion done in byte level to preserve endianess.
323 feed_common_init(struct pcm_feeder *f)
325 f->data = kmalloc(FEEDBUFSZ, M_FMTFEEDER, M_WAITOK|M_ZERO);
330 feed_common_free(struct pcm_feeder *f)
333 kfree(f->data, M_FMTFEEDER);
342 feed_8to16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
343 uint32_t count, void *source)
345 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
356 static struct pcm_feederdesc feeder_8to16le_desc[] = {
357 {FEEDER_FMT, AFMT_U8, AFMT_U16_LE, 0},
358 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
359 {FEEDER_FMT, AFMT_S8, AFMT_S16_LE, 0},
360 {FEEDER_FMT, AFMT_S8|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
363 static kobj_method_t feeder_8to16le_methods[] = {
364 KOBJMETHOD(feeder_feed, feed_8to16le),
367 FEEDER_DECLARE(feeder_8to16le, 0, NULL);
370 feed_16leto8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
371 uint32_t count, void *source)
374 uint8_t *src = (uint8_t *)f->data;
377 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
379 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
383 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
384 FMT_ALIGNBYTE(k &= ~1);
393 static struct pcm_feederdesc feeder_16leto8_desc[] = {
394 {FEEDER_FMT, AFMT_U16_LE, AFMT_U8, 0},
395 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
396 {FEEDER_FMT, AFMT_S16_LE, AFMT_S8, 0},
397 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S8|AFMT_STEREO, 0},
400 static kobj_method_t feeder_16leto8_methods[] = {
401 KOBJMETHOD(feeder_init, feed_common_init),
402 KOBJMETHOD(feeder_free, feed_common_free),
403 KOBJMETHOD(feeder_feed, feed_16leto8),
406 FEEDER_DECLARE(feeder_16leto8, 0, NULL);
409 feed_16leto24le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
410 uint32_t count, void *source)
414 k = (count / 3) << 1;
415 k = FEEDER_FEED(f->source, c, b, k, source);
417 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
421 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
422 FMT_ALIGNBYTE(k &= ~1);
433 static struct pcm_feederdesc feeder_16leto24le_desc[] = {
434 {FEEDER_FMT, AFMT_U16_LE, AFMT_U24_LE, 0},
435 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U24_LE|AFMT_STEREO, 0},
436 {FEEDER_FMT, AFMT_S16_LE, AFMT_S24_LE, 0},
437 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0},
440 static kobj_method_t feeder_16leto24le_methods[] = {
441 KOBJMETHOD(feeder_feed, feed_16leto24le),
444 FEEDER_DECLARE(feeder_16leto24le, 0, NULL);
447 feed_24leto16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
448 uint32_t count, void *source)
451 uint8_t *src = (uint8_t *)f->data;
453 k = (count * 3) >> 1;
454 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUF24SZ), source);
456 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
460 FMT_TEST(k % 3, "%s: Bytes not 24bit aligned.\n", __func__);
461 FMT_ALIGNBYTE(k -= k % 3);
471 static struct pcm_feederdesc feeder_24leto16le_desc[] = {
472 {FEEDER_FMT, AFMT_U24_LE, AFMT_U16_LE, 0},
473 {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
474 {FEEDER_FMT, AFMT_S24_LE, AFMT_S16_LE, 0},
475 {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
478 static kobj_method_t feeder_24leto16le_methods[] = {
479 KOBJMETHOD(feeder_init, feed_common_init),
480 KOBJMETHOD(feeder_free, feed_common_free),
481 KOBJMETHOD(feeder_feed, feed_24leto16le),
484 FEEDER_DECLARE(feeder_24leto16le, 1, NULL);
487 feed_16leto32le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
488 uint32_t count, void *source)
490 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
492 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
496 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
497 FMT_ALIGNBYTE(k &= ~1);
509 static struct pcm_feederdesc feeder_16leto32le_desc[] = {
510 {FEEDER_FMT, AFMT_U16_LE, AFMT_U32_LE, 0},
511 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U32_LE|AFMT_STEREO, 0},
512 {FEEDER_FMT, AFMT_S16_LE, AFMT_S32_LE, 0},
513 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S32_LE|AFMT_STEREO, 0},
516 static kobj_method_t feeder_16leto32le_methods[] = {
517 KOBJMETHOD(feeder_feed, feed_16leto32le),
520 FEEDER_DECLARE(feeder_16leto32le, 0, NULL);
523 feed_32leto16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
524 uint32_t count, void *source)
527 uint8_t *src = (uint8_t *)f->data;
530 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
532 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
536 FMT_TEST(k & 3, "%s: Bytes not 32bit aligned.\n", __func__);
537 FMT_ALIGNBYTE(k &= ~3);
548 static struct pcm_feederdesc feeder_32leto16le_desc[] = {
549 {FEEDER_FMT, AFMT_U32_LE, AFMT_U16_LE, 0},
550 {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
551 {FEEDER_FMT, AFMT_S32_LE, AFMT_S16_LE, 0},
552 {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
555 static kobj_method_t feeder_32leto16le_methods[] = {
556 KOBJMETHOD(feeder_init, feed_common_init),
557 KOBJMETHOD(feeder_free, feed_common_free),
558 KOBJMETHOD(feeder_feed, feed_32leto16le),
561 FEEDER_DECLARE(feeder_32leto16le, 1, NULL);
567 * Channel conversion (mono -> stereo)
570 feed_monotostereo8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
571 uint32_t count, void *source)
573 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
583 static struct pcm_feederdesc feeder_monotostereo8_desc[] = {
584 {FEEDER_FMT, AFMT_U8, AFMT_U8|AFMT_STEREO, 0},
585 {FEEDER_FMT, AFMT_S8, AFMT_S8|AFMT_STEREO, 0},
588 static kobj_method_t feeder_monotostereo8_methods[] = {
589 KOBJMETHOD(feeder_feed, feed_monotostereo8),
592 FEEDER_DECLARE(feeder_monotostereo8, 0, NULL);
595 feed_monotostereo16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
596 uint32_t count, void *source)
598 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
602 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
606 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
607 FMT_ALIGNBYTE(k &= ~1);
620 static struct pcm_feederdesc feeder_monotostereo16_desc[] = {
621 {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_LE|AFMT_STEREO, 0},
622 {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_LE|AFMT_STEREO, 0},
623 {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_BE|AFMT_STEREO, 0},
624 {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_BE|AFMT_STEREO, 0},
627 static kobj_method_t feeder_monotostereo16_methods[] = {
628 KOBJMETHOD(feeder_feed, feed_monotostereo16),
631 FEEDER_DECLARE(feeder_monotostereo16, 0, NULL);
634 feed_monotostereo24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
635 uint32_t count, void *source)
637 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
641 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
645 FMT_TEST(k % 3, "%s: Bytes not 24bit aligned.\n", __func__);
646 FMT_ALIGNBYTE(k -= k % 3);
662 static struct pcm_feederdesc feeder_monotostereo24_desc[] = {
663 {FEEDER_FMT, AFMT_U24_LE, AFMT_U24_LE|AFMT_STEREO, 0},
664 {FEEDER_FMT, AFMT_S24_LE, AFMT_S24_LE|AFMT_STEREO, 0},
665 {FEEDER_FMT, AFMT_U24_BE, AFMT_U24_BE|AFMT_STEREO, 0},
666 {FEEDER_FMT, AFMT_S24_BE, AFMT_S24_BE|AFMT_STEREO, 0},
669 static kobj_method_t feeder_monotostereo24_methods[] = {
670 KOBJMETHOD(feeder_feed, feed_monotostereo24),
673 FEEDER_DECLARE(feeder_monotostereo24, 0, NULL);
676 feed_monotostereo32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
677 uint32_t count, void *source)
679 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
683 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
687 FMT_TEST(k & 3, "%s: Bytes not 32bit aligned.\n", __func__);
688 FMT_ALIGNBYTE(k &= ~3);
707 static struct pcm_feederdesc feeder_monotostereo32_desc[] = {
708 {FEEDER_FMT, AFMT_U32_LE, AFMT_U32_LE|AFMT_STEREO, 0},
709 {FEEDER_FMT, AFMT_S32_LE, AFMT_S32_LE|AFMT_STEREO, 0},
710 {FEEDER_FMT, AFMT_U32_BE, AFMT_U32_BE|AFMT_STEREO, 0},
711 {FEEDER_FMT, AFMT_S32_BE, AFMT_S32_BE|AFMT_STEREO, 0},
714 static kobj_method_t feeder_monotostereo32_methods[] = {
715 KOBJMETHOD(feeder_feed, feed_monotostereo32),
718 FEEDER_DECLARE(feeder_monotostereo32, 0, NULL);
720 * Channel conversion (mono -> stereo) end
724 * Channel conversion (stereo -> mono)
727 feed_stereotomono8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
728 uint32_t count, void *source)
731 uint8_t *src = (uint8_t *)f->data;
734 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
736 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
740 FMT_TEST(k & 1, "%s: Bytes not 8bit (stereo) aligned.\n", __func__);
741 FMT_ALIGNBYTE(k &= ~1);
750 static struct pcm_feederdesc feeder_stereotomono8_desc[] = {
751 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_U8, 0},
752 {FEEDER_FMT, AFMT_S8|AFMT_STEREO, AFMT_S8, 0},
755 static kobj_method_t feeder_stereotomono8_methods[] = {
756 KOBJMETHOD(feeder_init, feed_common_init),
757 KOBJMETHOD(feeder_free, feed_common_free),
758 KOBJMETHOD(feeder_feed, feed_stereotomono8),
761 FEEDER_DECLARE(feeder_stereotomono8, 0, NULL);
764 feed_stereotomono16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
765 uint32_t count, void *source)
768 uint8_t *src = (uint8_t *)f->data;
771 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
773 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
777 FMT_TEST(k & 3, "%s: Bytes not 16bit (stereo) aligned.\n", __func__);
778 FMT_ALIGNBYTE(k &= ~3);
788 static struct pcm_feederdesc feeder_stereotomono16_desc[] = {
789 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U16_LE, 0},
790 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S16_LE, 0},
791 {FEEDER_FMT, AFMT_U16_BE|AFMT_STEREO, AFMT_U16_BE, 0},
792 {FEEDER_FMT, AFMT_S16_BE|AFMT_STEREO, AFMT_S16_BE, 0},
795 static kobj_method_t feeder_stereotomono16_methods[] = {
796 KOBJMETHOD(feeder_init, feed_common_init),
797 KOBJMETHOD(feeder_free, feed_common_free),
798 KOBJMETHOD(feeder_feed, feed_stereotomono16),
801 FEEDER_DECLARE(feeder_stereotomono16, 0, NULL);
804 feed_stereotomono24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
805 uint32_t count, void *source)
808 uint8_t *src = (uint8_t *)f->data;
811 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUF24SZ), source);
813 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
817 FMT_TEST(k % 6, "%s: Bytes not 24bit (stereo) aligned.\n", __func__);
818 FMT_ALIGNBYTE(k -= k % 6);
829 static struct pcm_feederdesc feeder_stereotomono24_desc[] = {
830 {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_U24_LE, 0},
831 {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_S24_LE, 0},
832 {FEEDER_FMT, AFMT_U24_BE|AFMT_STEREO, AFMT_U24_BE, 0},
833 {FEEDER_FMT, AFMT_S24_BE|AFMT_STEREO, AFMT_S24_BE, 0},
836 static kobj_method_t feeder_stereotomono24_methods[] = {
837 KOBJMETHOD(feeder_init, feed_common_init),
838 KOBJMETHOD(feeder_free, feed_common_free),
839 KOBJMETHOD(feeder_feed, feed_stereotomono24),
842 FEEDER_DECLARE(feeder_stereotomono24, 0, NULL);
845 feed_stereotomono32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
846 uint32_t count, void *source)
849 uint8_t *src = (uint8_t *)f->data;
852 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
854 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
858 FMT_TEST(k & 7, "%s: Bytes not 32bit (stereo) aligned.\n", __func__);
859 FMT_ALIGNBYTE(k &= ~7);
871 static struct pcm_feederdesc feeder_stereotomono32_desc[] = {
872 {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_U32_LE, 0},
873 {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_S32_LE, 0},
874 {FEEDER_FMT, AFMT_U32_BE|AFMT_STEREO, AFMT_U32_BE, 0},
875 {FEEDER_FMT, AFMT_S32_BE|AFMT_STEREO, AFMT_S32_BE, 0},
878 static kobj_method_t feeder_stereotomono32_methods[] = {
879 KOBJMETHOD(feeder_init, feed_common_init),
880 KOBJMETHOD(feeder_free, feed_common_free),
881 KOBJMETHOD(feeder_feed, feed_stereotomono32),
884 FEEDER_DECLARE(feeder_stereotomono32, 0, NULL);
886 * Channel conversion (stereo -> mono) end
893 feed_sign8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
894 uint32_t count, void *source)
896 int i, j = FEEDER_FEED(f->source, c, b, count, source);
903 static struct pcm_feederdesc feeder_sign8_desc[] = {
904 {FEEDER_FMT, AFMT_U8, AFMT_S8, 0},
905 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_S8|AFMT_STEREO, 0},
906 {FEEDER_FMT, AFMT_S8, AFMT_U8, 0},
907 {FEEDER_FMT, AFMT_S8|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
910 static kobj_method_t feeder_sign8_methods[] = {
911 KOBJMETHOD(feeder_feed, feed_sign8),
914 FEEDER_DECLARE(feeder_sign8, 0, NULL);
917 feed_sign16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
918 uint32_t count, void *source)
920 int i, j = FEEDER_FEED(f->source, c, b, count, source);
923 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
927 FMT_TEST(j & 1, "%s: Bytes not 16bit aligned.\n", __func__);
928 FMT_ALIGNBYTE(j &= ~1);
936 static struct pcm_feederdesc feeder_sign16le_desc[] = {
937 {FEEDER_FMT, AFMT_U16_LE, AFMT_S16_LE, 0},
938 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
939 {FEEDER_FMT, AFMT_S16_LE, AFMT_U16_LE, 0},
940 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
943 static kobj_method_t feeder_sign16le_methods[] = {
944 KOBJMETHOD(feeder_feed, feed_sign16le),
947 FEEDER_DECLARE(feeder_sign16le, 0, NULL);
950 feed_sign24le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
951 uint32_t count, void *source)
953 int i, j = FEEDER_FEED(f->source, c, b, count, source);
956 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
960 FMT_TEST(j % 3, "%s: Bytes not 24bit aligned.\n", __func__);
961 FMT_ALIGNBYTE(j -= j % 3);
969 static struct pcm_feederdesc feeder_sign24le_desc[] = {
970 {FEEDER_FMT, AFMT_U24_LE, AFMT_S24_LE, 0},
971 {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0},
972 {FEEDER_FMT, AFMT_S24_LE, AFMT_U24_LE, 0},
973 {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_U24_LE|AFMT_STEREO, 0},
976 static kobj_method_t feeder_sign24le_methods[] = {
977 KOBJMETHOD(feeder_feed, feed_sign24le),
980 FEEDER_DECLARE(feeder_sign24le, 0, NULL);
983 feed_sign32le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
984 uint32_t count, void *source)
986 int i, j = FEEDER_FEED(f->source, c, b, count, source);
989 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
993 FMT_TEST(j & 3, "%s: Bytes not 32bit aligned.\n", __func__);
994 FMT_ALIGNBYTE(j &= ~3);
1002 static struct pcm_feederdesc feeder_sign32le_desc[] = {
1003 {FEEDER_FMT, AFMT_U32_LE, AFMT_S32_LE, 0},
1004 {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_S32_LE|AFMT_STEREO, 0},
1005 {FEEDER_FMT, AFMT_S32_LE, AFMT_U32_LE, 0},
1006 {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_U32_LE|AFMT_STEREO, 0},
1009 static kobj_method_t feeder_sign32le_methods[] = {
1010 KOBJMETHOD(feeder_feed, feed_sign32le),
1013 FEEDER_DECLARE(feeder_sign32le, 0, NULL);
1015 * Sign conversion end.
1019 * Endian conversion.
1022 feed_endian16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
1023 uint32_t count, void *source)
1025 int i, j = FEEDER_FEED(f->source, c, b, count, source);
1029 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
1033 FMT_TEST(j & 1, "%s: Bytes not 16bit aligned.\n", __func__);
1034 FMT_ALIGNBYTE(j &= ~1);
1043 static struct pcm_feederdesc feeder_endian16_desc[] = {
1044 {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_BE, 0},
1045 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U16_BE|AFMT_STEREO, 0},
1046 {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_BE, 0},
1047 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S16_BE|AFMT_STEREO, 0},
1048 {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_LE, 0},
1049 {FEEDER_FMT, AFMT_U16_BE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
1050 {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_LE, 0},
1051 {FEEDER_FMT, AFMT_S16_BE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
1054 static kobj_method_t feeder_endian16_methods[] = {
1055 KOBJMETHOD(feeder_feed, feed_endian16),
1058 FEEDER_DECLARE(feeder_endian16, 0, NULL);
1061 feed_endian24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
1062 uint32_t count, void *source)
1064 int i, j = FEEDER_FEED(f->source, c, b, count, source);
1068 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
1072 FMT_TEST(j % 3, "%s: Bytes not 24bit aligned.\n", __func__);
1073 FMT_ALIGNBYTE(j -= j % 3);
1082 static struct pcm_feederdesc feeder_endian24_desc[] = {
1083 {FEEDER_FMT, AFMT_U24_LE, AFMT_U24_BE, 0},
1084 {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_U24_BE|AFMT_STEREO, 0},
1085 {FEEDER_FMT, AFMT_S24_LE, AFMT_S24_BE, 0},
1086 {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_S24_BE|AFMT_STEREO, 0},
1087 {FEEDER_FMT, AFMT_U24_BE, AFMT_U24_LE, 0},
1088 {FEEDER_FMT, AFMT_U24_BE|AFMT_STEREO, AFMT_U24_LE|AFMT_STEREO, 0},
1089 {FEEDER_FMT, AFMT_S24_BE, AFMT_S24_LE, 0},
1090 {FEEDER_FMT, AFMT_S24_BE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0},
1093 static kobj_method_t feeder_endian24_methods[] = {
1094 KOBJMETHOD(feeder_feed, feed_endian24),
1097 FEEDER_DECLARE(feeder_endian24, 0, NULL);
1100 feed_endian32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
1101 uint32_t count, void *source)
1103 int i, j = FEEDER_FEED(f->source, c, b, count, source);
1107 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
1111 FMT_TEST(j & 3, "%s: Bytes not 32bit aligned.\n", __func__);
1112 FMT_ALIGNBYTE(j &= ~3);
1118 b[i + 1] = b[i - 2];
1124 static struct pcm_feederdesc feeder_endian32_desc[] = {
1125 {FEEDER_FMT, AFMT_U32_LE, AFMT_U32_BE, 0},
1126 {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_U32_BE|AFMT_STEREO, 0},
1127 {FEEDER_FMT, AFMT_S32_LE, AFMT_S32_BE, 0},
1128 {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_S32_BE|AFMT_STEREO, 0},
1129 {FEEDER_FMT, AFMT_U32_BE, AFMT_U32_LE, 0},
1130 {FEEDER_FMT, AFMT_U32_BE|AFMT_STEREO, AFMT_U32_LE|AFMT_STEREO, 0},
1131 {FEEDER_FMT, AFMT_S32_BE, AFMT_S32_LE, 0},
1132 {FEEDER_FMT, AFMT_S32_BE|AFMT_STEREO, AFMT_S32_LE|AFMT_STEREO, 0},
1135 static kobj_method_t feeder_endian32_methods[] = {
1136 KOBJMETHOD(feeder_feed, feed_endian32),
1139 FEEDER_DECLARE(feeder_endian32, 0, NULL);
1141 * Endian conversion end