home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c329 / 2.img / EXAMPLES / MUSIC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-23  |  5.0 KB  |  155 lines

  1. /*
  2.  * MUSIC.C
  3.  * Usage: RUN386 -CALLBUFS 1 MUSIC
  4.  * Purpose: demonstrates interfacing between assembly
  5.  * language and NDP C programs. The NDP code calls
  6.  * protected mode assembly language routines. These
  7.  * in turn communicate with a real mode assembly
  8.  * language routine. These assembly routines are used
  9.  * to control the underlying PC hardware. They do so
  10.  * by reading from and writing to ports and by
  11.  * taking over the timer tick interrupt.
  12.  * Copyright (C) MicroWay, Inc., 1989
  13.  *
  14.  */
  15.  
  16. #include <stdio.h>
  17.  
  18. #define WHOLE           64
  19. #define WHOLEDOT        WHOLE+WHOLE/2
  20. #define HALF            WHOLE/2
  21. #define HALFDOT         WHOLE/2+WHOLE/4
  22. #define QUARTER         WHOLE/4
  23. #define QUARTERDOT      WHOLE/4+WHOLE/8
  24. #define EIGHTH          WHOLE/8
  25. #define EIGHTHDOT       WHOLE/8+WHOLE/16
  26. #define SIXTEENTH       WHOLE/16
  27. #define SIXTEENTHDOT    WHOLE/16+WHOLE/32
  28. #define THIRTYSECOND    WHOLE/32
  29. #define THIRTYSECONDDOT WHOLE/32+WHOLE/64
  30. #define SIXTYFOURTH     WHOLE/64
  31. #define NONE            0
  32.  
  33. #define ERROR_VAL -1
  34.  
  35. /* This example plays musical tunes. The tune is
  36.  * represented by an array of structures. Each
  37.  * structure represents a note: the first field
  38.  * gives the note's duration and the second field
  39.  * denotes its name. Each name represents a note
  40.  * in the tempered chromatic scale. The names take
  41.  * one of three forms:
  42.  *             'A-G' ['#'|'b'] '0-8'
  43.  *   or        'A-G' '0-8'
  44.  *   or        'R'
  45.  * The first letter of every note must be in upper
  46.  * case - lower case 'b' is reserved to indicate the
  47.  * tone is a flat. If the note is a sharp or a flat,
  48.  * the second character is a '#' or a 'b' and the
  49.  * third character is a digit indicating the octave.
  50.  * If the note is not a sharp or a flat, then the
  51.  * second character is a digit indicating the octave.
  52.  * The only other character allowed is an upper case
  53.  * 'R', to denote rest or pause. Every name occupies
  54.  * 4 bytes and has 1, 2 or 3 printable characters, the
  55.  * rest being null bytes(s) (value 0, not character '0').
  56.  * Since this is a tempered scale, the frequency of
  57.  * adjacent sharps and flats is the same, e.g., G#0 and
  58.  * Ab0 have the same pitch.
  59.  *
  60.  */
  61.  
  62. typedef struct {
  63.         int     duration;   /* time to sound the NOTE */
  64.         char    name[4];    /* name of the NOTE */
  65. } NOTE;
  66.  
  67.  
  68. /* The following data structure holds information about
  69.  * a tone in the tempered chromatic scale. There is an
  70.  * array of such structures defined in the assembly
  71.  * language module PLAY.S. Each structure holds
  72.  * information about a tone in the tempered chromatic
  73.  * scale and the entire array spans eight octaves.
  74.  * The first field of these is the name of the tone
  75.  * and takes essentially the same form as the name
  76.  * field in the NOTE structure. The tones range from
  77.  * C0 to C8, middle C being C4. The second field is
  78.  * the frequency of the tone, e.g., A4 is 440 Hertz.
  79.  * The third field is the count between pulses to the
  80.  * speaker and is inversely proportional to the
  81.  * frequency. Notes C0 to E0 will not play, because
  82.  * their frequency is too low (i.e., their count is
  83.  * too high and occupies more than 16 bits) - using
  84.  * them will generate an error. For details on these
  85.  * structures, see PLAY.S.
  86.  *
  87.  */
  88. typedef struct {
  89.         char name[4];   /* name of the tone */
  90.         float freq;     /* frequency of the tone */
  91.         int count;      /* Timer freq div by tone freq */
  92. } TONE;
  93.  
  94. /* Next, the tune to be played */
  95. NOTE tune [] = {   
  96.         WHOLE,    "C5",
  97.         HALF,     "E5",
  98.         WHOLE,    "G5",
  99.         HALF,     "E5",
  100.         QUARTER,  "R",
  101.         WHOLE,    "F4",
  102.         QUARTER,  "D5",
  103.         HALF,     "B4"
  104.         WHOLE,    "C5",
  105.         NONE,     ""
  106. };
  107.  
  108. extern TONE tcs [];  /* Octaves in the Tempered Chromatic Scale */
  109. extern void init_tcs();
  110. extern int init_timer_isr();
  111. extern int play();
  112. extern int restore_timer_isr();
  113.  
  114. void main ()
  115.  
  116. {
  117.         int i;
  118.  
  119.         init_tcs();     /* initialize tempered chromatic scales */
  120.  
  121. /* display initialized tempered chromatic scales */
  122.         i = 0;
  123.         while (*tcs[i].name) {
  124.                 printf ("%s\t%4.2f\t%d\n",tcs[i].name,
  125.                         tcs[i].freq,tcs[i].count);
  126.                 i++;
  127.         }
  128.  
  129. /* set up new timer interrupt service routine */
  130.         i = init_timer_isr();
  131.         if (i == ERROR_VAL) {
  132.                 printf ("Problem in initializing new timer ISR\n");
  133.                 printf ("Be sure to invoke RUN386.EXE with ");
  134.                 printf ("-CALLBUFS equal to at least 1\n");
  135.                 exit(1);
  136.         }
  137.  
  138. /* play a little tune */
  139.         i = play(tune); 
  140.         if (i == ERROR_VAL) {
  141.                 printf ("Problem in play function\n");
  142.                 exit(1);
  143.         }
  144.  
  145. /* restore old timer interrupt service routine */
  146.         i = restore_timer_isr();
  147.         if (i == ERROR_VAL) {
  148.                 printf ("Problem in restoring old timer ISR\n");
  149.                 exit(1);
  150.         }
  151.  
  152.         exit(0);
  153. }
  154.  
  155.