[comp.sources.sun] v02i010: Music player for SS1s

mcgrew@dartagnan.rutgers.edu (Charles Mcgrew) (02/06/90)

Submitted-by: ttl@astroatc.uucp (Tony Laundrie)
Posting-number: Volume 2, Issue 10
Archive-name: ss1-music


Here is a brief audio program that I wrote for generating music on the SUN
SPARCstation audio device.  If you make any changes or improvements, please
send them to me, ...uwvax!astroatc!ttl  or  ttl@astroatc.UUCP

After unwrapping and Making the executable "beep", you can play a song
by typing "beep < soundfile".  Several soundfiles (dixie, growforme, suddenly,
and jingle) are included.  Have fun!


[ Typing in tunes for this program to play is pretty easy -- I typed
in the first two pages from "here comes the sun" in about 45 minutes
(that includes 'learning-curve' time)...  I'd like to keep an archive
of music people write, so send them in!  Music files will be kept in
src/sun-sources/music in the anonymous ftp location of rutgers.edu.
Also, the first batch of sparc-playable sounds has arrived, and is in
src/sun-sources/sounds.  See src/sun-sources/README for more info. -CWM]


# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
 
echo x - Makefile
sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//'

beep:	beep.c
	cc -O -o beep beep.c
@//E*O*F Makefile//
chmod u=rw,g=r,o=r Makefile
 
echo x - README
sed 's/^@//' > "README" <<'@//E*O*F README//'
For music files used with the beep program,

The first line is:
RATE (low = fast), PITCH (low = low), VOLUME (low = quiet), DECAY (0 = no decay)

Floating point numbers accepted for RATE, VOLUME, and DECAY.

All other lines represent notes and rests, as follows:

VOL BEATS NOTE WORD

VOL and BEATS must be integers.

VOL is multiplied by first line VOLUME to get note's volume (range = 0-255).
Use VOL = 0 for a rest.

BEATS is multiplied by first line RATE to get note's length (units = 1/32 sec).
Result should be an integer.

NOTE consists of an octave (0-8) concatenated with a note (a-g) concatenated
with a flat or sharp (b or #).  Badly-formed notes are not detected.

The word is printed to standard output.
Words suffixed with - don't have a space automatically printed after them.
Words suffixed with \ have a newline appended.



See "growforme" for an example.
@//E*O*F README//
chmod u=rw,g=r,o=r README
 
echo x - beep.c
sed 's/^@//' > "beep.c" <<'@//E*O*F beep.c//'
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sun/audioio.h>
#define BUFLEN 256

static int notes[9][12] = {
   { 1002, 946, 893, 843, 795, 751, 709, 669, 631, 596, 562, 531 },
   {  501, 473, 446, 421, 398, 375, 354, 334, 316, 298, 281, 265 },
   {  250, 236, 223, 211, 199, 188, 177, 167, 158, 149, 141, 133 },
   {  125, 118, 112, 105,  99,  94,  89,  84,  79,  74,  70,  66 },
   {   63,  59,  56,  53,  50,  47,  44,  42,  39,  37,  35,  33 },
   {   31,  30,  28,  26,  25,  23,  22,  21,  20,  19,  18,  17 },
   {   16,  15,  14,  13,  12,  11,  11,  10,  10,   9,   9,   8 },
   {    7,   7,   7,   7,   6,   6,   6,   5,   5,   5,   4,   4 },
   {    4,   4,   3,   3,   3,   3,   3,   3,   2,   2,   2,   2 }
};

static int conv[7] = {9, 11, 0, 2, 4, 5, 7};

int oct, n, length, f, period, j, i, k;
float speed, loudness, volume, decay;
int tone;
char buf[BUFLEN];
char mess[80], *p;

main (argc, argv)
int argc;
char *argv[];
{
   f = open ("/dev/audio", O_WRONLY);
   scanf ("%f %d %f %f", &speed, &tone, &loudness, &decay);
CONT:
   do {
      ioctl (f, AUDIOWRITEQ, &n);
   } while (n);
   if (gets (mess) == NULL) exit (0);
   if (sscanf (mess, "%f%d%s%s", &volume, &length, buf, mess) == 4) {
      n = strlen(mess);
      if (mess[n-1] == '-') {
	 mess[n-1] = '\0';
	 fputs (mess, stdout);
      }
      else if (mess[n-1] == '\\') {
	 mess[n-1] = '\0';
	 fputs (mess, stdout);
	 putchar ('\n');
      }
      else {
	 fputs (mess, stdout);
	 putchar (' ');
      }
      fflush (stdout);
   }
   volume = loudness * volume;
   length = (int) (speed * length);
   oct = buf[0] - '0';
   n = conv[buf[1] - 'a'];
   if (buf[2] == 'b') --n;
   else if (buf[2] == '#') ++n;
   n = n + tone;
   period = notes[oct][n];

   i = 0;
   k = 0;
   for (;;) {
      for (j = 0; j < period>>1; ++j) {
	 buf[i++] = 0;
	 if ((volume = volume - decay) < 0.0) volume = 0.0;
	 if (i >= BUFLEN) {
	    write (f,buf,BUFLEN);
	    if (++k >= length) goto CONT;
	    i = 0;
	 }
      }
      for (j = 0; j < ((period>>1) + (period & 0x1)); ++j) {
	 buf[i++] = (int) volume;
	 if ((volume = volume - decay) < 0.0) volume = 0.0;
	 if (i >= BUFLEN) {
	    write (f,buf,BUFLEN);
	    if (++k >= length) goto CONT;
	    i = 0;
	 }
      }
   }
}
@//E*O*F beep.c//
chmod u=rw,g=r,o=r beep.c
 
echo x - dixie
sed 's/^@//' > "dixie" <<'@//E*O*F dixie//'
0.8 0 127 0.44
2 4 5g
2 4 5e
2 4 5c
0 4 0c
2 4 5c
0 4 0c
2 4 5c
2 4 5d
2 4 5e
2 4 5f
2 4 5g
0 4 0c
2 4 5g
0 4 0c
2 4 5g
0 4 0c
2 4 5e
@//E*O*F dixie//
chmod u=rw,g=r,o=r dixie
 
echo x - growforme
sed 's/^@//' > "growforme" <<'@//E*O*F growforme//'
1 12 255 0
0 35 0c
1 6 2bb I've
0 1 0c 
1 6 2bb gi-
0 1 0c 
1 6 3eb ven
0 1 0c 
1 6 3f you
0 1 0c 
1 13 3g sun-
0 1 0c 
1 28 3eb shine,\
0 14 0c 
1 6 2bb I've
0 1 0c 
1 6 2bb gi-
0 1 0c 
1 6 3eb ven
0 1 0c 
1 6 3g you
0 1 0c 
1 21 3bb dirt,\
0 35 0c 
1 6 3eb You've
0 1 0c 
1 6 3eb gi-
0 1 0c 
1 6 3ab ven
0 1 0c 
1 6 3bb me
0 1 0c 
1 6 4c noth-
0 1 0c 
1 6 3bb 
0 1 0c 
1 28 3ab in',\
0 14 0c 
1 6 3eb But
0 1 0c 
1 6 3eb heart-
0 1 0c 
1 6 3ab ache
0 1 0c 
1 6 4c and
0 1 0c 
1 21 4eb hurt.\
0 35 0c 
1 6 4eb I'm
0 1 0c 
1 6 4eb beg-
0 1 0c 
1 6 4d gin'
0 1 0c 
1 6 4c you
0 1 0c 
1 13 3bb sweet-
0 1 0c 
1 28 3g ly,\
0 14 0c 
1 6 3eb I'm
0 1 0c 
1 6 3eb down
0 1 0c 
1 6 3f on
0 1 0c 
1 6 3g my
0 1 0c 
1 42 3ab knees,\
0 28 0c 
1 13 4cb Oh
0 1 0c 
1 42 4c please,
0 14 0c 
1 13 4d grow
0 1 0c 
1 13 4d for
0 1 0c 
1 21 4eb me!\
0 35 0c \
1 6 3eb I've
0 1 0c 
1 6 3eb gi-
0 1 0c 
1 6 3f ven
0 1 0c 
1 6 3g you
0 1 0c 
1 13 3g south-
0 1 0c 
1 20 3e ern
0 1 0c 
1 6 3f ex-
0 1 0c 
1 13 3g po-
0 1 0c 
1 20 3ab sure
0 1 0c 
1 6 3bb to
0 1 0c 
1 6 3bb get
0 1 0c 
1 6 3ab you
0 1 0c 
1 6 3g to
0 1 0c 
1 21 3ab thrive,\
0 14 0c 
1 6 3f I've
0 1 0c 
1 6 3f pinched
0 1 0c 
1 6 3g you
0 1 0c 
1 6 3ab back
0 1 0c 
1 13 3a hard
0 1 0c 
1 13 3f# like
0 1 0c 
1 13 3g I'm
0 1 0c 
1 13 3a s'posed
0 1 0c 
1 13 3bb ta,
0 1 0c 
1 13 4c you're
0 1 0c 
1 13 4c bare-
0 1 0c 
1 13 3bb ly
0 1 0c 
1 13 3a a-
0 1 0c 
1 13 3bb live,\
0 1 0c 
1 6 3eb I've
0 1 0c 
1 6 3eb tried
0 1 0c 
1 6 3ab you
0 1 0c 
1 6 3bb at
0 1 0c 
1 13 4c lev-
0 1 0c 
1 13 3ab els
0 1 0c 
1 13 3bb of
0 1 0c 
1 13 4c mois-
0 1 0c 
1 6 4d ture
0 1 0c 
0 13 0c 
0 1 0c 
1 6 4c from
0 1 0c 
1 13 3bb des-
0 1 0c 
1 13 4c ert
0 1 0c 
1 13 4d to
0 1 0c 
1 21 4eb mud,\
0 14 0c 
1 6 4eb I've
0 1 0c 
1 6 4eb gi-
0 1 0c 
1 6 4eb ven
0 1 0c 
1 6 4eb you
0 1 0c 
1 6 4eb grow
0 1 0c 
1 6 4eb lights
0 1 0c 
1 6 4eb and
0 1 0c 
1 6 4eb min-
0 1 0c 
1 6 4eb er-
0 1 0c 
1 6 4eb al
0 1 0c 
1 6 4eb sup-
0 1 0c 
1 6 4d ple-
0 1 0c 
1 6 4c ments,\
0 1 0c 
1 6 4d What
0 1 0c 
1 6 4d do
0 1 0c 
1 6 4d you
0 1 0c 
1 6 4d want
0 1 0c 
1 6 4eb from
0 1 0c 
1 6 4e me?
0 1 0c 
1 7 4f Blood?!\
0 7 0c \
1 6 2bb I've
0 1 0c 
1 6 2bb gi-
0 1 0c 
1 6 3eb ven
0 1 0c 
1 6 3f you
0 1 0c 
1 13 3g sun-
0 1 0c 
1 28 3eb light,\
0 14 0c 
1 6 2bb I've
0 1 0c 
1 6 2bb gi-
0 1 0c 
1 6 3eb ven
0 1 0c 
1 6 3g you
0 1 0c 
1 21 3bb rain,\
0 35 0c 
1 6 3eb Looks
0 1 0c 
1 6 3eb like
0 1 0c 
1 6 3ab you're
0 1 0c 
1 6 3bb not
0 1 0c 
1 6 4c hap-
0 1 0c 
1 6 3bb 
0 1 0c 
1 28 3ab py,\
0 7 0c 
1 6 3eb 'Less
0 1 0c 
1 6 3eb I
0 1 0c 
1 6 3eb o-
0 1 0c 
1 6 3ab pen
0 1 0c 
1 6 4c a
0 1 0c 
1 49 4eb vein,\
0 7 0c 
1 6 4eb I'll
0 1 0c 
1 6 4eb give
0 1 0c 
1 6 4d you
0 1 0c 
1 6 4c a
0 1 0c 
1 6 3bb few
0 1 0c 
1 14 3g drops,\
0 35 0c 
1 6 3eb If
0 1 0c 
1 6 3eb that-
0 1 0c 
1 6 3f 'll
0 1 0c 
1 6 3g ap-
0 1 0c 
1 21 3ab pease,\
0 42 0c 
1 20 4cb Now
0 1 0c 
1 42 4c please,
0 28 0c 
1 13 4c oh
0 1 0c 
1 41 4d please,
0 1 0c 
1 20 4c grow
0 1 0c 
1 20 3bb for
0 1 0c 
1 301 4eb me!\
0 35 0c
@//E*O*F growforme//
chmod u=rw,g=r,o=r growforme
 
echo x - jingle
sed 's/^@//' > "jingle" <<'@//E*O*F jingle//'
4 0 127 0
1 1 4c
1 3 4f
1 1 4e
1 2 4f
1 2 4a
1 3 4g
1 1 4f
1 2 4g
@//E*O*F jingle//
chmod u=rw,g=r,o=r jingle
 
echo x - suddenly
sed 's/^@//' > "suddenly" <<'@//E*O*F suddenly//'
1 12 255 0
0 25 0c
1 9 3d Lift
0 1 0c 
1 9 3e up
0 1 0c 
1 9 3f# your
0 1 0c 
1 20 3e head,\
0 20 0c 
1 9 2a Wash
0 1 0c 
1 9 3d off
0 1 0c 
1 9 3e your
0 1 0c 
1 9 3f# mas-
0 1 0c 
1 19 3e ca-
0 1 0c 
1 10 2a ra,\
0 20 0c 
1 9 3f# Here,
0 1 0c 
1 9 3g# take
0 1 0c 
1 9 3a my
0 1 0c 
1 19 3a Klee-
0 1 0c 
1 9 2a nex,\
0 1 0c 
1 9 2a Wipe
0 1 0c 
1 9 3c# that
0 1 0c 
1 9 3d lip-
0 1 0c 
1 9 3c# stick
0 1 0c 
1 9 2b a-
0 1 0c 
1 20 3c# way,\
0 30 0c \
1 9 3d Show
0 1 0c 
1 9 3e me
0 1 0c 
1 9 3f# your
0 1 0c 
1 20 3e face,\
0 30 0c 
1 9 3d Clean
0 1 0c 
1 9 3e as
0 1 0c 
1 9 3f# the
0 1 0c 
1 19 3e mor-
0 1 0c 
1 10 2a nin',\
0 15 0c 
1 4 2a I
0 1 0c 
1 9 3f# know
0 1 0c 
1 9 3g# things
0 1 0c 
1 9 3a were
0 1 0c 
1 20 3a bad,\
0 25 0c 
1 4 3e But
0 1 0c 
1 14 3e now
0 1 0c 
1 14 3a they're
0 1 0c 
1 9 3g# o-
0 1 0c 
1 60 3a kay,\
0 60 0c \
1 14 4c# Sud-
0 1 0c 
1 14 3b den-
0 1 0c 
1 9 3a ly
0 1 0c 
1 29 3a Sey-
0 1 0c 
1 50 3f# mour
0 30 0c 
1 9 3f# is
0 1 0c 
1 14 3f# stand-
0 1 0c 
1 14 3g# in'
0 1 0c 
1 9 3a be-
0 1 0c 
1 29 3e side
0 1 0c 
1 50 3c# you,\
0 30 0c 
1 9 3c# You
0 1 0c 
1 14 4c# don't
0 1 0c 
1 14 3b need
0 1 0c 
1 9 3a no
0 1 0c 
1 29 3b make-
0 1 0c 
1 50 3g# up,
0 30 0c 
1 9 3e don't
0 1 0c 
1 14 3f# have
0 1 0c 
1 14 3a to
0 1 0c 
1 9 3b pre-
0 1 0c 
1 119 4c# tend,\
0 1 0c 
1 14 4c# Sud-
0 1 0c 
1 14 3b den-
0 1 0c 
1 9 3a ly
0 1 0c 
1 29 3a Sey-
0 1 0c 
1 50 3f# mour
0 30 0c 
1 9 3f# is
0 1 0c 
1 14 3f# here
0 1 0c 
1 14 3g# to
0 1 0c 
1 9 3a pro-
0 1 0c 
1 39 3e vide
0 1 0c 
1 40 3a you,\
0 40 0c 
1 14 3f# Sweet
0 1 0c 
1 14 3g# un-
0 1 0c 
1 9 3a der-
0 1 0c 
1 24 4c# stand-
0 1 0c 
1 4 3b 
0 1 0c 
1 9 3a 
0 1 0c 
1 40 3a ing,
0 40 0c 
1 14 3e Sey-
0 1 0c 
1 14 3a mour's
0 1 0c 
1 9 3g# your
0 1 0c 
1 40 3a friend.\
0 25 0c
@//E*O*F suddenly//
chmod u=rw,g=r,o=r suddenly
 
exit 0