Source-Changes-HG archive

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

[src/trunk]: src/sys/dev Rework about the rest note in speaker(4).



details:   https://anonhg.NetBSD.org/src/rev/d32b9c58d18f
branches:  trunk
changeset: 960930:d32b9c58d18f
user:      isaki <isaki%NetBSD.org@localhost>
date:      Sat Apr 03 04:10:30 2021 +0000

description:
Rework about the rest note in speaker(4).
- Obsolete the sc_rest callback.  The rest note operation can be done by
  the common spkr layer.  This also fixes PR kern/56060.
  This work-in-progress patch was left in my local tree for years. :(
- Improve calculations of tone and rest length.

diffstat:

 sys/dev/isa/spkr_pcppi.c |   24 +-------
 sys/dev/spkr.c           |  124 +++++++++++++++++++++++++++++++++-------------
 sys/dev/spkr_audio.c     |   24 ++------
 sys/dev/spkrvar.h        |    6 +-
 4 files changed, 100 insertions(+), 78 deletions(-)

diffs (truncated from 337 to 300 lines):

diff -r 836ff05e6a6a -r d32b9c58d18f sys/dev/isa/spkr_pcppi.c
--- a/sys/dev/isa/spkr_pcppi.c  Sat Apr 03 03:21:53 2021 +0000
+++ b/sys/dev/isa/spkr_pcppi.c  Sat Apr 03 04:10:30 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: spkr_pcppi.c,v 1.12 2021/04/03 03:21:53 isaki Exp $    */
+/*     $NetBSD: spkr_pcppi.c,v 1.13 2021/04/03 04:10:30 isaki Exp $    */
 
 /*
  * Copyright (c) 1990 Eric S. Raymond (esr%snark.thyrsus.com@localhost)
@@ -43,7 +43,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spkr_pcppi.c,v 1.12 2021/04/03 03:21:53 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spkr_pcppi.c,v 1.13 2021/04/03 04:10:30 isaki Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -79,8 +79,6 @@
     spkr_pcppi_probe, spkr_pcppi_attach, spkr_pcppi_detach, NULL,
     spkr_pcppi_rescan, spkr_pcppi_childdet, 0);
 
-#define SPKRPRI (PZERO - 1)
-
 /* emit tone of frequency hz for given number of ticks */
 static void
 spkr_pcppi_tone(device_t self, u_int xhz, u_int ticks)
@@ -92,22 +90,6 @@
        (*sc->sc_bell_func)(sc->sc_pcppicookie, xhz, ticks, PCPPI_BELL_SLEEP);
 }
 
-/* rest for given number of ticks */
-static void
-spkr_pcppi_rest(device_t self, int ticks)
-{
-       /*
-        * Set timeout to endrest function, then give up the timeslice.
-        * This is so other processes can execute while the rest is being
-        * waited out.
-        */
-#ifdef SPKRDEBUG
-       aprint_debug_dev(self, "%s: %d\n", __func__, ticks);
-#endif /* SPKRDEBUG */
-       if (ticks > 0)
-               tsleep(self, SPKRPRI | PCATCH, device_xname(self), ticks);
-}
-
 static int
 spkr_pcppi_probe(device_t parent, cfdata_t cf, void *aux)
 {
@@ -125,7 +107,7 @@
 
        sc->sc_pcppicookie = pa->pa_cookie;
        sc->sc_bell_func = pa->pa_bell_func;
-       spkr_attach(self, spkr_pcppi_tone, spkr_pcppi_rest);
+       spkr_attach(self, spkr_pcppi_tone);
        if (!pmf_device_register(self, NULL, NULL))
                aprint_error_dev(self, "couldn't establish power handler\n");
 }
diff -r 836ff05e6a6a -r d32b9c58d18f sys/dev/spkr.c
--- a/sys/dev/spkr.c    Sat Apr 03 03:21:53 2021 +0000
+++ b/sys/dev/spkr.c    Sat Apr 03 04:10:30 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: spkr.c,v 1.18 2021/04/03 03:21:53 isaki Exp $  */
+/*     $NetBSD: spkr.c,v 1.19 2021/04/03 04:10:30 isaki Exp $  */
 
 /*
  * Copyright (c) 1990 Eric S. Raymond (esr%snark.thyrsus.com@localhost)
@@ -43,7 +43,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spkr.c,v 1.18 2021/04/03 03:21:53 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spkr.c,v 1.19 2021/04/03 04:10:30 isaki Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "wsmux.h"
@@ -99,12 +99,10 @@
  *
  * Play string interpretation is modelled on IBM BASIC 2.0's PLAY statement;
  * M[LNS] are missing and the ~ synonym and octave-tracking facility is added.
- * Requires spkr_tone(), spkr_rest(). String play is not interruptible
- * except possibly at physical block boundaries.
+ * String play is not interruptible except possibly at physical block
+ * boundaries.
  */
 
-#define dtoi(c)                ((c) - '0')
-
 /*
  * Magic number avoidance...
  */
@@ -156,45 +154,82 @@
        sc->sc_octprefix = true;/* act as though there was an initial O(n) */
 }
 
-/* play tone of proper duration for current rhythm signature */
+#define SPKRPRI (PZERO - 1)
+
+/* Rest for given number of ticks */
 static void
-playtone(struct spkr_softc *sc, int pitch, int val, int sustain)
+rest(struct spkr_softc *sc, int ticks)
 {
-       int sound, silence, snum = 1, sdenom = 1;
+
+#ifdef SPKRDEBUG
+       device_printf(sc->sc_dev, "%s: rest for %d ticks\n", __func__, ticks);
+#endif /* SPKRDEBUG */
+       KASSERT(ticks > 0);
+
+       tsleep(sc->sc_dev, SPKRPRI | PCATCH, device_xname(sc->sc_dev), ticks);
+}
+
+/*
+ * Play tone of proper duration for current rhythm signature.
+ * note indicates "O0C" = 0, "O0C#" = 1, "O0D" = 2, ... , and
+ * -1 indiacates a rest.
+ * val indicates the length, "L4" = 4, "L8" = 8.
+ * sustain indicates the number of subsequent dots that extend the sound
+ * by one a half.
+ */
+static void
+playtone(struct spkr_softc *sc, int note, int val, int sustain)
+{
+       int whole;
+       int total;
+       int sound;
+       int silence;
 
        /* this weirdness avoids floating-point arithmetic */
+       whole = sc->sc_whole;
        for (; sustain; sustain--) {
-               snum *= NUM_MULT;
-               sdenom *= DENOM_MULT;
+               whole *= NUM_MULT;
+               val *= DENOM_MULT;
        }
 
-       if (pitch == -1) {
-               (*sc->sc_rest)(sc->sc_dev, sc->sc_whole
-                   * snum / (val * sdenom));
+       /* Total length in tick */
+       total = whole / val;
+
+       if (note == -1) {
+#ifdef SPKRDEBUG
+               device_printf(sc->sc_dev, "%s: rest for %d ticks\n",
+                   __func__, total);
+#endif /* SPKRDEBUG */
+               if (total != 0)
+                       rest(sc, total);
                return;
        }
 
-       int fac = sc->sc_whole * (FILLTIME - sc->sc_fill);
-       int fval = FILLTIME * val;
-       sound = (sc->sc_whole * snum) / (val * sdenom) -  fac / fval;
-       silence = fac * snum / (fval * sdenom);
+       /*
+        * Rest 1/8 (if NORMAL) or 3/8 (if STACCATO) in tick.
+        * silence should be rounded down.
+        */
+       silence = total * (FILLTIME - sc->sc_fill) / FILLTIME;
+       sound = total - silence;
 
 #ifdef SPKRDEBUG
        device_printf(sc->sc_dev,
-           "%s: pitch %d for %d ticks, rest for %d ticks\n", __func__,
-           pitch, sound, silence);
+           "%s: note %d for %d ticks, rest for %d ticks\n", __func__,
+           note, sound, silence);
 #endif /* SPKRDEBUG */
 
-       (*sc->sc_tone)(sc->sc_dev, pitchtab[pitch], sound);
-       if (sc->sc_fill != LEGATO)
-               (*sc->sc_rest)(sc->sc_dev, silence);
+       if (sound != 0)
+               (*sc->sc_tone)(sc->sc_dev, pitchtab[note], sound);
+       if (silence != 0)
+               rest(sc, silence);
 }
 
 /* interpret and play an item from a notation string */
 static void
 playstring(struct spkr_softc *sc, const char *cp, size_t slen)
 {
-       int             pitch, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
+       int pitch;
+       int lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
 
 #define GETNUM(cp, v)  \
        for (v = 0; slen > 0 && isdigit((unsigned char)cp[1]); ) { \
@@ -357,16 +392,26 @@
        }
 }
 
-/******************* UNIX DRIVER HOOKS BEGIN HERE **************************
- *
- * This section implements driver hooks to run playstring() and the spkr_tone()
- * and spkr_rest() functions defined above.
- */
+/******************* UNIX DRIVER HOOKS BEGIN HERE **************************/
 #define spkrenter(d)   device_lookup_private(&spkr_cd, d)
 
+/*
+ * Attaches spkr.  Specify tone function with the following specification:
+ *
+ * void
+ * tone(device_t self, u_int pitch, u_int tick)
+ *     plays a beep with specified parameters.
+ *     The argument 'pitch' specifies the pitch of a beep in Hz.  The argument
+ *     'tick' specifies the period of a beep in tick(9).  This function waits
+ *     to finish playing the beep and then halts it.
+ *     If the pitch is zero, it halts all sound if any (for compatibility
+ *     with the past confused specifications, but there should be no sound at
+ *     this point).  And it returns immediately, without waiting ticks.  So
+ *     you cannot use this as a rest.
+ *     If the tick is zero, it returns immediately.
+ */
 void
-spkr_attach(device_t self, void (*tone)(device_t, u_int, u_int),
-    void (*rest)(device_t, int))
+spkr_attach(device_t self, void (*tone)(device_t, u_int, u_int))
 {
        struct spkr_softc *sc = device_private(self);
 
@@ -375,7 +420,6 @@
 #endif /* SPKRDEBUG */
        sc->sc_dev = self;
        sc->sc_tone = tone;
-       sc->sc_rest = rest;
        sc->sc_inbuf = NULL;
        sc->sc_wsbelldev = NULL;
 
@@ -492,13 +536,21 @@
        return 0;
 }
 
+/*
+ * Play tone specified by tp.
+ * tp->frequency is the frequency (0 means a rest).
+ * tp->duration is the length in tick (returns immediately if 0).
+ */
 static void
 playonetone(struct spkr_softc *sc, tone_t *tp)
 {
-    if (tp->frequency == 0)
-           (*sc->sc_rest)(sc->sc_dev, tp->duration);
-    else
-           (*sc->sc_tone)(sc->sc_dev, tp->frequency, tp->duration);
+       if (tp->duration <= 0)
+               return;
+
+       if (tp->frequency == 0)
+               rest(sc, tp->duration);
+       else
+               (*sc->sc_tone)(sc->sc_dev, tp->frequency, tp->duration);
 }
 
 int
diff -r 836ff05e6a6a -r d32b9c58d18f sys/dev/spkr_audio.c
--- a/sys/dev/spkr_audio.c      Sat Apr 03 03:21:53 2021 +0000
+++ b/sys/dev/spkr_audio.c      Sat Apr 03 04:10:30 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: spkr_audio.c,v 1.10 2021/04/03 03:21:53 isaki Exp $    */
+/*     $NetBSD: spkr_audio.c,v 1.11 2021/04/03 04:10:30 isaki Exp $    */
 
 /*-
  * Copyright (c) 2016 Nathanial Sloss <nathanialsloss%yahoo.com.au@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spkr_audio.c,v 1.10 2021/04/03 03:21:53 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spkr_audio.c,v 1.11 2021/04/03 04:10:30 isaki Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -71,21 +71,11 @@
 #ifdef SPKRDEBUG
        device_printf(self, "%s: %u %u\n", __func__, xhz, ticks);
 #endif /* SPKRDEBUG */
-       audiobell(sc->sc_audiodev, xhz, hztoms(ticks),
-           sc->sc_spkr.sc_vol, 0);
-}
 
-static void
-spkr_audio_rest(device_t self, int ticks)
-{
-       struct spkr_audio_softc *sc = device_private(self);
-       
-#ifdef SPKRDEBUG
-       aprint_debug_dev(self, "%s: %d\n", __func__, ticks);
-#endif /* SPKRDEBUG */
-       if (ticks > 0)
-               audiobell(sc->sc_audiodev, 0, hztoms(ticks),
-                   sc->sc_spkr.sc_vol, 0);
+       if (xhz == 0 || ticks == 0)
+               return;



Home | Main Index | Thread Index | Old Index