From: jwalz Date: Sat, 5 Jan 2002 21:05:59 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: MOVE2GIT~3659 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=60778cbe7d33b21526cfb515e4c0bdcb55fdfbce;p=nethack *** empty log message *** --- diff --git a/sys/unix/snd86unx.shr b/sys/unix/snd86unx.shr new file mode 100644 index 000000000..bfbae3fd2 --- /dev/null +++ b/sys/unix/snd86unx.shr @@ -0,0 +1,1064 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# READ.ME +# install.bsd +# spkr.7 +# Makefile +# spkr.c +# spkr.h +# interp.c +# Files +# Install +# Master +# Name +# Node +# Remove +# Size +# System +# playtest +# +echo x - READ.ME +sed 's/^X//' >READ.ME << 'END-of-READ.ME' +X Console Speaker Driver Package (v1.1) +X +X by Eric S. Raymond (esr@snark.thyrsus.com) +X +XThis package gives 80386 machines running SVr3.2 or later the ability to play +Xtunes on the console speaker. It has been extended to 386BSD (and possibly +XBSDI) by Andrew A. Chernov, and to SCO UNIX 3.2.4 (and possibly other VPIX +Xsystems) by Andreas Arens. +X +XThe following files are contained in the kit: +X +XDocumentation and examples: +XREAD.ME -- this file +Xspeaker.7 -- man page for the driver +Xplaytest -- test script exercising familiar tunes +X +XInstallable driver kit parts, for SVr3.2 or later: +XFiles -- list of driver package file locations +XInstall -- installation script for driver kit +XMaster -- mdevice entry for speaker driver +XName -- name entry foe speaker driver +XNode -- /dev node specification file +XRemove -- Driver removal script +XSize -- installation size data +XSystem -- sdevice entry for speaker driver +X +XDriver source code, for SVr3.2 or later and 386BSD: +XMakefile -- Makefile for driver code +Xspkr.c -- the driver source +Xspeaker.h -- ioctl interface file +X +XCommon source code: +Xinterp.c -- play string interpretation code +X +XFor SVr3.2 or later, simply type `make' and wait. Then type ./Install +Xand follow its instructions. You will have to install the man pages by hand. +XBe aware that the speaker.7 man page uses tbl(1) constructs. +X +XFor 386BSD, follow the installation instructions in install.bsd. +X +XFor SCO UNIX 3.2.4, no new kernel drivers are needed, and you need only +Xcopy interp.c to your src directory and proceed with making NetHack, with +XVPIX_MUSIC set in unixconf.h. +X +XInteresting tunes mailed to the author will be periodically posted in batches +Xand added to the test script for future versions. +X +X Revision notes +X +X1.1 -- fixed minor bug in M[LSN] interpretation, added octave-tracking. +X Tweaked the playtest examples. +END-of-READ.ME +echo x - install.bsd +sed 's/^X//' >install.bsd << 'END-of-install.bsd' +XCopy spkr.c and interp.c to /sys/i386/isa +XCopy spkr.h to /sys/sys +X +X----------------------------------------------------------------------------- +X +XFile /sys/i386/conf/YOUR_MACHINE_NAME +Xadd following line: +X +Xpseudo-device speaker +X +X----------------------------------------------------------------------------- +X +XFile /sys/i386/conf/files.i386 +Xadd following line: +X +Xi386/isa/spkr.c optional speaker +X +X----------------------------------------------------------------------------- +X +XFile /sys/i386/i386/conf.c +X[major number 20 (hex) is registered for spkr driver, don't change it] +Xadd following code: +X +X#include "speaker.h" +X#if NSPEAKER > 0 +Xint spkropen(),spkrclose(),spkrwrite(),spkrioctl(); +X#else +X#define spkropen enxio +X#define spkrclose enxio +X#define spkrwrite enxio +X#define spkrioctl enxio +X#endif +X ... +X +Xstruct cdevsw cdevsw[] = +X{ +X ... +X +X { spkropen, spkrclose, enxio, spkrwrite, /*20*/ +X spkrioctl, enxio, enxio, NULL, +X enxio, enxio, enxio }, +X ... +X +X----------------------------------------------------------------------------- +X +XMake corresponding device: +X +X mknod /dev/speaker c 32 0 +X +X[major number 32 (20 hex) is registered for spkr driver, don't change it] +X +X----------------------------------------------------------------------------- +X +XGo to /sys/i386/conf and type +X config YOUR_MACHINE_NAME +Xthen go to /sys/compile/YOUR_MACHINE_NAME and type +X make depend +X make +X +END-of-install.bsd +echo x - spkr.7 +sed 's/^X//' >spkr.7 << 'END-of-spkr.7' +X.TH SPKR 7 +X.SH NAME +Xspkr \- console speaker device driver +X.SH DESCRIPTION +XThe speaker device driver allows applications to control the PC console +Xspeaker on an IBM-PC-compatible machine running UNIX. +X.PP +XOnly one process may have this device open at any given time; open() and +Xclose() are used to lock and relinquish it. An attempt to open() when +Xanother process has the device locked will return -1 with an EBUSY error +Xindication. Writes to the device are interpreted as 'play strings' in a +Xsimple ASCII melody notation. An ioctl() for tone generation at arbitrary +Xfrequencies is also supported. +X.PP +XSound-generation does \fInot\fR monopolize the processor; in fact, the driver +Xspends most of its time sleeping while the PC hardware is emitting +Xtones. Other processes may emit beeps while the driver is running. +X.PP +XApplications may call ioctl() on a speaker file descriptor to control the +Xspeaker driver directly; definitions for the ioctl() interface are in +Xsys/spkr.h. The tone_t structure used in these calls has two fields, +Xspecifying a frequency (in hz) and a duration (in 1/100ths of a second). +XA frequency of zero is interpreted as a rest. +X.PP +XAt present there are two such ioctls. SPKRTONE accepts a pointer to a +Xsingle tone structure as third argument and plays it. SPKRTUNE accepts a +Xpointer to the first of an array of tone structures and plays them in +Xcontinuous sequence; this array must be terminated by a final member with +Xa zero duration. +X.PP +XThe play-string language is modelled on the PLAY statement conventions of +XIBM BASIC 2.0. The MB, MF and X primitives of PLAY are not useful in a UNIX +Xenvironment and are omitted. The `octave-tracking' feature is also new. +X.PP +XThere are 84 accessible notes numbered 1-83 in 7 octaves, each running from +XC to B, numbered 0-6; the scale is equal-tempered A440 and octave 3 starts +Xwith middle C. By default, the play function emits half-second notes with the +Xlast 1/16th second being `rest time'. +X.PP +XPlay strings are interpreted left to right as a series of play command groups; +Xletter case is ignored. Play command groups are as follows: +X.PP +XCDEFGAB -- letters A through G cause the corresponding note to be played in the +Xcurrent octave. A note letter may optionally be followed by an \fIaccidental +Xsign\fR, one of # + or -; the first two of these cause it to be sharped one +Xhalf-tone, the last causes it to be flatted one half-tone. It may also be +Xfollowed by a time value number and by sustain dots (see below). Time values +Xare interpreted as for the L command below;. +X.PP +XO -- if is numeric, this sets the current octave. may also be one +Xof 'L' or 'N' to enable or disable octave-tracking (it is disabled by default). +XWhen octave-tracking is on, interpretation of a pair of letter notes will +Xchange octaves if necessary in order to make the smallest possible jump between +Xnotes. Thus "olbc" will be played as "olb>c", and "olcb" as "olc, < and O[0123456]. +X.PP +X> -- bump the current octave up one. +X.PP +X< -- drop the current octave down one. +X.PP +XN -- play note n, n being 1 to 84 or 0 for a rest of current time value. +XMay be followedv by sustain dots. +X.PP +XL -- sets the current time value for notes. The default is L4, quarter +Xnotes. The lowest possible value is 1; values up to 64 are accepted. L1 sets +Xwhole notes, L2 sets half notes, L4 sets quarter notes, etc.. +X.PP +XP -- pause (rest), with interpreted as for L. May be followed by +Xsustain dots. May also be written '~'. +X.PP +XT -- Sets the number of quarter notes per minute; default is 120. Musical +Xnames for common tempi are: +X +X.TS +Xa a a. +X Tempo Beats Per Minute +Xvery slow Larghissimo +X Largo 40-60 +X Larghetto 60-66 +X Grave +X Lento +X Adagio 66-76 +Xslow Adagietto +X Andante 76-108 +Xmedium Andantino +X Moderato 108-120 +Xfast Allegretto +X Allegro 120-168 +X Vivace +X Veloce +X Presto 168-208 +Xvery fast Prestissimo +X.TE +X.PP +XM[LNS] -- set articulation. MN (N for normal) is the default; the last 1/8th of +Xthe note's value is rest time. You can set ML for legato (no rest space) or +XMS (staccato) 1/4 rest space. +X.PP +XNotes (that is, CDEFGAB or N command character groups) may be followed by +Xsustain dots. Each dot causes the note's value to be lengthened by one-half +Xfor each one. Thus, a note dotted once is held for 3/2 of its undotted value; +Xdotted twice, it is held 9/4, and three times would give 27/8. +X.PP +XWhitespace in play strings is simply skipped and may be used to separate +Xmelody sections. +X.SH BUGS +XDue to roundoff in the pitch tables and slop in the tone-generation and timer +Xhardware (neither of which was designed for precision), neither pitch accuracy +Xnor timings will be mathematically exact. There is no volume control. +X.PP +XIn play strings which are very long (longer than your system's physical I/O +Xblocks) note suffixes or numbers may occasionally be parsed incorrectly due +Xto crossing a block boundary. +X.SH FILES +X/dev/speaker -- speaker device file +X.SH AUTHOR +XEric S. Raymond (esr@snark.thyrsus.com) Feb 1990 +END-of-spkr.7 +echo x - Makefile +sed 's/^X//' >Makefile << 'END-of-Makefile' +X# +X# Speaker driver package makefile +X# +XCFLAGS = -I. -O # -DDEBUG +XLDFLAGS = -s +X +Xall: Driver.o +X +Xinstall: +X ./Install +X +XDriver.o: spkr.c +X $(CC) $(CFLAGS) -c spkr.c +X mv spkr.o Driver.o +X +Xclean: +X rm -f Driver.o *~ speaker.shar +X +XDSP = Files Install Master Name Node Remove Size System +Xshar: +X shar READ.ME install.bsd spkr.7 Makefile spkr.[ch] \ +X interp.c $(DSP) playtest >speaker.shar +END-of-Makefile +echo x - spkr.c +sed 's/^X//' >spkr.c << 'END-of-spkr.c' +X/* +X * spkr.c -- device driver for console speaker on 80386 +X * +X * v1.1 by Eric S. Raymond (esr@snark.thyrsus.com) Feb 1990 +X * modified for 386bsd by Andrew A. Chernov +X */ +X +X#ifdef __386BSD__ +X#include "speaker.h" +X#endif +X#if !defined(__386BSD__) || (NSPEAKER > 0) +X +X#ifdef __386BSD__ +X#include "types.h" +X#include "param.h" +X#include "errno.h" +X#include "buf.h" +X#include "uio.h" +X +X#define CADDR caddr_t +X#define err_ret(x) return(x) +X#else /* SYSV */ +X#include +X#include +X#include +X#include +X#include +X#include +X#include +X#include +X#include +X +X#define CADDR char * +X#define err_ret(x) u.u_error = (x) +X#endif +X +X#include "spkr.h" +X +X/**************** MACHINE DEPENDENT PART STARTS HERE ************************* +X * +X * This section defines a function tone() which causes a tone of given +X * frequency and duration from the 80x86's console speaker. +X * Another function endtone() is defined to force sound off, and there is +X * also a rest() entry point to do pauses. +X * +X * Audible sound is generated using the Programmable Interval Timer (PIT) and +X * Programmable Peripheral Interface (PPI) attached to the 80x86's speaker. The +X * PPI controls whether sound is passed through at all; the PIT's channel 2 is +X * used to generate clicks (a square wave) of whatever frequency is desired. +X * +X * The non-BSD code requires SVr3.2-compatible inb(), outb(), timeout(), +X * sleep(), and wakeup(). +X */ +X +X/* +X * PIT and PPI port addresses and control values +X * +X * Most of the magic is hidden in the TIMER_PREP value, which selects PIT +X * channel 2, frequency LSB first, square-wave mode and binary encoding. +X * The encoding is as follows: +X * +X * +----------+----------+---------------+-----+ +X * | 1 0 | 1 1 | 0 1 1 | 0 | +X * | SC1 SC0 | RW1 RW0 | M2 M1 M0 | BCD | +X * +----------+----------+---------------+-----+ +X * Counter Write Mode 3 Binary +X * Channel 2 LSB first, (Square Wave) Encoding +X * MSB second +X */ +X#define PPI 0x61 /* port of Programmable Peripheral Interface */ +X#define PPI_SPKR 0x03 /* turn these PPI bits on to pass sound */ +X#define PIT_CTRL 0x43 /* PIT control address */ +X#define PIT_COUNT 0x42 /* PIT count address */ +X#define PIT_MODE 0xB6 /* set timer mode for sound generation */ +X +X/* +X * Magic numbers for timer control. +X */ +X#define TIMER_CLK 1193180L /* corresponds to 18.2 MHz tick rate */ +X +Xstatic int endtone() +X/* turn off the speaker, ending current tone */ +X{ +X wakeup((CADDR)endtone); +X outb(PPI, inb(PPI) & ~PPI_SPKR); +X} +X +Xstatic void tone(hz, ticks) +X/* emit tone of frequency hz for given number of ticks */ +Xunsigned int hz, ticks; +X{ +X unsigned int divisor = TIMER_CLK / hz; +X int sps; +X +X#ifdef DEBUG +X printf("tone: hz=%d ticks=%d\n", hz, ticks); +X#endif /* DEBUG */ +X +X /* set timer to generate clicks at given frequency in Hertz */ +X#ifdef __386BSD__ +X sps = spltty(); +X#else +X sps = spl5(); +X#endif +X outb(PIT_CTRL, PIT_MODE); /* prepare timer */ +X outb(PIT_COUNT, (unsigned char) divisor); /* send lo byte */ +X outb(PIT_COUNT, (divisor >> 8)); /* send hi byte */ +X splx(sps); +X +X /* turn the speaker on */ +X outb(PPI, inb(PPI) | PPI_SPKR); +X +X /* +X * Set timeout to endtone function, then give up the timeslice. +X * This is so other processes can execute while the tone is being +X * emitted. +X */ +X timeout((CADDR)endtone, (CADDR)NULL, ticks); +X sleep((CADDR)endtone, PZERO - 1); +X} +X +Xstatic int endrest() +X/* end a rest */ +X{ +X wakeup((CADDR)endrest); +X} +X +Xstatic void rest(ticks) +X/* rest for given number of ticks */ +Xint ticks; +X{ +X /* +X * Set timeout to endrest function, then give up the timeslice. +X * This is so other processes can execute while the rest is being +X * waited out. +X */ +X#ifdef DEBUG +X printf("rest: %d\n", ticks); +X#endif /* DEBUG */ +X timeout((CADDR)endrest, (CADDR)NULL, ticks); +X sleep((CADDR)endrest, PZERO - 1); +X} +X +X#include "interp.c" /* playinit() and playstring() */ +X +X/******************* UNIX DRIVER HOOKS BEGIN HERE ************************** +X * +X * This section implements driver hooks to run playstring() and the tone(), +X * endtone(), and rest() functions defined above. For non-BSD systems, +X * SVr3.2-compatible copyin() is also required. +X */ +X +Xstatic int spkr_active; /* exclusion flag */ +X#ifdef __386BSD__ +Xstatic struct buf *spkr_inbuf; /* incoming buf */ +X#endif +X +Xint spkropen(dev) +Xdev_t dev; +X{ +X#ifdef DEBUG +X printf("spkropen: entering with dev = %x\n", dev); +X#endif /* DEBUG */ +X +X if (minor(dev) != 0) +X err_ret(ENXIO); +X else if (spkr_active) +X err_ret(EBUSY); +X else +X { +X playinit(); +X#ifdef __386BSD__ +X spkr_inbuf = geteblk(DEV_BSIZE); +X#endif +X spkr_active = 1; +X } +X#ifdef __386BSD__ +X return(0); +X#endif +X} +X +X#ifdef __386BSD__ +Xint spkrwrite(dev, uio) +Xstruct uio *uio; +X#else +Xint spkrwrite(dev) +X#endif +Xdev_t dev; +X{ +X#ifdef __386BSD__ +X register unsigned n; +X char *cp; +X int error; +X#endif +X#ifdef DEBUG +X#ifdef __386BSD__ +X printf("spkrwrite: entering with dev = %x, count = %d\n", +X dev, uio->uio_resid); +X#else +X printf("spkrwrite: entering with dev = %x, u.u_count = %d\n", +X dev, u.u_count); +X#endif +X#endif /* DEBUG */ +X +X if (minor(dev) != 0) +X err_ret(ENXIO); +X else +X { +X#ifdef __386BSD__ +X n = MIN(DEV_BSIZE, uio->uio_resid); +X cp = spkr_inbuf->b_un.b_addr; +X error = uiomove(cp, n, uio); +X if (!error) +X playstring(cp, n); +X return(error); +X#else +X char bfr[STD_BLK]; +X +X copyin(u.u_base, bfr, u.u_count); +X playstring(bfr, u.u_count); +X u.u_base += u.u_count; +X u.u_count = 0; +X#endif +X } +X} +X +Xint spkrclose(dev) +Xdev_t dev; +X{ +X#ifdef DEBUG +X printf("spkrclose: entering with dev = %x\n", dev); +X#endif /* DEBUG */ +X +X if (minor(dev) != 0) +X err_ret(ENXIO); +X else +X { +X endtone(); +X#ifdef __386BSD__ +X brelse(spkr_inbuf); +X#endif +X spkr_active = 0; +X } +X#ifdef __386BSD__ +X return(0); +X#endif +X} +X +Xint spkrioctl(dev, cmd, cmdarg) +Xdev_t dev; +Xint cmd; +XCADDR cmdarg; +X{ +X#ifdef DEBUG +X printf("spkrioctl: entering with dev = %x, cmd = %x\n", dev, cmd); +X#endif /* DEBUG */ +X +X if (minor(dev) != 0) +X err_ret(ENXIO); +X else if (cmd == SPKRTONE) +X { +X tone_t *tp = (tone_t *)cmdarg; +X +X if (tp->frequency == 0) +X rest(tp->duration); +X else +X tone(tp->frequency, tp->duration); +X } +X else if (cmd == SPKRTUNE) +X { +X#ifdef __386BSD__ +X tone_t *tp = (tone_t *)(*(caddr_t *)cmdarg); +X tone_t ttp; +X int error; +X +X for (; ; tp++) { +X error = copyin(tp, &ttp, sizeof(tone_t)); +X if (error) +X return(error); +X if (ttp.duration == 0) +X break; +X if (ttp.frequency == 0) +X rest(ttp.duration); +X else +X tone(ttp.frequency, ttp.duration); +X } +X#else +X tone_t *tp = (tone_t *)cmdarg; +X +X for (; tp->duration; tp++) +X if (tp->frequency == 0) +X rest(tp->duration); +X else +X tone(tp->frequency, tp->duration); +X#endif +X } +X else +X err_ret(EINVAL); +X#ifdef __386BSD__ +X return(0); +X#endif +X} +X +X#endif /* !defined(__386BSD__) || (NSPEAKER > 0) */ +X/* spkr.c ends here */ +END-of-spkr.c +echo x - spkr.h +sed 's/^X//' >spkr.h << 'END-of-spkr.h' +X/* +X * spkr.h -- interface definitions for speaker ioctl() +X * +X * v1.1 by Eric S. Raymond (esr@snark.thyrsus.com) Feb 1990 +X * modified for 386bsd by Andrew A. Chernov +X */ +X +X#ifndef _SPKR_H_ +X#define _SPKR_H_ +X +X#ifdef __386BSD__ +X#ifndef KERNEL +X#include +X#else +X#include "ioctl.h" +X#endif +X +X#define SPKRTONE _IOW('S', 1, tone_t) /* emit tone */ +X#define SPKRTUNE _IO('S', 2) /* emit tone sequence*/ +X#else /* SYSV */ +X#define SPKRIOC ('S'<<8) +X#define SPKRTONE (SPKRIOC|1) /* emit tone */ +X#define SPKRTUNE (SPKRIOC|2) /* emit tone sequence*/ +X#endif +X +Xtypedef struct +X{ +X int frequency; /* in hertz */ +X int duration; /* in 1/100ths of a second */ +X} +Xtone_t; +X +X#endif /* _SPKR_H_ */ +X/* spkr.h ends here */ +END-of-spkr.h +echo x - interp.c +sed 's/^X//' >interp.c << 'END-of-interp.c' +X/* +X * interp.c -- device driver for console speaker on 80386 +X * +X * v1.1 by Eric S. Raymond (esr@snark.thyrsus.com) Feb 1990 +X * +X * this is the part of the code common to all 386 UNIX OSes +X * +X * playinit() and playstring() are called from the appropriate driver +X */ +X +X#ifdef __386BSD__ +X#include "param.h" +X#else +X#include +X#endif +X +X#ifndef HZ +X#define HZ 60 +X#endif +X +X +X/**************** PLAY STRING INTERPRETER BEGINS HERE ********************** +X * +X * Play string interpretation is modelled on IBM BASIC 2.0's PLAY statement; +X * M[LNS] are missing and the ~ synonym and octave-tracking facility is added. +X * Requires tone(), rest(), and endtone(). String play is not interruptible +X * except possibly at physical block boundaries. +X */ +X +Xtypedef int bool; +X#ifndef TRUE +X#define TRUE 1 +X#endif +X#ifndef FALSE +X#define FALSE 0 +X#endif +X +X#define toupper(c) ((c) - ' ' * (((c) >= 'a') && ((c) <= 'z'))) +X#define isdigit(c) (((c) >= '0') && ((c) <= '9')) +X#define dtoi(c) ((c) - '0') +X +Xstatic int octave; /* currently selected octave */ +Xstatic int whole; /* whole-note time at current tempo, in ticks */ +Xstatic int value; /* whole divisor for note time, quarter note = 1 */ +Xstatic int fill; /* controls spacing of notes */ +Xstatic bool octtrack; /* octave-tracking on? */ +Xstatic bool octprefix; /* override current octave-tracking state? */ +X +X/* +X * Magic number avoidance... +X */ +X#define SECS_PER_MIN 60 /* seconds per minute */ +X#define WHOLE_NOTE 4 /* quarter notes per whole note */ +X#define MIN_VALUE 64 /* the most we can divide a note by */ +X#define DFLT_VALUE 4 /* default value (quarter-note) */ +X#define FILLTIME 8 /* for articulation, break note in parts */ +X#define STACCATO 6 /* 6/8 = 3/4 of note is filled */ +X#define NORMAL 7 /* 7/8ths of note interval is filled */ +X#define LEGATO 8 /* all of note interval is filled */ +X#define DFLT_OCTAVE 4 /* default octave */ +X#define MIN_TEMPO 32 /* minimum tempo */ +X#define DFLT_TEMPO 120 /* default tempo */ +X#define MAX_TEMPO 255 /* max tempo */ +X#define NUM_MULT 3 /* numerator of dot multiplier */ +X#define DENOM_MULT 2 /* denominator of dot multiplier */ +X +X/* letter to half-tone: A B C D E F G */ +Xstatic int notetab[8] = {9, 11, 0, 2, 4, 5, 7}; +X +X/* +X * This is the American Standard A440 Equal-Tempered scale with frequencies +X * rounded to nearest integer. Thank Goddess for the good ol' CRC Handbook... +X * our octave 0 is standard octave 2. +X */ +X#define OCTAVE_NOTES 12 /* semitones per octave */ +Xstatic int pitchtab[] = +X{ +X/* C C# D D# E F F# G G# A A# B*/ +X/* 0 */ 65, 69, 73, 78, 82, 87, 93, 98, 103, 110, 117, 123, +X/* 1 */ 131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247, +X/* 2 */ 262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494, +X/* 3 */ 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988, +X/* 4 */ 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1975, +X/* 5 */ 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951, +X/* 6 */ 4186, 4435, 4698, 4978, 5274, 5588, 5920, 6272, 6644, 7040, 7459, 7902, +X}; +X +Xstatic void playinit() +X{ +X octave = DFLT_OCTAVE; +X whole = (HZ * SECS_PER_MIN * WHOLE_NOTE) / DFLT_TEMPO; +X fill = NORMAL; +X value = DFLT_VALUE; +X octtrack = FALSE; +X octprefix = TRUE; /* act as though there was an initial O(n) */ +X} +X +Xstatic void playtone(pitch, value, sustain) +X/* play tone of proper duration for current rhythm signature */ +Xint pitch, value, sustain; +X{ +X register int sound, silence, snum = 1, sdenom = 1; +X +X /* this weirdness avoids floating-point arithmetic */ +X for (; sustain; sustain--) +X { +X snum *= NUM_MULT; +X sdenom *= DENOM_MULT; +X } +X +X if (pitch == -1) +X rest(whole * snum / (value * sdenom)); +X else +X { +X sound = (whole * snum) / (value * sdenom) +X - (whole * (FILLTIME - fill)) / (value * FILLTIME); +X silence = whole * (FILLTIME-fill) * snum / (FILLTIME * value * sdenom); +X +X#ifdef DEBUG +X printf("playtone: pitch %d for %d ticks, rest for %d ticks\n", +X pitch, sound, silence); +X#endif /* DEBUG */ +X +X tone(pitchtab[pitch], sound); +X if (fill != LEGATO) +X rest(silence); +X } +X} +X +Xstatic int abs(n) +Xint n; +X{ +X if (n < 0) +X return(-n); +X else +X return(n); +X} +X +Xstatic void playstring(cp, slen) +X/* interpret and play an item from a notation string */ +Xchar *cp; +Xsize_t slen; +X{ +X int pitch, lastpitch = OCTAVE_NOTES * DFLT_OCTAVE; +X +X#define GETNUM(cp, v) for(v=0; isdigit(cp[1]) && slen > 0; ) \ +X {v = v * 10 + (*++cp - '0'); slen--;} +X for (; slen--; cp++) +X { +X int sustain, timeval, tempo; +X register char c = toupper(*cp); +X +X#ifdef DEBUG +X printf("playstring: %c (%x)\n", c, c); +X#endif /* DEBUG */ +X +X switch (c) +X { +X case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': +X +X /* compute pitch */ +X pitch = notetab[c - 'A'] + octave * OCTAVE_NOTES; +X +X /* this may be followed by an accidental sign */ +X if (cp[1] == '#' || cp[1] == '+') +X { +X ++pitch; +X ++cp; +X slen--; +X } +X else if (cp[1] == '-') +X { +X --pitch; +X ++cp; +X slen--; +X } +X +X /* +X * If octave-tracking mode is on, and there has been no octave- +X * setting prefix, find the version of the current letter note +X * closest to the last regardless of octave. +X */ +X if (octtrack && !octprefix) +X { +X if (abs(pitch-lastpitch) > abs(pitch+OCTAVE_NOTES-lastpitch)) +X { +X ++octave; +X pitch += OCTAVE_NOTES; +X } +X +X if (abs(pitch-lastpitch) > abs((pitch-OCTAVE_NOTES)-lastpitch)) +X { +X --octave; +X pitch -= OCTAVE_NOTES; +X } +X } +X octprefix = FALSE; +X lastpitch = pitch; +X +X /* ...which may in turn be followed by an override time value */ +X GETNUM(cp, timeval); +X if (timeval <= 0 || timeval > MIN_VALUE) +X timeval = value; +X +X /* ...and/or sustain dots */ +X for (sustain = 0; cp[1] == '.'; cp++) +X { +X slen--; +X sustain++; +X } +X +X /* time to emit the actual tone */ +X playtone(pitch, timeval, sustain); +X break; +X +X case 'O': +X if (cp[1] == 'N' || cp[1] == 'n') +X { +X octprefix = octtrack = FALSE; +X ++cp; +X slen--; +X } +X else if (cp[1] == 'L' || cp[1] == 'l') +X { +X octtrack = TRUE; +X ++cp; +X slen--; +X } +X else +X { +X GETNUM(cp, octave); +X if (octave >= sizeof(pitchtab) / OCTAVE_NOTES) +X octave = DFLT_OCTAVE; +X octprefix = TRUE; +X } +X break; +X +X case '>': +X if (octave < sizeof(pitchtab) / OCTAVE_NOTES - 1) +X octave++; +X octprefix = TRUE; +X break; +X +X case '<': +X if (octave > 0) +X octave--; +X octprefix = TRUE; +X break; +X +X case 'N': +X GETNUM(cp, pitch); +X for (sustain = 0; cp[1] == '.'; cp++) +X { +X slen--; +X sustain++; +X } +X playtone(pitch - 1, value, sustain); +X break; +X +X case 'L': +X GETNUM(cp, value); +X if (value <= 0 || value > MIN_VALUE) +X value = DFLT_VALUE; +X break; +X +X case 'P': +X case '~': +X /* this may be followed by an override time value */ +X GETNUM(cp, timeval); +X if (timeval <= 0 || timeval > MIN_VALUE) +X timeval = value; +X for (sustain = 0; cp[1] == '.'; cp++) +X { +X slen--; +X sustain++; +X } +X playtone(-1, timeval, sustain); +X break; +X +X case 'T': +X GETNUM(cp, tempo); +X if (tempo < MIN_TEMPO || tempo > MAX_TEMPO) +X tempo = DFLT_TEMPO; +X whole = (HZ * SECS_PER_MIN * WHOLE_NOTE) / tempo; +X break; +X +X case 'M': +X if (cp[1] == 'N' || cp[1] == 'n') +X { +X fill = NORMAL; +X ++cp; +X slen--; +X } +X else if (cp[1] == 'L' || cp[1] == 'l') +X { +X fill = LEGATO; +X ++cp; +X slen--; +X } +X else if (cp[1] == 'S' || cp[1] == 's') +X { +X fill = STACCATO; +X ++cp; +X slen--; +X } +X break; +X } +X } +X} +END-of-interp.c +echo x - Files +sed 's/^X//' >Files << 'END-of-Files' +X/usr/include/sys/spkr.h +END-of-Files +echo x - Install +sed 's/^X//' >Install << 'END-of-Install' +X# +X# Speaker driver installation script +X# +XTMP=/tmp/speaker.err +XERR1=" Errors have been written to the file $TMP." +XERR2=" The Speaker Driver software was not installed." +X +Xecho "Installing Speaker Driver Software Package" +X +X/etc/conf/bin/idcheck -p speaker 2>$TMP +Xif [ $? != 0 ] +Xthen +X echo "The speaker package is already at least partly installed. +X Removing the old version now..." +X /etc/conf/bin/idinstall -d speaker +Xfi +X +X/etc/conf/bin/idinstall -a -k speaker 2>>$TMP +Xif [ $? != 0 ] +Xthen +X message "There was an error during package installation. $ERR1 $ERR2" +X exit 1 +Xfi +X +X/etc/conf/bin/idbuild 2>>$TMP +Xif [ $? != 0 ] +Xthen +X message "There was an error during kernel reconfiguration. $ERR1 $ERR2" +X exit 1 +Xfi +X +Xrm -f $TMP +X +Xcp spkr.h /usr/include/sys/spkr.h +X +Xecho "Performing shutdown..." +Xcd /; exec /etc/shutdown -g0 -y +END-of-Install +echo x - Master +sed 's/^X//' >Master << 'END-of-Master' +Xspeaker ocwi iocH spkr 0 0 1 1 -1 +END-of-Master +echo x - Name +sed 's/^X//' >Name << 'END-of-Name' +X386 UNIX Speaker Device Driver Package +END-of-Name +echo x - Node +sed 's/^X//' >Node << 'END-of-Node' +Xspeaker speaker c 0 +END-of-Node +echo x - Remove +sed 's/^X//' >Remove << 'END-of-Remove' +X# +X# Speaker driver remove script +X# +XTMP=/tmp/speaker.err +XRERR="Errors have been written to the file $TMP." +X +Xecho "Removing Speaker Driver Software Package" +X +X/etc/conf/bin/idinstall -d speaker 2>$TMP +Xif [ $? != 0 ] +Xthen +X message "There was an error during package removal. $RERR" +X exit 1 +Xfi +X +X/etc/conf/bin/idbuild 2>>$TMP +Xif [ $? != 0 ] +Xthen +X message "There was an error during kernel reconfiguration. $RERR" +X exit 1 +Xfi +X +Xrm -f /dev/speaker $TMP /usr/include/sys/spkr.h +X +Xexit 0 +END-of-Remove +echo x - Size +sed 's/^X//' >Size << 'END-of-Size' +XROOT=1400 +XUSR=100 +END-of-Size +echo x - System +sed 's/^X//' >System << 'END-of-System' +Xspeaker Y 1 0 0 0 0 0 0 0 +END-of-System +echo x - playtest +sed 's/^X//' >playtest << 'END-of-playtest' +X: +X# Test script for the speaker driver +X# +X# v1.0 by Eric S. Raymond (Feb 1990) +X# modified for 386bsd by Andrew A. Chernov +X# +Xreveille="t255l8c.f.afc~c.f.afc~c.f.afc.f.a..f.~c.f.afc~c.f.afc~c.f.afc~c.f.." +Xcontact="f" +Xdance="t240dcdc/dev/speaker;; +Xcontact) echo $contact >/dev/speaker;; +Xdance) echo $dance >/dev/speaker;; +Xloony) echo $loony >/dev/speaker;; +X*) +X echo "No such tune. Available tunes are:" +X echo +X echo "reveille -- Reveille" +X echo "contact -- Contact theme from Close Encounters" +X echo "dance -- Lord of the Dance (aka Simple Gifts)" +X echo "loony -- Loony Toons theme" +X ;; +Xesac +END-of-playtest +exit