summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--games/morse/Makefile2
-rw-r--r--games/morse/morse.c2
-rw-r--r--share/man/man4/Makefile6
-rw-r--r--share/man/man4/man4.i386/Makefile2
-rw-r--r--share/man/man4/man4.i386/spkr.4249
-rw-r--r--share/man/man4/spkr.48
-rw-r--r--sys/amd64/conf/NOTES3
-rw-r--r--sys/conf/files.amd641
-rw-r--r--sys/conf/files.i3862
-rw-r--r--sys/conf/files.pc982
-rw-r--r--sys/dev/speaker/speaker.h6
-rw-r--r--sys/dev/speaker/spkr.c2
-rw-r--r--sys/i386/include/speaker.h23
-rw-r--r--sys/i386/isa/spkr.c656
-rw-r--r--sys/modules/Makefile1
-rw-r--r--sys/modules/speaker/Makefile2
16 files changed, 28 insertions, 939 deletions
diff --git a/games/morse/Makefile b/games/morse/Makefile
index 44b20ba..92d1121 100644
--- a/games/morse/Makefile
+++ b/games/morse/Makefile
@@ -4,7 +4,7 @@
PROG= morse
MAN= morse.6
-.if ${MACHINE_ARCH} == "i386"
+.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64"
CFLAGS += -DSPEAKER=\"/dev/speaker\"
.endif
diff --git a/games/morse/morse.c b/games/morse/morse.c
index eb9e4d4..87f97dc 100644
--- a/games/morse/morse.c
+++ b/games/morse/morse.c
@@ -64,7 +64,7 @@ static const char rcsid[] =
#include <unistd.h>
#ifdef SPEAKER
-#include <machine/speaker.h>
+#include <dev/speaker/speaker.h>
#endif
struct morsetab {
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index b22b7ed..d6e0d3d 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -301,6 +301,7 @@ MAN= aac.4 \
snd_vibes.4 \
snp.4 \
spic.4 \
+ ${_spkr.4} \
splash.4 \
sppp.4 \
ste.4 \
@@ -461,6 +462,7 @@ MLINKS+=sk.4 if_sk.4
MLINKS+=sl.4 if_sl.4
MLINKS+=smp.4 SMP.4
MLINKS+=sn.4 if_sn.4
+MLINKS+=${_spkr.4} ${_speaker.4}
MLINKS+=splash.4 screensaver.4
MLINKS+=ste.4 if_ste.4
MLINKS+=stf.4 if_stf.4
@@ -484,8 +486,10 @@ MLINKS+=xe.4 if_xe.4
MLINKS+=xl.4 if_xl.4
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386"
-_nve.4= nve.4
_if_nve.4= if_nve.4
+_nve.4= nve.4
+_spkr.4= spkr.4
+_speaker.4= speaker.4
.endif
.if exists(${.CURDIR}/man4.${MACHINE_ARCH})
diff --git a/share/man/man4/man4.i386/Makefile b/share/man/man4/man4.i386/Makefile
index 43e8525..c5ca2d7 100644
--- a/share/man/man4/man4.i386/Makefile
+++ b/share/man/man4/man4.i386/Makefile
@@ -43,7 +43,6 @@ MAN= acpi_asus.4 \
scd.4 \
smapi.4 \
snc.4 \
- spkr.4 \
sr.4 \
streams.4 \
svr4.4 \
@@ -57,7 +56,6 @@ MLINKS+=ndis.4 if_ndis.4
MLINKS+=oltr.4 if_oltr.4
MLINKS+=pae.4 PAE.4
MLINKS+=sbni.4 if_sbni.4
-MLINKS+=spkr.4 speaker.4
MANSUBDIR=/i386
diff --git a/share/man/man4/man4.i386/spkr.4 b/share/man/man4/man4.i386/spkr.4
deleted file mode 100644
index fc0ed99..0000000
--- a/share/man/man4/man4.i386/spkr.4
+++ /dev/null
@@ -1,249 +0,0 @@
-.\"
-.\" $FreeBSD$
-.\"
-.Dd November 7, 1993
-.Dt SPKR 4 i386
-.Os
-.Sh NAME
-.Nm speaker ,
-.Nm spkr
-.Nd console speaker device driver
-.Sh SYNOPSIS
-.Cd device speaker
-.In machine/speaker.h
-.Sh DESCRIPTION
-The speaker device driver allows applications to control the PC console
-speaker on an
-.Tn IBM-PC Ns --compatible
-machine running
-.Fx .
-.Pp
-Only one process may have this device open at any given time;
-.Xr open 2
-and
-.Xr close 2
-are used to lock and relinquish it.
-An attempt to open when
-another process has the device locked will return -1 with an
-.Er EBUSY
-error
-indication.
-Writes to the device are interpreted as `play strings' in a
-simple ASCII melody notation.
-An
-.Xr ioctl 2
-request
-for tone generation at arbitrary
-frequencies is also supported.
-.Pp
-Sound-generation does not monopolize the processor; in fact, the driver
-spends most of its time sleeping while the PC hardware is emitting
-tones.
-Other processes may emit beeps while the driver is running.
-.Pp
-Applications may call
-.Xr ioctl 2
-on a speaker file descriptor to control the
-speaker driver directly; definitions for the
-.Xr ioctl 2
-interface are in
-.In machine/speaker.h .
-The
-.Li tone_t
-structure used in these calls has two fields,
-specifying a frequency (in Hz) and a duration (in 1/100ths of a second).
-A frequency of zero is interpreted as a rest.
-.Pp
-At present there are two such
-.Xr ioctl 2
-calls.
-.Dv SPKRTONE
-accepts a pointer to a
-single tone structure as third argument and plays it.
-.Dv SPKRTUNE
-accepts a
-pointer to the first of an array of tone structures and plays them in
-continuous sequence; this array must be terminated by a final member with
-a zero duration.
-.Pp
-The play-string language is modeled on the PLAY statement conventions of
-.Tn IBM
-Advanced BASIC 2.0.
-The
-.Li MB ,
-.Li MF ,
-and
-.Li X
-primitives of PLAY are not
-useful in a timesharing environment and are omitted.
-The `octave-tracking'
-feature and the slur mark are new.
-.Pp
-There are 84 accessible notes numbered 1-84 in 7 octaves, each running from
-C to B, numbered 0-6; the scale is equal-tempered A440 and octave 3 starts
-with middle C.
-By default, the play function emits half-second notes with the
-last 1/16th second being `rest time'.
-.Pp
-Play strings are interpreted left to right as a series of play command groups;
-letter case is ignored.
-Play command groups are as follows:
-.Bl -tag -width CDEFGABxx
-.It Li CDEFGAB
-Letters A through G cause the corresponding note to be played in the
-current octave.
-A note letter may optionally be followed by an
-.Dq Em "accidental sign" ,
-one of # + or -; the first two of these cause it to be sharped one
-half-tone, the last causes it to be flatted one half-tone.
-It may
-also be followed by a time value number and by sustain dots (see
-below).
-Time values are interpreted as for the L command below.
-.It Ns Li O Sy n
-If
-.Sy n
-is numeric, this sets the current octave.
-.Sy n
-may also be one of
-.Li L
-or
-.Li N
-to enable or disable octave-tracking (it is disabled by default).
-When octave-tracking is on, interpretation of a pair of letter notes
-will change octaves if necessary in order to make the smallest
-possible jump between notes.
-Thus ``olbc'' will be played as
-``olb>c'', and ``olcb'' as ``olc<b''.
-Octave locking is disabled for
-one letter note following >, < and O[0123456].
-(The octave-locking
-feature is not supported in
-.Tn IBM
-BASIC.)
-.It Li >
-Bump the current octave up one.
-.It Li <
-Drop the current octave down one.
-.It Ns Li N Sy n
-Play note
-.Sy n ,
-.Sy n
-being 1 to 84 or 0 for a rest of current time value.
-May be followed by sustain dots.
-.It Ns Li L Sy n
-Sets the current time value for notes.
-The default is
-.Li L4 ,
-quarter or crotchet notes.
-The lowest possible value is 1; values up
-to 64 are accepted.
-.Li L1
-sets whole notes,
-.Li L2
-sets half notes,
-.Li L4
-sets quarter notes, etc.
-.It Ns Li P Sy n
-Pause (rest), with
-.Sy n
-interpreted as for
-.Li L Sy n .
-May be followed by
-sustain dots.
-May also be written
-.Li ~ .
-.It Ns Li T Sy n
-Sets the number of quarter notes per minute; default is 120.
-Musical
-names for common tempi are:
-.Bd -literal -offset indent
- Tempo Beats Per Minute
-very slow Larghissimo
- Largo 40-60
- Larghetto 60-66
- Grave
- Lento
- Adagio 66-76
-slow Adagietto
- Andante 76-108
-medium Andantino
- Moderato 108-120
-fast Allegretto
- Allegro 120-168
- Vivace
- Veloce
- Presto 168-208
-very fast Prestissimo
-.Ed
-.It Li M[LNS]
-Set articulation.
-.Li MN
-.Li ( N
-for normal) is the default; the last 1/8th of
-the note's value is rest time.
-You can set
-.Li ML
-for legato (no rest space) or
-.Li MS
-for staccato (1/4 rest space).
-.El
-.Pp
-Notes (that is,
-.Li CDEFGAB
-or
-.Li N
-command character groups) may be followed by
-sustain dots.
-Each dot causes the note's value to be lengthened by one-half
-for each one.
-Thus, a note dotted once is held for 3/2 of its undotted value;
-dotted twice, it is held 9/4, and three times would give 27/8.
-.Pp
-A note and its sustain dots may also be followed by a slur mark (underscore).
-This causes the normal micro-rest after the note to be filled in, slurring it
-to the next one.
-(The slur feature is not supported in
-.Tn IBM
-BASIC.)
-.Pp
-Whitespace in play strings is simply skipped and may be used to separate
-melody sections.
-.Sh FILES
-.Bl -tag -width /dev/speakerxx
-.It Pa /dev/speaker
-speaker device file
-.El
-.Sh SEE ALSO
-.Xr spkrtest 8
-.Sh HISTORY
-The
-.Nm
-device appeared in
-.Fx 1.0 .
-.Sh AUTHORS
-.An Eric S. Raymond Aq esr@snark.thyrsus.com
-June 1990
-.Sh "PORTED BY"
-.An Andrew A. Chernov Aq ache@astral.msk.su
-.Sh BUGS
-Due to roundoff in the pitch tables and slop in the tone-generation and timer
-hardware (neither of which was designed for precision), neither pitch accuracy
-nor timings will be mathematically exact.
-There is no volume control.
-.Pp
-The action of two or more sustain dots does not reflect standard musical
-notation, in which each dot adds half the value of the previous dot
-modifier, not half the value of the note as modified.
-Thus, a note dotted
-once is held for 3/2 of its undotted value; dotted twice, it is held 7/4,
-and three times would give 15/8.
-The multiply-by-3/2 interpretation,
-however, is specified in the
-.Tn IBM
-BASIC manual and has been retained for
-compatibility.
-.Pp
-In play strings which are very long (longer than your system's physical I/O
-blocks) note suffixes or numbers may occasionally be parsed incorrectly due
-to crossing a block boundary.
diff --git a/share/man/man4/spkr.4 b/share/man/man4/spkr.4
index fc0ed99..1f39a1ee 100644
--- a/share/man/man4/spkr.4
+++ b/share/man/man4/spkr.4
@@ -1,8 +1,8 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 7, 1993
-.Dt SPKR 4 i386
+.Dd November 10, 2005
+.Dt SPKR 4
.Os
.Sh NAME
.Nm speaker ,
@@ -10,7 +10,7 @@
.Nd console speaker device driver
.Sh SYNOPSIS
.Cd device speaker
-.In machine/speaker.h
+.In dev/speaker/speaker.h
.Sh DESCRIPTION
The speaker device driver allows applications to control the PC console
speaker on an
@@ -47,7 +47,7 @@ on a speaker file descriptor to control the
speaker driver directly; definitions for the
.Xr ioctl 2
interface are in
-.In machine/speaker.h .
+.In dev/speaker/speaker.h .
The
.Li tone_t
structure used in these calls has two fields,
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index ee8aaf8..8f1566d 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -107,6 +107,9 @@ options CLK_USE_I8254_CALIBRATION
#####################################################################
# MISCELLANEOUS DEVICES AND OPTIONS
+device speaker #Play IBM BASIC-style noises out your speaker
+hint.speaker.0.at="isa"
+hint.speaker.0.port="0x61"
device gzip #Exec gzipped a.out's. REQUIRES COMPAT_AOUT!
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index d2ed8d7..eb742e3 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -179,6 +179,7 @@ dev/ppc/ppc.c optional ppc
dev/ppc/ppc_puc.c optional ppc puc
dev/sio/sio.c optional sio
dev/sio/sio_isa.c optional sio isa
+dev/speaker/spkr.c optional speaker
dev/syscons/apm/apm_saver.c optional apm_saver apm
dev/syscons/schistory.c optional sc
dev/syscons/scmouse.c optional sc
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index f5de557..770066d 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -208,6 +208,7 @@ dev/sbni/if_sbni_isa.c optional sbni isa
dev/sbni/if_sbni_pci.c optional sbni pci
dev/sio/sio.c optional sio
dev/sio/sio_isa.c optional sio isa
+dev/speaker/spkr.c optional speaker
dev/sr/if_sr_isa.c optional sr isa
dev/syscons/apm/apm_saver.c optional apm_saver apm
dev/syscons/schistory.c optional sc
@@ -335,7 +336,6 @@ i386/isa/pcvt/pcvt_vtf.c optional vt
i386/isa/pmtimer.c optional pmtimer
i386/isa/prof_machdep.c optional profiling-routine
i386/isa/spic.c optional spic
-i386/isa/spkr.c optional speaker
i386/isa/vesa.c optional vga vesa
i386/linux/imgact_linux.c optional compat_linux
i386/linux/linux_dummy.c optional compat_linux
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index 41024b1..06a9e1a 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -126,6 +126,7 @@ dev/snc/dp83932subr.c optional snc
dev/snc/if_snc.c optional snc
dev/snc/if_snc_cbus.c optional snc isa
dev/snc/if_snc_pccard.c optional snc pccard
+dev/speaker/spkr.c optional speaker
dev/syscons/apm/apm_saver.c optional apm_saver apm
dev/syscons/schistory.c optional sc
dev/syscons/scmouse.c optional sc
@@ -212,7 +213,6 @@ i386/isa/isa.c optional isa
i386/isa/npx.c optional npx
i386/isa/pmtimer.c optional pmtimer
i386/isa/prof_machdep.c optional profiling-routine
-i386/isa/spkr.c optional speaker
i386/linux/imgact_linux.c optional compat_linux
i386/linux/linux_dummy.c optional compat_linux
i386/linux/linux_locore.s optional compat_linux \
diff --git a/sys/dev/speaker/speaker.h b/sys/dev/speaker/speaker.h
index 6b1f021..9e195c3 100644
--- a/sys/dev/speaker/speaker.h
+++ b/sys/dev/speaker/speaker.h
@@ -7,8 +7,8 @@
* $FreeBSD$
*/
-#ifndef _MACHINE_SPEAKER_H_
-#define _MACHINE_SPEAKER_H_
+#ifndef _DEV_SPEAKER_SPEAKER_H_
+#define _DEV_SPEAKER_SPEAKER_H_
#include <sys/ioccom.h>
@@ -26,4 +26,4 @@ typedef struct
* see the spkr(4) man page for details.
*/
-#endif /* !_MACHINE_SPEAKER_H_ */
+#endif /* !_DEV_SPEAKER_SPEAKER_H_ */
diff --git a/sys/dev/speaker/spkr.c b/sys/dev/speaker/spkr.c
index d265e7c..bad65c1 100644
--- a/sys/dev/speaker/spkr.c
+++ b/sys/dev/speaker/spkr.c
@@ -20,9 +20,9 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <isa/isavar.h>
#include <machine/clock.h>
-#include <machine/speaker.h>
#include <machine/ppireg.h>
#include <machine/timerreg.h>
+#include <dev/speaker/speaker.h>
static d_open_t spkropen;
static d_close_t spkrclose;
diff --git a/sys/i386/include/speaker.h b/sys/i386/include/speaker.h
index 6b1f021..2950b47 100644
--- a/sys/i386/include/speaker.h
+++ b/sys/i386/include/speaker.h
@@ -1,29 +1,16 @@
/*
- * speaker.h -- interface definitions for speaker ioctl()
- *
- * v1.4 by Eric S. Raymond (esr@snark.thyrsus.com) Aug 1993
- * modified for FreeBSD by Andrew A. Chernov <ache@astral.msk.su>
- *
* $FreeBSD$
*/
#ifndef _MACHINE_SPEAKER_H_
#define _MACHINE_SPEAKER_H_
-#include <sys/ioccom.h>
+#include <sys/cdefs.h>
-#define SPKRTONE _IOW('S', 1, tone_t) /* emit tone */
-#define SPKRTUNE _IO('S', 2) /* emit tone sequence*/
+#ifdef __CC_SUPPORTS_WARNING
+#warning "machine/speaker.h is deprecated. Include dev/speaker/speaker.h instead."
+#endif
-typedef struct
-{
- int frequency; /* in hertz */
- int duration; /* in 1/100ths of a second */
-} tone_t;
-
-/*
- * Strings written to the speaker device are interpreted as tunes and played;
- * see the spkr(4) man page for details.
- */
+#include <dev/speaker/speaker.h>
#endif /* !_MACHINE_SPEAKER_H_ */
diff --git a/sys/i386/isa/spkr.c b/sys/i386/isa/spkr.c
deleted file mode 100644
index d265e7c..0000000
--- a/sys/i386/isa/spkr.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/*-
- * spkr.c -- device driver for console speaker
- *
- * v1.4 by Eric S. Raymond (esr@snark.thyrsus.com) Aug 1993
- * modified for FreeBSD by Andrew A. Chernov <ache@astral.msk.su>
- * modified for PC98 by Kakefuda
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/uio.h>
-#include <sys/conf.h>
-#include <sys/ctype.h>
-#include <sys/malloc.h>
-#include <isa/isavar.h>
-#include <machine/clock.h>
-#include <machine/speaker.h>
-#include <machine/ppireg.h>
-#include <machine/timerreg.h>
-
-static d_open_t spkropen;
-static d_close_t spkrclose;
-static d_write_t spkrwrite;
-static d_ioctl_t spkrioctl;
-
-static struct cdevsw spkr_cdevsw = {
- .d_version = D_VERSION,
- .d_flags = D_NEEDGIANT,
- .d_open = spkropen,
- .d_close = spkrclose,
- .d_write = spkrwrite,
- .d_ioctl = spkrioctl,
- .d_name = "spkr",
-};
-
-static MALLOC_DEFINE(M_SPKR, "spkr", "Speaker buffer");
-
-/**************** MACHINE DEPENDENT PART STARTS HERE *************************
- *
- * This section defines a function tone() which causes a tone of given
- * frequency and duration from the ISA console speaker.
- * Another function endtone() is defined to force sound off, and there is
- * also a rest() entry point to do pauses.
- *
- * Audible sound is generated using the Programmable Interval Timer (PIT) and
- * Programmable Peripheral Interface (PPI) attached to the ISA speaker. The
- * PPI controls whether sound is passed through at all; the PIT's channel 2 is
- * used to generate clicks (a square wave) of whatever frequency is desired.
- */
-
-#ifdef PC98
-#define SPKR_DESC "PC98 speaker"
-#else
-#define SPKR_DESC "PC speaker"
-#endif
-
-#define SPKRPRI PSOCK
-static char endtone, endrest;
-
-static void tone(unsigned int thz, unsigned int ticks);
-static void rest(int ticks);
-static void playinit(void);
-static void playtone(int pitch, int value, int sustain);
-static void playstring(char *cp, size_t slen);
-
-/* emit tone of frequency thz for given number of ticks */
-static void
-tone(thz, ticks)
- unsigned int thz, ticks;
-{
- unsigned int divisor;
- int sps;
-
- if (thz <= 0)
- return;
-
- divisor = timer_freq / thz;
-
-#ifdef DEBUG
- (void) printf("tone: thz=%d ticks=%d\n", thz, ticks);
-#endif /* DEBUG */
-
- /* set timer to generate clicks at given frequency in Hertz */
- sps = splclock();
-
- if (timer_spkr_acquire()) {
- /* enter list of waiting procs ??? */
- splx(sps);
- return;
- }
- splx(sps);
- disable_intr();
- spkr_set_pitch(divisor);
- enable_intr();
-
- /* turn the speaker on */
- ppi_spkr_on();
-
- /*
- * Set timeout to endtone function, then give up the timeslice.
- * This is so other processes can execute while the tone is being
- * emitted.
- */
- if (ticks > 0)
- tsleep(&endtone, SPKRPRI | PCATCH, "spkrtn", ticks);
- ppi_spkr_off();
- sps = splclock();
- timer_spkr_release();
- splx(sps);
-}
-
-/* rest for given number of ticks */
-static void
-rest(ticks)
- 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 DEBUG
- (void) printf("rest: %d\n", ticks);
-#endif /* DEBUG */
- if (ticks > 0)
- tsleep(&endrest, SPKRPRI | PCATCH, "spkrrs", ticks);
-}
-
-/**************** PLAY STRING INTERPRETER BEGINS HERE **********************
- *
- * Play string interpretation is modelled on IBM BASIC 2.0's PLAY statement;
- * M[LNS] are missing; the ~ synonym and the _ slur mark and the octave-
- * tracking facility are added.
- * Requires tone(), rest(), and endtone(). String play is not interruptible
- * except possibly at physical block boundaries.
- */
-
-typedef int bool;
-#define TRUE 1
-#define FALSE 0
-
-#define dtoi(c) ((c) - '0')
-
-static int octave; /* currently selected octave */
-static int whole; /* whole-note time at current tempo, in ticks */
-static int value; /* whole divisor for note time, quarter note = 1 */
-static int fill; /* controls spacing of notes */
-static bool octtrack; /* octave-tracking on? */
-static bool octprefix; /* override current octave-tracking state? */
-
-/*
- * Magic number avoidance...
- */
-#define SECS_PER_MIN 60 /* seconds per minute */
-#define WHOLE_NOTE 4 /* quarter notes per whole note */
-#define MIN_VALUE 64 /* the most we can divide a note by */
-#define DFLT_VALUE 4 /* default value (quarter-note) */
-#define FILLTIME 8 /* for articulation, break note in parts */
-#define STACCATO 6 /* 6/8 = 3/4 of note is filled */
-#define NORMAL 7 /* 7/8ths of note interval is filled */
-#define LEGATO 8 /* all of note interval is filled */
-#define DFLT_OCTAVE 4 /* default octave */
-#define MIN_TEMPO 32 /* minimum tempo */
-#define DFLT_TEMPO 120 /* default tempo */
-#define MAX_TEMPO 255 /* max tempo */
-#define NUM_MULT 3 /* numerator of dot multiplier */
-#define DENOM_MULT 2 /* denominator of dot multiplier */
-
-/* letter to half-tone: A B C D E F G */
-static int notetab[8] = {9, 11, 0, 2, 4, 5, 7};
-
-/*
- * This is the American Standard A440 Equal-Tempered scale with frequencies
- * rounded to nearest integer. Thank Goddess for the good ol' CRC Handbook...
- * our octave 0 is standard octave 2.
- */
-#define OCTAVE_NOTES 12 /* semitones per octave */
-static int pitchtab[] =
-{
-/* C C# D D# E F F# G G# A A# B*/
-/* 0 */ 65, 69, 73, 78, 82, 87, 93, 98, 103, 110, 117, 123,
-/* 1 */ 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247,
-/* 2 */ 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494,
-/* 3 */ 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988,
-/* 4 */ 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1975,
-/* 5 */ 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951,
-/* 6 */ 4186, 4435, 4698, 4978, 5274, 5588, 5920, 6272, 6644, 7040, 7459, 7902,
-};
-
-static void
-playinit()
-{
- octave = DFLT_OCTAVE;
- whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO;
- fill = NORMAL;
- value = DFLT_VALUE;
- octtrack = FALSE;
- octprefix = TRUE; /* act as though there was an initial O(n) */
-}
-
-/* play tone of proper duration for current rhythm signature */
-static void
-playtone(pitch, value, sustain)
- int pitch, value, sustain;
-{
- register int sound, silence, snum = 1, sdenom = 1;
-
- /* this weirdness avoids floating-point arithmetic */
- for (; sustain; sustain--)
- {
- /* See the BUGS section in the man page for discussion */
- snum *= NUM_MULT;
- sdenom *= DENOM_MULT;
- }
-
- if (value == 0 || sdenom == 0)
- return;
-
- if (pitch == -1)
- rest(whole * snum / (value * sdenom));
- else
- {
- sound = (whole * snum) / (value * sdenom)
- - (whole * (FILLTIME - fill)) / (value * FILLTIME);
- silence = whole * (FILLTIME-fill) * snum / (FILLTIME * value * sdenom);
-
-#ifdef DEBUG
- (void) printf("playtone: pitch %d for %d ticks, rest for %d ticks\n",
- pitch, sound, silence);
-#endif /* DEBUG */
-
- tone(pitchtab[pitch], sound);
- if (fill != LEGATO)
- rest(silence);
- }
-}
-
-/* interpret and play an item from a notation string */
-static void
-playstring(cp, slen)
- char *cp;
- size_t slen;
-{
- int pitch, oldfill, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE;
-
-#define GETNUM(cp, v) for(v=0; isdigit(cp[1]) && slen > 0; ) \
- {v = v * 10 + (*++cp - '0'); slen--;}
- for (; slen--; cp++)
- {
- int sustain, timeval, tempo;
- register char c = toupper(*cp);
-
-#ifdef DEBUG
- (void) printf("playstring: %c (%x)\n", c, c);
-#endif /* DEBUG */
-
- switch (c)
- {
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
-
- /* compute pitch */
- pitch = notetab[c - 'A'] + octave * OCTAVE_NOTES;
-
- /* this may be followed by an accidental sign */
- if (cp[1] == '#' || cp[1] == '+')
- {
- ++pitch;
- ++cp;
- slen--;
- }
- else if (cp[1] == '-')
- {
- --pitch;
- ++cp;
- slen--;
- }
-
- /*
- * If octave-tracking mode is on, and there has been no octave-
- * setting prefix, find the version of the current letter note
- * closest to the last regardless of octave.
- */
- if (octtrack && !octprefix)
- {
- if (abs(pitch-lastpitch) > abs(pitch+OCTAVE_NOTES-lastpitch))
- {
- ++octave;
- pitch += OCTAVE_NOTES;
- }
-
- if (abs(pitch-lastpitch) > abs((pitch-OCTAVE_NOTES)-lastpitch))
- {
- --octave;
- pitch -= OCTAVE_NOTES;
- }
- }
- octprefix = FALSE;
- lastpitch = pitch;
-
- /* ...which may in turn be followed by an override time value */
- GETNUM(cp, timeval);
- if (timeval <= 0 || timeval > MIN_VALUE)
- timeval = value;
-
- /* ...and/or sustain dots */
- for (sustain = 0; cp[1] == '.'; cp++)
- {
- slen--;
- sustain++;
- }
-
- /* ...and/or a slur mark */
- oldfill = fill;
- if (cp[1] == '_')
- {
- fill = LEGATO;
- ++cp;
- slen--;
- }
-
- /* time to emit the actual tone */
- playtone(pitch, timeval, sustain);
-
- fill = oldfill;
- break;
-
- case 'O':
- if (cp[1] == 'N' || cp[1] == 'n')
- {
- octprefix = octtrack = FALSE;
- ++cp;
- slen--;
- }
- else if (cp[1] == 'L' || cp[1] == 'l')
- {
- octtrack = TRUE;
- ++cp;
- slen--;
- }
- else
- {
- GETNUM(cp, octave);
- if (octave >= sizeof(pitchtab) / sizeof(pitchtab[0]) / OCTAVE_NOTES)
- octave = DFLT_OCTAVE;
- octprefix = TRUE;
- }
- break;
-
- case '>':
- if (octave < sizeof(pitchtab) / sizeof(pitchtab[0]) / OCTAVE_NOTES - 1)
- octave++;
- octprefix = TRUE;
- break;
-
- case '<':
- if (octave > 0)
- octave--;
- octprefix = TRUE;
- break;
-
- case 'N':
- GETNUM(cp, pitch);
- for (sustain = 0; cp[1] == '.'; cp++)
- {
- slen--;
- sustain++;
- }
- oldfill = fill;
- if (cp[1] == '_')
- {
- fill = LEGATO;
- ++cp;
- slen--;
- }
- playtone(pitch - 1, value, sustain);
- fill = oldfill;
- break;
-
- case 'L':
- GETNUM(cp, value);
- if (value <= 0 || value > MIN_VALUE)
- value = DFLT_VALUE;
- break;
-
- case 'P':
- case '~':
- /* this may be followed by an override time value */
- GETNUM(cp, timeval);
- if (timeval <= 0 || timeval > MIN_VALUE)
- timeval = value;
- for (sustain = 0; cp[1] == '.'; cp++)
- {
- slen--;
- sustain++;
- }
- playtone(-1, timeval, sustain);
- break;
-
- case 'T':
- GETNUM(cp, tempo);
- if (tempo < MIN_TEMPO || tempo > MAX_TEMPO)
- tempo = DFLT_TEMPO;
- whole = (hz * SECS_PER_MIN * WHOLE_NOTE) / tempo;
- break;
-
- case 'M':
- if (cp[1] == 'N' || cp[1] == 'n')
- {
- fill = NORMAL;
- ++cp;
- slen--;
- }
- else if (cp[1] == 'L' || cp[1] == 'l')
- {
- fill = LEGATO;
- ++cp;
- slen--;
- }
- else if (cp[1] == 'S' || cp[1] == 's')
- {
- fill = STACCATO;
- ++cp;
- slen--;
- }
- break;
- }
- }
-}
-
-/******************* UNIX DRIVER HOOKS BEGIN HERE **************************
- *
- * This section implements driver hooks to run playstring() and the tone(),
- * endtone(), and rest() functions defined above.
- */
-
-static int spkr_active = FALSE; /* exclusion flag */
-static char *spkr_inbuf; /* incoming buf */
-
-static int
-spkropen(dev, flags, fmt, td)
- struct cdev *dev;
- int flags;
- int fmt;
- struct thread *td;
-{
-#ifdef DEBUG
- (void) printf("spkropen: entering with dev = %s\n", devtoname(dev));
-#endif /* DEBUG */
-
- if (minor(dev) != 0)
- return(ENXIO);
- else if (spkr_active)
- return(EBUSY);
- else
- {
-#ifdef DEBUG
- (void) printf("spkropen: about to perform play initialization\n");
-#endif /* DEBUG */
- playinit();
- spkr_inbuf = malloc(DEV_BSIZE, M_SPKR, M_WAITOK);
- spkr_active = TRUE;
- return(0);
- }
-}
-
-static int
-spkrwrite(dev, uio, ioflag)
- struct cdev *dev;
- struct uio *uio;
- int ioflag;
-{
-#ifdef DEBUG
- printf("spkrwrite: entering with dev = %s, count = %d\n",
- devtoname(dev), uio->uio_resid);
-#endif /* DEBUG */
-
- if (minor(dev) != 0)
- return(ENXIO);
- else if (uio->uio_resid > (DEV_BSIZE - 1)) /* prevent system crashes */
- return(E2BIG);
- else
- {
- unsigned n;
- char *cp;
- int error;
-
- n = uio->uio_resid;
- cp = spkr_inbuf;
- error = uiomove(cp, n, uio);
- if (!error) {
- cp[n] = '\0';
- playstring(cp, n);
- }
- return(error);
- }
-}
-
-static int
-spkrclose(dev, flags, fmt, td)
- struct cdev *dev;
- int flags;
- int fmt;
- struct thread *td;
-{
-#ifdef DEBUG
- (void) printf("spkrclose: entering with dev = %s\n", devtoname(dev));
-#endif /* DEBUG */
-
- if (minor(dev) != 0)
- return(ENXIO);
- else
- {
- wakeup(&endtone);
- wakeup(&endrest);
- free(spkr_inbuf, M_SPKR);
- spkr_active = FALSE;
- return(0);
- }
-}
-
-static int
-spkrioctl(dev, cmd, cmdarg, flags, td)
- struct cdev *dev;
- unsigned long cmd;
- caddr_t cmdarg;
- int flags;
- struct thread *td;
-{
-#ifdef DEBUG
- (void) printf("spkrioctl: entering with dev = %s, cmd = %lx\n",
- devtoname(dev), cmd);
-#endif /* DEBUG */
-
- if (minor(dev) != 0)
- return(ENXIO);
- else if (cmd == SPKRTONE)
- {
- tone_t *tp = (tone_t *)cmdarg;
-
- if (tp->frequency == 0)
- rest(tp->duration);
- else
- tone(tp->frequency, tp->duration);
- return 0;
- }
- else if (cmd == SPKRTUNE)
- {
- tone_t *tp = (tone_t *)(*(caddr_t *)cmdarg);
- tone_t ttp;
- int error;
-
- for (; ; tp++) {
- error = copyin(tp, &ttp, sizeof(tone_t));
- if (error)
- return(error);
- if (ttp.duration == 0)
- break;
- if (ttp.frequency == 0)
- rest(ttp.duration);
- else
- tone(ttp.frequency, ttp.duration);
- }
- return(0);
- }
- return(EINVAL);
-}
-
-/*
- * Install placeholder to claim the resources owned by the
- * AT tone generator.
- */
-static struct isa_pnp_id speaker_ids[] = {
-#ifndef PC98
- { 0x0008d041 /* PNP0800 */, SPKR_DESC },
-#endif
- { 0 }
-};
-
-static struct cdev *speaker_dev;
-
-static int
-speaker_probe(device_t dev)
-{
- int error;
-
- error = ISA_PNP_PROBE(device_get_parent(dev), dev, speaker_ids);
-
- /* PnP match */
- if (error == 0)
- return (0);
-
- /* No match */
- if (error == ENXIO)
- return (ENXIO);
-
- /* Not configured by hints. */
- if (strncmp(device_get_name(dev), "speaker", 9))
- return (ENXIO);
-
- device_set_desc(dev, SPKR_DESC);
-
- return (0);
-}
-
-static int
-speaker_attach(device_t dev)
-{
-
- if (speaker_dev) {
- device_printf(dev, "Already attached!\n");
- return (ENXIO);
- }
-
- speaker_dev = make_dev(&spkr_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
- "speaker");
- return (0);
-}
-
-static int
-speaker_detach(device_t dev)
-{
- destroy_dev(speaker_dev);
- return (0);
-}
-
-static device_method_t speaker_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, speaker_probe),
- DEVMETHOD(device_attach, speaker_attach),
- DEVMETHOD(device_detach, speaker_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- { 0, 0 }
-};
-
-static driver_t speaker_driver = {
- "speaker",
- speaker_methods,
- 1, /* no softc */
-};
-
-static devclass_t speaker_devclass;
-
-DRIVER_MODULE(speaker, isa, speaker_driver, speaker_devclass, 0, 0);
-#ifndef PC98
-DRIVER_MODULE(speaker, acpi, speaker_driver, speaker_devclass, 0, 0);
-#endif
-
-/* spkr.c ends here */
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 41dd04f..c11405f 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -448,6 +448,7 @@ _safe= safe
_scsi_low= scsi_low
_smbfs= smbfs
_sound= sound
+_speaker= speaker
_sppp= sppp
_twa= twa
.endif
diff --git a/sys/modules/speaker/Makefile b/sys/modules/speaker/Makefile
index 69267d5..1a4c5ac 100644
--- a/sys/modules/speaker/Makefile
+++ b/sys/modules/speaker/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
-.PATH: ${.CURDIR}/../../i386/isa
+.PATH: ${.CURDIR}/../../dev/speaker
KMOD= speaker
SRCS= spkr.c
OpenPOWER on IntegriCloud