SOUND.CPP 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. #include <string.h>
  2. #include <dos.h>
  3. #include "sound.h"
  4. #include "debug4g.h"
  5. #include "error.h"
  6. #include "inifile.h"
  7. #include "misc.h"
  8. #include "globals.h"
  9. #include "music.h"
  10. #include "fx_man.h"
  11. #include <memcheck.h>
  12. #define kSampleRate 11110
  13. #define kMaxChannels 32
  14. static BOOL sndActive = FALSE;
  15. int gMusicDevice;
  16. int gMusicVolume;
  17. int gMidiPort;
  18. int gFXDevice;
  19. int gMixBits;
  20. int gChannels;
  21. int gMixVoices;
  22. int gMixRate;
  23. int gFXVolume;
  24. fx_blaster_config gSBConfig;
  25. RESHANDLE hSong;
  26. BYTE *pSong = NULL;
  27. int songSize;
  28. struct SAMPLE2D
  29. {
  30. int hVoice;
  31. RESHANDLE hResource;
  32. };
  33. SAMPLE2D Channel[kMaxChannels];
  34. SAMPLE2D *FindChannel( void )
  35. {
  36. for (int i = kMaxChannels - 1; Channel[i].hResource != NULL > 0; i--)
  37. {
  38. if ( i < 0 )
  39. ThrowError("No free channel available for sample", ES_ERROR);
  40. }
  41. return &Channel[i];
  42. }
  43. /*---------------------------------------------------------------------
  44. Function: LoadMidi
  45. Loads the midi file from disk.
  46. ---------------------------------------------------------------------*/
  47. void sndPlaySong( char *songName, BOOL loopflag )
  48. {
  49. if ( gMusicDevice == -1 )
  50. return;
  51. if ( pSong )
  52. sndStopSong();
  53. if ( strlen(songName) == 0 )
  54. return;
  55. hSong = gSysRes.Lookup(songName, ".MID");
  56. if (hSong == NULL)
  57. {
  58. dprintf("Could not load song %s\n", songName);
  59. return;
  60. }
  61. songSize = gSysRes.Size(hSong);
  62. pSong = (BYTE *)gSysRes.Lock(hSong);
  63. dpmiLockMemory(FP_OFF(pSong), songSize);
  64. // reset the volume, in case we were fading
  65. MUSIC_SetVolume(gMusicVolume);
  66. // start the song
  67. MUSIC_PlaySong(pSong, loopflag);
  68. }
  69. BOOL sndIsSongPlaying( void )
  70. {
  71. if ( gMusicDevice == -1 )
  72. return FALSE;
  73. return (BOOL)MUSIC_SongPlaying();
  74. }
  75. void sndFadeSong( int nMilliseconds )
  76. {
  77. MUSIC_FadeVolume(0, nMilliseconds);
  78. }
  79. void sndStopSong( void )
  80. {
  81. if ( gMusicDevice == -1 )
  82. return;
  83. if ( pSong )
  84. {
  85. MUSIC_StopSong();
  86. dpmiUnlockMemory(FP_OFF(pSong), songSize);
  87. gSysRes.Unlock(hSong);
  88. pSong = NULL;
  89. }
  90. }
  91. static void SoundCallback( ulong id )
  92. {
  93. int *phVoice = (int *)id;
  94. *phVoice = 0;
  95. }
  96. void sndStartSample( char *sampleName, int nVol, int nChannel )
  97. {
  98. if ( gFXDevice == -1 )
  99. return;
  100. if ( strlen(sampleName) == 0 )
  101. return;
  102. SAMPLE2D *pChannel;
  103. if (nChannel == -1)
  104. pChannel = FindChannel();
  105. else
  106. pChannel = &Channel[nChannel];
  107. // if this is a fixed channel with an active voice, kill the sound
  108. if ( pChannel->hVoice > 0 )
  109. FX_StopSound(pChannel->hVoice);
  110. pChannel->hResource = gSysRes.Lookup(sampleName, ".RAW");
  111. if (pChannel->hResource == NULL)
  112. {
  113. dprintf("Could not load sample %s\n", sampleName);
  114. return;
  115. }
  116. int sampleSize = gSysRes.Size(pChannel->hResource);
  117. BYTE *pRaw = (BYTE *)gSysRes.Lock(pChannel->hResource);
  118. pChannel->hVoice = FX_PlayRaw(
  119. pRaw, sampleSize, kSampleRate, 0, nVol, nVol, nVol, nVol,
  120. (ulong)&pChannel->hVoice);
  121. }
  122. void sndProcess( void )
  123. {
  124. for (int i = 0; i < kMaxChannels; i++)
  125. {
  126. if (Channel[i].hVoice <= 0 && Channel[i].hResource != NULL )
  127. {
  128. gSysRes.Unlock(Channel[i].hResource);
  129. Channel[i].hResource = NULL;
  130. }
  131. }
  132. }
  133. static void GetSettings( void )
  134. {
  135. FX_GetBlasterSettings(&gSBConfig);
  136. // Read current setup
  137. gMusicDevice = BloodINI.GetKeyInt("Sound Setup", "MusicDevice", -1);
  138. gMusicVolume = BloodINI.GetKeyInt("Sound Setup", "MusicVolume", 200);
  139. gMidiPort = BloodINI.GetKeyHex("Sound Setup", "MidiPort", gSBConfig.Midi);
  140. gFXDevice = BloodINI.GetKeyInt("Sound Setup", "FXDevice", -1);
  141. gMixBits = BloodINI.GetKeyInt("Sound Setup", "Bits", 16);
  142. gChannels = BloodINI.GetKeyInt("Sound Setup", "Channels", 2);
  143. gMixVoices = BloodINI.GetKeyInt("Sound Setup", "Voices", 16);
  144. gMixRate = BloodINI.GetKeyInt("Sound Setup", "MixRate", 22050);
  145. gFXVolume = BloodINI.GetKeyInt("Sound Setup", "FXVolume", 200);
  146. gSBConfig.Address = BloodINI.GetKeyInt("Sound Setup", "BlasterAddress", gSBConfig.Address);
  147. gSBConfig.Type = BloodINI.GetKeyInt("Sound Setup", "BlasterType", gSBConfig.Type);
  148. gSBConfig.Interrupt = BloodINI.GetKeyInt("Sound Setup", "BlasterInterrupt", gSBConfig.Interrupt);
  149. gSBConfig.Dma8 = BloodINI.GetKeyInt("Sound Setup", "BlasterDma8", gSBConfig.Dma8);
  150. gSBConfig.Dma16 = BloodINI.GetKeyInt("Sound Setup", "BlasterDma16", gSBConfig.Dma16);
  151. gSBConfig.Emu = BloodINI.GetKeyInt("Sound Setup", "BlasterEmu", gSBConfig.Emu);
  152. }
  153. void InitSoundDevice(void)
  154. {
  155. int status;
  156. if ( gFXDevice == -1 )
  157. return;
  158. // Do special Sound Blaster, AWE32 stuff
  159. if ( gFXDevice == SoundBlaster || gFXDevice == Awe32 )
  160. {
  161. int MaxVoices;
  162. int MaxBits;
  163. int MaxChannels;
  164. status = FX_SetupSoundBlaster(gSBConfig, &MaxVoices, &MaxBits, &MaxChannels);
  165. }
  166. else
  167. {
  168. fx_device device;
  169. status = FX_SetupCard( gFXDevice, &device );
  170. }
  171. if ( status != FX_Ok )
  172. ThrowError(FX_ErrorString(status), ES_ERROR);
  173. status = FX_Init( gFXDevice, gMixVoices, gChannels, gMixBits, gMixRate );
  174. if ( status != FX_Ok )
  175. ThrowError(FX_ErrorString(status), ES_ERROR);
  176. FX_SetVolume(gFXVolume);
  177. // Set up our fx callback so we can unlock sound resources
  178. FX_SetCallBack(SoundCallback);
  179. }
  180. void InitMusicDevice(void)
  181. {
  182. int status;
  183. if ( gMusicDevice == -1 )
  184. return;
  185. status = MUSIC_Init( gMusicDevice, gMidiPort);
  186. if ( status != MUSIC_Ok )
  187. ThrowError(MUSIC_ErrorString( status ), ES_ERROR);
  188. RESHANDLE hTimbres = gSysRes.Lookup("GMTIMBRE", ".TMB");
  189. if ( hTimbres != NULL )
  190. MUSIC_RegisterTimbreBank((BYTE *)gSysRes.Load(hTimbres));
  191. MUSIC_SetVolume(gMusicVolume);
  192. }
  193. /***********************************************************************
  194. * Remove sound/music drivers
  195. **********************************************************************/
  196. void sndTerm(void)
  197. {
  198. // prevent this from shutting down more than once
  199. if ( sndActive )
  200. {
  201. sndStopSong();
  202. dprintf("MUSIC_Shutdown()\n");
  203. MUSIC_Shutdown();
  204. FX_Shutdown();
  205. sndActive = FALSE;
  206. }
  207. }
  208. /***********************************************************************
  209. * Initialize sound/music drivers
  210. **********************************************************************/
  211. void sndInit(void)
  212. {
  213. GetSettings();
  214. InitSoundDevice();
  215. InitMusicDevice();
  216. atexit(sndTerm);
  217. sndActive = TRUE;
  218. }