7 #define WIN32_LEAN_AND_MEAN
17 #include "gr.h" // needed for piggy.h
27 #define MAX_SOUND_SLOTS 32
31 //added/changed on 980905 by adb to make sfx volume work
32 #define SOUND_MAX_VOLUME F1_0
33 int digi_volume = SOUND_MAX_VOLUME;
37 WAVEFORMATEX waveformat;
44 int playing; // Is there a sample playing on this channel?
45 int looped; // Play this sample looped?
46 fix pan; // 0 = far left, 1 = far right
47 fix volume; // 0 = nothing, 1 = fully on
48 //changed on 980905 by adb from char * to unsigned char *
49 unsigned char *samples;
51 unsigned int length; // Length of the sample
52 unsigned int position; // Position we are at at the moment.
53 LPDIRECTSOUNDBUFFER lpsb;
54 } SoundSlots[MAX_SOUND_SLOTS];
57 int midi_volume = 255;
58 int digi_midi_song_playing = 0;
59 int digi_last_midi_song = 0;
60 int digi_last_midi_song_loop = 0;
62 static int Digi_initialized = 0;
63 static int digi_atexit_initialised=0;
65 //added on 980905 by adb to add rotating/volume based sound kill system
66 static int digi_max_channels = 16;
67 static int next_handle = 0;
68 int SampleHandles[32];
69 void reset_sounds_on_channel(int channel);
72 void digi_reset_digi_sounds(void);
80 digi_reset_digi_sounds();
81 IDirectSound_Release(lpds);
86 /* Initialise audio devices. */
91 if (!Digi_initialized && g_hWnd){
93 memset(&waveformat, 0, sizeof(waveformat));
94 waveformat.wFormatTag=WAVE_FORMAT_PCM;
95 waveformat.wBitsPerSample=8;
96 waveformat.nChannels = 1;
97 waveformat.nSamplesPerSec = digi_sample_rate; //11025;
98 waveformat.nBlockAlign = waveformat.nChannels * (waveformat.wBitsPerSample / 8);
99 waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign;
101 if ((hr = DirectSoundCreate(NULL, &lpds, NULL)) != DS_OK)
104 if ((hr = IDirectSound_SetCooperativeLevel(lpds, g_hWnd, DSSCL_PRIORITY)) //hWndMain
107 IDirectSound_Release(lpds);
111 memset(&dsbd, 0, sizeof(dsbd));
112 dsbd.dwSize = sizeof(dsbd);
113 dsbd.dwFlags = DSBCAPS_CTRLDEFAULT | DSBCAPS_GETCURRENTPOSITION2;
114 dsbd.dwBufferBytes = 8192;
116 dsbd.lpwfxFormat = &waveformat;
118 Digi_initialized = 1;
121 if (!digi_atexit_initialised){
123 digi_atexit_initialised=1;
128 // added 2000/01/15 Matt Mueller -- remove some duplication (and fix a big memory leak, in the kill=0 one case)
129 static int DS_release_slot(int slot, int kill)
131 if (SoundSlots[slot].lpsb)
135 IDirectSoundBuffer_GetStatus(SoundSlots[slot].lpsb, &s);
136 if (s & DSBSTATUS_PLAYING)
139 IDirectSoundBuffer_Stop(SoundSlots[slot].lpsb);
143 IDirectSoundBuffer_Release(SoundSlots[slot].lpsb);
144 SoundSlots[slot].lpsb = NULL;
146 SoundSlots[slot].playing = 0;
150 void digi_stop_all_channels()
154 for (i = 0; i < MAX_SOUND_SLOTS; i++)
159 static int get_free_slot()
163 for (i=0; i<MAX_SOUND_SLOTS; i++)
165 if (DS_release_slot(i, 0))
171 int D1vol2DSvol(fix d1v){
172 //multiplying by 1.5 doesn't help. DirectSound uses dB for volume, rather than a linear scale like d1 wants.
173 //I had to pull out a math book, but here is the code to fix it :) -Matt Mueller
179 // return log2(f2fl(d1v))*1000;//no log2? hm.
180 return log(f2fl(d1v))/log(2)*1000.0;
184 int digi_start_sound(short soundnum, fix volume, int pan, int looping, int loop_start, int loop_end, int soundobj)
190 if (!Digi_initialized)
193 // added on 980905 by adb from original source to add sound kill system
194 // play at most digi_max_channel samples, if possible kill sample with low volume
198 if ((SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing))
200 if ((SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries < digi_max_channels))
202 //mprintf((0, "Not stopping loud sound %d.\n", next_handle));
204 if (next_handle >= digi_max_channels)
209 //mprintf((0, "[SS:%d]", next_handle));
210 SampleHandles[next_handle] = -1;
214 slot = get_free_slot();
218 SoundSlots[slot].soundno = soundnum;
219 SoundSlots[slot].samples = Sounddat(soundnum)->data;
220 SoundSlots[slot].length = Sounddat(soundnum)->length;
221 SoundSlots[slot].volume = fixmul(digi_volume, volume);
222 SoundSlots[slot].pan = pan;
223 SoundSlots[slot].position = 0;
224 SoundSlots[slot].looped = 0;
225 SoundSlots[slot].playing = 1;
227 memset(&waveformat, 0, sizeof(waveformat));
228 waveformat.wFormatTag = WAVE_FORMAT_PCM;
229 waveformat.wBitsPerSample = Sounddat(soundnum)->bits;
230 waveformat.nChannels = 1;
231 waveformat.nSamplesPerSec = Sounddat(soundnum)->freq; //digi_sample_rate;
232 waveformat.nBlockAlign = waveformat.nChannels * (waveformat.wBitsPerSample / 8);
233 waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign;
235 memset(&dsbd, 0, sizeof(dsbd));
236 dsbd.dwSize = sizeof(dsbd);
237 dsbd.dwFlags = DSBCAPS_CTRLDEFAULT | DSBCAPS_GETCURRENTPOSITION2;
239 dsbd.dwBufferBytes = SoundSlots[slot].length;
240 dsbd.lpwfxFormat = &waveformat;
242 hr = IDirectSound_CreateSoundBuffer(lpds, &dsbd, &SoundSlots[slot].lpsb, NULL);
245 printf("Createsoundbuffer failed! hr=0x%X\n", (int)hr);
253 IDirectSoundBuffer_Lock(SoundSlots[slot].lpsb, 0, Sounddat(soundnum)->length,
254 &ptr1, &len1, &ptr2, &len2, 0);
255 memcpy(ptr1, Sounddat(soundnum)->data, MIN(len1, Sounddat(soundnum)->length));
256 IDirectSoundBuffer_Unlock(SoundSlots[slot].lpsb, ptr1, len1, ptr2, len2);
259 IDirectSoundBuffer_SetPan(SoundSlots[slot].lpsb, ((int)(f2fl(pan) * 20000.0)) - 10000);
260 IDirectSoundBuffer_SetVolume(SoundSlots[slot].lpsb, D1vol2DSvol(SoundSlots[slot].volume));
261 IDirectSoundBuffer_Play(SoundSlots[slot].lpsb, 0, 0, 0);
263 // added on 980905 by adb to add sound kill system from original sos digi.c
264 reset_sounds_on_channel(slot);
265 SampleHandles[next_handle] = slot;
267 if (next_handle >= digi_max_channels)
274 // Returns the channel a sound number is playing on, or
276 int digi_find_channel(int soundno)
278 if (!Digi_initialized)
284 if (GameSounds[soundno].data == NULL)
290 //FIXME: not implemented
294 //added on 980905 by adb to add sound kill system from original sos digi.c
295 void reset_sounds_on_channel( int channel )
299 for (i=0; i<digi_max_channels; i++)
300 if (SampleHandles[i] == channel)
301 SampleHandles[i] = -1;
305 //added on 980905 by adb from original source to make sfx volume work
306 void digi_set_digi_volume( int dvolume )
308 dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
309 if ( dvolume > SOUND_MAX_VOLUME )
310 digi_volume = SOUND_MAX_VOLUME;
311 else if ( dvolume < 0 )
314 digi_volume = dvolume;
316 if ( !Digi_initialized ) return;
322 void digi_set_volume( int dvolume, int mvolume )
324 digi_set_digi_volume(dvolume);
325 digi_set_midi_volume(mvolume);
328 int digi_is_sound_playing(int soundno)
332 soundno = digi_xlat_sound(soundno);
334 for (i = 0; i < MAX_SOUND_SLOTS; i++)
335 //changed on 980905 by adb: added SoundSlots[i].playing &&
336 if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno)
343 //added on 980905 by adb to make sound channel setting work
344 void digi_set_max_channels(int n) {
345 digi_max_channels = n;
347 if ( digi_max_channels < 1 )
348 digi_max_channels = 1;
349 if (digi_max_channels > MAX_SOUND_SLOTS)
350 digi_max_channels = MAX_SOUND_SLOTS;
352 if ( !Digi_initialized ) return;
354 digi_reset_digi_sounds();
357 int digi_get_max_channels() {
358 return digi_max_channels;
362 void digi_reset_digi_sounds() {
365 for (i=0; i< MAX_SOUND_SLOTS; i++) {
366 DS_release_slot(i, 1);
369 //added on 980905 by adb to reset sound kill system
370 memset(SampleHandles, 255, sizeof(SampleHandles));
375 int digi_is_channel_playing(int channel)
377 if (!Digi_initialized)
380 return SoundSlots[channel].playing;
383 void digi_set_channel_volume(int channel, int volume)
385 if (!Digi_initialized)
388 if (!SoundSlots[channel].playing)
391 SoundSlots[channel].volume = fixmuldiv(volume, digi_volume, F1_0);
394 void digi_set_channel_pan(int channel, int pan)
396 if (!Digi_initialized)
399 if (!SoundSlots[channel].playing)
402 SoundSlots[channel].pan = pan;
405 void digi_stop_sound(int channel)
407 SoundSlots[channel].playing=0;
408 SoundSlots[channel].soundobj = -1;
409 SoundSlots[channel].persistent = 0;
412 void digi_end_sound(int channel)
414 if (!Digi_initialized)
417 if (!SoundSlots[channel].playing)
420 SoundSlots[channel].soundobj = -1;
421 SoundSlots[channel].persistent = 0;
425 int digi_midi_song_playing = 0;
426 static int Digi_initialized = 0;
427 int midi_volume = 255;
429 int digi_get_settings() { return 0; }
430 int digi_init() { Digi_initialized = 1; return 0; }
434 void digi_set_digi_volume( int dvolume ) {}
435 void digi_set_volume( int dvolume, int mvolume ) {}
437 int digi_is_sound_playing(int soundno) { return 0; }
439 void digi_set_max_channels(int n) {}
440 int digi_get_max_channels() { return 0; }
445 // MIDI stuff follows.
447 void digi_stop_current_song()
449 if ( digi_midi_song_playing ) {
452 digi_midi_song_playing = 0;
456 void digi_set_midi_volume( int n )
467 // scale up from 0-127 to 0-0xffff
468 mm_volume = (midi_volume << 1) | (midi_volume & 1);
469 mm_volume |= (mm_volume << 8);
472 midiOutSetVolume((HMIDIOUT)hmp->hmidi, mm_volume | mm_volume << 16);
475 void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop )
477 if (!Digi_initialized) return;
479 digi_stop_current_song();
481 //added on 5/20/99 by Victor Rachels to fix crash/etc
482 if(filename == NULL) return;
483 if(midi_volume < 1) return;
484 //end this section addition - VR
486 if ((hmp = hmp_open(filename))) {
488 digi_midi_song_playing = 1;
489 digi_set_midi_volume(midi_volume);
492 printf("hmp_open failed\n");
494 void digi_pause_midi() {}
495 void digi_resume_midi() {}
498 void digi_stop_current_song() {}
499 void digi_set_midi_volume( int n ) {}
500 void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {}
501 void digi_pause_midi() {}
502 void digi_resume_midi() {}
511 if (!Digi_initialized)
514 for (i = 0; i < digi_max_channels; i++)
516 if (digi_is_channel_playing(i))
520 mprintf_at((0, 2, 0, "DIGI: Active Sound Channels: %d/%d (HMI says %d/32) ", n_voices, digi_max_channels, -1));
521 //mprintf_at((0, 3, 0, "DIGI: Number locked sounds: %d ", digi_total_locks ));