diff --git a/lib/libc/sys/modfind.2 b/lib/libc/sys/modfind.2 new file mode 100644 index 000000000000..8e83d9a25a53 --- /dev/null +++ b/lib/libc/sys/modfind.2 @@ -0,0 +1,79 @@ +.\" +.\" Copyright (c) 1999 Chris Costello +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd September 28, 2000 +.Dt MODFIND 2 +.Os FreeBSD +.Sh NAME +.Nm modfind +.Nd returns the modid of a kernel module +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.Fd #include +.Fd #include +.Ft int +.Fn modfind "const char *modname" +.Sh DESCRIPTION +The function +.Fn modfind +returns the modid of the kernel module referenced by +.Fa modname . +.Sh RETURN VALUES +.Fn modfind +returns the modid of the kernel module referenced by +.Fa file . +Upon error, +.Fn modfind +returns -1 and sets +.Va errno +to indicate the error. +.Sh ERRORS +.Va errno +is set to the following if +.Fn modfind +fails: +.Bl -tag -width Er +.It Bq Er EFAULT +The data required for this operation could not be read from the kernel space. +.It Bq Er ENOENT +The file specified is not loaded in the kernel. +.Sh SEE ALSO +.Xr kldfirstmod 2 , +.Xr kldload 2 , +.Xr kldnext 2 , +.Xr kldstat 2 , +.Xr kldunload 2 , +.Xr modnext 2 , +.Xr modfnext 2 , +.Xr modstat 2 , +.Xr kld 4 +.Sh HISTORY +The +.Nm kld +interface first appeared in +.Fx 3.0 . diff --git a/lib/libc/sys/modnext.2 b/lib/libc/sys/modnext.2 new file mode 100644 index 000000000000..2e301f82e8ad --- /dev/null +++ b/lib/libc/sys/modnext.2 @@ -0,0 +1,84 @@ +.\" +.\" Copyright (c) 1999 Chris Costello +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd September 28, 2000 +.Dt MODNEXT 2 +.Os FreeBSD +.Sh NAME +.Nm modnext +.Nd return the modid of the next kernel module +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.Fd #include +.Fd #include +.Ft int +.Fn modnext "int modid" +.Ft int +.Fn modfnext "int modid" +.Sh DESCRIPTION +The function +.Fn modnext +returns the modid of the next kernel module (that is, the one after +.Va modid ) +or 0 if +.Va modid +is the last module in the list. +.Pp +If the +.Va modid +value is 0, then +.Fn modnext +will return the modid of the first module. +.Fn modfnext +must always be given a valid modid. +.Sh RETURN VALUES +.Fn modnext +returns the modid of the next module (see DESCRIPTION) or 0. If an error +occurs, +.Va errno +is set to indicate the error. +.Sh ERRORS +The only error set by +.Fn modnext +is ENOENT, which is set when +.Va modid +refers to a kernel module that does not exist (isn't loaded). +.Sh SEE ALSO +.Xr kldfind 2 , +.Xr kldfirstmod 2 , +.Xr kldload 2 , +.Xr kldstat 2 , +.Xr kldunload 2 , +.Xr modfind 2 , +.Xr modstat 2 , +.Xr kld 4 +.Sh HISTORY +The +.Nm kld +interface first appeared in +.Fx 3.0 . diff --git a/lib/libc/sys/modstat.2 b/lib/libc/sys/modstat.2 new file mode 100644 index 000000000000..e02279a08e44 --- /dev/null +++ b/lib/libc/sys/modstat.2 @@ -0,0 +1,124 @@ +.\" +.\" Copyright (c) 1999 Chris Costello +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd September 28, 2000 +.Dt MODSTAT 2 +.Os FreeBSD +.Sh NAME +.Nm kldstat +.Nd get status of kernel module +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.Fd #include +.Fd #include +.Ft int +.Fn modstat "int modid" "struct module_stat *stat" +.Sh DESCRIPTION +The +.Fn modstat +function writes the info for the kernel module referred to by +.Fa modid +into +.Fa stat . +.Bd -literal +struct module_stat { + int version; /* set to sizeof(module_stat) */ + char name[MAXPATHLEN]; + int refs; + int id; + modspecific_t data; +}; +typedef union modspecific { + int intval; + u_int u_intval; + long longval; + u_long u_longval; +} modspecific_t; +.Ed +.Pp +.Bl -tag -width XXXaddress +.It version +This field is set to the size of the structure mentioned above by the code +calling +.Fn modstat , +and not +.Fn modstat +itself. +.It name +The name of the module referred to by +.Fa modid . +.It refs +The number of modules referenced by +.Fa modid . +.It id +The id of the module specified in +.Fa modid . +.It data +Module specific data. +.Sh RETURN VALUES +.Fn modstat +seems to always return 0. +.Sh ERRORS +The information for the module referred to by +.Fa modid +is filled into the structure pointed to by +.Fa stat +unless: +.Bl -tag -width Er +.It Bq Er ENOENT +The module was not found (probably not loaded). +.It Bq Er EINVAL +The version specified in the +.Fa version +field of stat is not the proper version. You would need to rebuild world, the +kernel, or your application, if this error occurs, given that you did properly +fill in the +.Fa version +field. +.It Bq Er EFAULT +There was a problem copying one, some, or all of the fields into +.Fa stat +in the +.Fn copyout +function. +.Sh SEE ALSO +.Xr kldfind 2 , +.Xr kldfirstmod 2 , +.Xr kldload 2 , +.Xr kldnext 2 , +.Xr kldunload 2 , +.Xr modnext 2 , +.Xr modfind 2 , +.Xr modfnext 2 , +.Xr kld 4 , +.Xr kldstat 8 +.Sh HISTORY +The +.Nm kld +interface first appeared in +.Fx 3.0 . diff --git a/sys/dev/sound/pcm/feeder.h b/sys/dev/sound/pcm/feeder.h new file mode 100644 index 000000000000..40f866c5ee06 --- /dev/null +++ b/sys/dev/sound/pcm/feeder.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 1999 Cameron Grant + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +void feeder_register(void *p); +pcm_feeder *feeder_get(struct pcm_feederdesc *desc); +pcm_feeder *feeder_getroot(void); +int feeder_set(pcm_feeder *feeder, int what, int value); + +u_int32_t chn_fmtchain(pcm_channel *c, u_int32_t *to); +int chn_addfeeder(pcm_channel *c, pcm_feeder *f); +int chn_removefeeder(pcm_channel *c); +pcm_feeder *chn_findfeeder(pcm_channel *c, u_int32_t type); + +#define FEEDER_DECLARE(feeder) SYSINIT(feeder, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register, &feeder) + +#define FEEDER_ROOT 1 +#define FEEDER_FMT 2 +#define FEEDER_RATE 3 +#define FEEDER_FILTER 4 +#define FEEDER_VOLUME 5 +#define FEEDER_LAST FEEDER_VOLUME + +#define FEEDRATE_SRC 1 +#define FEEDRATE_DST 2 + + diff --git a/sys/dev/sound/pcm/feeder_fmt.c b/sys/dev/sound/pcm/feeder_fmt.c new file mode 100644 index 000000000000..e056da625b76 --- /dev/null +++ b/sys/dev/sound/pcm/feeder_fmt.c @@ -0,0 +1,496 @@ +/* + * Copyright (c) 1999 Cameron Grant + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include + +#define FEEDBUFSZ 8192 + +static unsigned char ulaw_to_u8[] = { + 3, 7, 11, 15, 19, 23, 27, 31, + 35, 39, 43, 47, 51, 55, 59, 63, + 66, 68, 70, 72, 74, 76, 78, 80, + 82, 84, 86, 88, 90, 92, 94, 96, + 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, + 113, 114, 114, 115, 115, 116, 116, 117, + 117, 118, 118, 119, 119, 120, 120, 121, + 121, 121, 122, 122, 122, 122, 123, 123, + 123, 123, 124, 124, 124, 124, 125, 125, + 125, 125, 125, 125, 126, 126, 126, 126, + 126, 126, 126, 126, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 253, 249, 245, 241, 237, 233, 229, 225, + 221, 217, 213, 209, 205, 201, 197, 193, + 190, 188, 186, 184, 182, 180, 178, 176, + 174, 172, 170, 168, 166, 164, 162, 160, + 158, 157, 156, 155, 154, 153, 152, 151, + 150, 149, 148, 147, 146, 145, 144, 143, + 143, 142, 142, 141, 141, 140, 140, 139, + 139, 138, 138, 137, 137, 136, 136, 135, + 135, 135, 134, 134, 134, 134, 133, 133, + 133, 133, 132, 132, 132, 132, 131, 131, + 131, 131, 131, 131, 130, 130, 130, 130, + 130, 130, 130, 130, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, +}; + +static unsigned char u8_to_ulaw[] = { + 0, 0, 0, 0, 0, 1, 1, 1, + 1, 2, 2, 2, 2, 3, 3, 3, + 3, 4, 4, 4, 4, 5, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 10, 11, 11, 11, + 11, 12, 12, 12, 12, 13, 13, 13, + 13, 14, 14, 14, 14, 15, 15, 15, + 15, 16, 16, 17, 17, 18, 18, 19, + 19, 20, 20, 21, 21, 22, 22, 23, + 23, 24, 24, 25, 25, 26, 26, 27, + 27, 28, 28, 29, 29, 30, 30, 31, + 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, + 47, 49, 51, 53, 55, 57, 59, 61, + 63, 66, 70, 74, 78, 84, 92, 104, + 254, 231, 219, 211, 205, 201, 197, 193, + 190, 188, 186, 184, 182, 180, 178, 176, + 175, 174, 173, 172, 171, 170, 169, 168, + 167, 166, 165, 164, 163, 162, 161, 160, + 159, 159, 158, 158, 157, 157, 156, 156, + 155, 155, 154, 154, 153, 153, 152, 152, + 151, 151, 150, 150, 149, 149, 148, 148, + 147, 147, 146, 146, 145, 145, 144, 144, + 143, 143, 143, 143, 142, 142, 142, 142, + 141, 141, 141, 141, 140, 140, 140, 140, + 139, 139, 139, 139, 138, 138, 138, 138, + 137, 137, 137, 137, 136, 136, 136, 136, + 135, 135, 135, 135, 134, 134, 134, 134, + 133, 133, 133, 133, 132, 132, 132, 132, + 131, 131, 131, 131, 130, 130, 130, 130, + 129, 129, 129, 129, 128, 128, 128, 128, +}; + +/*****************************************************************************/ + +static int +feed_8to16le(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream) +{ + int i, j, k; + + k = f->source->feed(f->source, c, b, count / 2, stream); + j = k - 1; + i = j * 2 + 1; + while (i > 0 && j >= 0) { + b[i--] = b[j--]; + b[i--] = 0; + } + return k * 2; +} + +static struct pcm_feederdesc desc_8to16le[] = { + {FEEDER_FMT, AFMT_U8, AFMT_U16_LE, 0}, + {FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_U16_LE | AFMT_STEREO, 0}, + {FEEDER_FMT, AFMT_S8, AFMT_S16_LE, 0}, + {FEEDER_FMT, AFMT_S8 | AFMT_STEREO, AFMT_S16_LE | AFMT_STEREO, 0}, + {0}, +}; +static pcm_feeder feeder_8to16le = { + "8to16le", + 0, + desc_8to16le, + NULL, + NULL, + NULL, + feed_8to16le, +}; +FEEDER_DECLARE(feeder_8to16le); + +/*****************************************************************************/ + +static int +feed_16to8_init(pcm_feeder *f) +{ + f->data = malloc(FEEDBUFSZ, M_DEVBUF, M_NOWAIT); + return (f->data == NULL); +} + +static int +feed_16to8_free(pcm_feeder *f) +{ + if (f->data) free(f->data, M_DEVBUF); + f->data = NULL; + return 0; +} + +static int +feed_16leto8(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream) +{ + u_int32_t i = 0, toget = count * 2; + int j = 1, k; + + k = f->source->feed(f->source, c, f->data, min(toget, FEEDBUFSZ), stream); + while (j < k) { + b[i++] = ((u_int8_t *)f->data)[j]; + j += 2; + } + return i; +} + +static struct pcm_feederdesc desc_16leto8[] = { + {FEEDER_FMT, AFMT_U16_LE, AFMT_U8, 0}, + {FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_U8 | AFMT_STEREO, 0}, + {FEEDER_FMT, AFMT_S16_LE, AFMT_S8, 0}, + {FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_S8 | AFMT_STEREO, 0}, + {0}, +}; +static pcm_feeder feeder_16leto8 = { + "16leto8", + 1, + desc_16leto8, + feed_16to8_init, + feed_16to8_free, + NULL, + feed_16leto8, +}; +FEEDER_DECLARE(feeder_16leto8); + +/*****************************************************************************/ + +static int +feed_monotostereo8(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream) +{ + int i, j, k = f->source->feed(f->source, c, b, count / 2, stream); + + j = k - 1; + i = j * 2 + 1; + while (i > 0 && j >= 0) { + b[i--] = b[j]; + b[i--] = b[j]; + j--; + } + return k * 2; +} + +static struct pcm_feederdesc desc_monotostereo8[] = { + {FEEDER_FMT, AFMT_U8, AFMT_U8 | AFMT_STEREO, 0}, + {FEEDER_FMT, AFMT_S8, AFMT_S8 | AFMT_STEREO, 0}, + {0}, +}; +static pcm_feeder feeder_monotostereo8 = { + "monotostereo8", + 0, + desc_monotostereo8, + NULL, + NULL, + NULL, + feed_monotostereo8, +}; +FEEDER_DECLARE(feeder_monotostereo8); + +/*****************************************************************************/ + +static int +feed_monotostereo16(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream) +{ + int i, j, k = f->source->feed(f->source, c, b, count / 2, stream); + u_int8_t x, y; + + j = k - 1; + i = j * 2 + 1; + while (i > 3 && j >= 1) { + x = b[j--]; + y = b[j--]; + b[i--] = x; + b[i--] = y; + b[i--] = x; + b[i--] = y; + } + return k * 2; +} + +static struct pcm_feederdesc desc_monotostereo16[] = { + {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_LE | AFMT_STEREO, 0}, + {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_LE | AFMT_STEREO, 0}, + {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_BE | AFMT_STEREO, 0}, + {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_BE | AFMT_STEREO, 0}, + {0}, +}; +static pcm_feeder feeder_monotostereo16 = { + "monotostereo16", + 0, + desc_monotostereo16, + NULL, + NULL, + NULL, + feed_monotostereo16, +}; +FEEDER_DECLARE(feeder_monotostereo16); + +/*****************************************************************************/ + +static int +feed_stereotomono8_init(pcm_feeder *f) +{ + f->data = malloc(FEEDBUFSZ, M_DEVBUF, M_NOWAIT); + return (f->data == NULL); +} + +static int +feed_stereotomono8_free(pcm_feeder *f) +{ + if (f->data) free(f->data, M_DEVBUF); + f->data = NULL; + return 0; +} + +static int +feed_stereotomono8(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream) +{ + u_int32_t i = 0, toget = count * 2; + int j = 0, k; + + k = f->source->feed(f->source, c, f->data, min(toget, FEEDBUFSZ), stream); + while (j < k) { + b[i++] = ((u_int8_t *)f->data)[j]; + j += 2; + } + return i; +} + +static struct pcm_feederdesc desc_stereotomono8[] = { + {FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_U8, 0}, + {FEEDER_FMT, AFMT_S8 | AFMT_STEREO, AFMT_S8, 0}, + {0}, +}; +static pcm_feeder feeder_stereotomono8 = { + "stereotomono8", + 1, + desc_stereotomono8, + feed_stereotomono8_init, + feed_stereotomono8_free, + NULL, + feed_stereotomono8, +}; +FEEDER_DECLARE(feeder_stereotomono8); + +/*****************************************************************************/ + +static int +feed_stereotomono16_init(pcm_feeder *f) +{ + f->data = malloc(FEEDBUFSZ, M_DEVBUF, M_NOWAIT); + return (f->data == NULL); +} + +static int +feed_stereotomono16_free(pcm_feeder *f) +{ + if (f->data) free(f->data, M_DEVBUF); + f->data = NULL; + return 0; +} + +static int +feed_stereotomono16(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream) +{ + u_int32_t i = 0, toget = count * 2; + int j = 0, k; + + k = f->source->feed(f->source, c, f->data, min(toget, FEEDBUFSZ), stream); + while (j < k) { + b[i++] = ((u_int8_t *)f->data)[j]; + b[i++] = ((u_int8_t *)f->data)[j + 1]; + j += 4; + } + return i; +} + +static struct pcm_feederdesc desc_stereotomono16[] = { + {FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_U16_LE, 0}, + {FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_S16_LE, 0}, + {FEEDER_FMT, AFMT_U16_BE | AFMT_STEREO, AFMT_U16_BE, 0}, + {FEEDER_FMT, AFMT_S16_BE | AFMT_STEREO, AFMT_S16_BE, 0}, + {0}, +}; +static pcm_feeder feeder_stereotomono16 = { + "stereotomono16", + 1, + desc_stereotomono16, + feed_stereotomono16_init, + feed_stereotomono16_free, + NULL, + feed_stereotomono16, +}; +FEEDER_DECLARE(feeder_stereotomono16); + +/*****************************************************************************/ + +static int +feed_endian(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream) +{ + u_int8_t t; + int i = 0, j = f->source->feed(f->source, c, b, count, stream); + + while (i < j) { + t = b[i]; + b[i] = b[i + 1]; + b[i + 1] = t; + i += 2; + } + return i; +} + +static struct pcm_feederdesc desc_endian[] = { + {FEEDER_FMT, AFMT_U16_LE, AFMT_U16_BE, 0}, + {FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_U16_BE | AFMT_STEREO, 0}, + {FEEDER_FMT, AFMT_S16_LE, AFMT_S16_BE, 0}, + {FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_S16_BE | AFMT_STEREO, 0}, + {FEEDER_FMT, AFMT_U16_BE, AFMT_U16_LE, 0}, + {FEEDER_FMT, AFMT_U16_BE | AFMT_STEREO, AFMT_U16_LE | AFMT_STEREO, 0}, + {FEEDER_FMT, AFMT_S16_BE, AFMT_S16_LE, 0}, + {FEEDER_FMT, AFMT_S16_BE | AFMT_STEREO, AFMT_S16_LE | AFMT_STEREO, 0}, + {0}, +}; +static pcm_feeder feeder_endian = { + "endian", + -1, + desc_endian, + NULL, + NULL, + NULL, + feed_endian, +}; +FEEDER_DECLARE(feeder_endian); + +/*****************************************************************************/ + +static int +feed_sign(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream) +{ + int i = 0, j = f->source->feed(f->source, c, b, count, stream); + int ssz = (int)f->data, ofs = ssz - 1; + + while (i < j) { + b[i + ofs] ^= 0x80; + i += ssz; + } + return i; +} + +static struct pcm_feederdesc desc_sign8[] = { + {FEEDER_FMT, AFMT_U8, AFMT_S8, 0}, + {FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_S8 | AFMT_STEREO, 0}, + {FEEDER_FMT, AFMT_S8, AFMT_U8, 0}, + {FEEDER_FMT, AFMT_S8 | AFMT_STEREO, AFMT_U8 | AFMT_STEREO, 0}, + {0}, +}; +static pcm_feeder feeder_sign8 = { + "sign8", + 0, + desc_sign8, + NULL, + NULL, + NULL, + feed_sign, + (void *)1, +}; +FEEDER_DECLARE(feeder_sign8); + +static struct pcm_feederdesc desc_sign16le[] = { + {FEEDER_FMT, AFMT_U16_LE, AFMT_S16_LE, 0}, + {FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_S16_LE | AFMT_STEREO, 0}, + {FEEDER_FMT, AFMT_S16_LE, AFMT_U16_LE, 0}, + {FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_U16_LE | AFMT_STEREO, 0}, + {0}, +}; +static pcm_feeder feeder_sign16le = { + "sign16le", + -1, + desc_sign16le, + NULL, + NULL, + NULL, + feed_sign, + (void *)2, +}; +FEEDER_DECLARE(feeder_sign16le); + +/*****************************************************************************/ + +static int +feed_table(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream) +{ + int i = 0, j = f->source->feed(f->source, c, b, count, stream); + + while (i < j) { + b[i] = ((u_int8_t *)f->data)[b[i]]; + i++; + } + return i; +} + +static struct pcm_feederdesc desc_ulawtou8[] = { + {FEEDER_FMT, AFMT_MU_LAW, AFMT_U8, 0}, + {FEEDER_FMT, AFMT_MU_LAW | AFMT_STEREO, AFMT_U8 | AFMT_STEREO, 0}, + {0}, +}; +static pcm_feeder feeder_ulawtou8 = { + "ulawtou8", + 0, + desc_ulawtou8, + NULL, + NULL, + NULL, + feed_table, + ulaw_to_u8, +}; +FEEDER_DECLARE(feeder_ulawtou8); + +static struct pcm_feederdesc desc_u8toulaw[] = { + {FEEDER_FMT, AFMT_U8, AFMT_MU_LAW, 0}, + {FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_MU_LAW | AFMT_STEREO, 0}, + {0}, +}; +static pcm_feeder feeder_u8toulaw = { + "u8toulaw", + 0, + desc_u8toulaw, + NULL, + NULL, + NULL, + feed_table, + u8_to_ulaw, +}; +FEEDER_DECLARE(feeder_u8toulaw); + +