Module Name: src Committed By: isaki Date: Sat Sep 12 06:09:17 UTC 2020
Modified Files: src/sys/dev/audio: mulaw.c Log Message: Improve slinear16-to-mulaw conversion calculation. It's about 2~3 times faster on my amd64 and x68k(68030). To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/dev/audio/mulaw.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/audio/mulaw.c diff -u src/sys/dev/audio/mulaw.c:1.3 src/sys/dev/audio/mulaw.c:1.4 --- src/sys/dev/audio/mulaw.c:1.3 Sat Jan 11 04:06:13 2020 +++ src/sys/dev/audio/mulaw.c Sat Sep 12 06:09:16 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: mulaw.c,v 1.3 2020/01/11 04:06:13 isaki Exp $ */ +/* $NetBSD: mulaw.c,v 1.4 2020/09/12 06:09:16 isaki Exp $ */ /* * Copyright (C) 2017 Tetsuya Isaki. All rights reserved. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mulaw.c,v 1.3 2020/01/11 04:06:13 isaki Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mulaw.c,v 1.4 2020/09/12 06:09:16 isaki Exp $"); #include <sys/types.h> #include <sys/systm.h> @@ -45,7 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: mulaw.c,v 1. * * 2. Calculation (default) * It calculates mu-law with full spec and its precision is 14bit. - * It's about 10 times slower but the size is less than a half (on m68k, + * It's about 3 times slower but the size is less than a half (on m68k, * for example). * * mu-law is no longer a popular format. I think size-optimized is better. @@ -247,33 +247,40 @@ audio_internal_to_mulaw32(audio_filter_a m = slinear8_to_mulaw[val]; #else /* 14bit (fullspec, slow but small) encoder */ - int16_t val; + uint16_t val; int c; - val = (int16_t)(*s++ >> (AUDIO_INTERNAL_BITS - 16)); - if (val < 0) { + val = *s++ >> (AUDIO_INTERNAL_BITS - 16); + if ((int16_t)val < 0) { m = 0; } else { val = ~val; m = 0x80; } /* limit */ - if (val < -8158 * 4) + if ((int16_t)val < -8158 * 4) val = -8158 * 4; val -= 33 * 4; /* bias */ - val <<= 1; - for (c = 0; c < 7; c++) { - if (val >= 0) { - break; - } + // Before(1) Before(2) Before(3) + // S0MMMMxx_xxxxxxxx 0MMMMxxx_xxxxxxx0 c=0,v=0MMMMxxx_xxxxxxx0 + // S10MMMMx_xxxxxxxx 10MMMMxx_xxxxxxx0 c=1,v=0MMMMxxx_xxxxxx00 + // S110MMMM_xxxxxxxx 110MMMMx_xxxxxxx0 c=2,v=0MMMMxxx_xxxxx000 + // : : : + // S1111110_MMMMxxxx 1111110M_MMMxxxx0 c=6,v=0MMMMxxx_x0000000 - m += (1 << 4); /* exponent */ - val <<= 1; - } + // (1) Push out sign bit val <<= 1; - m += (val >> 12) & 0x0f; /* mantissa */ + // (2) Find first zero (and align val to left) + c = 0; + if (val >= 0xf000) c += 4, val <<= 4; + if (val >= 0xc000) c += 2, val <<= 2; + if (val >= 0x8000) c += 1, val <<= 1; + + // (3) + m += (c << 4); + m += (val >> 11) & 0x0f; #endif #if defined(MULAW32)