Date: Sat, 17 Dec 2005 03:37:15 +0900 (JST) From: Kazuhito HONDA <kazuhito@ph.noda.tus.ac.jp> To: freebsd-multimedia@freebsd.org Subject: patch for 24-bit soft volume and uaudio's tiny fix Message-ID: <20051217.033715.343188712.kazuhito@ph.noda.tus.ac.jp>
next in thread | raw e-mail | index | archive | help
----Next_Part(Sat_Dec_17_03:37:15_2005_980)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hello, We have already had a soft volume, feeder_volume_s16(). But it is of 16 bit. So 24-bit sound streams are always downgraded to 16-bit before soft volume even though a sound device has a 24-bit port. Thus 24-bit soft volume is necessary. This mail has a patch for 24-bit soft volume. I tried to use it with `SB Live! 24-bit external' and it worked. And the patch includes a fix of tiny mistakes in uaudio.c, too. Sincerely yours, Kazuhito HONDA ----Next_Part(Sat_Dec_17_03:37:15_2005_980)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="sv_ua_patch" --- sys/dev/sound/pcm/feeder_volume.c.old Tue Nov 22 10:13:37 2005 +++ sys/dev/sound/pcm/feeder_volume.c Sat Dec 17 02:41:08 2005 @@ -67,6 +67,49 @@ feed_volume_s16(struct pcm_feeder *f, st return k; } +static int +feed_volume_s24(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b, + uint32_t count, void *source) +{ + int i, k, vol[2]; + int32_t buf, j; + uint8_t *buf8; + + k = FEEDER_FEED(f->source, c, b, (count / 3) * 3, source); + if (k < 3) { +#if 0 + device_printf(c->dev, "%s: Not enough data (Got: %d bytes)\n", + __func__, k); +#endif + return 0; + } +#if 0 + if (k % 3) + device_printf(c->dev, "%s: Bytes not 24bit aligned.\n", __func__); +#endif + k -= k % 3; + i = k; + vol[0] = c->volume & 0x7f; + vol[1] = (c->volume >> 8) & 0x7f; + while (i > 2) { + buf = 0; + buf8 = (int8_t *) (&buf); + buf8[0] = b[--i]; + buf8[1] = b[--i]; + buf8[2] = b[--i]; + j = (vol[i & 1] * buf) / 100; + if (j > 8388607) + j = 8388607; + if (j < -8388608) + j = -8388608; + buf8 = (int8_t *) (&j); + b[i + 2] = buf8[0]; + b[i + 1] = buf8[1]; + b[i] = buf8[2]; + } + return k; +} + static struct pcm_feederdesc feeder_volume_s16_desc[] = { {FEEDER_VOLUME, AFMT_S16_LE|AFMT_STEREO, AFMT_S16_LE|AFMT_STEREO, 0}, {0, 0, 0, 0}, @@ -76,3 +119,13 @@ static kobj_method_t feeder_volume_s16_m {0, 0} }; FEEDER_DECLARE(feeder_volume_s16, 2, NULL); + +static struct pcm_feederdesc feeder_volume_s24_desc[] = { + {FEEDER_VOLUME, AFMT_S24_LE|AFMT_STEREO, AFMT_S24_LE|AFMT_STEREO, 0}, + {0, 0, 0, 0}, +}; +static kobj_method_t feeder_volume_s24_methods[] = { + KOBJMETHOD(feeder_feed, feed_volume_s24), + {0, 0} +}; +FEEDER_DECLARE(feeder_volume_s24, 2, NULL); --- sys/dev/sound/pcm/channel.c.old Fri Dec 16 23:44:24 2005 +++ sys/dev/sound/pcm/channel.c Fri Dec 16 23:57:30 2005 @@ -1372,9 +1372,19 @@ chn_buildfeeder(struct pcm_channel *c) for (type = FEEDER_RATE; type <= FEEDER_LAST; type++) { if (flags & (1 << type)) { desc.type = type; - desc.in = 0; desc.out = 0; desc.flags = 0; + if (type == FEEDER_VOLUME) { + if (c->feeder->desc->out & (AFMT_S24_LE | AFMT_S24_BE | AFMT_U24_LE | AFMT_U24_BE)) { + desc.in = AFMT_S24_LE | AFMT_STEREO; + } else if (c->feeder->desc->out & (AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE)) { + desc.in = AFMT_S16_LE | AFMT_STEREO; + } else { + desc.in = 0; + } + } else { + desc.in = 0; + } DEB(printf("find feeder type %d, ", type)); fc = feeder_getclass(&desc); DEB(printf("got %p\n", fc)); --- sys/dev/sound/usb/uaudio.c.old Sun Nov 13 23:20:26 2005 +++ sys/dev/sound/usb/uaudio.c Sat Dec 17 00:00:11 2005 @@ -3909,10 +3909,10 @@ const struct uaudio_conversion const acc {AUDIO_ENCODING_SLINEAR_LE, 8, AFMT_S8}, {AUDIO_ENCODING_SLINEAR_LE, 16, AFMT_S16_LE}, {AUDIO_ENCODING_SLINEAR_LE, 24, AFMT_S24_LE}, - {AUDIO_ENCODING_SLINEAR_LE, 24, AFMT_S32_LE}, + {AUDIO_ENCODING_SLINEAR_LE, 32, AFMT_S32_LE}, {AUDIO_ENCODING_SLINEAR_BE, 16, AFMT_S16_BE}, {AUDIO_ENCODING_SLINEAR_BE, 24, AFMT_S24_BE}, - {AUDIO_ENCODING_SLINEAR_BE, 24, AFMT_S32_BE}, + {AUDIO_ENCODING_SLINEAR_BE, 32, AFMT_S32_BE}, {AUDIO_ENCODING_ALAW, 8, AFMT_A_LAW}, {AUDIO_ENCODING_ULAW, 8, AFMT_MU_LAW}, {0,0,0} ----Next_Part(Sat_Dec_17_03:37:15_2005_980)----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20051217.033715.343188712.kazuhito>