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_WAITOK|M_ZERO);
332 feed_common_free(struct pcm_feeder *f)
335 kfree(f->data, M_FMTFEEDER);
344 feed_8to16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
345 uint32_t count, void *source)
347 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
358 static struct pcm_feederdesc feeder_8to16le_desc[] = {
359 {FEEDER_FMT, AFMT_U8, AFMT_U16_LE, 0},
360 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
361 {FEEDER_FMT, AFMT_S8, AFMT_S16_LE, 0},
362 {FEEDER_FMT, AFMT_S8|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
365 static kobj_method_t feeder_8to16le_methods[] = {
366 KOBJMETHOD(feeder_feed, feed_8to16le),
369 FEEDER_DECLARE(feeder_8to16le, 0, NULL);
372 feed_16leto8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
373 uint32_t count, void *source)
376 uint8_t *src = (uint8_t *)f->data;
379 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
381 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
385 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
386 FMT_ALIGNBYTE(k &= ~1);
395 static struct pcm_feederdesc feeder_16leto8_desc[] = {
396 {FEEDER_FMT, AFMT_U16_LE, AFMT_U8, 0},
397 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
398 {FEEDER_FMT, AFMT_S16_LE, AFMT_S8, 0},
399 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S8|AFMT_STEREO, 0},
402 static kobj_method_t feeder_16leto8_methods[] = {
403 KOBJMETHOD(feeder_init, feed_common_init),
404 KOBJMETHOD(feeder_free, feed_common_free),
405 KOBJMETHOD(feeder_feed, feed_16leto8),
408 FEEDER_DECLARE(feeder_16leto8, 0, NULL);
411 feed_16leto24le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
412 uint32_t count, void *source)
416 k = (count / 3) << 1;
417 k = FEEDER_FEED(f->source, c, b, k, source);
419 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
423 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
424 FMT_ALIGNBYTE(k &= ~1);
435 static struct pcm_feederdesc feeder_16leto24le_desc[] = {
436 {FEEDER_FMT, AFMT_U16_LE, AFMT_U24_LE, 0},
437 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U24_LE|AFMT_STEREO, 0},
438 {FEEDER_FMT, AFMT_S16_LE, AFMT_S24_LE, 0},
439 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0},
442 static kobj_method_t feeder_16leto24le_methods[] = {
443 KOBJMETHOD(feeder_feed, feed_16leto24le),
446 FEEDER_DECLARE(feeder_16leto24le, 0, NULL);
449 feed_24leto16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
450 uint32_t count, void *source)
453 uint8_t *src = (uint8_t *)f->data;
455 k = (count * 3) >> 1;
456 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUF24SZ), source);
458 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
462 FMT_TEST(k % 3, "%s: Bytes not 24bit aligned.\n", __func__);
463 FMT_ALIGNBYTE(k -= k % 3);
473 static struct pcm_feederdesc feeder_24leto16le_desc[] = {
474 {FEEDER_FMT, AFMT_U24_LE, AFMT_U16_LE, 0},
475 {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
476 {FEEDER_FMT, AFMT_S24_LE, AFMT_S16_LE, 0},
477 {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
480 static kobj_method_t feeder_24leto16le_methods[] = {
481 KOBJMETHOD(feeder_init, feed_common_init),
482 KOBJMETHOD(feeder_free, feed_common_free),
483 KOBJMETHOD(feeder_feed, feed_24leto16le),
486 FEEDER_DECLARE(feeder_24leto16le, 1, NULL);
489 feed_16leto32le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
490 uint32_t count, void *source)
492 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
494 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
498 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
499 FMT_ALIGNBYTE(k &= ~1);
511 static struct pcm_feederdesc feeder_16leto32le_desc[] = {
512 {FEEDER_FMT, AFMT_U16_LE, AFMT_U32_LE, 0},
513 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U32_LE|AFMT_STEREO, 0},
514 {FEEDER_FMT, AFMT_S16_LE, AFMT_S32_LE, 0},
515 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S32_LE|AFMT_STEREO, 0},
518 static kobj_method_t feeder_16leto32le_methods[] = {
519 KOBJMETHOD(feeder_feed, feed_16leto32le),
522 FEEDER_DECLARE(feeder_16leto32le, 0, NULL);
525 feed_32leto16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
526 uint32_t count, void *source)
529 uint8_t *src = (uint8_t *)f->data;
532 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
534 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
538 FMT_TEST(k & 3, "%s: Bytes not 32bit aligned.\n", __func__);
539 FMT_ALIGNBYTE(k &= ~3);
550 static struct pcm_feederdesc feeder_32leto16le_desc[] = {
551 {FEEDER_FMT, AFMT_U32_LE, AFMT_U16_LE, 0},
552 {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
553 {FEEDER_FMT, AFMT_S32_LE, AFMT_S16_LE, 0},
554 {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
557 static kobj_method_t feeder_32leto16le_methods[] = {
558 KOBJMETHOD(feeder_init, feed_common_init),
559 KOBJMETHOD(feeder_free, feed_common_free),
560 KOBJMETHOD(feeder_feed, feed_32leto16le),
563 FEEDER_DECLARE(feeder_32leto16le, 1, NULL);
569 * Channel conversion (mono -> stereo)
572 feed_monotostereo8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
573 uint32_t count, void *source)
575 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
585 static struct pcm_feederdesc feeder_monotostereo8_desc[] = {
586 {FEEDER_FMT, AFMT_U8, AFMT_U8|AFMT_STEREO, 0},
587 {FEEDER_FMT, AFMT_S8, AFMT_S8|AFMT_STEREO, 0},
590 static kobj_method_t feeder_monotostereo8_methods[] = {
591 KOBJMETHOD(feeder_feed, feed_monotostereo8),
594 FEEDER_DECLARE(feeder_monotostereo8, 0, NULL);
597 feed_monotostereo16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
598 uint32_t count, void *source)
600 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
604 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
608 FMT_TEST(k & 1, "%s: Bytes not 16bit aligned.\n", __func__);
609 FMT_ALIGNBYTE(k &= ~1);
622 static struct pcm_feederdesc feeder_monotostereo16_desc[] = {
623 {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_LE|AFMT_STEREO, 0},
624 {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_LE|AFMT_STEREO, 0},
625 {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_BE|AFMT_STEREO, 0},
626 {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_BE|AFMT_STEREO, 0},
629 static kobj_method_t feeder_monotostereo16_methods[] = {
630 KOBJMETHOD(feeder_feed, feed_monotostereo16),
633 FEEDER_DECLARE(feeder_monotostereo16, 0, NULL);
636 feed_monotostereo24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
637 uint32_t count, void *source)
639 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
643 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
647 FMT_TEST(k % 3, "%s: Bytes not 24bit aligned.\n", __func__);
648 FMT_ALIGNBYTE(k -= k % 3);
664 static struct pcm_feederdesc feeder_monotostereo24_desc[] = {
665 {FEEDER_FMT, AFMT_U24_LE, AFMT_U24_LE|AFMT_STEREO, 0},
666 {FEEDER_FMT, AFMT_S24_LE, AFMT_S24_LE|AFMT_STEREO, 0},
667 {FEEDER_FMT, AFMT_U24_BE, AFMT_U24_BE|AFMT_STEREO, 0},
668 {FEEDER_FMT, AFMT_S24_BE, AFMT_S24_BE|AFMT_STEREO, 0},
671 static kobj_method_t feeder_monotostereo24_methods[] = {
672 KOBJMETHOD(feeder_feed, feed_monotostereo24),
675 FEEDER_DECLARE(feeder_monotostereo24, 0, NULL);
678 feed_monotostereo32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
679 uint32_t count, void *source)
681 int i, j, k = FEEDER_FEED(f->source, c, b, count >> 1, source);
685 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
689 FMT_TEST(k & 3, "%s: Bytes not 32bit aligned.\n", __func__);
690 FMT_ALIGNBYTE(k &= ~3);
709 static struct pcm_feederdesc feeder_monotostereo32_desc[] = {
710 {FEEDER_FMT, AFMT_U32_LE, AFMT_U32_LE|AFMT_STEREO, 0},
711 {FEEDER_FMT, AFMT_S32_LE, AFMT_S32_LE|AFMT_STEREO, 0},
712 {FEEDER_FMT, AFMT_U32_BE, AFMT_U32_BE|AFMT_STEREO, 0},
713 {FEEDER_FMT, AFMT_S32_BE, AFMT_S32_BE|AFMT_STEREO, 0},
716 static kobj_method_t feeder_monotostereo32_methods[] = {
717 KOBJMETHOD(feeder_feed, feed_monotostereo32),
720 FEEDER_DECLARE(feeder_monotostereo32, 0, NULL);
722 * Channel conversion (mono -> stereo) end
726 * Channel conversion (stereo -> mono)
729 feed_stereotomono8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
730 uint32_t count, void *source)
733 uint8_t *src = (uint8_t *)f->data;
736 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
738 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
742 FMT_TEST(k & 1, "%s: Bytes not 8bit (stereo) aligned.\n", __func__);
743 FMT_ALIGNBYTE(k &= ~1);
752 static struct pcm_feederdesc feeder_stereotomono8_desc[] = {
753 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_U8, 0},
754 {FEEDER_FMT, AFMT_S8|AFMT_STEREO, AFMT_S8, 0},
757 static kobj_method_t feeder_stereotomono8_methods[] = {
758 KOBJMETHOD(feeder_init, feed_common_init),
759 KOBJMETHOD(feeder_free, feed_common_free),
760 KOBJMETHOD(feeder_feed, feed_stereotomono8),
763 FEEDER_DECLARE(feeder_stereotomono8, 0, NULL);
766 feed_stereotomono16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
767 uint32_t count, void *source)
770 uint8_t *src = (uint8_t *)f->data;
773 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
775 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
779 FMT_TEST(k & 3, "%s: Bytes not 16bit (stereo) aligned.\n", __func__);
780 FMT_ALIGNBYTE(k &= ~3);
790 static struct pcm_feederdesc feeder_stereotomono16_desc[] = {
791 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U16_LE, 0},
792 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S16_LE, 0},
793 {FEEDER_FMT, AFMT_U16_BE|AFMT_STEREO, AFMT_U16_BE, 0},
794 {FEEDER_FMT, AFMT_S16_BE|AFMT_STEREO, AFMT_S16_BE, 0},
797 static kobj_method_t feeder_stereotomono16_methods[] = {
798 KOBJMETHOD(feeder_init, feed_common_init),
799 KOBJMETHOD(feeder_free, feed_common_free),
800 KOBJMETHOD(feeder_feed, feed_stereotomono16),
803 FEEDER_DECLARE(feeder_stereotomono16, 0, NULL);
806 feed_stereotomono24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
807 uint32_t count, void *source)
810 uint8_t *src = (uint8_t *)f->data;
813 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUF24SZ), source);
815 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
819 FMT_TEST(k % 6, "%s: Bytes not 24bit (stereo) aligned.\n", __func__);
820 FMT_ALIGNBYTE(k -= k % 6);
831 static struct pcm_feederdesc feeder_stereotomono24_desc[] = {
832 {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_U24_LE, 0},
833 {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_S24_LE, 0},
834 {FEEDER_FMT, AFMT_U24_BE|AFMT_STEREO, AFMT_U24_BE, 0},
835 {FEEDER_FMT, AFMT_S24_BE|AFMT_STEREO, AFMT_S24_BE, 0},
838 static kobj_method_t feeder_stereotomono24_methods[] = {
839 KOBJMETHOD(feeder_init, feed_common_init),
840 KOBJMETHOD(feeder_free, feed_common_free),
841 KOBJMETHOD(feeder_feed, feed_stereotomono24),
844 FEEDER_DECLARE(feeder_stereotomono24, 0, NULL);
847 feed_stereotomono32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
848 uint32_t count, void *source)
851 uint8_t *src = (uint8_t *)f->data;
854 k = FEEDER_FEED(f->source, c, src, min(k, FEEDBUFSZ), source);
856 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
860 FMT_TEST(k & 7, "%s: Bytes not 32bit (stereo) aligned.\n", __func__);
861 FMT_ALIGNBYTE(k &= ~7);
873 static struct pcm_feederdesc feeder_stereotomono32_desc[] = {
874 {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_U32_LE, 0},
875 {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_S32_LE, 0},
876 {FEEDER_FMT, AFMT_U32_BE|AFMT_STEREO, AFMT_U32_BE, 0},
877 {FEEDER_FMT, AFMT_S32_BE|AFMT_STEREO, AFMT_S32_BE, 0},
880 static kobj_method_t feeder_stereotomono32_methods[] = {
881 KOBJMETHOD(feeder_init, feed_common_init),
882 KOBJMETHOD(feeder_free, feed_common_free),
883 KOBJMETHOD(feeder_feed, feed_stereotomono32),
886 FEEDER_DECLARE(feeder_stereotomono32, 0, NULL);
888 * Channel conversion (stereo -> mono) end
895 feed_sign8(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
896 uint32_t count, void *source)
898 int i, j = FEEDER_FEED(f->source, c, b, count, source);
905 static struct pcm_feederdesc feeder_sign8_desc[] = {
906 {FEEDER_FMT, AFMT_U8, AFMT_S8, 0},
907 {FEEDER_FMT, AFMT_U8|AFMT_STEREO, AFMT_S8|AFMT_STEREO, 0},
908 {FEEDER_FMT, AFMT_S8, AFMT_U8, 0},
909 {FEEDER_FMT, AFMT_S8|AFMT_STEREO, AFMT_U8|AFMT_STEREO, 0},
912 static kobj_method_t feeder_sign8_methods[] = {
913 KOBJMETHOD(feeder_feed, feed_sign8),
916 FEEDER_DECLARE(feeder_sign8, 0, NULL);
919 feed_sign16le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
920 uint32_t count, void *source)
922 int i, j = FEEDER_FEED(f->source, c, b, count, source);
925 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
929 FMT_TEST(j & 1, "%s: Bytes not 16bit aligned.\n", __func__);
930 FMT_ALIGNBYTE(j &= ~1);
938 static struct pcm_feederdesc feeder_sign16le_desc[] = {
939 {FEEDER_FMT, AFMT_U16_LE, AFMT_S16_LE, 0},
940 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
941 {FEEDER_FMT, AFMT_S16_LE, AFMT_U16_LE, 0},
942 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
945 static kobj_method_t feeder_sign16le_methods[] = {
946 KOBJMETHOD(feeder_feed, feed_sign16le),
949 FEEDER_DECLARE(feeder_sign16le, 0, NULL);
952 feed_sign24le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
953 uint32_t count, void *source)
955 int i, j = FEEDER_FEED(f->source, c, b, count, source);
958 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
962 FMT_TEST(j % 3, "%s: Bytes not 24bit aligned.\n", __func__);
963 FMT_ALIGNBYTE(j -= j % 3);
971 static struct pcm_feederdesc feeder_sign24le_desc[] = {
972 {FEEDER_FMT, AFMT_U24_LE, AFMT_S24_LE, 0},
973 {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0},
974 {FEEDER_FMT, AFMT_S24_LE, AFMT_U24_LE, 0},
975 {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_U24_LE|AFMT_STEREO, 0},
978 static kobj_method_t feeder_sign24le_methods[] = {
979 KOBJMETHOD(feeder_feed, feed_sign24le),
982 FEEDER_DECLARE(feeder_sign24le, 0, NULL);
985 feed_sign32le(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
986 uint32_t count, void *source)
988 int i, j = FEEDER_FEED(f->source, c, b, count, source);
991 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
995 FMT_TEST(j & 3, "%s: Bytes not 32bit aligned.\n", __func__);
996 FMT_ALIGNBYTE(j &= ~3);
1004 static struct pcm_feederdesc feeder_sign32le_desc[] = {
1005 {FEEDER_FMT, AFMT_U32_LE, AFMT_S32_LE, 0},
1006 {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_S32_LE|AFMT_STEREO, 0},
1007 {FEEDER_FMT, AFMT_S32_LE, AFMT_U32_LE, 0},
1008 {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_U32_LE|AFMT_STEREO, 0},
1011 static kobj_method_t feeder_sign32le_methods[] = {
1012 KOBJMETHOD(feeder_feed, feed_sign32le),
1015 FEEDER_DECLARE(feeder_sign32le, 0, NULL);
1017 * Sign conversion end.
1021 * Endian conversion.
1024 feed_endian16(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
1025 uint32_t count, void *source)
1027 int i, j = FEEDER_FEED(f->source, c, b, count, source);
1031 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
1035 FMT_TEST(j & 1, "%s: Bytes not 16bit aligned.\n", __func__);
1036 FMT_ALIGNBYTE(j &= ~1);
1045 static struct pcm_feederdesc feeder_endian16_desc[] = {
1046 {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_BE, 0},
1047 {FEEDER_FMT, AFMT_U16_LE|AFMT_STEREO, AFMT_U16_BE|AFMT_STEREO, 0},
1048 {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_BE, 0},
1049 {FEEDER_FMT, AFMT_S16_LE|AFMT_STEREO, AFMT_S16_BE|AFMT_STEREO, 0},
1050 {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_LE, 0},
1051 {FEEDER_FMT, AFMT_U16_BE|AFMT_STEREO, AFMT_U16_LE|AFMT_STEREO, 0},
1052 {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_LE, 0},
1053 {FEEDER_FMT, AFMT_S16_BE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0},
1056 static kobj_method_t feeder_endian16_methods[] = {
1057 KOBJMETHOD(feeder_feed, feed_endian16),
1060 FEEDER_DECLARE(feeder_endian16, 0, NULL);
1063 feed_endian24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
1064 uint32_t count, void *source)
1066 int i, j = FEEDER_FEED(f->source, c, b, count, source);
1070 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
1074 FMT_TEST(j % 3, "%s: Bytes not 24bit aligned.\n", __func__);
1075 FMT_ALIGNBYTE(j -= j % 3);
1084 static struct pcm_feederdesc feeder_endian24_desc[] = {
1085 {FEEDER_FMT, AFMT_U24_LE, AFMT_U24_BE, 0},
1086 {FEEDER_FMT, AFMT_U24_LE|AFMT_STEREO, AFMT_U24_BE|AFMT_STEREO, 0},
1087 {FEEDER_FMT, AFMT_S24_LE, AFMT_S24_BE, 0},
1088 {FEEDER_FMT, AFMT_S24_LE|AFMT_STEREO, AFMT_S24_BE|AFMT_STEREO, 0},
1089 {FEEDER_FMT, AFMT_U24_BE, AFMT_U24_LE, 0},
1090 {FEEDER_FMT, AFMT_U24_BE|AFMT_STEREO, AFMT_U24_LE|AFMT_STEREO, 0},
1091 {FEEDER_FMT, AFMT_S24_BE, AFMT_S24_LE, 0},
1092 {FEEDER_FMT, AFMT_S24_BE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0},
1095 static kobj_method_t feeder_endian24_methods[] = {
1096 KOBJMETHOD(feeder_feed, feed_endian24),
1099 FEEDER_DECLARE(feeder_endian24, 0, NULL);
1102 feed_endian32(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
1103 uint32_t count, void *source)
1105 int i, j = FEEDER_FEED(f->source, c, b, count, source);
1109 FMT_TRACE("%s: Not enough data (Got: %d bytes)\n",
1113 FMT_TEST(j & 3, "%s: Bytes not 32bit aligned.\n", __func__);
1114 FMT_ALIGNBYTE(j &= ~3);
1120 b[i + 1] = b[i - 2];
1126 static struct pcm_feederdesc feeder_endian32_desc[] = {
1127 {FEEDER_FMT, AFMT_U32_LE, AFMT_U32_BE, 0},
1128 {FEEDER_FMT, AFMT_U32_LE|AFMT_STEREO, AFMT_U32_BE|AFMT_STEREO, 0},
1129 {FEEDER_FMT, AFMT_S32_LE, AFMT_S32_BE, 0},
1130 {FEEDER_FMT, AFMT_S32_LE|AFMT_STEREO, AFMT_S32_BE|AFMT_STEREO, 0},
1131 {FEEDER_FMT, AFMT_U32_BE, AFMT_U32_LE, 0},
1132 {FEEDER_FMT, AFMT_U32_BE|AFMT_STEREO, AFMT_U32_LE|AFMT_STEREO, 0},
1133 {FEEDER_FMT, AFMT_S32_BE, AFMT_S32_LE, 0},
1134 {FEEDER_FMT, AFMT_S32_BE|AFMT_STEREO, AFMT_S32_LE|AFMT_STEREO, 0},
1137 static kobj_method_t feeder_endian32_methods[] = {
1138 KOBJMETHOD(feeder_feed, feed_endian32),
1141 FEEDER_DECLARE(feeder_endian32, 0, NULL);
1143 * Endian conversion end