2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/sys/dev/sound/pcm/feeder_fmt.c,v 1.1.2.5 2002/04/22 15:49:36 cg Exp $
27 * $DragonFly: src/sys/dev/sound/pcm/feeder_fmt.c,v 1.2 2003/06/17 04:28:31 dillon Exp $
30 #include <dev/sound/pcm/sound.h>
32 #include "feeder_if.h"
34 SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pcm/feeder_fmt.c,v 1.2 2003/06/17 04:28:31 dillon Exp $");
36 MALLOC_DEFINE(M_FMTFEEDER, "fmtfeed", "pcm format feeder");
38 #define FEEDBUFSZ 8192
40 static unsigned char ulaw_to_u8[] = {
41 3, 7, 11, 15, 19, 23, 27, 31,
42 35, 39, 43, 47, 51, 55, 59, 63,
43 66, 68, 70, 72, 74, 76, 78, 80,
44 82, 84, 86, 88, 90, 92, 94, 96,
45 98, 99, 100, 101, 102, 103, 104, 105,
46 106, 107, 108, 109, 110, 111, 112, 113,
47 113, 114, 114, 115, 115, 116, 116, 117,
48 117, 118, 118, 119, 119, 120, 120, 121,
49 121, 121, 122, 122, 122, 122, 123, 123,
50 123, 123, 124, 124, 124, 124, 125, 125,
51 125, 125, 125, 125, 126, 126, 126, 126,
52 126, 126, 126, 126, 127, 127, 127, 127,
53 127, 127, 127, 127, 127, 127, 127, 127,
54 128, 128, 128, 128, 128, 128, 128, 128,
55 128, 128, 128, 128, 128, 128, 128, 128,
56 128, 128, 128, 128, 128, 128, 128, 128,
57 253, 249, 245, 241, 237, 233, 229, 225,
58 221, 217, 213, 209, 205, 201, 197, 193,
59 190, 188, 186, 184, 182, 180, 178, 176,
60 174, 172, 170, 168, 166, 164, 162, 160,
61 158, 157, 156, 155, 154, 153, 152, 151,
62 150, 149, 148, 147, 146, 145, 144, 143,
63 143, 142, 142, 141, 141, 140, 140, 139,
64 139, 138, 138, 137, 137, 136, 136, 135,
65 135, 135, 134, 134, 134, 134, 133, 133,
66 133, 133, 132, 132, 132, 132, 131, 131,
67 131, 131, 131, 131, 130, 130, 130, 130,
68 130, 130, 130, 130, 129, 129, 129, 129,
69 129, 129, 129, 129, 129, 129, 129, 129,
70 128, 128, 128, 128, 128, 128, 128, 128,
71 128, 128, 128, 128, 128, 128, 128, 128,
72 128, 128, 128, 128, 128, 128, 128, 128,
75 static unsigned char u8_to_ulaw[] = {
76 0, 0, 0, 0, 0, 1, 1, 1,
77 1, 2, 2, 2, 2, 3, 3, 3,
78 3, 4, 4, 4, 4, 5, 5, 5,
79 5, 6, 6, 6, 6, 7, 7, 7,
80 7, 8, 8, 8, 8, 9, 9, 9,
81 9, 10, 10, 10, 10, 11, 11, 11,
82 11, 12, 12, 12, 12, 13, 13, 13,
83 13, 14, 14, 14, 14, 15, 15, 15,
84 15, 16, 16, 17, 17, 18, 18, 19,
85 19, 20, 20, 21, 21, 22, 22, 23,
86 23, 24, 24, 25, 25, 26, 26, 27,
87 27, 28, 28, 29, 29, 30, 30, 31,
88 31, 32, 33, 34, 35, 36, 37, 38,
89 39, 40, 41, 42, 43, 44, 45, 46,
90 47, 49, 51, 53, 55, 57, 59, 61,
91 63, 66, 70, 74, 78, 84, 92, 104,
92 254, 231, 219, 211, 205, 201, 197, 193,
93 190, 188, 186, 184, 182, 180, 178, 176,
94 175, 174, 173, 172, 171, 170, 169, 168,
95 167, 166, 165, 164, 163, 162, 161, 160,
96 159, 159, 158, 158, 157, 157, 156, 156,
97 155, 155, 154, 154, 153, 153, 152, 152,
98 151, 151, 150, 150, 149, 149, 148, 148,
99 147, 147, 146, 146, 145, 145, 144, 144,
100 143, 143, 143, 143, 142, 142, 142, 142,
101 141, 141, 141, 141, 140, 140, 140, 140,
102 139, 139, 139, 139, 138, 138, 138, 138,
103 137, 137, 137, 137, 136, 136, 136, 136,
104 135, 135, 135, 135, 134, 134, 134, 134,
105 133, 133, 133, 133, 132, 132, 132, 132,
106 131, 131, 131, 131, 130, 130, 130, 130,
107 129, 129, 129, 129, 128, 128, 128, 128,
110 static unsigned char alaw_to_ulaw[] = {
111 42, 43, 40, 41, 46, 47, 44, 45,
112 34, 35, 32, 33, 38, 39, 36, 37,
113 57, 58, 55, 56, 61, 62, 59, 60,
114 49, 50, 48, 48, 53, 54, 51, 52,
115 10, 11, 8, 9, 14, 15, 12, 13,
116 2, 3, 0, 1, 6, 7, 4, 5,
117 26, 27, 24, 25, 30, 31, 28, 29,
118 18, 19, 16, 17, 22, 23, 20, 21,
119 98, 99, 96, 97, 102, 103, 100, 101,
120 93, 93, 92, 92, 95, 95, 94, 94,
121 116, 118, 112, 114, 124, 126, 120, 122,
122 106, 107, 104, 105, 110, 111, 108, 109,
123 72, 73, 70, 71, 76, 77, 74, 75,
124 64, 65, 63, 63, 68, 69, 66, 67,
125 86, 87, 84, 85, 90, 91, 88, 89,
126 79, 79, 78, 78, 82, 83, 80, 81,
127 170, 171, 168, 169, 174, 175, 172, 173,
128 162, 163, 160, 161, 166, 167, 164, 165,
129 185, 186, 183, 184, 189, 190, 187, 188,
130 177, 178, 176, 176, 181, 182, 179, 180,
131 138, 139, 136, 137, 142, 143, 140, 141,
132 130, 131, 128, 129, 134, 135, 132, 133,
133 154, 155, 152, 153, 158, 159, 156, 157,
134 146, 147, 144, 145, 150, 151, 148, 149,
135 226, 227, 224, 225, 230, 231, 228, 229,
136 221, 221, 220, 220, 223, 223, 222, 222,
137 244, 246, 240, 242, 252, 254, 248, 250,
138 234, 235, 232, 233, 238, 239, 236, 237,
139 200, 201, 198, 199, 204, 205, 202, 203,
140 192, 193, 191, 191, 196, 197, 194, 195,
141 214, 215, 212, 213, 218, 219, 216, 217,
142 207, 207, 206, 206, 210, 211, 208, 209,
145 static unsigned char ulaw_to_alaw[] = {
146 42, 43, 40, 41, 46, 47, 44, 45,
147 34, 35, 32, 33, 38, 39, 36, 37,
148 58, 59, 56, 57, 62, 63, 60, 61,
149 50, 51, 48, 49, 54, 55, 52, 53,
150 10, 11, 8, 9, 14, 15, 12, 13,
151 2, 3, 0, 1, 6, 7, 4, 5,
152 27, 24, 25, 30, 31, 28, 29, 18,
153 19, 16, 17, 22, 23, 20, 21, 106,
154 104, 105, 110, 111, 108, 109, 98, 99,
155 96, 97, 102, 103, 100, 101, 122, 120,
156 126, 127, 124, 125, 114, 115, 112, 113,
157 118, 119, 116, 117, 75, 73, 79, 77,
158 66, 67, 64, 65, 70, 71, 68, 69,
159 90, 91, 88, 89, 94, 95, 92, 93,
160 82, 82, 83, 83, 80, 80, 81, 81,
161 86, 86, 87, 87, 84, 84, 85, 85,
162 170, 171, 168, 169, 174, 175, 172, 173,
163 162, 163, 160, 161, 166, 167, 164, 165,
164 186, 187, 184, 185, 190, 191, 188, 189,
165 178, 179, 176, 177, 182, 183, 180, 181,
166 138, 139, 136, 137, 142, 143, 140, 141,
167 130, 131, 128, 129, 134, 135, 132, 133,
168 155, 152, 153, 158, 159, 156, 157, 146,
169 147, 144, 145, 150, 151, 148, 149, 234,
170 232, 233, 238, 239, 236, 237, 226, 227,
171 224, 225, 230, 231, 228, 229, 250, 248,
172 254, 255, 252, 253, 242, 243, 240, 241,
173 246, 247, 244, 245, 203, 201, 207, 205,
174 194, 195, 192, 193, 198, 199, 196, 197,
175 218, 219, 216, 217, 222, 223, 220, 221,
176 210, 210, 211, 211, 208, 208, 209, 209,
177 214, 214, 215, 215, 212, 212, 213, 213,
180 /*****************************************************************************/
183 feed_8to16le(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
187 k = FEEDER_FEED(f->source, c, b, count / 2, source);
190 while (i > 0 && j >= 0) {
197 static struct pcm_feederdesc feeder_8to16le_desc[] = {
198 {FEEDER_FMT, AFMT_U8, AFMT_U16_LE, 0},
199 {FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_U16_LE | AFMT_STEREO, 0},
200 {FEEDER_FMT, AFMT_S8, AFMT_S16_LE, 0},
201 {FEEDER_FMT, AFMT_S8 | AFMT_STEREO, AFMT_S16_LE | AFMT_STEREO, 0},
204 static kobj_method_t feeder_8to16le_methods[] = {
205 KOBJMETHOD(feeder_feed, feed_8to16le),
208 FEEDER_DECLARE(feeder_8to16le, 0, NULL);
210 /*****************************************************************************/
213 feed_16to8_init(struct pcm_feeder *f)
215 f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_WAITOK | M_ZERO);
216 return (f->data)? 0 : ENOMEM;
220 feed_16to8_free(struct pcm_feeder *f)
223 free(f->data, M_FMTFEEDER);
229 feed_16leto8(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
231 u_int32_t i = 0, toget = count * 2;
234 k = FEEDER_FEED(f->source, c, f->data, min(toget, FEEDBUFSZ), source);
236 b[i++] = ((u_int8_t *)f->data)[j];
242 static struct pcm_feederdesc feeder_16leto8_desc[] = {
243 {FEEDER_FMT, AFMT_U16_LE, AFMT_U8, 0},
244 {FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_U8 | AFMT_STEREO, 0},
245 {FEEDER_FMT, AFMT_S16_LE, AFMT_S8, 0},
246 {FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_S8 | AFMT_STEREO, 0},
249 static kobj_method_t feeder_16leto8_methods[] = {
250 KOBJMETHOD(feeder_init, feed_16to8_init),
251 KOBJMETHOD(feeder_free, feed_16to8_free),
252 KOBJMETHOD(feeder_feed, feed_16leto8),
255 FEEDER_DECLARE(feeder_16leto8, 1, NULL);
257 /*****************************************************************************/
260 feed_monotostereo8(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
262 int i, j, k = FEEDER_FEED(f->source, c, b, count / 2, source);
266 while (i > 0 && j >= 0) {
274 static struct pcm_feederdesc feeder_monotostereo8_desc[] = {
275 {FEEDER_FMT, AFMT_U8, AFMT_U8 | AFMT_STEREO, 0},
276 {FEEDER_FMT, AFMT_S8, AFMT_S8 | AFMT_STEREO, 0},
279 static kobj_method_t feeder_monotostereo8_methods[] = {
280 KOBJMETHOD(feeder_feed, feed_monotostereo8),
283 FEEDER_DECLARE(feeder_monotostereo8, 0, NULL);
285 /*****************************************************************************/
288 feed_monotostereo16(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
290 int i, j, k = FEEDER_FEED(f->source, c, b, count / 2, source);
295 while (i > 3 && j >= 1) {
306 static struct pcm_feederdesc feeder_monotostereo16_desc[] = {
307 {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_LE | AFMT_STEREO, 0},
308 {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_LE | AFMT_STEREO, 0},
309 {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_BE | AFMT_STEREO, 0},
310 {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_BE | AFMT_STEREO, 0},
313 static kobj_method_t feeder_monotostereo16_methods[] = {
314 KOBJMETHOD(feeder_feed, feed_monotostereo16),
317 FEEDER_DECLARE(feeder_monotostereo16, 0, NULL);
319 /*****************************************************************************/
322 feed_stereotomono8_init(struct pcm_feeder *f)
324 f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_WAITOK | M_ZERO);
325 return (f->data)? 0 : ENOMEM;
329 feed_stereotomono8_free(struct pcm_feeder *f)
332 free(f->data, M_FMTFEEDER);
338 feed_stereotomono8(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
340 u_int32_t i = 0, toget = count * 2;
343 k = FEEDER_FEED(f->source, c, f->data, min(toget, FEEDBUFSZ), source);
345 b[i++] = ((u_int8_t *)f->data)[j];
351 static struct pcm_feederdesc feeder_stereotomono8_desc[] = {
352 {FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_U8, 0},
353 {FEEDER_FMT, AFMT_S8 | AFMT_STEREO, AFMT_S8, 0},
356 static kobj_method_t feeder_stereotomono8_methods[] = {
357 KOBJMETHOD(feeder_init, feed_stereotomono8_init),
358 KOBJMETHOD(feeder_free, feed_stereotomono8_free),
359 KOBJMETHOD(feeder_feed, feed_stereotomono8),
362 FEEDER_DECLARE(feeder_stereotomono8, 1, NULL);
364 /*****************************************************************************/
367 feed_stereotomono16_init(struct pcm_feeder *f)
369 f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_WAITOK | M_ZERO);
370 return (f->data)? 0 : ENOMEM;
374 feed_stereotomono16_free(struct pcm_feeder *f)
377 free(f->data, M_FMTFEEDER);
383 feed_stereotomono16(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
385 u_int32_t i = 0, toget = count * 2;
388 k = FEEDER_FEED(f->source, c, f->data, min(toget, FEEDBUFSZ), source);
390 b[i++] = ((u_int8_t *)f->data)[j];
391 b[i++] = ((u_int8_t *)f->data)[j + 1];
397 static struct pcm_feederdesc feeder_stereotomono16_desc[] = {
398 {FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_U16_LE, 0},
399 {FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_S16_LE, 0},
400 {FEEDER_FMT, AFMT_U16_BE | AFMT_STEREO, AFMT_U16_BE, 0},
401 {FEEDER_FMT, AFMT_S16_BE | AFMT_STEREO, AFMT_S16_BE, 0},
404 static kobj_method_t feeder_stereotomono16_methods[] = {
405 KOBJMETHOD(feeder_init, feed_stereotomono16_init),
406 KOBJMETHOD(feeder_free, feed_stereotomono16_free),
407 KOBJMETHOD(feeder_feed, feed_stereotomono16),
410 FEEDER_DECLARE(feeder_stereotomono16, 1, NULL);
412 /*****************************************************************************/
415 feed_endian(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
418 int i = 0, j = FEEDER_FEED(f->source, c, b, count, source);
429 static struct pcm_feederdesc feeder_endian_desc[] = {
430 {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_BE, 0},
431 {FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_U16_BE | AFMT_STEREO, 0},
432 {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_BE, 0},
433 {FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_S16_BE | AFMT_STEREO, 0},
434 {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_LE, 0},
435 {FEEDER_FMT, AFMT_U16_BE | AFMT_STEREO, AFMT_U16_LE | AFMT_STEREO, 0},
436 {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_LE, 0},
437 {FEEDER_FMT, AFMT_S16_BE | AFMT_STEREO, AFMT_S16_LE | AFMT_STEREO, 0},
440 static kobj_method_t feeder_endian_methods[] = {
441 KOBJMETHOD(feeder_feed, feed_endian),
444 FEEDER_DECLARE(feeder_endian, 0, NULL);
446 /*****************************************************************************/
449 feed_sign(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
451 int i = 0, j = FEEDER_FEED(f->source, c, b, count, source);
452 intptr_t ssz = (intptr_t)f->data, ofs = ssz - 1;
461 static struct pcm_feederdesc feeder_sign8_desc[] = {
462 {FEEDER_FMT, AFMT_U8, AFMT_S8, 0},
463 {FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_S8 | AFMT_STEREO, 0},
464 {FEEDER_FMT, AFMT_S8, AFMT_U8, 0},
465 {FEEDER_FMT, AFMT_S8 | AFMT_STEREO, AFMT_U8 | AFMT_STEREO, 0},
468 static kobj_method_t feeder_sign8_methods[] = {
469 KOBJMETHOD(feeder_feed, feed_sign),
472 FEEDER_DECLARE(feeder_sign8, 0, (void *)1);
474 static struct pcm_feederdesc feeder_sign16le_desc[] = {
475 {FEEDER_FMT, AFMT_U16_LE, AFMT_S16_LE, 0},
476 {FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_S16_LE | AFMT_STEREO, 0},
477 {FEEDER_FMT, AFMT_S16_LE, AFMT_U16_LE, 0},
478 {FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_U16_LE | AFMT_STEREO, 0},
481 static kobj_method_t feeder_sign16le_methods[] = {
482 KOBJMETHOD(feeder_feed, feed_sign),
485 FEEDER_DECLARE(feeder_sign16le, -1, (void *)2);
487 /*****************************************************************************/
490 feed_table(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
492 int i = 0, j = FEEDER_FEED(f->source, c, b, count, source);
495 b[i] = ((u_int8_t *)f->data)[b[i]];
501 static struct pcm_feederdesc feeder_ulawtou8_desc[] = {
502 {FEEDER_FMT, AFMT_MU_LAW, AFMT_U8, 0},
503 {FEEDER_FMT, AFMT_MU_LAW | AFMT_STEREO, AFMT_U8 | AFMT_STEREO, 0},
506 static kobj_method_t feeder_ulawtou8_methods[] = {
507 KOBJMETHOD(feeder_feed, feed_table),
510 FEEDER_DECLARE(feeder_ulawtou8, 0, ulaw_to_u8);
512 static struct pcm_feederdesc feeder_u8toulaw_desc[] = {
513 {FEEDER_FMT, AFMT_U8, AFMT_MU_LAW, 0},
514 {FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_MU_LAW | AFMT_STEREO, 0},
517 static kobj_method_t feeder_u8toulaw_methods[] = {
518 KOBJMETHOD(feeder_feed, feed_table),
521 FEEDER_DECLARE(feeder_u8toulaw, 0, u8_to_ulaw);
523 static struct pcm_feederdesc feeder_alawtoulaw_desc[] = {
524 {FEEDER_FMT, AFMT_A_LAW, AFMT_MU_LAW, 0},
525 {FEEDER_FMT, AFMT_A_LAW | AFMT_STEREO, AFMT_MU_LAW | AFMT_STEREO, 0},
528 static kobj_method_t feeder_alawtoulaw_methods[] = {
529 KOBJMETHOD(feeder_feed, feed_table),
532 FEEDER_DECLARE(feeder_alawtoulaw, 0, alaw_to_ulaw);
534 static struct pcm_feederdesc feeder_ulawtoalaw_desc[] = {
535 {FEEDER_FMT, AFMT_MU_LAW, AFMT_A_LAW, 0},
536 {FEEDER_FMT, AFMT_MU_LAW | AFMT_STEREO, AFMT_A_LAW | AFMT_STEREO, 0},
539 static kobj_method_t feeder_ulawtoalaw_methods[] = {
540 KOBJMETHOD(feeder_feed, feed_table),
543 FEEDER_DECLARE(feeder_ulawtoalaw, 0, ulaw_to_alaw);