home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / dos / prg / midas / examples / effects.c < prev    next >
C/C++ Source or Header  |  1994-08-06  |  8KB  |  261 lines

  1. /*      EFFECTS.C
  2.  *
  3.  * Example on how to play simultaneous music and sound effects
  4.  * using MIDAS Sound System
  5.  *
  6.  * Copyright 1994 Petteri Kangaslampi and Jarno Paananen
  7.  *
  8.  * This file is part of the MIDAS Sound System, and may only be
  9.  * used, modified and distributed under the terms of the MIDAS
  10.  * Sound System license, LICENSE.TXT. By continuing to use,
  11.  * modify or distribute this file you indicate that you have
  12.  * read the license and understand and accept it fully.
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <conio.h>
  18. #include "midas.h"
  19.  
  20.  
  21. /* number of sound effect channels: */
  22. #define FXCHANNELS 2
  23.  
  24. /* sound effect playing rate: */
  25. #define FXRATE 11050
  26.  
  27.  
  28.  
  29. char            *usage =
  30. "Usage:\tEFFECTS\t<module> <effect #1> <effect #2> [options]\n\n"
  31. "Options:\n"
  32. "\t-sx\tForce Sound Device x (1 = GUS, 2 = PAS, 3 = WSS, 4 = SB,\n"
  33. "\t\t5 = No Sound)\n"
  34. "\t-pxxx\tForce I/O port xxx (hex) for Sound Device\n"
  35. "\t-ix\tForce IRQ x for Sound Device\n"
  36. "\t-dx\tForce DMA channel x for Sound Device\n"
  37. "\t-mxxxxx\tSet mixing rate to xxxxx Hz\n"
  38. "\t-e\tDisable EMS usage\n"
  39. "\t-t\tDisable ProTracker BPM tempos\n"
  40. "\t-u\tEnable Surround\n"
  41. "\t-oxxx\tForce output mode (8 = 8-bit, 1 = 16-bit, s = stereo, m = mono)\n";
  42.  
  43.  
  44. unsigned        fxChannel = 0;
  45.  
  46. extern ushort masterVolume;
  47.  
  48.  
  49.  
  50. /****************************************************************************\
  51. *
  52. * Function:     unsigned LoadEffect(char *fileName)
  53. *
  54. * Description:  Loads a raw effect sample that can be used with PlayEffect().
  55. *
  56. * Input:        char *fileName          name of sample file
  57. *
  58. * Returns:      Instrument handle that can be used with PlayEffect() and
  59. *               FreeEffect().
  60. *
  61. \****************************************************************************/
  62.  
  63. unsigned LoadEffect(char *fileName)
  64. {
  65.     ushort      instHandle;             /* sound device instrument handle */
  66.     int         error;
  67.     fileHandle  f;
  68.     long        smpLength;              /* sample length */
  69.     uchar       *smpBuf;                /* sample loading buffer */
  70.  
  71.     /* open sound effect file: */
  72.     if ( (error = fileOpen(fileName, fileOpenRead, &f)) != OK )
  73.         midasError(errorMsg[error]);
  74.  
  75.     /* get file length: */
  76.     if ( (error = fileGetSize(f, &smpLength)) != OK )
  77.         midasError(errorMsg[error]);
  78.  
  79.     /* check that sample length is not too long: */
  80.     if ( smpLength > SMPMAX )
  81.         midasError("Effect sample too long");
  82.  
  83.     /* allocate memory for sample loading buffer: */
  84.     if ( (error = memAlloc(smpLength, (void**) &smpBuf)) != OK )
  85.         midasError(errorMsg[error]);
  86.  
  87.     /* load sample: */
  88.     if ( (error = fileRead(f, smpBuf, smpLength)) != OK )
  89.         midasError(errorMsg[error]);
  90.  
  91.     /* close sample file: */
  92.     if ( (error = fileClose(f)) != OK )
  93.         midasError(errorMsg[error]);
  94.  
  95.     /* Add sample to Sound Device list and get instrument handle to
  96.        instHandle: */
  97.     error = SD->AddInstrument(smpBuf, smp8bit, smpLength, 0, 0, 64, 0,
  98.         &instHandle);
  99.     if ( error != OK )
  100.         midasError(errorMsg[error]);
  101.  
  102.     /* deallocate sample allocation buffer: */
  103.     if ( (error = memFree(smpBuf)) != OK )
  104.         midasError(errorMsg[error]);
  105.  
  106.     /* return instrument handle: */
  107.     return instHandle;
  108. }
  109.  
  110.  
  111.  
  112.  
  113. /****************************************************************************\
  114. *
  115. * Function:     void FreeEffect(unsigned instHandle)
  116. *
  117. * Description:  Deallocates a sound effect
  118. *
  119. * Input:        unsigned instHandle     effect instrument handle returned by
  120. *                                       LoadEffect()
  121. *
  122. \****************************************************************************/
  123.  
  124. void FreeEffect(unsigned instHandle)
  125. {
  126.     int         error;
  127.  
  128.     /* remove instrument from Sound Device list: */
  129.     if ( (error = SD->RemInstrument(instHandle)) != OK )
  130.         midasError(errorMsg[error]);
  131. }
  132.  
  133.  
  134.  
  135.  
  136. /****************************************************************************\
  137. *
  138. * Function:     void PlayEffect(ushort instHandle, ulong rate, ushort volume,
  139. *                   short panning)
  140. *
  141. * Description:  Plays a sound effect
  142. *
  143. * Input:        ushort instHandle       effect instrument handle, returned by
  144. *                                           LoadEffect().
  145. *               ulong rate              effect sampling rate, in Hz
  146. *               ushort volume           effect playing volume, 0-64
  147. *               short panning           effect panning (see enum sdPanning in
  148. *                                           SDEVICE.H)
  149. *
  150. \****************************************************************************/
  151.  
  152. void PlayEffect(ushort instHandle, ulong rate, ushort volume,
  153.     short panning)
  154. {
  155.     int         error;
  156.  
  157.     /* set effect instrument to current effect channel: */
  158.     if ( (error = SD->SetInstrument(fxChannel, instHandle)) != OK )
  159.         midasError(errorMsg[error]);
  160.  
  161.     /* set effect volume: */
  162.     if ( (error = SD->SetVolume(fxChannel, volume)) != OK )
  163.         midasError(errorMsg[error]);
  164.  
  165.     /* set effect panning: */
  166.     if ( (error = SD->SetPanning(fxChannel, panning)) != OK )
  167.         midasError(errorMsg[error]);
  168.  
  169.     /* start playing effect: */
  170.     if ( (error = SD->PlaySound(fxChannel, rate)) != OK )
  171.         midasError(errorMsg[error]);
  172.  
  173.     fxChannel++;                        /* channel for next effect */
  174.     if ( fxChannel >= FXCHANNELS )
  175.         fxChannel = 0;
  176. }
  177.  
  178.  
  179.  
  180. int main(int argc, char *argv[])
  181. {
  182.     mpModule    *mod;                   /* pointer to current module struct */
  183.     unsigned    effect1, effect2;       /* sound effect instrument handles */
  184.     int         quit = 0;
  185.     int         error;
  186.     unsigned    masterVolume = 64;      /* music master volume */
  187.  
  188.     /* argv[0] is the program name, argv[1] the module filename, argv[2]
  189.        and argv[3] are the effect file names. Rest are options which
  190.        MIDAS should handle */
  191.  
  192.     /* if there aren't enough arguments, show usage and exit */
  193.     if  ( argc < 4 )
  194.     {
  195.         puts(usage);
  196.         exit(EXIT_SUCCESS);
  197.     }
  198.  
  199.     midasSetDefaults();                 /* set MIDAS defaults */
  200.     midasParseEnvironment();            /* parse MIDAS environment string */
  201.     midasParseOptions(argc-4, &argv[4]);    /* let MIDAS parse all options */
  202.     midasInit();                        /* initialize MIDAS Sound System */
  203.     /* Load module and start playing, leaving FXCHANNELS first channels for
  204.        sound effects: */
  205.     mod = midasPlayModule(argv[1], FXCHANNELS);
  206.  
  207.     /* Load sound effect samples and store the instrument handles to the
  208.        table effects[]: */
  209.     effect1 = LoadEffect(argv[2]);
  210.     effect2 = LoadEffect(argv[3]);
  211.     if ( (error = MP->SetMasterVolume(masterVolume)) != OK )
  212.         midasError(errorMsg[error]);
  213.  
  214.     puts("Press 1 & 2 to play effects, +/- to adjust music volume or Esc to "
  215.          "quit.");
  216.  
  217.     while ( !quit )
  218.     {
  219.         switch ( getch() )
  220.         {
  221.             case 27:    /* Escape - quit */
  222.                 quit = 1;
  223.                 break;
  224.  
  225.             case '1':   /* '1' - play first effect */
  226.                 PlayEffect(effect1, FXRATE, 64, -40);
  227.                 break;
  228.  
  229.             case '2':   /* '2' - play second effect */
  230.                 PlayEffect(effect2, FXRATE, 64, 40);
  231.                 break;
  232.  
  233.             case '+':
  234.                 if ( masterVolume < 64 )
  235.                 {
  236.                     masterVolume++;
  237.                     if ( (error = MP->SetMasterVolume(masterVolume)) != OK )
  238.                         midasError(errorMsg[error]);
  239.                 }
  240.                 printf("Music volume: %02i\r", masterVolume);
  241.                 break;
  242.  
  243.             case '-':
  244.                 if ( masterVolume > 0 )
  245.                 {
  246.                     masterVolume--;
  247.                     if ( (error = MP->SetMasterVolume(masterVolume)) != OK )
  248.                         midasError(errorMsg[error]);
  249.                 }
  250.                 printf("Music volume: %02i\r", masterVolume);
  251.                 break;
  252.         }
  253.     }
  254.     midasStopModule(mod);               /* stop playing */
  255.     FreeEffect(effect1);                /* deallocate effect #1 */
  256.     FreeEffect(effect2);                /* deallocate effect #2 */
  257.     midasClose();                       /* uninitialize MIDAS */
  258.  
  259.     return 0;
  260. }
  261.