home *** CD-ROM | disk | FTP | other *** search
/ C++ Games Programming / CPPGAMES.ISO / fgl / fglight / manuals.arj / USER15.DOC < prev    next >
Text File  |  1995-02-06  |  27KB  |  654 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7. Chapter 15
  8.  
  9.  
  10.  
  11.  
  12.  
  13. Sound Effects                                                                  
  14. 330   Fastgraph User's Guide
  15.  
  16.  
  17. Overview
  18.  
  19.      In the realm of the IBM PC and PS/2 family of systems, a sound is defined
  20. by its frequency, duration, and volume. The frequency of a sound is measured
  21. in units called Hertz. While the PC and PS/2 can produce sounds ranging from
  22. 18 to more than one million Hertz, the average human can hear sounds between
  23. 20 and about 20,000 Hertz. The length of a sound, called its duration, is
  24. expressed in clock ticks; there are either 18.2 of 72.8 clock ticks per
  25. second, depending on the method used to produce the sound. Finally, the volume
  26. determines the loudness of the sound. As we'll see in this chapter, we can
  27. control a sound's volume only on the PCjr and Tandy 1000 systems.
  28.  
  29.      Fastgraph offers several different methods for producing sound effects.
  30. These include single tones, a series of tones expressed numerically, or a
  31. series of tones expressed as musical notes. The sound effects may be discrete,
  32. continuous, or performed at the same time as other activity. The sound-related
  33. routines are independent of the other parts of Fastgraph and do not require
  34. any initialization routines be called.
  35.  
  36.  
  37. Sound Sources
  38.  
  39.      All members of the PC and PS/2 families can produce sounds using the
  40. 8253-5 programmable timer chip and the internal speaker. This method is
  41. limited to producing single sounds of given frequencies and durations,
  42. although we can combine these sounds to create interesting audio effects or
  43. play music. When we use this technique, we have no control over the sound
  44. volume. In fact, sound volumes often vary slightly on different systems
  45. because the physical properties of the speaker and its housing are not always
  46. the same.
  47.  
  48.      The PCjr and Tandy 1000 systems have an additional, more powerful chip
  49. for producing sounds. This is the Texas Instruments SN76496A sound chip,
  50. called the TI sound chip for short. The TI sound chip has three independent
  51. voice channels for producing pure tones, and a fourth channel for generating
  52. periodic or white noise. Each voice channel has a separate volume control that
  53. allows us to control the loudness of the sound it emits.
  54.  
  55.  
  56. Synchronous Sound
  57.  
  58.      A sound effect is said to be synchronous if it is produced while no other
  59. activity is being performed. In other words, a program makes a synchronous
  60. sound by starting the sound, waiting for a specified duration, and then
  61. stopping the sound. The program must wait for the sound to complete before
  62. doing anything else. As long as the duration is relatively short, the fact
  63. that the sound is synchronous has little or no effect on the program's
  64. execution speed. Fastgraph includes routines for producing synchronous sound
  65. using either the 8253-5 programmable timer or the TI sound chip.
  66.  
  67.      The fg_sound routine uses the programmable timer to produce a sound of a
  68. given frequency and duration. The frequency, defined by the first argument, is
  69. expressed in Hertz and must be an integer value between 18 and 32,767. The
  70. second argument defines the duration and is expressed in clock ticks; there    
  71.                                               Chapter 15:  Sound Effects   331
  72.  
  73. are 18.2 clock ticks per second. If the duration is zero or negative, the
  74. sound will continue until it is stopped with fg_quiet.
  75.  
  76.      Example 15-1 uses fg_sound to create different sound effects, pausing for
  77. one second between each. It first produces three distinct sounds of 20, 100,
  78. and 1,000 Hertz. Each of these sounds lasts for approximately 1/6 of a second
  79. (three clock ticks). The program then makes a warbling noise by quickly
  80. alternating sounds of similar frequencies. Finally, the program creates a
  81. sliding tone of increasing frequencies between 100 and 500 Hertz. Each tone in
  82. this sequence lasts for two clock ticks, so it takes about 4.5 seconds to play
  83. the entire sequence. In all cases, example 15-1 displays an identifying
  84. message just before each sound.
  85.  
  86.                                  Example 15-1.
  87.  
  88.               #include <fastgraf.h>
  89.               #include <stdio.h>
  90.               void main(void);
  91.  
  92.               void main()
  93.               {
  94.                  int freq;
  95.  
  96.                  fg_initpm();
  97.                  printf("20 Hz tone...\n");
  98.                  fg_sound(20,3);
  99.                  fg_waitfor(18);
  100.  
  101.                  printf("100 Hz tone...\n");
  102.                  fg_sound(100,3);
  103.                  fg_waitfor(18);
  104.  
  105.                  printf("1000 Hz tone...\n");
  106.                  fg_sound(1000,3);
  107.                  fg_waitfor(18);
  108.  
  109.                  printf("warble...\n");
  110.                  fg_sound(400,1);
  111.                  fg_sound(410,1);
  112.                  fg_sound(400,1);
  113.                  fg_sound(410,1);
  114.                  fg_waitfor(18);
  115.  
  116.                  printf("sliding tone from 100 to 500 Hz...\n");
  117.                  for (freq = 100; freq <= 500; freq+=10)
  118.                     fg_sound(freq,2);
  119.               }
  120.  
  121.  
  122.      The fg_voice routine is analogous to fg_sound, but it uses the TI sound
  123. chip rather than the programmable timer to create sound. For this reason,
  124. fg_voice can only be used on the PCjr or Tandy 1000 systems. The TI sound chip
  125. allows us to control the volume of a sound, and it also offers four distinct
  126. voice channels. Thus, fg_voice requires two additional arguments besides
  127. frequency and duration to define the voice channel and sound volume.           
  128. 332   Fastgraph User's Guide
  129.  
  130.      The first argument to fg_voice defines the voice channel, as shown here:
  131.  
  132.                             value meaning
  133.  
  134.                               1   voice channel #1
  135.                               2   voice channel #2
  136.                               3   voice channel #3
  137.                               4   voice channel #4, periodic noise
  138.                               5   voice channel #4, white noise
  139.  
  140. If we use voice channels 1, 2, or 3, the second argument defines the sound
  141. frequency in Hertz, between 18 and 32,767. If we use voice channel 4, however,
  142. the second argument instead is a value that represents a specific frequency,
  143. as shown in this table:
  144.  
  145.                                    value frequency
  146.  
  147.                                      0   512 Hertz
  148.                                      1  1024 Hertz
  149.                                      2  2048 Hertz
  150.  
  151. The third argument defines the sound volume. It must be between 0 and 15,
  152. where 0 is silent and 15 is loudest. The fourth argument defines the sound
  153. duration in clock ticks. As with fg_sound, there are 18.2 clock ticks per
  154. second, and if the duration is zero or negative, the sound will continue until
  155. stopped with fg_quiet.
  156.  
  157.      Example 15-2 uses fg_voice to create different sound effects using the TI
  158. sound chip. As in example 15-1, there is a pause of one second between each.
  159. The program first calls fg_testmode to be sure it is running on a PCjr or
  160. Tandy 1000 system (video mode 9 is only available on these systems). If so,
  161. the program uses voice channel #4 to produce a 2,048 Hertz periodic noise,
  162. followed by white noise of the same frequency. Both sounds are emitted at the
  163. maximum volume level (15) and last for about 1/6 of a second each (three clock
  164. ticks). After these noises, example 15-2 produces a 500 Hertz tone of
  165. increasing volume. In all cases, the program displays an identifying message
  166. just before each sound.
  167.  
  168.                                  Example 15-2.
  169.  
  170.               #include <fastgraf.h>
  171.               #include <stdio.h>
  172.               #include <stdlib.h>
  173.               void main(void);
  174.  
  175.               void main()
  176.               {
  177.                  int volume;
  178.  
  179.                  fg_initpm();
  180.                  if (fg_testmode(9,0) == 0) {
  181.                     printf("This program requires a PCjr or ");
  182.                     printf("a Tandy 1000 system.\n");
  183.                     exit(1);
  184.                     }                                                          
  185.                                               Chapter 15:  Sound Effects   333
  186.  
  187.                  printf("2048 Hz periodic noise...\n");
  188.                  fg_voice(4,2,15,3);
  189.                  fg_waitfor(18);
  190.  
  191.                  printf("2048 Hz white noise...\n");
  192.                  fg_voice(5,2,15,3);
  193.                  fg_waitfor(18);
  194.  
  195.                  printf("500 Hz tone of increasing volume...\n");
  196.                  for (volume = 1; volume <= 15; volume++) {
  197.                     fg_voice(1,500,volume,0);
  198.                     fg_waitfor(4);
  199.                     }
  200.  
  201.                  fg_quiet();
  202.               }
  203.  
  204.  
  205.      Note how example 15-2 uses a duration of zero (continuous sound) and
  206. fg_waitfor to specify the duration for each volume level the 500 Hertz tone
  207. sequence. This causes the transition between changes in volume to blend better
  208. with each other. The fg_quiet routine, which stops continuous sound started
  209. with fg_sound or fg_voice, ends the sound after the final volume level.
  210.  
  211.      Both fg_sound and fg_voice produce a single sound. We've seen how to
  212. combine sounds to produce sound effects, but still the individual sounds are
  213. defined numerically -- that is, by a certain frequency and duration. It is
  214. often easier to create sounds from musical notes, and for this reason
  215. Fastgraph includes a routine fg_music that produces such sounds. The fg_music
  216. routine uses the programmable timer to produce synchronous sound; it does not
  217. support the TI sound chip.
  218.  
  219.      The fg_music routine has a single argument called the music string,
  220. passed by reference as a byte array or character string. The music string is
  221. simply a variable-length sequence of music commands, followed by a dollar-sign
  222. ($) terminator. Music commands are summarized in the following table.
  223.  
  224. command   meaning
  225.  
  226. A thru G  Play the specified note in the current octave.
  227.  
  228. #         May be appended to a note character (A through G) to make that note
  229.           sharp.
  230.  
  231. .         May be appended to a note character (A through G) or a sharp (#) to
  232.           extend that note by half its normal length. Multiple dots may be
  233.           used, and each will again extend the note by half as much as the
  234.           previous extension.
  235.  
  236. Ln        Set the length of subsequent notes and pauses. The value of n is an
  237.           integer between 1 and 64, where 1 indicates a whole note, 2 a half
  238.           note, 4 a quarter note, and so forth. If no L command is present, L4
  239.           is assumed.
  240.  
  241. On        Set the octave for subsequent notes. The value of n may be an
  242.           integer between 0 and 6 to set a specific octave. It also can be a   
  243. 334   Fastgraph User's Guide
  244.  
  245.           plus (+) or minus (-) character to increment or decrement the
  246.           current octave number. Octave 4 contains middle C, and if no O
  247.           command is present, O4 is assumed.
  248.  
  249. P         Pause (rest) for the duration specified by the most recent L
  250.           command.
  251.  
  252. Sn        Set the amount of silence between notes. The value of n is an
  253.           integer between 0 and 2. If n is 0, each note plays for the full
  254.           period set by the L command (music legato). If n is 1, each note
  255.           plays for 7/8 the period set by the L command (music normal). If n
  256.           is 2, each note plays for 3/4 the period set by the L command (music
  257.           staccato). If no S command is present, S1 is assumed.
  258.  
  259. Tn        Set the tempo of the music (the number of quarter notes per minute).
  260.           The value of n is an integer between 32 and 255. If no T command is
  261.           present, T120 is assumed.
  262.  
  263. The fg_music routine ignores any other characters in the music string. It also
  264. ignores command values outside the allowable range, such as T20 or O8.
  265.  
  266.      Example 15-3 illustrates some uses of fg_music. The program plays the
  267. first few bars of "Mary Had a Little Lamb", followed by the musical scale
  268. (including sharps) in two octaves, and finally the introduction to Beethoven's
  269. Fifth Symphony. There is a pause of one second between each piece of music,
  270. and the program displays the titles before playing the music. Blank characters
  271. appear in the music strings to help make them more readable.
  272.  
  273.                                  Example 15-3.
  274.  
  275.  
  276.     #include <fastgraf.h>
  277.     #include <stdio.h>
  278.     void main(void);
  279.  
  280.     void main()
  281.     {
  282.     {  fg_initpm();
  283.        printf("Mary Had a Little Lamb...\n");
  284.        fg_music("T150 L8 EDCDEEE P DDD P EGG P EDCDEEE L16 P L8 EDDEDC$");
  285.        fg_waitfor(18);
  286.  
  287.        printf("up the scale in two octaves...\n");
  288.        fg_music("L16 CC#DD#EFF#GG#AA#B O+ CC#DD#EFF#GG#AA#B$");
  289.        fg_waitfor(18);
  290.  
  291.        printf("Beethoven's Fifth Symphony...\n");
  292.        fg_music("T180 O2 L2 P L8 P GGG L2 D# L24 P L8 P FFF L2 D$");
  293.     }                                                                          
  294.                                               Chapter 15:  Sound Effects   335
  295.  
  296.  
  297. Asynchronous Sound
  298.  
  299.      Sounds made concurrently with other activity in a program are said to be
  300. asynchronous. Fastgraph's routines that produce asynchronous sound just start
  301. the sound and then immediately return control to the calling program. The
  302. sounds will automatically stop when the end of the sequence is reached, and
  303. you also can suspend or stop it on demand before that time. None of
  304. Fastgraph's asynchronous sound routines have any effect if there is already
  305. asynchronous sound in progress. In addition, the asynchronous sound routines
  306. temporarily disable the synchronous sound routines (fg_sound, fg_voice, and
  307. fg_music) while asynchronous sound is in progress.
  308.  
  309.      To expand the range of sound effects and to play fast-tempo music,
  310. Fastgraph temporarily quadruples the clock tick interrupt rate from 18.2 to
  311. 72.8 ticks per second while producing asynchronous sound. Because many disk
  312. controllers rely on the 18.2 tick per second clock rate to synchronize disk
  313. accesses, your programs should not perform any disk operations when
  314. asynchronous sound is in progress.
  315.  
  316.      The fg_sounds routine is the asynchronous version of fg_sound. It uses
  317. the programmable timer to play a sequence of tones simultaneous to other
  318. operations. This routine expects as its first argument a variable-length
  319. integer array, passed by reference, containing pairs of frequency and duration
  320. values. As with fg_sound, each frequency is expressed in Hertz and must be
  321. between 18 and 32,767. The durations are also measured in clock ticks, but
  322. because the interrupt rate is quadrupled, there are 72.8 instead of 18.2 ticks
  323. per second.
  324.  
  325.      The format of the frequency and duration array passed to fg_sounds is
  326. shown here:
  327.  
  328.  
  329.                           [0]    frequency of sound 1
  330.  
  331.                           [1]    duration  of sound 1
  332.  
  333.                           [2]    frequency of sound 2
  334.  
  335.                           [3]    duration  of sound 2
  336.  
  337.                                            .
  338.                                            .
  339.                                            .
  340.  
  341.                        [2n-2]    frequency of sound n
  342.  
  343.                        [2n-1]    duration  of sound n
  344.  
  345.                          [2n]       terminator (0)
  346.  
  347.  
  348. Note that a null character (that is, a zero byte) terminates the array. The
  349. second argument passed to fg_sounds is an integer value indicating the number
  350. of times to cycle through the frequency and duration array. If this value is
  351. negative, the sounds will continue until stopped with fg_hush or fg_hushnext.  
  352. 336   Fastgraph User's Guide
  353.  
  354.  
  355.      Example 15-4 uses fg_sounds to play the 100 to 500 Hertz sliding tone
  356. sequence of example 15-1. To prove the sounds are being made concurrently with
  357. other operations, messages are displayed while the sequence is playing. This
  358. is controlled by the Fastgraph routine fg_playing, which returns a value of 1
  359. if asynchronous sounds are in progress, and 0 if not. Note how the duration
  360. must be specified as 8 clock ticks (instead of 2 as in example 15-1) to
  361. compensate for the quadrupled clock tick interrupt rate.
  362.  
  363.                                  Example 15-4.
  364.  
  365.                  #include <fastgraf.h>
  366.                  #include <stdio.h>
  367.                  void main(void);
  368.  
  369.                  void main()
  370.                  {
  371.                     int i;
  372.                     int freq;
  373.                     int sound_array[83];
  374.  
  375.                     i = 0;
  376.                     for (freq = 100; freq <= 500; freq+=10) {
  377.                        sound_array[i++] = freq;
  378.                        sound_array[i++] = 8;
  379.                        }
  380.                     sound_array[i] = 0;
  381.  
  382.                     fg_initpm();
  383.                     fg_sounds(sound_array,1);
  384.  
  385.                     while(fg_playing())
  386.                        printf("Still playing...\n");
  387.                  }
  388.  
  389.  
  390.      Just as fg_sounds is analogous to fg_sound, there is a Fastgraph routine
  391. fg_voices that is similar to fg_voice. That is, fg_voices uses the TI sound
  392. chip to play an asynchronous sequence of tones. Its arguments are the same as
  393. those of fg_sounds, but the structure of the sound array is different. Its
  394. structure is:
  395.  
  396.  
  397.                           [0]    channel # of sound 1
  398.  
  399.                           [1]    frequency of sound 1
  400.  
  401.                           [2]    volume    of sound 1
  402.  
  403.                           [3]    duration  of sound 1
  404.  
  405.                                            .
  406.                                            .
  407.                                            .
  408.  
  409.                        [4n-4]    channel # of sound n                          
  410.                                               Chapter 15:  Sound Effects   337
  411.  
  412.  
  413.                        [4n-3]    frequency of sound n
  414.  
  415.                        [4n-2]    volume    of sound n
  416.  
  417.                        [4n-1]    duration  of sound n
  418.  
  419.                          [4n]       terminator (0)
  420.  
  421.  
  422. The channel numbers, frequencies, volumes, and durations must be in the same
  423. ranges as discussed in the description of fg_voice, except the durations are
  424. quadrupled because of the accelerated clock tick interrupt rate. Again, note
  425. that a null character (that is, a zero byte) terminates the array.
  426.  
  427.      Example 15-5 uses fg_voices to play the 500 Hertz tone sequence of
  428. increasing volume introduced in example 15-2. As in example 15-4, the program
  429. displays messages while the tone sequence is playing to demonstrate the sounds
  430. are being made concurrently with other operations. Note how the duration is
  431. now 16 clock ticks (instead of 4 as in example 15-2) because of the quadrupled
  432. clock tick interrupt rate.
  433.  
  434.                                  Example 15-5.
  435.  
  436.             #include <fastgraf.h>
  437.             #include <stdio.h>
  438.             void main(void);
  439.  
  440.             void main()
  441.             {
  442.                int voice_array[61];
  443.                int i;
  444.                int volume;
  445.  
  446.                fg_initpm();
  447.                if (fg_testmode(9,0) == 0) {
  448.                   printf("This program requires a PCjr or ");
  449.                   printf("a Tandy 1000 system.\n");
  450.                   exit(1);
  451.                   }
  452.  
  453.                i = 0;
  454.                for (volume = 1; volume <= 15; volume++) {
  455.                   voice_array[i++] = 1;      /* use channel 1 */
  456.                   voice_array[i++] = 500;    /* 500 Hz frequency */
  457.                   voice_array[i++] = volume; /* variable volume */
  458.                   voice_array[i++] = 16;     /* duration */
  459.                   }
  460.                voice_array[i] = 0;
  461.  
  462.                fg_voices(voice_array,1);
  463.  
  464.                while(fg_playing())
  465.                   printf("Still playing...\n");
  466.             }                                                                  
  467. 338   Fastgraph User's Guide
  468.  
  469.  
  470.      There is also an asynchronous version of fg_music. It is called
  471. fg_musicb, and it uses the same format music string as fg_music does. However,
  472. fg_musicb has a second argument that specifies the number of times to cycle
  473. through the music string. If this value is negative, the music will play
  474. repetitively until you stop it with fg_hush or fg_hushnext.
  475.  
  476.      Example 15-6 plays the same three pieces of music as example 15-3, but it
  477. does so concurrently with other operations. As the music plays, the program
  478. continuously displays the title of each piece. Note how we can take advantage
  479. of the repetition in the music string for the "up the scale" sequence by
  480. playing the sequence twice.
  481.  
  482.                                  Example 15-6.
  483.  
  484.    #include <fastgraf.h>
  485.    #include <stdio.h>
  486.    void main(void);
  487.  
  488.    void main()
  489.    {
  490.       fg_initpm();
  491.       fg_musicb("T150 L8 EDCDEEE P DDD P EGG P EDCDEEE L16 P L8 EDDEDC$",1);
  492.       while (fg_playing())
  493.          printf("Mary Had a Little Lamb...\n");
  494.       fg_waitfor(18);
  495.  
  496.       fg_musicb("L16 CC#DD#EFF#GG#AA#B O+$",2);
  497.       while (fg_playing())
  498.          printf("up the scale in two octaves...\n");
  499.       fg_waitfor(18);
  500.  
  501.       fg_musicb("T180 O2 L2 P L8 P GGG L2 D# L24 P L8 P FFF L2 D$",1);
  502.       while (fg_playing())
  503.          printf("Beethoven's Fifth Symphony...\n");
  504.    }
  505.  
  506.  
  507.      The next example demonstrates the effects of the Fastgraph routines
  508. fg_hush and fg_hushnext, which stop sounds started with fg_sounds, fg_voices,
  509. or fg_musicb. The fg_hush routine immediately stops asynchronous sound, while
  510. fg_hushnext does so when the current cycle finishes. Neither routine has any
  511. arguments, and neither routine has any effect if no asynchronous sound is in
  512. progress. Furthermore, note that fg_hushnext has no effect unless the
  513. asynchronous sound is continuous.
  514.  
  515.      Example 15-7 runs in any text or graphics video mode. It displays
  516. rectangles in up to 16 colors while playing continuous asynchronous music. The
  517. program periodically checks for keystrokes with fg_intkey, and it continues to
  518. play the music while there is no keyboard activity. If you press the Escape
  519. key, the program uses fg_hush to stop the music immediately; this causes an
  520. exit from the while loop. If you press any other key, the program uses
  521. fg_hushnext to stop the music as soon as the current repetition finishes. Once
  522. it does, the program exits the while loop because fg_playing will return a
  523. value of zero.                                                                 
  524.                                               Chapter 15:  Sound Effects   339
  525.  
  526.                                  Example 15-7.
  527.  
  528.       #include <fastgraf.h>
  529.       void main(void);
  530.  
  531.       #define ESC 27
  532.  
  533.       void main()
  534.       {
  535.          int color;
  536.          int old_mode;
  537.          unsigned char key, aux;
  538.  
  539.          fg_initpm();
  540.          old_mode = fg_getmode();
  541.          fg_setmode(fg_automode());
  542.          color = 0;
  543.  
  544.          fg_musicb("O4 L16 CC#DD#EFF#GG#AA#B O+ CC#DD#EFF#GG#AA#B$",-1);
  545.  
  546.          while (fg_playing())
  547.          {
  548.             color = (color + 1) & 15;
  549.             fg_setcolor(color);
  550.             fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
  551.  
  552.             fg_waitfor(4);
  553.             fg_intkey(&key,&aux);
  554.             if (key == ESC)
  555.                fg_hush();
  556.             else if (key+aux != 0)
  557.                fg_hushnext();
  558.          }
  559.  
  560.          fg_setmode(old_mode);
  561.          fg_reset();
  562.       }
  563.  
  564.  
  565.      Example 15-7 also demonstrates an important side-effect of fg_musicb when
  566. playing continuous music. Any length, octave, silence, or tempo values changed
  567. within the string are not reset to their original values at the beginning of
  568. each repetition. If we did not include the O4 command at the beginning of the
  569. string, the later O+ command would cause the music to play in octaves 4 and 5
  570. during the first repetition, 5 and 6 during the second repetition, and octave
  571. 6 for all subsequent repetitions (because you cannot increase the octave
  572. number above 6).
  573.  
  574.      The final two routines relating to asynchronous sound are fg_resume and
  575. fg_suspend. The fg_suspend routine suspends music previously started by
  576. fg_musicb, while fg_resume restarts the music from the point where it was
  577. suspended. Example 15-8 plays the first few bars of "Mary Had a Little Lamb".
  578. If you press any key while the song is playing, it stops. Then, after another
  579. keystroke, the music resumes and continues until finished.                     
  580. 340   Fastgraph User's Guide
  581.                                  Example 15-8.
  582.  
  583.    #include <fastgraf.h>
  584.    #include <stdio.h>
  585.    void main(void);
  586.  
  587.    void main()
  588.    {
  589.       fg_initpm();
  590.       fg_musicb("T150 L8 EDCDEEE P DDD P EGG P EDCDEEE L16 P L8 EDDEDC$",1);
  591.       fg_waitkey();
  592.  
  593.       fg_suspend();
  594.       printf("Music suspended.  Press any key to resume.\n");
  595.       fg_waitkey();
  596.  
  597.       fg_resume();
  598.       printf("Music resumed.\n");
  599.       while (fg_playing());
  600.       printf("Music finished.\n");
  601.    }
  602.  
  603.  
  604. The fg_suspend routine has no effect if there is no asynchronous music in
  605. progress. Similarly, fg_resume has no effect if there is no suspended music.
  606. If you call fg_suspend and then need to cancel the music or exit to DOS
  607. instead of restarting the music, call fg_hush instead of fg_resume.
  608.  
  609.  
  610. Summary of Sound Routines
  611.  
  612.      This section summarizes the functional descriptions of the Fastgraph
  613. routines presented in this chapter. More detailed information about these
  614. routines, including their arguments and return values, may be found in the
  615. Fastgraph Reference Manual.
  616.  
  617.      FG_HUSH immediately stops asynchronous sound started with fg_sounds,
  618. fg_voices, or fg_musicb.
  619.  
  620.      FG_HUSHNEXT is similar to fg_hush, but it does not stop the asynchronous
  621. sound until the current repetition finishes.
  622.  
  623.      FG_MUSIC uses the programmable timer to play a sequence of musical tones.
  624.  
  625.      FG_MUSICB is the asynchronous version of fg_music. It uses the
  626. programmable timer to play a sequence of musical tones, concurrent with other
  627. activity.
  628.  
  629.      FG_PLAYING determines whether or not there is any asynchronous sound in
  630. progress.
  631.  
  632.      FG_QUIET stops continuous synchronous sound started with fg_sound or
  633. fg_voice.
  634.  
  635.      FG_RESUME restarts asynchronous music previously suspended by fg_suspend. 
  636.                                               Chapter 15:  Sound Effects   341
  637.  
  638.      FG_SOUND produces a tone of a specified frequency and duration using the
  639. programmable timer.
  640.  
  641.      FG_SOUNDS is the asynchronous version of fg_sound. It can play a series
  642. of tones of specified frequencies and durations, concurrent with other
  643. activity.
  644.  
  645.      FG_SUSPEND suspends asynchronous music previously started by fg_musicb.
  646.  
  647.      FG_VOICE produces a tone of a specified frequency, duration, and volume
  648. using one of the TI sound chip's four voice channels.
  649.  
  650.      FG_VOICES is the asynchronous version of fg_voice. It can play a series
  651. of tones of specified frequencies, durations, and volumes, concurrent with
  652. other activity.                                                                
  653. 342   Fastgraph User's Guide
  654.