home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d158 / yachtc3.lha / YachtC3 / src / bonesound.c < prev    next >
C/C++ Source or Header  |  1988-10-02  |  19KB  |  665 lines

  1. /* SCALES
  2.  *
  3.  *   by Steven A. Bennett
  4.  *
  5.  *   This program demonstrates the use of the Audio functions
  6.  * in the "ROM" to produce four voice sound.  It uses a simple
  7.  * waveform (sawtooth) with no amplitude control (ie, envelope)
  8.  * or frequency variation (ie, vibrato), but these can easily be
  9.  * implemented through the use of setpv(), below.
  10.  * This program may be freely distributed.
  11.  *
  12.  * NOTES
  13.  *
  14.  *   - This program was written fairly quickly, without the aid
  15.  * of the ROM Kernal Manual (save about 10 pages of notes copied
  16.  * from my dealer's copy).  Therefore, if anyone sees anything too
  17.  * much out of the ordinary, bear with it.  (Particularly in mind
  18.  * is CreatePort(), of whose use I inferred from several programs
  19.  * I have downloaded from both BIX and CompuServe)  Furthermore, this
  20.  * particular implementation was written with a full blown music
  21.  * driver in mind, therefore, some code may seem ineffecient, for
  22.  * the sake of speed.  Finally, I tend to get a bit sloppy when i'm
  23.  * working past midnight, so there may be some messy areas.
  24.  *
  25.  * REVISIONS
  26.  *
  27.  *   12/25/85 - Single voice driver written. (SAB)
  28.  *   12/26/85 - Multi-voice capability added. (SAB)
  29.  *   12/28/85 - Error handling refined (see FinishProg()) (SAB)
  30.  *   12/30/85 - Fixed cleanup routine. (SAB)
  31.  *    1/10/86 - Mod to work with Both Manx and Lattice - crunch@well.UUCP
  32.  *   12/30/87 - mod for independent process  M.E.S.
  33.  *
  34.  */
  35.  
  36. #include "exec/types.h"
  37. #include "exec/memory.h"
  38. #include "devices/audio.h"
  39. #include "stdio.h"
  40. #include "math.h"
  41.  
  42. #define  PRIORITY          50L    /* Priority for Audio Channel usage */
  43. #define  NBR_IOA_STRUCTS   10L    /* Number of IOAudio structures used */
  44. #define  PV_IOA_STRUCT     0L     /* index to ioapv struct */
  45. #define  FIN_IOA_STRUCT    9L     /* index to finishioa struct */
  46. #define  BIG_WAVE          256L   /* size of biggest waveform */
  47. #define  NBR_WAVES         7L     /* number of waves per instrument */
  48. #define  WAVES_TOTAL       1024L  /* alloc size for instrument's waves */
  49. #define  YES               1L
  50. #define  NO                0L
  51.  
  52. extern struct MsgPort *CreatePort();
  53. extern void *AllocMem();
  54. extern ULONG onoff;        /* for using as a process M.E.S.  */
  55.  
  56. UBYTE aMap[] = { 0x0f };                  /* allocate four channels */
  57. long  voiceMap[] = { 1, 2, 4, 8 };
  58. struct IOAudio *ioa, *finishioa, *ioapv;
  59. struct IOAudio *ioainuse[4];
  60. struct IOAudio *freeioa[4];
  61. long unitno = 1;
  62. int error;
  63. int waiting[4] = { NO, NO, NO, NO };
  64. int woffsets[] =
  65.    { 0, 256, 384, 448, 480, 496, 504, 508, 510 };
  66. int wlen[] =
  67.    { 256, 128, 64, 32, 16, 8, 4, 2, 1 };
  68. int perval[] =
  69.    { 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226, 214 };
  70. BYTE *wptr;
  71. BYTE *owptr[4] = { NULL, NULL, NULL, NULL };
  72.  
  73. char *portstring[] = {
  74.    "Audio one",
  75.    "Audio two",
  76.    "Audio three",
  77.    "Audio four",
  78.    "Audio five",
  79.    "Audio six",
  80.    "Audio seven",
  81.    "Audio eight" };              /* names for the CreatePorts */
  82.  
  83. /* InitIOA()
  84.  *   This function initializes all IOAudio structures used by this
  85.  * program.
  86.  *
  87.  * NOTES
  88.  *   This version sets up enough IOAudio structures for four voices, plus
  89.  * a ADCMD_FINISH and an ADCMD_PERVOL, which are both synchronous.
  90.  * The ioainuse array is assumed to be the IOAudio structure which is
  91.  * being used by the current CMD_WRITE command for each voice.  The freeioa
  92.  * array is there so that no <click> is made when switching CMD_WRITEs.
  93.  * (ie., for speed)  Since the pointers are swapped when the switch occurs,
  94.  * one can always make the same assumption.  Note that ALL of the
  95.  * asynchronous (ie., ioainuse and freeioa) structures ought to have a
  96.  * unique ReplyPort (or so I think).  The IOAudio structure used to
  97.  * Open the Device must also have a ReplyPort, but it may not have to be
  98.  * unique.  I am taking no chances, however.
  99.  */
  100.  
  101. InitIOA()
  102.    {
  103.    register int i;
  104.  
  105.    /* alloc the IOAudio structures
  106.     */
  107.    ioa = (struct IOAudio *)AllocMem((NBR_IOA_STRUCTS * (long)sizeof(*ioa)),
  108.       MEMF_PUBLIC | MEMF_CLEAR);
  109.    if (ioa == NULL)
  110.       FinishProg(1);
  111.  
  112.    /* set the various IOAudio structure pointers
  113.     */
  114.    for (i = 0; i < 4; ++i)
  115.       {
  116.       ioainuse[i] = &ioa[i + 1];
  117.       freeioa[i] = &ioa[i + 5];
  118.       }
  119.    ioapv = &ioa[PV_IOA_STRUCT];
  120.    finishioa = &ioa[FIN_IOA_STRUCT];
  121.  
  122.    /* Open the Audio Device.  This requires a ReplyPort, so we'll
  123.     * make it now, and reuse it later as part of ioapv, although it
  124.     * doesn't need one.  aMap[] is an array containing sets of
  125.     * bitmaps which allow various combinations of voices to be allocated.
  126.     * since we want all four voices, there is only one combination which
  127.     * will serve.
  128.     */
  129.    ioa->ioa_Request.io_Message.mn_Node.ln_Pri = PRIORITY;
  130.    ioa->ioa_Request.io_Message.mn_ReplyPort =
  131.       CreatePort("Audio zero", 0L);
  132.    if (ioa->ioa_Request.io_Message.mn_ReplyPort == NULL)
  133.       FinishProg(2);
  134.    ioa->ioa_Data = aMap;
  135.    ioa->ioa_Length = (long)sizeof(aMap);
  136.    error = OpenDevice(AUDIONAME, 0L, ioa, 0L);
  137.    if (error)
  138.       FinishProg(3);
  139.  
  140.    /* setup the finishioa and ioapv structs.  The IOF_QUICK flag
  141.     * makes them synchronous in all cases.
  142.     */
  143.    *finishioa = *ioa;
  144.    finishioa->ioa_Request.io_Flags = IOF_QUICK;
  145.    ioapv->ioa_Request.io_Flags = IOF_QUICK;
  146.  
  147.    finishioa->ioa_Request.io_Command = ADCMD_FINISH;
  148.    ioapv->ioa_Request.io_Command = ADCMD_PERVOL;
  149.  
  150.    /* setup the ioainuse and freeioa struct arrays.  All eight of
  151.     * them must have unique ReplyPorts, hence the CreatePort()s
  152.     * below.  portstring contains different port names for the
  153.     * eight ports.  (I have no idea as to what the zero in the
  154.     * CreatePort is used for, so don't ask.)
  155.     */
  156.    for (i = 0; i < 4; ++i)
  157.       {
  158.       *freeioa[i] = *ioa;
  159.       *ioainuse[i] = *ioa;
  160.       freeioa[i]->ioa_Request.io_Message.mn_ReplyPort =
  161.          CreatePort(portstring[i], 0L);
  162.       ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort =
  163.          CreatePort(portstring[i + 4], 0L);
  164.       }
  165.    for (i = 0; i < 4; ++i)
  166.       if (freeioa[i]->ioa_Request.io_Message.mn_ReplyPort == NULL ||
  167.          ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort == NULL)
  168.          FinishProg(4);
  169.    }
  170.  
  171. /* FinishProg(finishcode)
  172.  *    int finishcode;
  173.  *
  174.  *    displays an error message, if necessary, based on the value
  175.  * of finishcode, frees all allocated stuff (again based on finishcode)
  176.  * and then exits.
  177.  *
  178.  * NOTES
  179.  *   This is basically a tidy little "clean up" routine used by all exit
  180.  * routines in this program.  Since all the allocated "stuff" is supposed
  181.  * to be in global variables, freeing it up in one global location is
  182.  * much easier then doing it elsewhere.
  183.  *
  184.  */
  185.  
  186. char *errormsgs[] = {
  187.    "Finished!\n",
  188.    "Cannot allocate memory for IOAudio structures\n",
  189.    "Cannot create ReplyPort for OpenDevice call\n",
  190.    "Cannot open Audio Device\n",
  191.    "Cannot create ReplyPort(s) for remaining IOAudio structures\n",
  192.    "Cannot allocate memory for waveform\n",
  193.    "If you see this during execution, execute the programmer.\n" };
  194.  
  195. FinishProg(finishcode)
  196.    register int finishcode;
  197. {
  198.    register int i;
  199.  
  200.    printf(errormsgs[finishcode]);
  201.    switch(finishcode)
  202.       {
  203.          case 0:
  204.               /* free up the WaveNode list  (currently, just wptr) */
  205.               FreeMem(wptr, WAVES_TOTAL);
  206.  
  207.          case 4:
  208.          case 5:
  209.              /* free up all ReplyPorts save the first.  Since we could be
  210.               * here due to an error in allocating same, we check first.
  211.               * (And yes, Virginia, we do fall through here)
  212.               */
  213.          for (i = 0; i < 4; ++i)
  214.            {
  215.             if (freeioa[i]->ioa_Request.io_Message.mn_ReplyPort)
  216.                 DeletePort(freeioa[i]->ioa_Request.io_Message.mn_ReplyPort);
  217.             if (ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort)
  218.                 DeletePort(ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort);
  219.            }
  220.  
  221.               /* Close the Audio Device
  222.                */
  223.          CloseDevice(ioa);
  224.  
  225.          case 3:
  226.              /* Delete the first ReplyPort
  227.               */
  228.              DeletePort(ioa->ioa_Request.io_Message.mn_ReplyPort);
  229.  
  230.          case 2:
  231.                /* Free the ioa memory
  232.                 */
  233.                FreeMem(ioa, (NBR_IOA_STRUCTS * (long)sizeof(*ioa)));
  234.  
  235.       }
  236. if (finishcode) exit(1L);
  237. return;
  238. }
  239.  
  240. /* setwpv()
  241.  *
  242.  *   starts a sound on the channel specified by the global variable
  243.  * unitno.  By swapping between two IOAudio structures, this routine
  244.  * is able to accomplish it's task without a noticeable delay.
  245.  *
  246.  * NOTES
  247.  *   This routine should only be used when a waveform change is
  248.  * required, either due to frequency going out of the range of the
  249.  * existing waveform, or a different waveform has been chosen.  In
  250.  * most cases, setpv() will be sufficient.  Also, don't complain about
  251.  * the usage of io_Unit.  I didn't like it either.
  252.  *
  253.  */
  254.  
  255. setwpv(wf, len, per, vol, voice)
  256.    register char *wf;
  257.    register int len, per, vol, voice;
  258.    {
  259.    register struct IOAudio *tmpioa;
  260.  
  261.    /* the next three lines are probably unnecessary and can be
  262.     * done instead in InitIOA, but why take chances?
  263.     */
  264.    freeioa[voice]->ioa_Request.io_Command = CMD_WRITE;
  265.    freeioa[voice]->ioa_Request.io_Flags = ADIOF_PERVOL | IOF_QUICK;
  266.    freeioa[voice]->ioa_Cycles = 0;
  267.  
  268.    /* Assign the unit numbers to the (<ahem>) pointer?
  269.     */
  270.    freeioa[voice]->ioa_Request.io_Unit = (struct Unit *)unitno;
  271.    finishioa->ioa_Request.io_Unit = (struct Unit *)unitno;
  272.  
  273.    /* Set the parameters
  274.     */
  275.    freeioa[voice]->ioa_Data = (UBYTE *)wf;
  276.    freeioa[voice]->ioa_Length = len;
  277.    freeioa[voice]->ioa_Period = per;
  278.    freeioa[voice]->ioa_Volume = vol;
  279.  
  280.    /* Terminate the old request, if there is one.  waiting[] is an
  281.     * boolean (well, pseudo-boolean) array stating if there was an
  282.     * old request.  The old CMD_WRITE must be finished, and the reply
  283.     * received, before the new CMD_WRITE will work.  I am not certain
  284.     * why this is necessary.  Originally, I tried a
  285.     *               BeginIO(freeioa[voice]);
  286.     *               BeginIO(finishioa);
  287.     *               WaitIO(ioainuse[voice]);
  288.     * series, but the net effect was that the freeioa request was
  289.     * ignored (without error), and the ioainuse request continued
  290.     * blindly onwards.  I had assumed that it would act as a FIFO queue,
  291.     * but apparently not.
  292.     */
  293.    if (waiting[voice])
  294.       {
  295.       BeginIO(finishioa);
  296.       WaitIO(ioainuse[voice]);
  297.       waiting[voice] = NO;
  298.       }
  299.  
  300.    /* now start up the new voice
  301.     */
  302.    BeginIO(freeioa[voice]);
  303.    error = CheckIO(freeioa[voice]);
  304.    if (error)
  305.       {
  306.       printf("Error on CMD_WRITE\n");
  307.       WaitIO(freeioa[voice]);
  308.       }
  309.    waiting[voice] = YES;
  310.  
  311.    /* swap the pointers.  That way, the next time we pass through, we
  312.     * will still work.
  313.     */
  314.    tmpioa = ioainuse[voice];
  315.    ioainuse[voice] = freeioa[voice];
  316.    freeioa[voice] = tmpioa;
  317.    }
  318.  
  319. /* setpv(per, vol)
  320.  *   int per, vol;
  321.  *
  322.  *   Changes the period and volume of the currently executing
  323.  * CMD_WRITE on the specified unitno.
  324.  *
  325.  * NOTES
  326.  *   This routine is perfect <ahem> as it is, both for single and
  327.  * multiple voices.  It can be used to change frequency, within limits,
  328.  * change volume, and simulate vibrato and envelope controls.
  329.  * For those of you wondering where I got my period values
  330.  * from, look in the ABASIC manual, page 138.  Or, if you wish, you
  331.  * can calculate it out for yourself using the formula:
  332.  *     period = C/(ns*hz)
  333.  *       - where C is the clock rate (3579545)
  334.  *               ns is the number of samples in a cycle of the wave
  335.  *               hz is the number of cycles per second.
  336.  * Thus, for middle A on the piano (440 hz) with 32 samples in the
  337.  * cycle of the waveform, one would get:
  338.  *     period = 3579545 / (32 * 440)
  339.  *            = 3579545 / 14080
  340.  *            = 254.229 (or pretty close)
  341.  * The period must be rounded to the nearest integer, which can result
  342.  * in a maximum frequency error of about .25%, assuming one uses the
  343.  * octave for frequency between period 226 and period 428.  (This comes
  344.  * out to be less than a twentieth step at the shortest period)
  345.  * period values of less than 127 are illegal, as there aren't enough
  346.  * cycles set aside for audio DMA for anything less.  period values of
  347.  * greater than 500 or so aren't recommended as the anti-aliasing
  348.  * filter isn't of much use then, and actually could cause a possible
  349.  * high pitched overtone, which I'm sure nobody wants.  Thus I am
  350.  * only going to use this to handle a single octave's range.
  351.  * Changes of octave are accomplished by doubling or halving the number
  352.  * of samples in one cycle of the waveform, and must, therefore, call
  353.  * setwpv().
  354.  */
  355.  
  356. setpv(per, vol)
  357.    register int per, vol;
  358.    {
  359.    ioapv->ioa_Period = per;
  360.    ioapv->ioa_Volume = vol;
  361.    ioapv->ioa_Request.io_Unit = (struct Unit *)unitno;
  362.    BeginIO(ioapv);
  363.    }
  364.  
  365. /* StopVoices()
  366.  *
  367.  *   Terminates all CMD_WRITE routines in progress, effectively
  368.  * ending all sound.  Volume is set to zero first, just to be tidy.
  369.  *
  370.  */
  371.  
  372. StopVoices()
  373.    {
  374.    register int voice;
  375.  
  376.    for (voice = 0; voice < 4; ++voice)
  377.       {
  378.       if (waiting[voice])
  379.          {
  380.          /* to stop a voice, we first set it's volume to zero
  381.           * (probably unnecessary) and then finish the CMD_WRITE.
  382.           */
  383.          unitno = voiceMap[voice];
  384.          setpv(128, 0);
  385.          finishioa->ioa_Request.io_Unit = (struct Unit *)unitno;
  386.          BeginIO(finishioa);
  387.          WaitIO(ioainuse[voice]);
  388.          waiting[voice] = NO;
  389.          }
  390.       }
  391.    }
  392.  
  393. /* setwave(wfp)
  394.  *   BYTE wfp;
  395.  *
  396.  *   this routine makes the first 256 bytes (lowest octave) of the
  397.  * sawtooth wave's waveform table.  wfp must have already been
  398.  * allocated and in CHIP MEMORY!!!  This is necessary later for the
  399.  * CMD_WRITE commands to work.
  400.  *   a sawtooth wave is a simple waveform, very easy to use.  It
  401.  * basically looks like this:
  402.  *
  403.  *     /|      /|      /|      /|
  404.  *    / |     / |     / |     / |
  405.  *   /  |    /  |    /  |    /  |
  406.  *  /   |   /   |   /   |   /   |
  407.  *      |  /    |  /    |  /    |  /
  408.  *      | /     | /     | /     | /
  409.  *      |/      |/      |/      |/
  410.  *
  411.  */
  412.  
  413. setwave(wfp)
  414.    register UBYTE *wfp;          /* This is a sneaky way of making a sawtooth */
  415.    {
  416.    register int i;
  417.  
  418.    for (i = 0; i < BIG_WAVE; ++i)
  419.       wfp[i] = i;
  420.    }
  421.  
  422. setsine(wfp)
  423. register UBYTE *wfp;
  424. {
  425.   register double x;
  426.  
  427.   for( x = -PI/2 ; x <= PI/2 ; x+=.1)
  428.   {
  429.     *wfp = (UBYTE)floor(100*sin(x));
  430.     wfp++;
  431.   }
  432. }
  433.  
  434. /* xpandwave(wfp)
  435.  *   BYTE *wfp;
  436.  *
  437.  * xpandwave expands a wave with only the base BIG_WAVE specified,
  438.  * into a set of NBR_WAVES waveforms, each for one octave.
  439.  * All of the waveforms are left in contiguous memory after the
  440.  * first wave, in order of decending sizes (256, 128, 64, ...)
  441.  *
  442.  * NOTES
  443.  *   Be forewarned that this function makes two assumptions.  The
  444.  * first is that there is enough memory in the wfp buffer to hold the
  445.  * expansion, and two, that the stuff is in chip mem.  (Actually,
  446.  * makewaves() makes that assumption instead.)  This function ought to
  447.  * work for any BIG_WAVE which is a power of two greater than 2^NBR_WAVES
  448.  *
  449.  */
  450.  
  451. xpandwave(wfp)
  452.    register BYTE *wfp;
  453.    {
  454.    register int i, j, rate;
  455.    register BYTE *tptr;
  456.  
  457.    rate = 1;
  458.    tptr = wfp + BIG_WAVE;
  459.    for (i = 0; i < NBR_WAVES - 1; ++i)
  460.       {
  461.       rate *= 2;
  462.       for (j = 0; j < BIG_WAVE; j += rate)
  463.          *tptr++ = wfp[j];
  464.       }
  465.    }
  466.  
  467. /* makewaves()
  468.  *
  469.  *   just makes a sawtooth waveform in chip mem and expands it without
  470.  * the pretty list control and file IO stuff.
  471.  *
  472.  */
  473.  
  474. makewaves()
  475.    {
  476.    /* allocate the memory for the waveform.
  477.     */
  478.    wptr = (BYTE *)AllocMem(WAVES_TOTAL, MEMF_CHIP);
  479.    if (wptr == NULL)
  480.       FinishProg(5);
  481.  
  482.    /* get and expand the waveform
  483.     */
  484.    /*   setwave(wptr);  */
  485.    setsine(wptr);
  486.    xpandwave(wptr);
  487.    }
  488.  
  489. /* strike(note, voice)
  490.  *   int note, voice;
  491.  *
  492.  * This nice little routine takes a note and plays it on the given
  493.  * voice.  At a fixed amplitude.  The note is basically an integer from
  494.  * 0 to 11 (c to b) plus 12 per octave above the first and lowest.  It
  495.  * uses a pointer to the last waveform used by the voice specified to
  496.  * determine if it needs to call setwpv() or just setpv().  The waveform
  497.  * is used by adding an index (woffsets[]) dependant on the octave.
  498.  * the length of the waveform (in wlen[]) is likewise dependant on
  499.  * the octave.  Note that octaves start with zero, not one.
  500.  */
  501.  
  502. strike(note, voice)
  503.    register int note, voice;
  504.    {
  505.    register int per, oct;
  506.    register BYTE *wfp;
  507.  
  508.    unitno = voiceMap[voice];
  509.    if (note >= 100)           /* play a rest. */
  510.       {
  511.       if (waiting[voice])
  512.          setpv(200, 0);
  513.       return;
  514.       }
  515.    oct = note / 12;
  516.    per = perval[note % 12];
  517.    wfp = wptr + woffsets[oct];
  518.  
  519.    /* if the waveform hasn't changed since the last strike,
  520.     * then only change the period.
  521.     */
  522.    if (wfp == owptr[voice])
  523.       setpv(per, 32);         /* fixed volume */
  524.    else
  525.       {
  526.       setwpv(wfp, wlen[oct], per, 32, voice);
  527.       owptr[voice] = wfp;
  528.       }
  529.    }
  530.  
  531. /*  unsigned int first_time = 0; */
  532. void YahtzeeSound(freak)
  533. register long freak;
  534. {
  535.    register int i, j;
  536.  
  537.    /* simple scale
  538.     */
  539.    for (i = 0; i < 24; ++i)
  540.       {
  541.       strike(i, 0);
  542.       Delay(freak);
  543.       }
  544.  
  545.    /* crossed scales
  546.     */
  547.    for (j = 48; i < 48; ++i, --j)
  548.       {
  549.       strike(i, 0);
  550.       strike(j, 1);
  551.       Delay(freak);
  552.       }
  553.  
  554.    /* crossed scales with lower in sync
  555.     */
  556.    for (j = 48; i < 72; ++i, --j)
  557.       {
  558.       strike(i, 0);
  559.       strike(i - 48, 1);
  560.       strike(j, 2);
  561.       Delay(freak);
  562.       }
  563.  
  564.    /* slow c chord...
  565.     */
  566.    strike(36, 0);
  567.    strike(100, 1);
  568.    strike(100, 2);
  569.    Delay(6 * freak);
  570.    strike(40, 1);
  571.    Delay(6 * freak);
  572.    strike(43, 2);
  573.    Delay(12 * freak);
  574.  
  575.    /* ...and into a minor with the fourth voice
  576.     */
  577.    strike(46, 3);
  578.    Delay(20 * freak);
  579.  
  580.    /* and two quick c chords to finish it up
  581.     */
  582.    restall();
  583.    Delay(2 * freak);
  584.    cchord();
  585.    Delay(2 * freak);
  586.    restall();
  587.    Delay(1L);
  588.    cchord();
  589.    Delay(20 * freak);
  590.    StopVoices();
  591.    return;
  592. }
  593.  
  594.  
  595. void Bomb(freak)
  596. register long freak;
  597. {
  598. register int i ;
  599.  
  600.    /*   simple scale    */
  601.  
  602.    for (i = 23; i > 1; --i)
  603.       {
  604.       strike(i, 0);
  605.       Delay(freak);
  606.       }
  607.    strike(1,0);
  608.    Delay(10 * freak);
  609.    StopVoices();
  610. return;
  611. }
  612.  
  613.  
  614. void Happy(freak)
  615. register long freak;
  616. {
  617.    /* two quick c chords */
  618.  
  619.    restall();
  620.    Delay(2 * freak);
  621.    cchord();
  622.    Delay(2 * freak);
  623.    restall();
  624.    Delay(1L);
  625.    cchord();
  626.    Delay(5 * freak);
  627.    StopVoices();
  628.    return;
  629. }
  630.  
  631. void Click(freak)
  632. register long freak;
  633. {
  634.    restall();
  635.    Delay(2 * freak);
  636.    mychord();
  637.    Delay(2 * freak);
  638.    StopVoices();
  639.    return;
  640. }
  641.  
  642. restall()
  643.    {
  644.    register int i;
  645.  
  646.    for (i = 0; i < 4; ++i)
  647.       strike(100, i);
  648.    }
  649.  
  650. cchord()
  651. {
  652.    strike(36, 0);
  653.    strike(40, 1);
  654.    strike(43, 2);
  655.    strike(48, 3);
  656. }
  657.  
  658. mychord()
  659. {
  660.    strike(54, 0);
  661.    strike(60, 1);
  662.    strike(66, 2);
  663.    strike(66, 3);
  664. }
  665.