1 
2 #include "witchaven.h"
3 #include "sound.h"
4 #include "compat.h"
5 #include "baselayer.h"
6 #include "renderlayer.h" // for win_gethwnd()
7 #include "build.h"
8 #include "cache1d.h"
9 #include "music.h"
10 #include "fx_man.h"
11 #include "hmpplay.h"
12 #include "keyboard.h"
13 #include "control.h"
14 #include "config.h"
15 #include "player.h"
16 
17 void SND_MIDIFlush(void);
18 char* SND_LoadMIDISong(int nSong);
19 int SND_PrepareMIDISong(int SongIndex);
20 int SND_StartMIDISong(int wSongHandle);
21 
22 int lavasnd = -1;
23 int batsnd = -1;
24 int cartsnd = -1;
25 
26 int SoundMode, wDIGIVol;
27 int MusicMode, wMIDIVol;
28 int use_rec_driver, voicecom_enabled;
29 int SD_Started;
30 int wMIDIDeviceID;
31 int SongPending;
32 
33 #define  _MIDI_MPU_401              0xa001
34 #define  _MIDI_FM                   0xa002
35 #define  _MIDI_OPL2                 0xa002
36 #define  _MIDI_OPL3                 0xa009
37 char *BaseSongPtr;
38 char *EmbSongPtr;
39 char *SpiceSongPtr;
40 
41 char *m_bnkptr, *d_bnkptr;
42 
43 #define MAX_ACTIVE_SONGS 4
44 
45 int hSOSSongHandles[MAX_ACTIVE_SONGS];
46 InitSong sSOSInitSongs[MAX_ACTIVE_SONGS];
47 TrackDevice sSOSTrackMap[MAX_ACTIVE_SONGS] = {
48     {
49         0xff, 0xff, 0xff, 0xff,
50         0xff, 0xff, 0xff, 0xff,
51         0xff, 0xff, 0xff, 0xff,
52         0xff, 0xff, 0xff, 0xff
53     },
54     {
55         0xff, 0xff, 0xff, 0xff,
56         0xff, 0xff, 0xff, 0xff,
57         0xff, 0xff, 0xff, 0xff,
58         0xff, 0xff, 0xff, 0xff
59     },
60     {
61         0xff, 0xff, 0xff, 0xff,
62         0xff, 0xff, 0xff, 0xff,
63         0xff, 0xff, 0xff, 0xff,
64         0xff, 0xff, 0xff, 0xff
65     },
66     {
67         0xff, 0xff, 0xff, 0xff,
68         0xff, 0xff, 0xff, 0xff,
69         0xff, 0xff, 0xff, 0xff,
70         0xff, 0xff, 0xff, 0xff
71     },
72 };
73 
74 static uint16_t songelements = 3;
75 static uint16_t arrangements = 3;
76 static uint16_t songsperlevel;
77 static uint16_t totallevels = 6;    // really there use two to test menusong
78 
79 uint32_t DigiList[4096];
80 uint32_t LoopList[4096];
81 uint32_t SongList[4096];
82 
83 uint32_t PanArray[] = {
84     // REAR to HARD LEFT (angle = 0->512)
85     0x8000,0x7000,0x6000,0x5000,0x4000,0x3000,0x2000,0x1000,0x0000,
86     // HARD LEFT to CENTER (angle = 513-1024)
87     0x1000,0x20F0,0x2000,0x3000,0x4000,0x5000,0x6000,0x7000,0x8000,
88     // CENTER to HARD RIGHT (angle = 1025-1536)
89     0x70F0,0x8000,0x9000,0xA000,0xB000,0xC000,0xD000,0xE000,0xF000,
90     // HARD RIGHT to REAR (angle = 1537-2047)
91     0xFFFF,0xF000,0xE000,0xD000,0xC000,0xB000,0xA000,0x9000,0x8000
92 };
93 
94 struct SampleType
95 {
96 //  int     playing;
97     int32_t nFXHandle;
98     int32_t number;
99     int32_t priority;
100     int32_t loopcount;
101     int32_t x, y;
102 
103     int nSize;
104     char* pData;
105 };
106 
107 SampleType SampleRay[MAX_ACTIVE_SAMPLES];
108 
109 
110 ambsounds ambsoundarray[] =
111 {
112     0,0,
113     S_WINDLOOP1,-1,
114     S_WINDLOOP2,-1,
115     S_WAVELOOP1,-1,
116     S_LAVALOOP1,-1,
117     S_WATERY,-1,
118     S_STONELOOP1,-1,
119     S_BATSLOOP,-1
120 };
121 
122 buildvfs_kfd hSoundFile = buildvfs_kfd_invalid;
123 buildvfs_kfd hLoopsFile = buildvfs_kfd_invalid;
124 buildvfs_kfd hSongsFile = buildvfs_kfd_invalid;
125 
126 
SND_SetupTables()127 void SND_SetupTables()
128 {
129     if (SoundMode)
130     {
131         hSoundFile = kopen4loadfrommod("joesnd", 0);
132         if (hSoundFile == buildvfs_kfd_invalid) {
133             crash("Couldn't open joesnd");
134         }
135 
136         int nSize = kfilelength(hSoundFile);
137         if (nSize < 4096) {
138             crash("Invalid size for joesdn");
139         }
140 
141         klseek(hSoundFile, nSize - 4096, SEEK_SET);
142 
143         if (kread(hSoundFile, DigiList, 4096) != 4096) {
144             crash("Couldn't read from joesnd");
145         }
146     }
147 
148     if (MusicMode == _LOOP_MUSIC)
149     {
150         hLoopsFile = kopen4loadfrommod("loops", 0);
151         if (hLoopsFile == buildvfs_kfd_invalid) {
152             crash("Couldn't open loops");
153         }
154 
155         int nSize = kfilelength(hLoopsFile);
156         if (nSize < 4096) {
157             crash("Invalid size for loops");
158         }
159 
160         klseek(hLoopsFile, nSize - 4096, SEEK_SET);
161 
162         if (kread(hLoopsFile, LoopList, 4096) != 4096) {
163             crash("Couldn't read from loops");
164         }
165     }
166     else if (MusicMode)
167     {
168         hSongsFile = kopen4loadfrommod("songs", 0);
169         if (hSongsFile == buildvfs_kfd_invalid) {
170             crash("Couldn't open songs");
171         }
172 
173         int nSize = kfilelength(hSongsFile);
174         if (nSize < 4096) {
175             crash("Invalid size for songs");
176         }
177 
178         klseek(hSongsFile, nSize - 4096, SEEK_SET);
179 
180         if (kread(hSongsFile, SongList, 4096) != 4096) {
181             crash("Couldn't read from songs");
182         }
183     }
184 
185     return;
186 }
187 
SND_LoadMidiIns(void)188 void SND_LoadMidiIns(void)
189 {
190     static int wLength;
191 
192     //JSA_DEMO check port address to verify FM device
193     buildvfs_kfd handle = kopen4loadfrommod("melodic.bnk", 0);
194     if (handle == buildvfs_kfd_invalid)
195         crash("MELODIC BANK FILE FAILED!");
196     m_bnkptr = (char*)malloc(0x152c);
197     kread(handle, m_bnkptr, 0x152c);
198     kclose(handle);
199     if (FMSetBank(m_bnkptr))
200         crash("BAD SetInsData MEL!");
201 
202     handle = kopen4loadfrommod("drum.bnk", 0);
203     if (handle == buildvfs_kfd_invalid)
204         crash("PERCUSSIVE BANK FILE FAILED!");
205     d_bnkptr = (char*)malloc(0x152c);
206     kread(handle, d_bnkptr, 0x152c);
207     kclose(handle);
208     if (FMSetBank(d_bnkptr))
209         printf("BAD SetInsData DRUM!");
210 }
211 
ASSCallback(intptr_t pSample)212 void ASSCallback(intptr_t pSample)
213 {
214     SampleType *sample = (SampleType*)pSample;
215     sample->loopcount = 0;
216     sample->nSize = 0;
217     sample->nFXHandle = 0;
218     sample->priority = 0;
219     sample->number = -1;
220 }
221 
222 extern int MV_MixRate;
223 extern int musiclevel;
224 
SND_Startup()225 void SND_Startup()
226 {
227     #ifdef MIXERTYPEWIN
228     void* initdata = (void*)win_gethwnd(); // used for DirectSound
229     #else
230     void* initdata = NULL;
231     #endif
232 
233     //  if (bNoSound)
234     //      return;
235 
236     if (FX_Init(NumVoices, NumChannels, MixRate, initdata) != FX_Ok)
237     {
238         //        crash("Error initializing sound card!\n");
239         initprintf("Error initializing sound card!\n");
240         //        DebugOut("ERROR: %s\n", FX_ErrorString(FX_Error));
241         return;
242     }
243 
244     FX_SetCallBack(ASSCallback);
245 
246     memset(SampleRay, 0, sizeof(SampleRay));
247     for (int i = 0; i < MAX_ACTIVE_SAMPLES; i++)
248     {
249         SampleRay[i].number = -1;
250  //       SampleRay[i].loopcount = -1;
251     }
252 
253     // init buffer space
254     for (int i = 0; i < MAX_ACTIVE_SAMPLES; i++) {
255         SampleRay[i].pData = new char[55000]; // just alloc a big block, like the original code
256     }
257 
258     // Init music
259     #if 1
260             // if they chose None lets return
261     #if 0
262     if (!MusicToggle)
263     {
264         gs.MusicOn = FALSE;
265         return;
266     }
267     #endif
268 
269     wMIDIVol = (musiclevel<<3);
270     wMIDIDeviceID = _MIDI_FM;
271     HMIInit(MV_MixRate);
272 
273     SND_LoadMidiIns();
274     for (int i = 0; i < MAX_ACTIVE_SONGS; i++)
275         hSOSSongHandles[i] = 0x7fff;
276 
277     songsperlevel = songelements * arrangements;
278 
279     HMISetMasterVolume(wMIDIVol);
280         /*
281     auto const fil = kopen4load("swtimbr.tmb", 0);
282 
283     if (fil != buildvfs_kfd_invalid)
284     {
285         int l = kfilelength(fil);
286         auto tmb = (uint8_t*)Xmalloc(l);
287         kread(fil, tmb, l);
288         AL_RegisterTimbreBank(tmb);
289         Xfree(tmb);
290         kclose(fil);
291     }
292     */
293     #endif
294 
295     // read in offset page lists
296     SND_SetupTables();
297 
298     SD_Started = 1;
299 }
300 
SND_Shutdown()301 void SND_Shutdown()
302 {
303     FX_Shutdown();
304 
305     for (int i = 0; i < MAX_ACTIVE_SAMPLES; i++)
306     {
307         if (SampleRay[i].pData) {
308             delete[] SampleRay[i].pData;
309         }
310     }
311 
312 
313     SND_MIDIFlush();
314     HMIUnInit();
315     if (m_bnkptr != NULL)
316         free(m_bnkptr);
317     if (d_bnkptr != NULL)
318         free(d_bnkptr);
319 
320     if (hSoundFile != buildvfs_kfd_invalid) {
321         kclose(hSoundFile);
322     }
323 
324     if (hLoopsFile != buildvfs_kfd_invalid) {
325         kclose(hLoopsFile);
326     }
327 
328     if (hSongsFile != buildvfs_kfd_invalid) {
329         kclose(hSongsFile);
330     }
331 
332     SD_Started = 0;
333 }
334 
SND_Sound(int nSound)335 int SND_Sound(int nSound)
336 {
337     if (!SoundMode)
338         return -1;
339 
340     return(SND_PlaySound(nSound, 0, 0, 0, 0));
341 }
342 
SND_PlaySound(int nSound,int32_t x,int32_t y,int16_t Pan,int16_t loopcount)343 int SND_PlaySound(int nSound, int32_t x, int32_t y, int16_t Pan, int16_t loopcount)
344 {
345     //return 0; // TODO
346 
347     short wVol, flag = 0;
348     int32_t sqrdist;
349     int32_t prioritize;
350     int i;
351 
352     if (!SoundMode)
353         return 0;
354 
355     prioritize = DigiList[(nSound * 3) + 2];
356 
357     if (((x == 0) && (y == 0)) || ((player[pyrn].x == x) && (player[pyrn].y == y)))
358     {
359         wVol = 0x7fff;
360         Pan = 0;
361     }
362     else
363     {
364         sqrdist = labs(player[pyrn].x - x) + labs(player[pyrn].y - y);
365         if (sqrdist < 1500)
366             wVol = 0x7fff;
367         else if (sqrdist > 8500)
368             wVol = 0x1f00;
369         else
370             wVol = 39000 - (sqrdist << 2);
371     }
372 
373     if (nSound == S_STONELOOP1)
374     {
375         for (i = 0, flag = 0; i < MAX_ACTIVE_SAMPLES; i++)
376         {
377             if (nSound == SampleRay[i].number)
378                 return 0;
379         }
380     }
381 
382     for (i = 0, flag = 0; i < MAX_ACTIVE_SAMPLES; i++)
383     {
384         if (SampleRay[i].nFXHandle <= 0)
385         {
386             flag = 1;
387             break;
388         }
389     }
390 
391     if (!flag && prioritize < 9)           // none available low priority
392         return 0;
393     else if (!flag)                        // none available but high priority
394     {
395         for (i = 0; i < MAX_ACTIVE_SAMPLES; i++)
396         {
397             if (SampleRay[i].priority < 9 && SampleRay[i].loopcount != -1)//sSOSSampleData[i].wLoopCount != -1)
398             {
399                 //if (!sosDIGISampleDone(hSOSDriverHandles[DIGI], SampleRay[i].SOSHandle) && (sSOSSampleData[i].dwSampleSize != 0))
400                 if (SampleRay[i].nFXHandle > 0)
401                 {
402                     FX_StopSound(SampleRay[i].nFXHandle);
403                     SampleRay[i].loopcount = 0;
404                     SampleRay[i].nSize = 0;
405                     SampleRay[i].nFXHandle = 0;
406 //                    SampleRay[i].playing = 0;
407                     SampleRay[i].priority = 0;
408                     SampleRay[i].number = -1;
409                     break;
410                 }
411             }
412         }
413     }
414 
415     if (i >= MAX_ACTIVE_SAMPLES)
416     {
417         return 0; // FIXME - this shouldn't trigger?
418     }
419 
420     assert(i >= 0 && i < 10);
421 
422     if (Pan) {
423         Pan = ((getangle(player[pyrn].x - x, player[pyrn].y - y) + (2047 - player[pyrn].ang)) % kAngleMask) >> 6;
424     }
425 
426     int SeekIndex = (DigiList[(nSound * 3) + 0] * 4096);
427 
428     if (klseek(hSoundFile, SeekIndex, SEEK_SET) < 0)
429     {
430         assert(1 == 2);
431     }
432 
433     SampleRay[i].nSize = (uint16_t)DigiList[(nSound * 3) + 1];
434 
435 //    assert(hSoundFileSize - SeekIndex >= SampleRay[i].nSize);
436 
437 
438     int nRead = kread(hSoundFile, SampleRay[i].pData, SampleRay[i].nSize);
439     if (nRead != SampleRay[i].nSize)
440     {
441         assert(1 == 2);
442     }
443 
444     SampleRay[i].nFXHandle = FX_PlayRaw(SampleRay[i].pData, SampleRay[i].nSize, 11025, 0, 32, 32, 32, 0, fix16_one, (intptr_t)&SampleRay[i]);
445     assert(SampleRay[i].nFXHandle > 0);
446 
447     #if 0 // TODO
448     if (loopcount)
449         sSOSSampleData[i].wLoopCount = loopcount;
450 
451     if (Pan)
452         Pan = ((getangle(player[pyrn].x - x, player[pyrn].y - y) + (2047 - player[pyrn].ang)) % 2047) >> 6;
453 
454     sSOSSampleData[wIndex].wSamplePanLocation = PanArray[Pan];
455     sSOSSampleData[wIndex].wVolume = wVol;
456     SampleRay[wIndex].SOSHandle = sosDIGIStartSample(hSOSDriverHandles[DIGI], &sSOSSampleData[wIndex]);
457     #endif
458 
459     SampleRay[i].x = x;
460     SampleRay[i].y = y;
461 //    SampleRay[i].playing = 1;
462     SampleRay[i].number = nSound;
463     SampleRay[i].priority = prioritize;
464     // TODO	ActiveSampleBits |= (0x01 << wIndex);
465 
466     return SampleRay[i].nFXHandle;
467 }
468 
playsound_loc(int nSound,int32_t xplc,int32_t yplc)469 void playsound_loc(int nSound, int32_t xplc, int32_t yplc)
470 {
471     SND_PlaySound(nSound, xplc, yplc, 1, 0);
472 }
473 
SND_UpdateSoundLoc(int which,int Volume,int Pan)474 void SND_UpdateSoundLoc(int which, int Volume, int Pan)
475 {
476     #if 0
477     gVol = Volume;
478     gPan = sosDIGISetPanLocation(hSOSDriverHandles[DIGI], SampleRay[which].SOSHandle, PanArray[Pan]);
479     sosDIGISetSampleVolume(hSOSDriverHandles[DIGI], SampleRay[which].SOSHandle, Volume);
480     #endif
481 }
482 
updatesound_loc()483 void updatesound_loc()
484 {
485     #if 0
486     unsigned wVol, wPan;
487     long sqrdist;
488 
489     if (!SoundMode)
490         return;
491 
492     for (int i = 0; i < MAX_ACTIVE_SAMPLES; i++)
493     {
494         if (SampleRay[i].playing && SampleRay[i].x && SampleRay[i].y)
495         {
496             if (sSOSSampleData[wIndex].dwSampleSize != 0)
497             {
498                 sqrdist = labs(player[pyrn].x - SampleRay[wIndex].x) +
499                     labs(player[pyrn].y - SampleRay[wIndex].y);
500 
501                 if (sqrdist < 1500)
502                     wVol = 0x7fff;
503                 else if (sqrdist > 8500)
504                     wVol = 0x1f00;
505                 else
506                     wVol = 39000 - (sqrdist << 2);
507 
508                 wPan = ((getangle(player[pyrn].x - SampleRay[wIndex].x, player[pyrn].y - SampleRay[wIndex].y) + (2047 - player[pyrn].ang)) % kAngleMask) >> 6;
509                 SND_UpdateSoundLoc(wIndex, wVol, wPan);
510                 //sprintf(displaybuf,"%dVol %x Pan %x Dist %ld",SampleRay[wIndex].number,wVol,wPan,sqrdist);
511                 //displaytime=100;
512             }
513         }
514     }
515     #endif
516 }
517 
SND_CheckLoops()518 void SND_CheckLoops()
519 {
520 }
521 
SND_StopLoop(int16_t nSound)522 void SND_StopLoop(int16_t nSound)
523 {
524 }
525 
SND_LoadSongs(uint16_t which)526 void SND_LoadSongs(uint16_t which)
527 {
528     static int index;
529 
530     index = songsperlevel * which;                  //vanilla
531 
532     //if digi_midi used skip to those songs
533     // if (wMIDIDeviceID == _MIDI_AWE32)
534     //     index += songelements;                            //skip past vanilla
535 
536     //if soundcanvas skip to those songs
537     if (wMIDIDeviceID == _MIDI_MPU_401/* || wMIDIDeviceID == _MIDI_GUS*/)
538         index += songelements * 2;
539 
540     BaseSongPtr = SND_LoadMIDISong(index + BASE_SONG);
541     EmbSongPtr = SND_LoadMIDISong(index + EMB_SONG);
542     SpiceSongPtr = SND_LoadMIDISong(index + SPICE_SONG);
543 }
544 
SND_StartMusic(int16_t level)545 void SND_StartMusic(int16_t level)
546 {
547     if ((!MusicMode) || !SD_Started)
548         return;
549 
550     if (level > 5)
551         level = rand() % 6;
552 
553     SND_SongFlush();
554     SND_LoadSongs(level);
555     SongPending = SND_PrepareMIDISong(BASE_SONG);
556     SND_StartMIDISong(SongPending);
557     SongPending = 0;
558 }
559 
SND_Mixer(int16_t wSource,int16_t wVolume)560 void SND_Mixer(int16_t wSource, int16_t wVolume)
561 {
562     if (wSource == MIDI) {
563         wMIDIVol = (wVolume << 3);
564         HMISetMasterVolume(wMIDIVol);
565     }
566 }
567 
SND_Sting(int16_t nSound)568 void SND_Sting(int16_t nSound)
569 {
570 }
571 
SND_FadeMusic()572 void SND_FadeMusic()
573 {
574 }
575 
576 // temp
577 int nMusicSize = 0;
578 
SND_LoadMIDISong(int nSong)579 char* SND_LoadMIDISong(int nSong)
580 {
581     uint32_t nLength = SongList[(nSong * 3) + 1];
582     uint32_t SeekIndex = (SongList[(nSong * 3) + 0] * 4096);
583     char* pData = (char*)malloc(nLength);
584 
585     klseek(hSongsFile, SeekIndex, SEEK_SET);
586     kread(hSongsFile, pData, nLength);
587 
588     nMusicSize = nLength;
589 
590     return pData;
591 }
592 
SND_MenuMusic(int nSong)593 void SND_MenuMusic(int nSong)
594 {
595     if (!MusicMode || !SD_Started)
596         return;
597 
598     if ((nSong == DEATHSONG) && (wMIDIDeviceID == _MIDI_FM))
599         return;
600     SND_SongFlush();
601 
602     if (nSong == MENUSONG)
603     {
604         if (wMIDIDeviceID == _MIDI_MPU_401/* || wMIDIDeviceID == _MIDI_AWE32 || wMIDIDeviceID == _MIDI_GUS*/)
605         {
606             BaseSongPtr = SND_LoadMIDISong((totallevels * songsperlevel) + BASE_SONG + 2);
607         }
608         else
609         {
610             BaseSongPtr = SND_LoadMIDISong((totallevels * songsperlevel) + BASE_SONG);
611         }
612     }
613     else if (wMIDIDeviceID == _MIDI_MPU_401/* || wMIDIDeviceID == _MIDI_AWE32 || wMIDIDeviceID == _MIDI_GUS*/)
614     {
615         BaseSongPtr = SND_LoadMIDISong((totallevels * songsperlevel) + 3 + BASE_SONG + 2);
616     }
617 
618     SongPending = SND_PrepareMIDISong(BASE_SONG);
619     SND_StartMIDISong(SongPending);
620     SongPending = 0;
621 }
622 
sosMIDISongCallback(uint32_t hSong)623 void sosMIDISongCallback(uint32_t hSong)
624 {
625     int i;
626     for (i = 0; i < MAX_ACTIVE_SONGS; i++)
627         if (hSong == hSOSSongHandles[i])
628             break;
629 
630     HMIUnInitSong(hSOSSongHandles[i]);
631     hSOSSongHandles[i] = 0x7fff;
632 }
633 
SND_PrepareMIDISong(int SongIndex)634 int SND_PrepareMIDISong(int SongIndex)
635 {
636     int status;
637     if (!MusicMode)
638         return(0x7fff);
639 
640     if (hSOSSongHandles[SongIndex] != 0x7fff)
641         return(0x7fff);
642 
643     if (SongIndex == BASE_SONG)
644         sSOSInitSongs[SongIndex].songptr = (uint8_t*)BaseSongPtr;
645     if (SongIndex == EMB_SONG)
646         sSOSInitSongs[SongIndex].songptr = (uint8_t*)EmbSongPtr;
647     if (SongIndex == SPICE_SONG)
648         sSOSInitSongs[SongIndex].songptr = (uint8_t*)SpiceSongPtr;
649 
650     sSOSInitSongs[SongIndex].callback = sosMIDISongCallback;
651     if ((status = HMIInitSong(&sSOSInitSongs[SongIndex], &sSOSTrackMap[SongIndex], (uint32_t*)&hSOSSongHandles[SongIndex])))
652     {
653         crash("Init Song Failed!");
654     }
655 
656     return((int)hSOSSongHandles[SongIndex]);
657 }
SND_StartMIDISong(int wSongHandle)658 int SND_StartMIDISong(int wSongHandle)
659 {
660     HMISetMasterVolume(wMIDIVol);
661     return(HMIStartSong(wSongHandle));
662 }
663 
SND_StopMIDISong(int wSongHandle)664 void SND_StopMIDISong(int wSongHandle)
665 {
666     int i;
667     for (i = 0; i < MAX_ACTIVE_SONGS; i++)
668         if (hSOSSongHandles[i] == wSongHandle)
669             break;
670 
671     if (i >= MAX_ACTIVE_SONGS)
672         return;
673 
674     if (!HMISongDone(hSOSSongHandles[i]))
675     {
676         HMIStopSong(hSOSSongHandles[i]);
677         HMIUnInitSong(hSOSSongHandles[i]);
678         hSOSSongHandles[i] = 0x7fff;
679         free(sSOSInitSongs[i].songptr);
680     }
681 }
682 
SND_SongFlush()683 void SND_SongFlush()
684 {
685     if (!MusicMode)
686         return;
687 
688     if (hSOSSongHandles[BASE_SONG] != 0x7fff)
689         SND_StopMIDISong(hSOSSongHandles[BASE_SONG]);
690     if (hSOSSongHandles[EMB_SONG] != 0x7fff)
691         SND_StopMIDISong(hSOSSongHandles[EMB_SONG]);
692     if (hSOSSongHandles[SPICE_SONG] != 0x7fff)
693         SND_StopMIDISong(hSOSSongHandles[SPICE_SONG]);
694 }
695 
SND_MIDIFlush(void)696 void SND_MIDIFlush(void)
697 {
698     int i;
699     for (i = 0; i < MAX_ACTIVE_SONGS; i++) {
700         if (!HMISongDone(hSOSSongHandles[i]))
701             HMIStopSong(hSOSSongHandles[i]);
702         if (hSOSSongHandles[i] != 0x7fff)
703             HMIUnInitSong(hSOSSongHandles[i]);
704         hSOSSongHandles[i] = 0x7fff;
705     }
706 
707     free(BaseSongPtr);
708     free(EmbSongPtr);
709     free(SpiceSongPtr);
710 }
711