home *** CD-ROM | disk | FTP | other *** search
/ Fun Online 1996 September / FOL0996.iso / GEARDEMO / WAVEMIX / MIXDESCR.TXT < prev    next >
Text File  |  1994-11-08  |  9KB  |  157 lines

  1. How WaveMix works. 
  2.  
  3. 1.  Mixing Sounds 
  4.  
  5. The low-level multimedia wave out put function (waveOutWrite) does not support multiple simultaneous 
  6. channels of output.  So in order to accomplish this we must fake out the output device.  This is done by 
  7. premixing the wave output and then sending this new wave to the wave output device.  The core concept 
  8. which wavemix uses to mix files at run time is very simple.  What it does is take a small slice off of each 
  9. input wave file  (each input is referred to as an "channel"), mix them together into an extra buffer which is 
  10. the same length of the slice and then submit this wave buffer to the multimedia function waveOutWrite.
  11.  
  12.                                    /|
  13.           _______________              __ /    |
  14. |-----------|     |        |             |  |    |
  15. |  Wave 1   |----|        |-------waveOutWrite()---|  |    |
  16. |-----------|     |        |             |  |    |
  17.          |        |             |  |    |
  18. |-----------|     |        |             |__|    |
  19. | Wave 2    |----| WaveMixer    |                 \  |
  20. |-----------|     |        |                   \|
  21.    ...         |        |
  22. |-----------|     |        |
  23. | Wave n    |----|        |
  24. |-----------|     |--------------|
  25.  
  26. A digital wave is essentially an array of wave samples.  At 11Khz 8bit Mono (which is used by the Wave 
  27. Mixer) a wave array (or buffer) will contain 11025 byte elements per sec. of the wave duration.  (i.e. a one 
  28. second wave will contain 11025 data samples, a 1 minute data wave will contain 60*11025=661500 
  29. samples).  To mix the waves in real time the input waves are summed together into another destination 
  30. buffer.  The destination buffer is typically a small size so that we can achieve real time results.  A typical 
  31. length is 1/8 th of a second = 11025/8=1378 samples. 
  32.  
  33. Waves are added as vectors. eg. D[i] = w1[i]+w2[i]+w3[i]+...+wn[i]
  34.  
  35. e.g.  Assuming that we have 4 waves playing and the slice length = 1378 samples. we could call a mixing 
  36. routine:  mixit(lpDest,rgpCDdata,4,1378); 
  37.  
  38. void mixit(LPSAMPLE lpDest, LPSAMPLE rgWaveSrc[], int iNumWaves, WORD wLen) 
  39.    int i,iSum; 
  40.    WORD ctr; 
  41.    ctr = 0; 
  42.    while (wLen) 
  43.    { 
  44.       iSum=128; /* 128 is the "normal" value (silence) for 8 bit 11KHz */ 
  45.       for (i=0;i<iNumWaves;i++) 
  46.          iSum = iSum + *(rgWaveSrc[i]+ctr) -128; 
  47.       PEG((int)0,iSum,(int)255); 
  48.       *lpDest++=iSum; 
  49.       ctr++; 
  50.       wLen--; 
  51.    } 
  52.  
  53. The above routine will visit the i th element in each source array, sum them into a destination variable 
  54. (iSum) that can accommodate any possible overflow (i.e. 8 bit elements are summed into a 16 bit 
  55. destination) and then the destination variable is converted back to the original magnitude (saturation is 
  56. done after the additions to minimize distortion). 
  57.  
  58. The destination buffer can now be submitted to the wave output device (using waveOutWrite) and the user 
  59. will hear all four sounds played simultaneously.  When the wave output device completes playing the 
  60. buffer it will return it to the client (WaveMix.DLL) with a request for more output data. 
  61.  
  62. Since the wave output device can only play data that has been submitted to it and it takes a finite amount of 
  63. time to mix the wave data, as soon as we submit the destination wave to the output device we must mix 
  64. another buffer with the next slice of data and submit it to the wave output device to avoid an interruption in 
  65. the audio output.  This buffer will get queued by the device and it will then play the data in it when it 
  66. finishes playing the data in the first buffer. 
  67.  
  68. While the output device is playing this second buffer we can mix the third slice into the first buffer and 
  69. then submit it back to the device.  We continue this "ping-pong" procedure of mixing the data and 
  70. submitting the buffer to the wave output device until we have submitted all the wave data, at that point 
  71. since we no longer submit data to the device it will stop playing.  Note: In practice we often use more than 
  72. two buffers (i.e. 3 or 4 is common)  We then replace the ping-pong action with a "juggling" system: 
  73.  
  74.     Wave Inputs
  75.    _______________     |----------|
  76.   |_______________|----|      |
  77.    _______________     |      |
  78.   |_______________|----| WaveMiver|
  79.    _______________     |      |
  80.   |_______________|----|      |
  81.                |----------|
  82.                 |
  83.                 |
  84.            _____________________________________________________
  85.           | Buffer 4: Curently being mixed by Wave Mixer Program|
  86.           |_____________________________________________________|
  87.               ^                      |
  88.               |                      |
  89.    _______________________|_____________________________   ___v__________________________________________
  90.   |Buffer 1: Returned to Wave Mixer after play completed|  |Buffer 3: Currently queued by wave out device|
  91.   |_____________________________________________________|  |_____________________________________________|
  92.                     ^                   |
  93.                     |                   |
  94.                _________|______________________________v__________
  95.               |Buffer 2: Currently being played by wave out device|
  96.               |___________________________________________________|
  97.                            |
  98.                            |    /|
  99.                           _|_ /  |
  100.                          |   |     |
  101.                          |   |     |
  102.                          |___|     |
  103.                               \  |
  104.                             \|
  105.  
  106. The above text and diagrams describe the mixing process.  There are, however, other situations which 
  107. occur that greatly complicate the mixing process:  Playing multiple files that are of uneven length, A 
  108. request to start a new wave playing while others are already playing, A request to terminate a specific wave 
  109. that is simultaneously playing with other wave files, A request to play multiple wave files and start them 
  110. together.  A request to pause the wave output, but not lose the current location. 
  111.  
  112. Playing multiple files of uneven length: 
  113.  
  114.   
  115.  
  116. The Wave Mixer has to take into account the possibility that the current slice will be shorter than the wave 
  117. slice which it is attempting to fill.  That is: one of the waves which it is mixing does not contain sufficient 
  118. data to have a sample mixed into all the elements of the destination buffer.  To handle the situation the 
  119. wave mixer must first determine if a wave like this exists.  If it does then it must determine how many 
  120. samples it can mix from that wave.  It will then mix from all the waves for that many samples.  Then it will 
  121. stop mixing that wave and mix the remaining waves for the second part of the destination buffer.  Since it 
  122. is possible that the same situation can occur again while mixing the remaining waves into the remaining 
  123. part of the buffer it must repeat the above process again.  This process will continue until the destination 
  124. buffer gets completely filled up or their is no more wave data remaining to be mixed.  At this point the 
  125. destination buffer is submitted to the wave output device. 
  126.  
  127. A request to start a new wave playing while others are already playing: "remixing" 
  128.  
  129. A complex situation that the real time wave mixer must handle is a request to play a new wave file while 
  130. there is currently other waves being played.  The reason that this is difficult is that the wave mixer is 
  131. actually mixing wave data a finite amount of time before the wave output that is currently being played by 
  132. the wave driver.  The wave mixer must determine the position at which the wave output device is actually 
  133. playing wave data, "remix" the wave data to include the new wave, notify the output device that the data it 
  134. is currently playing is no longer valid (waveOutReset( ) ) and submit new wave data to it that contains the 
  135. new wave too.  All of this must be done very quickly so that the user does not hear an interruption in the 
  136. audio. 
  137.  
  138. A second algorithm is also employed to achieve the above effect on hardware configurations where doing a 
  139. waveOutReset can cause an audible click or cause the hardware to slow down.  In these situations the wave 
  140. mixer queues the new wave but does not interrupt the wave output device.  When it mixes the next slice of 
  141. data it will include the new wave also.  This method can have a small delay which is the amount of time 
  142. from which the wave data is submitted to when it is played:  The driver must finish playing the current 
  143. buffer, play all the previously queued buffers, and then play the new buffer.  If there are three buffers being 
  144. juggled with the wave output device the delay can be the amount of time required to play two to three 
  145. buffers before the new wave data can be heard.  If the wave buffers are very short then it is difficult but not 
  146. impossible to hear the delay. 
  147.  
  148. A request to terminate a specific wave that is simultaneously playing with other wave files: 
  149.  
  150. Occasionally while playing multiple files the WaveMix.DLL will be requested to stop playing a wave on a 
  151. particular channel before that wave has completed playing, i.e. "flush" a channel.  This is handled in a 
  152. similar manner to starting a new wave while others are playing.  The wave mixer first determines the wave 
  153. output position.  It then removes the desired wave from the specified channel and "remixes" the remaining 
  154. waves from the obtained output position. 
  155.