add 16bit mono/stereo conversion feeder

prefer feeder chains of length 1 over length 2
This commit is contained in:
Cameron Grant 2000-09-09 21:24:03 +00:00
parent 306f91b60b
commit 58359dc594

View File

@ -29,6 +29,7 @@
#include <dev/sound/pcm/sound.h>
#define FEEDBUFSZ 8192
#undef FEEDER_DEBUG
static unsigned char ulaw_to_u8[] = {
3, 7, 11, 15, 19, 23, 27, 31,
@ -270,6 +271,38 @@ SYSINIT(feeder_monotostereo8, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register,
/*****************************************************************************/
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, feed_monotostereo16 };
SYSINIT(feeder_monotostereo16, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register, &feeder_monotostereo16);
/*****************************************************************************/
static int
feed_stereotomono8_init(pcm_feeder *f)
{
@ -310,6 +343,49 @@ SYSINIT(feeder_stereotomono8, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register,
/*****************************************************************************/
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, feed_stereotomono16 };
SYSINIT(feeder_stereotomono16, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register, &feeder_stereotomono16);
/*****************************************************************************/
static int
feed_endian(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream)
{
@ -529,17 +605,23 @@ chn_feedchain(pcm_channel *c, u_int32_t *to)
stop = c->feeder;
try = NULL;
max = 0;
while (try == NULL && max++ < 8)
while (try == NULL && max < 8) {
try = feeder_fmtchain(to, c->feeder, stop, max);
max++;
}
if (try == NULL)
return 0;
c->feeder = try;
c->align = 0;
/* printf("chain: "); */
#ifdef FEEDER_DEBUG
printf("chain: ");
#endif
while (try && (try != stop)) {
/* printf("%s [%d]", try->name, try->desc->idx); */
/* if (try->source) */
/* printf(" -> "); */
#ifdef FEEDER_DEBUG
printf("%s [%d]", try->name, try->desc->idx);
if (try->source)
printf(" -> ");
#endif
if (try->init)
try->init(try);
if (try->align > 0)
@ -548,6 +630,8 @@ chn_feedchain(pcm_channel *c, u_int32_t *to)
c->align = -try->align;
try = try->source;
}
/* printf("%s [%d]", try->name, try->desc->idx); */
#ifdef FEEDER_DEBUG
printf("%s [%d]\n", try->name, try->desc->idx);
#endif
return c->feeder->desc->out;
}