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
27 #include <dev/sound/pcm/sound.h>
29 #include "feeder_if.h"
31 SND_DECLARE_FILE("$FreeBSD: src/sys/dev/sound/pcm/feeder_fmt.c,v 1.1.2.5 2002/04/22 15:49:36 cg Exp $");
33 MALLOC_DEFINE(M_FMTFEEDER, "fmtfeed", "pcm format feeder");
35 #define FEEDBUFSZ 8192
37 static unsigned char ulaw_to_u8[] = {
38 3, 7, 11, 15, 19, 23, 27, 31,
39 35, 39, 43, 47, 51, 55, 59, 63,
40 66, 68, 70, 72, 74, 76, 78, 80,
41 82, 84, 86, 88, 90, 92, 94, 96,
42 98, 99, 100, 101, 102, 103, 104, 105,
43 106, 107, 108, 109, 110, 111, 112, 113,
44 113, 114, 114, 115, 115, 116, 116, 117,
45 117, 118, 118, 119, 119, 120, 120, 121,
46 121, 121, 122, 122, 122, 122, 123, 123,
47 123, 123, 124, 124, 124, 124, 125, 125,
48 125, 125, 125, 125, 126, 126, 126, 126,
49 126, 126, 126, 126, 127, 127, 127, 127,
50 127, 127, 127, 127, 127, 127, 127, 127,
51 128, 128, 128, 128, 128, 128, 128, 128,
52 128, 128, 128, 128, 128, 128, 128, 128,
53 128, 128, 128, 128, 128, 128, 128, 128,
54 253, 249, 245, 241, 237, 233, 229, 225,
55 221, 217, 213, 209, 205, 201, 197, 193,
56 190, 188, 186, 184, 182, 180, 178, 176,
57 174, 172, 170, 168, 166, 164, 162, 160,
58 158, 157, 156, 155, 154, 153, 152, 151,
59 150, 149, 148, 147, 146, 145, 144, 143,
60 143, 142, 142, 141, 141, 140, 140, 139,
61 139, 138, 138, 137, 137, 136, 136, 135,
62 135, 135, 134, 134, 134, 134, 133, 133,
63 133, 133, 132, 132, 132, 132, 131, 131,
64 131, 131, 131, 131, 130, 130, 130, 130,
65 130, 130, 130, 130, 129, 129, 129, 129,
66 129, 129, 129, 129, 129, 129, 129, 129,
67 128, 128, 128, 128, 128, 128, 128, 128,
68 128, 128, 128, 128, 128, 128, 128, 128,
69 128, 128, 128, 128, 128, 128, 128, 128,
72 static unsigned char u8_to_ulaw[] = {
73 0, 0, 0, 0, 0, 1, 1, 1,
74 1, 2, 2, 2, 2, 3, 3, 3,
75 3, 4, 4, 4, 4, 5, 5, 5,
76 5, 6, 6, 6, 6, 7, 7, 7,
77 7, 8, 8, 8, 8, 9, 9, 9,
78 9, 10, 10, 10, 10, 11, 11, 11,
79 11, 12, 12, 12, 12, 13, 13, 13,
80 13, 14, 14, 14, 14, 15, 15, 15,
81 15, 16, 16, 17, 17, 18, 18, 19,
82 19, 20, 20, 21, 21, 22, 22, 23,
83 23, 24, 24, 25, 25, 26, 26, 27,
84 27, 28, 28, 29, 29, 30, 30, 31,
85 31, 32, 33, 34, 35, 36, 37, 38,
86 39, 40, 41, 42, 43, 44, 45, 46,
87 47, 49, 51, 53, 55, 57, 59, 61,
88 63, 66, 70, 74, 78, 84, 92, 104,
89 254, 231, 219, 211, 205, 201, 197, 193,
90 190, 188, 186, 184, 182, 180, 178, 176,
91 175, 174, 173, 172, 171, 170, 169, 168,
92 167, 166, 165, 164, 163, 162, 161, 160,
93 159, 159, 158, 158, 157, 157, 156, 156,
94 155, 155, 154, 154, 153, 153, 152, 152,
95 151, 151, 150, 150, 149, 149, 148, 148,
96 147, 147, 146, 146, 145, 145, 144, 144,
97 143, 143, 143, 143, 142, 142, 142, 142,
98 141, 141, 141, 141, 140, 140, 140, 140,
99 139, 139, 139, 139, 138, 138, 138, 138,
100 137, 137, 137, 137, 136, 136, 136, 136,
101 135, 135, 135, 135, 134, 134, 134, 134,
102 133, 133, 133, 133, 132, 132, 132, 132,
103 131, 131, 131, 131, 130, 130, 130, 130,
104 129, 129, 129, 129, 128, 128, 128, 128,
107 static unsigned char alaw_to_ulaw[] = {
108 42, 43, 40, 41, 46, 47, 44, 45,
109 34, 35, 32, 33, 38, 39, 36, 37,
110 57, 58, 55, 56, 61, 62, 59, 60,
111 49, 50, 48, 48, 53, 54, 51, 52,
112 10, 11, 8, 9, 14, 15, 12, 13,
113 2, 3, 0, 1, 6, 7, 4, 5,
114 26, 27, 24, 25, 30, 31, 28, 29,
115 18, 19, 16, 17, 22, 23, 20, 21,
116 98, 99, 96, 97, 102, 103, 100, 101,
117 93, 93, 92, 92, 95, 95, 94, 94,
118 116, 118, 112, 114, 124, 126, 120, 122,
119 106, 107, 104, 105, 110, 111, 108, 109,
120 72, 73, 70, 71, 76, 77, 74, 75,
121 64, 65, 63, 63, 68, 69, 66, 67,
122 86, 87, 84, 85, 90, 91, 88, 89,
123 79, 79, 78, 78, 82, 83, 80, 81,
124 170, 171, 168, 169, 174, 175, 172, 173,
125 162, 163, 160, 161, 166, 167, 164, 165,
126 185, 186, 183, 184, 189, 190, 187, 188,
127 177, 178, 176, 176, 181, 182, 179, 180,
128 138, 139, 136, 137, 142, 143, 140, 141,
129 130, 131, 128, 129, 134, 135, 132, 133,
130 154, 155, 152, 153, 158, 159, 156, 157,
131 146, 147, 144, 145, 150, 151, 148, 149,
132 226, 227, 224, 225, 230, 231, 228, 229,
133 221, 221, 220, 220, 223, 223, 222, 222,
134 244, 246, 240, 242, 252, 254, 248, 250,
135 234, 235, 232, 233, 238, 239, 236, 237,
136 200, 201, 198, 199, 204, 205, 202, 203,
137 192, 193, 191, 191, 196, 197, 194, 195,
138 214, 215, 212, 213, 218, 219, 216, 217,
139 207, 207, 206, 206, 210, 211, 208, 209,
142 static unsigned char ulaw_to_alaw[] = {
143 42, 43, 40, 41, 46, 47, 44, 45,
144 34, 35, 32, 33, 38, 39, 36, 37,
145 58, 59, 56, 57, 62, 63, 60, 61,
146 50, 51, 48, 49, 54, 55, 52, 53,
147 10, 11, 8, 9, 14, 15, 12, 13,
148 2, 3, 0, 1, 6, 7, 4, 5,
149 27, 24, 25, 30, 31, 28, 29, 18,
150 19, 16, 17, 22, 23, 20, 21, 106,
151 104, 105, 110, 111, 108, 109, 98, 99,
152 96, 97, 102, 103, 100, 101, 122, 120,
153 126, 127, 124, 125, 114, 115, 112, 113,
154 118, 119, 116, 117, 75, 73, 79, 77,
155 66, 67, 64, 65, 70, 71, 68, 69,
156 90, 91, 88, 89, 94, 95, 92, 93,
157 82, 82, 83, 83, 80, 80, 81, 81,
158 86, 86, 87, 87, 84, 84, 85, 85,
159 170, 171, 168, 169, 174, 175, 172, 173,
160 162, 163, 160, 161, 166, 167, 164, 165,
161 186, 187, 184, 185, 190, 191, 188, 189,
162 178, 179, 176, 177, 182, 183, 180, 181,
163 138, 139, 136, 137, 142, 143, 140, 141,
164 130, 131, 128, 129, 134, 135, 132, 133,
165 155, 152, 153, 158, 159, 156, 157, 146,
166 147, 144, 145, 150, 151, 148, 149, 234,
167 232, 233, 238, 239, 236, 237, 226, 227,
168 224, 225, 230, 231, 228, 229, 250, 248,
169 254, 255, 252, 253, 242, 243, 240, 241,
170 246, 247, 244, 245, 203, 201, 207, 205,
171 194, 195, 192, 193, 198, 199, 196, 197,
172 218, 219, 216, 217, 222, 223, 220, 221,
173 210, 210, 211, 211, 208, 208, 209, 209,
174 214, 214, 215, 215, 212, 212, 213, 213,
177 /*****************************************************************************/
180 feed_8to16le(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
184 k = FEEDER_FEED(f->source, c, b, count / 2, source);
187 while (i > 0 && j >= 0) {
194 static struct pcm_feederdesc feeder_8to16le_desc[] = {
195 {FEEDER_FMT, AFMT_U8, AFMT_U16_LE, 0},
196 {FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_U16_LE | AFMT_STEREO, 0},
197 {FEEDER_FMT, AFMT_S8, AFMT_S16_LE, 0},
198 {FEEDER_FMT, AFMT_S8 | AFMT_STEREO, AFMT_S16_LE | AFMT_STEREO, 0},
201 static kobj_method_t feeder_8to16le_methods[] = {
202 KOBJMETHOD(feeder_feed, feed_8to16le),
205 FEEDER_DECLARE(feeder_8to16le, 0, NULL);
207 /*****************************************************************************/
210 feed_16to8_init(struct pcm_feeder *f)
212 f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_WAITOK | M_ZERO);
213 return (f->data)? 0 : ENOMEM;
217 feed_16to8_free(struct pcm_feeder *f)
220 free(f->data, M_FMTFEEDER);
226 feed_16leto8(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
228 u_int32_t i = 0, toget = count * 2;
231 k = FEEDER_FEED(f->source, c, f->data, min(toget, FEEDBUFSZ), source);
233 b[i++] = ((u_int8_t *)f->data)[j];
239 static struct pcm_feederdesc feeder_16leto8_desc[] = {
240 {FEEDER_FMT, AFMT_U16_LE, AFMT_U8, 0},
241 {FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_U8 | AFMT_STEREO, 0},
242 {FEEDER_FMT, AFMT_S16_LE, AFMT_S8, 0},
243 {FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_S8 | AFMT_STEREO, 0},
246 static kobj_method_t feeder_16leto8_methods[] = {
247 KOBJMETHOD(feeder_init, feed_16to8_init),
248 KOBJMETHOD(feeder_free, feed_16to8_free),
249 KOBJMETHOD(feeder_feed, feed_16leto8),
252 FEEDER_DECLARE(feeder_16leto8, 1, NULL);
254 /*****************************************************************************/
257 feed_monotostereo8(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
259 int i, j, k = FEEDER_FEED(f->source, c, b, count / 2, source);
263 while (i > 0 && j >= 0) {
271 static struct pcm_feederdesc feeder_monotostereo8_desc[] = {
272 {FEEDER_FMT, AFMT_U8, AFMT_U8 | AFMT_STEREO, 0},
273 {FEEDER_FMT, AFMT_S8, AFMT_S8 | AFMT_STEREO, 0},
276 static kobj_method_t feeder_monotostereo8_methods[] = {
277 KOBJMETHOD(feeder_feed, feed_monotostereo8),
280 FEEDER_DECLARE(feeder_monotostereo8, 0, NULL);
282 /*****************************************************************************/
285 feed_monotostereo16(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
287 int i, j, k = FEEDER_FEED(f->source, c, b, count / 2, source);
292 while (i > 3 && j >= 1) {
303 static struct pcm_feederdesc feeder_monotostereo16_desc[] = {
304 {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_LE | AFMT_STEREO, 0},
305 {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_LE | AFMT_STEREO, 0},
306 {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_BE | AFMT_STEREO, 0},
307 {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_BE | AFMT_STEREO, 0},
310 static kobj_method_t feeder_monotostereo16_methods[] = {
311 KOBJMETHOD(feeder_feed, feed_monotostereo16),
314 FEEDER_DECLARE(feeder_monotostereo16, 0, NULL);
316 /*****************************************************************************/
319 feed_stereotomono8_init(struct pcm_feeder *f)
321 f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_WAITOK | M_ZERO);
322 return (f->data)? 0 : ENOMEM;
326 feed_stereotomono8_free(struct pcm_feeder *f)
329 free(f->data, M_FMTFEEDER);
335 feed_stereotomono8(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
337 u_int32_t i = 0, toget = count * 2;
340 k = FEEDER_FEED(f->source, c, f->data, min(toget, FEEDBUFSZ), source);
342 b[i++] = ((u_int8_t *)f->data)[j];
348 static struct pcm_feederdesc feeder_stereotomono8_desc[] = {
349 {FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_U8, 0},
350 {FEEDER_FMT, AFMT_S8 | AFMT_STEREO, AFMT_S8, 0},
353 static kobj_method_t feeder_stereotomono8_methods[] = {
354 KOBJMETHOD(feeder_init, feed_stereotomono8_init),
355 KOBJMETHOD(feeder_free, feed_stereotomono8_free),
356 KOBJMETHOD(feeder_feed, feed_stereotomono8),
359 FEEDER_DECLARE(feeder_stereotomono8, 1, NULL);
361 /*****************************************************************************/
364 feed_stereotomono16_init(struct pcm_feeder *f)
366 f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_WAITOK | M_ZERO);
367 return (f->data)? 0 : ENOMEM;
371 feed_stereotomono16_free(struct pcm_feeder *f)
374 free(f->data, M_FMTFEEDER);
380 feed_stereotomono16(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
382 u_int32_t i = 0, toget = count * 2;
385 k = FEEDER_FEED(f->source, c, f->data, min(toget, FEEDBUFSZ), source);
387 b[i++] = ((u_int8_t *)f->data)[j];
388 b[i++] = ((u_int8_t *)f->data)[j + 1];
394 static struct pcm_feederdesc feeder_stereotomono16_desc[] = {
395 {FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_U16_LE, 0},
396 {FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_S16_LE, 0},
397 {FEEDER_FMT, AFMT_U16_BE | AFMT_STEREO, AFMT_U16_BE, 0},
398 {FEEDER_FMT, AFMT_S16_BE | AFMT_STEREO, AFMT_S16_BE, 0},
401 static kobj_method_t feeder_stereotomono16_methods[] = {
402 KOBJMETHOD(feeder_init, feed_stereotomono16_init),
403 KOBJMETHOD(feeder_free, feed_stereotomono16_free),
404 KOBJMETHOD(feeder_feed, feed_stereotomono16),
407 FEEDER_DECLARE(feeder_stereotomono16, 1, NULL);
409 /*****************************************************************************/
412 feed_endian(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
415 int i = 0, j = FEEDER_FEED(f->source, c, b, count, source);
426 static struct pcm_feederdesc feeder_endian_desc[] = {
427 {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_BE, 0},
428 {FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_U16_BE | AFMT_STEREO, 0},
429 {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_BE, 0},
430 {FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_S16_BE | AFMT_STEREO, 0},
431 {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_LE, 0},
432 {FEEDER_FMT, AFMT_U16_BE | AFMT_STEREO, AFMT_U16_LE | AFMT_STEREO, 0},
433 {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_LE, 0},
434 {FEEDER_FMT, AFMT_S16_BE | AFMT_STEREO, AFMT_S16_LE | AFMT_STEREO, 0},
437 static kobj_method_t feeder_endian_methods[] = {
438 KOBJMETHOD(feeder_feed, feed_endian),
441 FEEDER_DECLARE(feeder_endian, 0, NULL);
443 /*****************************************************************************/
446 feed_sign(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
448 int i = 0, j = FEEDER_FEED(f->source, c, b, count, source);
449 intptr_t ssz = (intptr_t)f->data, ofs = ssz - 1;
458 static struct pcm_feederdesc feeder_sign8_desc[] = {
459 {FEEDER_FMT, AFMT_U8, AFMT_S8, 0},
460 {FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_S8 | AFMT_STEREO, 0},
461 {FEEDER_FMT, AFMT_S8, AFMT_U8, 0},
462 {FEEDER_FMT, AFMT_S8 | AFMT_STEREO, AFMT_U8 | AFMT_STEREO, 0},
465 static kobj_method_t feeder_sign8_methods[] = {
466 KOBJMETHOD(feeder_feed, feed_sign),
469 FEEDER_DECLARE(feeder_sign8, 0, (void *)1);
471 static struct pcm_feederdesc feeder_sign16le_desc[] = {
472 {FEEDER_FMT, AFMT_U16_LE, AFMT_S16_LE, 0},
473 {FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_S16_LE | AFMT_STEREO, 0},
474 {FEEDER_FMT, AFMT_S16_LE, AFMT_U16_LE, 0},
475 {FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_U16_LE | AFMT_STEREO, 0},
478 static kobj_method_t feeder_sign16le_methods[] = {
479 KOBJMETHOD(feeder_feed, feed_sign),
482 FEEDER_DECLARE(feeder_sign16le, -1, (void *)2);
484 /*****************************************************************************/
487 feed_table(struct pcm_feeder *f, struct pcm_channel *c, u_int8_t *b, u_int32_t count, void *source)
489 int i = 0, j = FEEDER_FEED(f->source, c, b, count, source);
492 b[i] = ((u_int8_t *)f->data)[b[i]];
498 static struct pcm_feederdesc feeder_ulawtou8_desc[] = {
499 {FEEDER_FMT, AFMT_MU_LAW, AFMT_U8, 0},
500 {FEEDER_FMT, AFMT_MU_LAW | AFMT_STEREO, AFMT_U8 | AFMT_STEREO, 0},
503 static kobj_method_t feeder_ulawtou8_methods[] = {
504 KOBJMETHOD(feeder_feed, feed_table),
507 FEEDER_DECLARE(feeder_ulawtou8, 0, ulaw_to_u8);
509 static struct pcm_feederdesc feeder_u8toulaw_desc[] = {
510 {FEEDER_FMT, AFMT_U8, AFMT_MU_LAW, 0},
511 {FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_MU_LAW | AFMT_STEREO, 0},
514 static kobj_method_t feeder_u8toulaw_methods[] = {
515 KOBJMETHOD(feeder_feed, feed_table),
518 FEEDER_DECLARE(feeder_u8toulaw, 0, u8_to_ulaw);
520 static struct pcm_feederdesc feeder_alawtoulaw_desc[] = {
521 {FEEDER_FMT, AFMT_A_LAW, AFMT_MU_LAW, 0},
522 {FEEDER_FMT, AFMT_A_LAW | AFMT_STEREO, AFMT_MU_LAW | AFMT_STEREO, 0},
525 static kobj_method_t feeder_alawtoulaw_methods[] = {
526 KOBJMETHOD(feeder_feed, feed_table),
529 FEEDER_DECLARE(feeder_alawtoulaw, 0, alaw_to_ulaw);
531 static struct pcm_feederdesc feeder_ulawtoalaw_desc[] = {
532 {FEEDER_FMT, AFMT_MU_LAW, AFMT_A_LAW, 0},
533 {FEEDER_FMT, AFMT_MU_LAW | AFMT_STEREO, AFMT_A_LAW | AFMT_STEREO, 0},
536 static kobj_method_t feeder_ulawtoalaw_methods[] = {
537 KOBJMETHOD(feeder_feed, feed_table),
540 FEEDER_DECLARE(feeder_ulawtoalaw, 0, ulaw_to_alaw);