diff options
author | cg <cg@FreeBSD.org> | 1999-11-15 23:57:33 +0000 |
---|---|---|
committer | cg <cg@FreeBSD.org> | 1999-11-15 23:57:33 +0000 |
commit | 62195202a4620664c12dfff5153b025af7ccebc0 (patch) | |
tree | 1e174fe7d55795f4681b4d848c4b95846f2b9cc4 /sys/dev/sound/pcm/feeder.c | |
parent | acbfab4a2fd3e763202dc2be695a8b89a43cabfa (diff) | |
download | FreeBSD-src-62195202a4620664c12dfff5153b025af7ccebc0.zip FreeBSD-src-62195202a4620664c12dfff5153b025af7ccebc0.tar.gz |
this is a full fix for writes not aligned to the sample size selected.
should be a no-op in most cases.
Diffstat (limited to 'sys/dev/sound/pcm/feeder.c')
-rw-r--r-- | sys/dev/sound/pcm/feeder.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/sys/dev/sound/pcm/feeder.c b/sys/dev/sound/pcm/feeder.c index 4a59806..055dc98 100644 --- a/sys/dev/sound/pcm/feeder.c +++ b/sys/dev/sound/pcm/feeder.c @@ -106,10 +106,17 @@ static unsigned char u8_to_ulaw[] = { /*****************************************************************************/ static int -feed_root(pcm_feeder *feeder, u_int8_t *buffer, u_int32_t count, struct uio *stream) +feed_root(pcm_feeder *feeder, pcm_channel *ch, u_int8_t *buffer, u_int32_t count, struct uio *stream) { int ret, tmp = 0, c = 0; if (!count) panic("feed_root: count == 0"); + count &= ~((1 << ch->align) - 1); + if (!count) panic("feed_root: aligned count == 0"); + if (ch->smegcnt > 0) { + c = min(ch->smegcnt, count); + bcopy(ch->smegbuf, buffer, c); + ch->smegcnt -= c; + } while ((stream->uio_resid > 0) && (c < count)) { tmp = stream->uio_resid; ret = uiomove(buffer + c, count - c, stream); @@ -125,10 +132,10 @@ pcm_feeder feeder_root = { "root", 0, NULL, NULL, feed_root }; /*****************************************************************************/ static int -feed_8to16(pcm_feeder *f, u_int8_t *b, u_int32_t count, struct uio *stream) +feed_8to16(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, b, count / 2, stream); + k = f->source->feed(f->source, c, b, count / 2, stream); j = k - 1; i = j * 2 + 1; while (i > 0 && j >= 0) { @@ -157,11 +164,11 @@ feed_16to8_free(pcm_feeder *f) } static int -feed_16to8le(pcm_feeder *f, u_int8_t *b, u_int32_t count, struct uio *stream) +feed_16to8le(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, f->data, min(toget, FEEDBUFSZ), stream); + 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; @@ -174,9 +181,9 @@ static pcm_feeder feeder_16to8le = /*****************************************************************************/ static int -feed_monotostereo8(pcm_feeder *f, u_int8_t *b, u_int32_t count, struct uio *stream) +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, b, count / 2, 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) { @@ -207,11 +214,11 @@ feed_stereotomono8_free(pcm_feeder *f) } static int -feed_stereotomono8(pcm_feeder *f, u_int8_t *b, u_int32_t count, struct uio *stream) +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, f->data, min(toget, FEEDBUFSZ), stream); + 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; @@ -225,10 +232,10 @@ static pcm_feeder feeder_stereotomono8 = /*****************************************************************************/ static int -feed_endian(pcm_feeder *f, u_int8_t *b, u_int32_t count, struct uio *stream) +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, b, count, stream); + int i = 0, j = f->source->feed(f->source, c, b, count, stream); while (i < j) { t = b[i]; b[i] = b[i + 1]; @@ -242,9 +249,9 @@ static pcm_feeder feeder_endian = { "endian", -1, NULL, NULL, feed_endian }; /*****************************************************************************/ static int -feed_sign(pcm_feeder *f, u_int8_t *b, u_int32_t count, struct uio *stream) +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, b, count, 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; @@ -260,9 +267,9 @@ static pcm_feeder feeder_sign16 = /*****************************************************************************/ static int -feed_table(pcm_feeder *f, u_int8_t *b, u_int32_t count, struct uio *stream) +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, b, count, 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++; |