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