Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev The audio bell is now in 16 bit slinear format.



details:   https://anonhg.NetBSD.org/src/rev/2953e27eb4c3
branches:  trunk
changeset: 824192:2953e27eb4c3
user:      nat <nat%NetBSD.org@localhost>
date:      Sat May 27 10:54:47 2017 +0000

description:
The audio bell is now in 16 bit slinear format.

It is possible to use a frequency of 44.1 kHz as apposed to 8 kHz if
you specifiy:

options HIRES_BELL

in your kernel config file.

Changes to the way in which the wave is generated help reducing pops and
ticks in the bell.

The output of the high resolution bell has been tested extensively using
frequency spectographs generated by pkgsrc package audio/audacity.

This addresses PR kern/51784.

diffstat:

 sys/dev/audiobell.c     |  127 ++++++++++-----------
 sys/dev/audiobelldata.h |  285 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 346 insertions(+), 66 deletions(-)

diffs (truncated from 496 to 300 lines):

diff -r e8dbbb5fcc89 -r 2953e27eb4c3 sys/dev/audiobell.c
--- a/sys/dev/audiobell.c       Sat May 27 10:43:30 2017 +0000
+++ b/sys/dev/audiobell.c       Sat May 27 10:54:47 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: audiobell.c,v 1.16 2017/02/27 23:31:00 mrg Exp $       */
+/*     $NetBSD: audiobell.c,v 1.17 2017/05/27 10:54:47 nat Exp $       */
 
 
 /*
@@ -32,7 +32,7 @@
  */
 
 #include <sys/types.h>
-__KERNEL_RCSID(0, "$NetBSD: audiobell.c,v 1.16 2017/02/27 23:31:00 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audiobell.c,v 1.17 2017/05/27 10:54:47 nat Exp $");
 
 #include <sys/audioio.h>
 #include <sys/conf.h>
@@ -50,63 +50,44 @@
 #include <dev/audio_if.h>
 #include <dev/audiovar.h>
 #include <dev/audiobellvar.h>
+#ifdef HIRES_BELL
+#include <dev/audiobelldata.h>
 
-/* Convert a %age volume to an amount to add to u-law values */
-/* XXX Probably highly inaccurate -- should be regenerated */
-static const uint8_t volmap[] = {
-       0x7f, 0x67, 0x5b, 0x53, 0x49, 0x45, 0x41, 0x3e, 0x3a, 0x38,
-       0x36, 0x32, 0x30, 0x2f, 0x2e, 0x2c, 0x2b, 0x2a, 0x28, 0x27,
-       0x26, 0x25, 0x23, 0x22, 0x21, 0x1f, 0x1f, 0x1e, 0x1e, 0x1d,
-       0x1c, 0x1c, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18, 0x17, 0x17,
-       0x16, 0x15, 0x15, 0x14, 0x13, 0x13, 0x12, 0x11, 0x11, 0x10,
-       0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d,
-       0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09,
-       0x09, 0x09, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
-       0x06, 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x03,
-       0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
-       0x00
-};
+/* 44.1 kHz should reduce hum at higher pitches. */
+#define BELL_SAMPLE_RATE       44100
+#define BELL_SHIFT             19
+#else
+#define BELL_SAMPLE_RATE       8000
+#define BELL_SHIFT             24
+#endif
 
+#ifndef HIRES_BELL
 /* 1/4 cycle sine wave in u-law */
 /* XXX Probably highly inaccurate -- should be regenerated */
-static const uint8_t sinewave[] = {
-       0xff, 0xd3, 0xc5, 0xbc, 0xb6, 0xb0, 0xad, 0xaa,
-       0xa7, 0xa3, 0xa0, 0x9e, 0x9d, 0x9b, 0x9a, 0x98,
-       0x97, 0x96, 0x94, 0x93, 0x91, 0x90, 0x8f, 0x8e,
-       0x8e, 0x8d, 0x8c, 0x8c, 0x8b, 0x8b, 0x8a, 0x89,
-       0x89, 0x88, 0x88, 0x87, 0x87, 0x86, 0x86, 0x85,
-       0x85, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x82,
-       0x82, 0x82, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80,
-       0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-       0x80,
+static const int16_t sinewave[] = {
+       0x0000, 0x0324, 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, 
+       0x18f8, 0x1c0b, 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, 
+       0x30fb, 0x33de, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, 
+       0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, 
+       0x5a82, 0x5cb4, 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, 
+       0x6a6d, 0x6c24, 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, 
+       0x7641, 0x776c, 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, 
+       0x7d8a, 0x7e1d, 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, 
 };
-
-static inline uint8_t
-audiobell_ulawscale(uint8_t val, uint8_t vol)
-{
-       uint8_t result;
-
-       result = val + vol;
-       /* Spot underflow and just return silence */
-       if ((result ^ val) & 0x80)
-               return 0x7f;
-       return result;
-}
+#endif
 
 static inline void
-audiobell_expandwave(uint8_t *buf, int volume)
+audiobell_expandwave(int16_t *buf, int volume)
 {
        u_int i;
-       int uvol;
 
        KASSERT(volume >= 0 && volume <= 100);
-       uvol = volmap[volume];
-       for (i = 0; i < 65; i++)
-               buf[i] = audiobell_ulawscale(sinewave[i], uvol);
-       for (i = 65; i < 128; i++)
-                buf[i] = buf[128 - i];
-       for (i = 128; i < 256; i++)
-               buf[i] = buf[i - 128] ^ 0x80;
+       for (i = 0; i < __arraycount(sinewave); i++)
+               buf[i] = (int32_t)sinewave[i] * (int32_t)volume / 100;
+       for (i = __arraycount(sinewave); i < __arraycount(sinewave) * 2; i++)
+                buf[i] = buf[__arraycount(sinewave) * 2 - i - 1];
+       for (i = __arraycount(sinewave) * 2; i < __arraycount(sinewave) * 4; i++)
+               buf[i] = -buf[__arraycount(sinewave) * 4 - i - 1];
 }
 
 /*
@@ -114,21 +95,21 @@
  * Reference Manual (pp1624--1628).
  */
 static inline int
-audiobell_synthesize(uint8_t *buf, u_int pitch, u_int period, u_int volume)
+audiobell_synthesize(int16_t *buf, u_int pitch, u_int period, u_int volume,
+    uint32_t *phase)
 {
-       uint8_t *wave;
-       uint16_t phase;
+       int16_t *wave;
 
-       wave = malloc(256, M_TEMP, M_WAITOK);
+       wave = malloc(sizeof(sinewave) * 4, M_TEMP, M_WAITOK);
        if (wave == NULL) return -1;
        audiobell_expandwave(wave, volume);
-       pitch = pitch * 65536 / 8000;
-       period = period * 8; /* 8000 / 1000 */
-       phase = 0;
+       pitch = pitch * ((sizeof(sinewave) * 4) << BELL_SHIFT) /
+           BELL_SAMPLE_RATE / 2;
+       period = period * BELL_SAMPLE_RATE / 1000 / 2;
 
        for (; period != 0; period--) {
-               *buf++ = wave[phase >> 8];
-               phase += pitch;
+               *buf++ = wave[*phase >> BELL_SHIFT];
+               *phase += pitch;
        }
 
        free(wave, M_TEMP);
@@ -138,12 +119,13 @@
 void
 audiobell(void *v, u_int pitch, u_int period, u_int volume, int poll)
 {
-       uint8_t *buf;
+       int16_t *buf;
+       uint32_t phase;
        struct audio_info ai;
        struct uio auio;
        struct iovec aiov;
        struct file *fp;
-       int size, len, offset;
+       int size, len;
 
        fp = NULL;
        dev_t audio = AUDIO_DEVICE | device_unit((device_t)v);
@@ -160,22 +142,36 @@
                return;
        }
 
+       ai.play.sample_rate = BELL_SAMPLE_RATE;
+       ai.play.precision = 16;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+       ai.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
+#else
+       ai.play.encoding = AUDIO_ENCODING_SLINEAR_BE;
+#endif
+
+       if (audiobellioctl(fp, AUDIO_SETINFO, &ai) != 0) {
+               audiobellclose(fp);
+               return;
+       }
        buf = NULL;
 
-       if (ai.blocksize < 8192)
-               ai.blocksize = 8192;
+       if (ai.blocksize < BELL_SAMPLE_RATE)
+               ai.blocksize = BELL_SAMPLE_RATE;
 
-       len = period * 8;
+       len = period * BELL_SAMPLE_RATE / 1000 * 2;
        size = min(len, ai.blocksize);
        if (size == 0) goto out;
 
        buf = malloc(size, M_TEMP, M_WAITOK);
        if (buf == NULL) goto out;
-
-       offset = 0;
+ 
+       phase = 0;
        while (len > 0) {
                size = min(len, ai.blocksize);
-               if (audiobell_synthesize(buf, pitch, size / 8, volume) != 0)
+               if (audiobell_synthesize(buf, pitch, size *
+                               1000 / BELL_SAMPLE_RATE, volume, &phase) != 0)
                        goto out;
                aiov.iov_base = (void *)buf;
                aiov.iov_len = size;
@@ -188,7 +184,6 @@
 
                audiobellwrite(fp, NULL, &auio, NULL, 0);
                len -= size;
-               offset += size;
        }
 out:
        if (buf != NULL) free(buf, M_TEMP);
diff -r e8dbbb5fcc89 -r 2953e27eb4c3 sys/dev/audiobelldata.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/audiobelldata.h   Sat May 27 10:54:47 2017 +0000
@@ -0,0 +1,285 @@
+/*-
+ * Copyright (c) 2017 Nathanial Sloss <nathanialsloss%yahoo.com.au@localhost>
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/* High resolution 1/4 cycle sine wave in 16 bit-slinear */
+static const uint16_t sinewave[] = {
+       0x0000, 0x0019, 0x0032, 0x004b, 0x0064, 0x007d, 0x0096, 0x00af, 
+       0x00c9, 0x00e2, 0x00fb, 0x0114, 0x012d, 0x0146, 0x015f, 0x0178, 
+       0x0192, 0x01ab, 0x01c4, 0x01dd, 0x01f6, 0x020f, 0x0228, 0x0242, 
+       0x025b, 0x0274, 0x028d, 0x02a6, 0x02bf, 0x02d8, 0x02f1, 0x030b, 
+       0x0324, 0x033d, 0x0356, 0x036f, 0x0388, 0x03a1, 0x03ba, 0x03d4, 
+       0x03ed, 0x0406, 0x041f, 0x0438, 0x0451, 0x046a, 0x0483, 0x049c, 
+       0x04b6, 0x04cf, 0x04e8, 0x0501, 0x051a, 0x0533, 0x054c, 0x0565, 
+       0x057f, 0x0598, 0x05b1, 0x05ca, 0x05e3, 0x05fc, 0x0615, 0x062e, 
+       0x0647, 0x0660, 0x067a, 0x0693, 0x06ac, 0x06c5, 0x06de, 0x06f7, 
+       0x0710, 0x0729, 0x0742, 0x075b, 0x0775, 0x078e, 0x07a7, 0x07c0, 
+       0x07d9, 0x07f2, 0x080b, 0x0824, 0x083d, 0x0856, 0x086f, 0x0888, 
+       0x08a2, 0x08bb, 0x08d4, 0x08ed, 0x0906, 0x091f, 0x0938, 0x0951, 
+       0x096a, 0x0983, 0x099c, 0x09b5, 0x09ce, 0x09e7, 0x0a00, 0x0a19, 
+       0x0a33, 0x0a4c, 0x0a65, 0x0a7e, 0x0a97, 0x0ab0, 0x0ac9, 0x0ae2, 
+       0x0afb, 0x0b14, 0x0b2d, 0x0b46, 0x0b5f, 0x0b78, 0x0b91, 0x0baa, 
+       0x0bc3, 0x0bdc, 0x0bf5, 0x0c0e, 0x0c27, 0x0c40, 0x0c59, 0x0c72, 
+       0x0c8b, 0x0ca4, 0x0cbd, 0x0cd6, 0x0cef, 0x0d08, 0x0d21, 0x0d3a, 
+       0x0d53, 0x0d6c, 0x0d85, 0x0d9e, 0x0db7, 0x0dd0, 0x0de9, 0x0e02, 
+       0x0e1b, 0x0e34, 0x0e4d, 0x0e66, 0x0e7f, 0x0e98, 0x0eb1, 0x0eca, 
+       0x0ee3, 0x0efc, 0x0f15, 0x0f2e, 0x0f47, 0x0f60, 0x0f79, 0x0f92, 
+       0x0fab, 0x0fc4, 0x0fdd, 0x0ff5, 0x100e, 0x1027, 0x1040, 0x1059, 
+       0x1072, 0x108b, 0x10a4, 0x10bd, 0x10d6, 0x10ef, 0x1108, 0x1121, 
+       0x1139, 0x1152, 0x116b, 0x1184, 0x119d, 0x11b6, 0x11cf, 0x11e8, 
+       0x1201, 0x1219, 0x1232, 0x124b, 0x1264, 0x127d, 0x1296, 0x12af, 
+       0x12c8, 0x12e0, 0x12f9, 0x1312, 0x132b, 0x1344, 0x135d, 0x1376, 
+       0x138e, 0x13a7, 0x13c0, 0x13d9, 0x13f2, 0x140b, 0x1423, 0x143c, 
+       0x1455, 0x146e, 0x1487, 0x149f, 0x14b8, 0x14d1, 0x14ea, 0x1503, 
+       0x151b, 0x1534, 0x154d, 0x1566, 0x157f, 0x1597, 0x15b0, 0x15c9, 
+       0x15e2, 0x15fa, 0x1613, 0x162c, 0x1645, 0x165d, 0x1676, 0x168f, 
+       0x16a8, 0x16c0, 0x16d9, 0x16f2, 0x170a, 0x1723, 0x173c, 0x1755, 
+       0x176d, 0x1786, 0x179f, 0x17b7, 0x17d0, 0x17e9, 0x1802, 0x181a, 
+       0x1833, 0x184c, 0x1864, 0x187d, 0x1896, 0x18ae, 0x18c7, 0x18e0, 
+       0x18f8, 0x1911, 0x192a, 0x1942, 0x195b, 0x1973, 0x198c, 0x19a5, 
+       0x19bd, 0x19d6, 0x19ef, 0x1a07, 0x1a20, 0x1a38, 0x1a51, 0x1a6a, 
+       0x1a82, 0x1a9b, 0x1ab3, 0x1acc, 0x1ae4, 0x1afd, 0x1b16, 0x1b2e, 
+       0x1b47, 0x1b5f, 0x1b78, 0x1b90, 0x1ba9, 0x1bc1, 0x1bda, 0x1bf2, 
+       0x1c0b, 0x1c24, 0x1c3c, 0x1c55, 0x1c6d, 0x1c86, 0x1c9e, 0x1cb7, 
+       0x1ccf, 0x1ce8, 0x1d00, 0x1d19, 0x1d31, 0x1d49, 0x1d62, 0x1d7a, 
+       0x1d93, 0x1dab, 0x1dc4, 0x1ddc, 0x1df5, 0x1e0d, 0x1e25, 0x1e3e, 
+       0x1e56, 0x1e6f, 0x1e87, 0x1ea0, 0x1eb8, 0x1ed0, 0x1ee9, 0x1f01, 
+       0x1f19, 0x1f32, 0x1f4a, 0x1f63, 0x1f7b, 0x1f93, 0x1fac, 0x1fc4, 
+       0x1fdc, 0x1ff5, 0x200d, 0x2025, 0x203e, 0x2056, 0x206e, 0x2087, 
+       0x209f, 0x20b7, 0x20d0, 0x20e8, 0x2100, 0x2118, 0x2131, 0x2149, 
+       0x2161, 0x2179, 0x2192, 0x21aa, 0x21c2, 0x21da, 0x21f3, 0x220b, 
+       0x2223, 0x223b, 0x2254, 0x226c, 0x2284, 0x229c, 0x22b4, 0x22cd, 
+       0x22e5, 0x22fd, 0x2315, 0x232d, 0x2345, 0x235e, 0x2376, 0x238e, 
+       0x23a6, 0x23be, 0x23d6, 0x23ee, 0x2407, 0x241f, 0x2437, 0x244f, 
+       0x2467, 0x247f, 0x2497, 0x24af, 0x24c7, 0x24df, 0x24f7, 0x2510, 
+       0x2528, 0x2540, 0x2558, 0x2570, 0x2588, 0x25a0, 0x25b8, 0x25d0, 
+       0x25e8, 0x2600, 0x2618, 0x2630, 0x2648, 0x2660, 0x2678, 0x2690, 
+       0x26a8, 0x26c0, 0x26d8, 0x26f0, 0x2707, 0x271f, 0x2737, 0x274f, 
+       0x2767, 0x277f, 0x2797, 0x27af, 0x27c7, 0x27df, 0x27f7, 0x280e, 
+       0x2826, 0x283e, 0x2856, 0x286e, 0x2886, 0x289d, 0x28b5, 0x28cd, 
+       0x28e5, 0x28fd, 0x2915, 0x292c, 0x2944, 0x295c, 0x2974, 0x298c, 
+       0x29a3, 0x29bb, 0x29d3, 0x29eb, 0x2a02, 0x2a1a, 0x2a32, 0x2a49, 
+       0x2a61, 0x2a79, 0x2a91, 0x2aa8, 0x2ac0, 0x2ad8, 0x2aef, 0x2b07, 
+       0x2b1f, 0x2b36, 0x2b4e, 0x2b66, 0x2b7d, 0x2b95, 0x2bad, 0x2bc4, 
+       0x2bdc, 0x2bf3, 0x2c0b, 0x2c23, 0x2c3a, 0x2c52, 0x2c69, 0x2c81, 
+       0x2c99, 0x2cb0, 0x2cc8, 0x2cdf, 0x2cf7, 0x2d0e, 0x2d26, 0x2d3d, 
+       0x2d55, 0x2d6c, 0x2d84, 0x2d9b, 0x2db3, 0x2dca, 0x2de2, 0x2df9, 
+       0x2e11, 0x2e28, 0x2e3f, 0x2e57, 0x2e6e, 0x2e86, 0x2e9d, 0x2eb5, 



Home | Main Index | Thread Index | Old Index