home *** CD-ROM | disk | FTP | other *** search
/ Bila Vrana / BILA_VRANA.iso / 031A / MELODY26.ZIP / MELODY26.EXE / UTILS / SOUNDSYS.C < prev    next >
Text File  |  1996-01-06  |  14KB  |  254 lines

  1. /* ------------------------------------------------------------------- */
  2. /* SOUNDSYS.C - Background sound system for the IBM-PC and compatibles */
  3. /* ------------------------------------------------------------------- */
  4. /*              Written by Juan Jimenez                                */
  5. /*              Micro Consulting Associates                            */
  6. /*              868 Ashford 6B                                         */
  7. /*              San Juan, P.R. 00907-1018                              */
  8. /*              (809) 725-9470 FAX (809) 721-8470 GEmail: J.JIMENEZ    */
  9. /*              For Turbo C 1.5 or higher, though can be ported...     */
  10. /*              Released on 3/7/89                                     */
  11. /* ------------------------------------------------------------------- */
  12. /* This code is hereby placed in the PUBLIC DOMAIN. This means that I  */
  13. /* am giving it to you at no charge, and you can do with it whatever   */
  14. /* you want, without any restrictions or requests for donations,       */
  15. /* (though if you feel like it I'd be happy if you sent me $10, but if */
  16. /* you don't feel like it that's fine with me too). I'm, putting it    */
  17. /* the public domain because I've had a good response to some of my    */
  18. /* shareware stuff (like GSETUP), and I feel I should give something   */
  19. /* nice in return to the community, for free. The only thing that I    */
  20. /* -DO- ask if that if you use it, please give me credit for this      */
  21. /* implementation, and NEUROMANCER for the original one...             */
  22. /* ------------------------------------------------------------------- */
  23. /* This file contains the C source code for a background sound system  */
  24. /* that can be used in games and other types of applications that want */
  25. /* to produce sounds and noises in the background without interfering  */
  26. /* with the current foreground tasks (like the game play code...)      */
  27. /* ------------------------------------------------------------------- */
  28. /* The reason I coded this was because I couldn't find anything that   */
  29. /* would do the job. This code is loosely based on NEUROMANCER's code  */
  30. /* which he graciously sent to me as a base to start off with. His     */
  31. /* played a predefine sound set, I allow free-form input to produce    */
  32. /* just about any kinds of sounds for all kinds of purposes as long as */
  33. /* the sounds are not overly complex. The sampling rate here is 500hz  */
  34. /* which means that the lowest period of time that a particular note   */
  35. /* can be played is 1/500th of a second. This should be more than      */
  36. /* sufficient for most complex applications and games.                 */
  37. /* ------------------------------------------------------------------- */
  38. /* The way this code works is as follows:                              */
  39. /*                                                                     */
  40. /* 1) Before you do anything with this sound system, you have to make  */
  41. /* sure that you initialize it. This is done with one simple call to   */
  42. /* init_sound(), with no arguments. init_sound redirects interrupt 8,  */
  43. /* the hardware timer interrupt (clock tick) from it's destination     */
  44. /* inside DOS to ourselves. We save that vector 'cause we'll need it   */
  45. /* later on, as you shall soon see. It then modifies the system timer  */
  46. /* to issue 500 ticks per second instead of 18.2. This clock signal    */
  47. /* is the heart of the sound system. We use 500 clock ticks because    */
  48. /* it is A) a nice round number and B) about as slow a tick as you can */
  49. /* have to produce smooth sound.                                       */
  50. /*                                                                     */
  51. /* 2) Once you call init_sound(), the system is running and ready to   */
  52. /* receive input. This is done with the submit_sound() routine. This   */
  53. /* routine takes two arguments, both integer values. The first is the  */
  54. /* frequency of the sound to be generated, the second is the duration  */
  55. /* of the sound in 1/500th's of a second. submit_sound keeps a queue   */
  56. /* which can hold up to 8k submissions. It has two possible return     */
  57. /* values. If the queue had room left and the submission was posted,   */
  58. /* it returns an integer value of 0. If the queue was full, the entry  */
  59. /* you sent to it is thrown away and you get back a value of -1. That  */
  60. /* is about as simple as it can get.                                   */
  61. /*                                                                     */
  62. /* 3) Every time a clock tick is generated (500 times a second), the   */
  63. /* soundsystem() interrupt service routine takes over. It first checks */
  64. /* to see how many clock ticks have been issued. If 27 ticks have been */
  65. /* issued (count is kept in tickcount), we make a quick call to the    */
  66. /* DOS timer interrupt service routine. This effectively emulates the  */
  67. /* standard DOS clock. If we did not do this, the clock would never be */
  68. /* updated while the sound system is running, or your clock would go   */
  69. /* to Warp 10 and by the time you finished your clock would be set to  */
  70. /* some date in the next century... If 27 ticks have gone by, we reset */
  71. /* that counter as well. Now, the variable backduration is the one     */
  72. /* that keeps track of a sound which is currently being played. If     */
  73. /* backduration is greater than 0, that means a sound is in progress.  */
  74. /* We simply decrement backduration by one, and return to your program.*/
  75. /* If backduration is 0, we check to see if there are no sounds in the */
  76. /* queue. If there are, we start the sound going with the specified    */
  77. /* frequency, set backduration to the number of ticks it should last,  */
  78. /* and return. If there are no sounds in the queue, we set the sound   */
  79. /* to a random tone limited by the value in the global variable        */
  80. /* "frequency". The background random noise is controlled by the var   */
  81. /* "back_sound". If you set it to "ON" the background noise is on, if  */
  82. /* you set it to "OFF" the noise is turned off.                        */
  83. /*                                                                     */
  84. /* 4) Once your program is finished, you MUST remember to call the     */
  85. /* restore_sound() routine. This gives back the timer to DOS and       */
  86. /* resets the system timer back to the normal 18.2 ticks per second.   */
  87. /* ------------------------------------------------------------------- */
  88. /*           LIMITATIONS AND CAVEATS! READ THIS CAREFULLY!             */
  89. /* ------------------------------------------------------------------- */
  90. /* 1) This routine CANNOT be active while debugging your code in the   */
  91. /* REMOTE DEBUG mode of Turbo Debugger. It WILL crash the debugger.    */
  92. /* By remote debugging I mean the use of TDREMOTE to debug code that   */
  93. /* is running on one machine with another machine via a serial port.   */
  94. /*                                                                     */
  95. /* 2) This routine will most likely interfere with network adapters,   */
  96. /* though I don't know why. I just tell people not to run my programs  */
  97. /* that use this stuff on a network workstation.                       */
  98. /*                                                                     */
  99. /* 3) This code was written on 80286 and 80386 boxes. On 4.77 mhz 8088 */
  100. /* machines it does not do as well I would like it to. You can try     */
  101. /* making the soundsystem() routine smaller, but the only way I can    */
  102. /* think of that is going to assembly language, and even then this     */
  103. /* is pretty small as it is, so... You can also try and reduce the     */
  104. /* sampling rate, which is set in init_sound(). You do have to know    */
  105. /* how the system timer chip runs to program it. If you need help, do  */
  106. /* call or send me e-mail on GEnie.                                    */
  107. /* ------------------------------------------------------------------- */
  108. /* That's it. How's that for documentation, eh? hehe...                */
  109. /* ------------------------------------------------------------------- */
  110.  
  111. #include <stdio