1 /* $Id: digi.c,v 1.4 2002-08-02 11:05:25 btb Exp $ */
4 * SDL digital audio support
18 #include <SDL/SDL_audio.h>
25 #include "gr.h" // needed for piggy.h
33 int digi_sample_rate=11025;
35 //edited 05/17/99 Matt Mueller - added ifndef NO_ASM
36 //added on 980905 by adb to add inline fixmul for mixer on i386
39 #define do_fixmul(x,y) \
42 asm("imull %2\n\tshrdl %3,%1,%0" \
43 : "=a"(_ax), "=d"(_dx) \
44 : "rm"(y), "i"(16), "0"(x)); \
47 extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); }
53 //changed on 980905 by adb to increase number of concurrent sounds
54 #define MAX_SOUND_SLOTS 32
56 #define SOUND_BUFFER_SIZE 512
60 /* This table is used to add two sound values together and pin
61 * the value to avoid overflow. (used with permission from ARDI)
62 * DPH: Taken from SDL/src/SDL_mixer.c.
64 static const Uint8 mix8[] =
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
78 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
79 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
80 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
81 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
82 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
83 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
84 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
85 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
86 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
87 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
88 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
89 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
90 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
91 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
92 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
93 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
94 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
95 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
96 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
97 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
98 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
99 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
100 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF,
101 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
102 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
103 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
104 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
105 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
106 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
107 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
108 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
109 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
110 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
111 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
112 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
115 #define SOF_USED 1 // Set if this sample is used
116 #define SOF_PLAYING 2 // Set if this sample is playing on a channel
117 #define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits.
118 #define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos
119 #define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once
121 typedef struct sound_object {
122 short signature; // A unique signature to this sound
123 ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long.
124 fix max_volume; // Max volume that this sound is playing at
125 fix max_distance; // The max distance that this sound can be heard at...
126 int volume; // Volume that this sound is playing at
127 int pan; // Pan value that this sound is playing at
128 int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set.
129 short soundnum; // The sound number that is playing
132 short segnum; // Used if SOF_LINK_TO_POS field is used
137 short objnum; // Used if SOF_LINK_TO_OBJ field is used
142 #define lp_segnum link.pos.segnum
143 #define lp_sidenum link.pos.sidenum
144 #define lp_position link.pos.position
146 #define lo_objnum link.obj.objnum
147 #define lo_objsignature link.obj.objsignature
149 #define MAX_SOUND_OBJECTS 16
150 sound_object SoundObjects[MAX_SOUND_OBJECTS];
151 short next_signature=0;
153 //added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2
154 #define SOUND_MAX_VOLUME (F1_0 / 2)
156 int digi_volume = SOUND_MAX_VOLUME;
161 static int digi_initialised = 0;
165 int playing; // Is there a sample playing on this channel?
166 int looped; // Play this sample looped?
167 fix pan; // 0 = far left, 1 = far right
168 fix volume; // 0 = nothing, 1 = fully on
169 //changed on 980905 by adb from char * to unsigned char *
170 unsigned char *samples;
172 unsigned int length; // Length of the sample
173 unsigned int position; // Position we are at at the moment.
174 } SoundSlots[MAX_SOUND_SLOTS];
176 static SDL_AudioSpec WaveSpec;
177 static int digi_sounds_initialized = 0;
179 //added on 980905 by adb to add rotating/volume based sound kill system
180 static int digi_max_channels = 16;
181 static int next_handle = 0;
182 int SampleHandles[32];
183 void reset_sounds_on_channel(int channel);
186 void digi_reset_digi_sounds(void);
188 /* Audio mixing callback */
189 //changed on 980905 by adb to cleanup, add pan support and optimize mixer
190 static void audio_mixcallback(void *userdata, Uint8 *stream, int len)
192 Uint8 *streamend = stream + len;
193 struct sound_slot *sl;
195 for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++)
199 Uint8 *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length;
200 Uint8 *sp = stream, s;
205 if ((x = sl->pan) & 0x8000)
207 vl = 0x20000 - x * 2;
215 vl = fixmul(vl, (x = sl->volume));
217 while (sp < streamend)
226 sldata = sl->samples;
228 v = *(sldata++) - 0x80;
230 *(sp++) = mix8[ s + fixmul(v, vl) + 0x80 ];
232 *(sp++) = mix8[ s + fixmul(v, vr) + 0x80 ];
234 sl->position = sldata - sl->samples;
240 /* Initialise audio devices. */
243 if (SDL_InitSubSystem(SDL_INIT_AUDIO)<0){
244 Error("SDL audio initialisation failed: %s.",SDL_GetError());
246 //added on 980905 by adb to init sound kill system
247 memset(SampleHandles, 255, sizeof(SampleHandles));
250 WaveSpec.freq = 11025;
251 //added/changed by Sam Lantinga on 12/01/98 for new SDL version
252 WaveSpec.format = AUDIO_U8;
253 WaveSpec.channels = 2;
254 //end this section addition/change - SL
255 WaveSpec.samples = SOUND_BUFFER_SIZE;
256 WaveSpec.callback = audio_mixcallback;
258 if ( SDL_OpenAudio(&WaveSpec, NULL) < 0 ) {
259 //edited on 10/05/98 by Matt Mueller - should keep running, just with no sound.
260 Warning("\nError: Couldn't open audio: %s\n", SDL_GetError());
268 digi_initialised = 1;
273 void digi_reset() { }
275 /* Shut down audio */
278 if (!digi_initialised) return;
279 digi_initialised = 0;
283 /* Find the sound which actually equates to a sound number */
284 int digi_xlat_sound(int soundno)
286 if ( soundno < 0 ) return -1;
289 soundno = AltSounds[soundno];
290 if ( soundno == 255 ) return -1;
292 return Sounds[soundno];
295 static int get_free_slot()
298 for (i=0; i<MAX_SOUND_SLOTS; i++)
300 if (!SoundSlots[i].playing) return i;
305 int digi_start_sound(int soundnum, fix volume, fix pan, int unknown1, int unknown2, int unknown3, int unknown4)
310 if (!digi_initialised) return -1;
312 //added on 980905 by adb from original source to add sound kill system
313 // play at most digi_max_channel samples, if possible kill sample with low volume
317 if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing) )
319 if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
321 //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
323 if ( next_handle >= digi_max_channels )
328 //mprintf(( 0, "[SS:%d]", next_handle ));
329 SoundSlots[SampleHandles[next_handle]].playing = 0;
330 SampleHandles[next_handle] = -1;
334 slot = get_free_slot();
335 if (slot<0) return -1;
337 SoundSlots[slot].soundno = soundnum;
338 SoundSlots[slot].samples = GameSounds[soundnum].data;
339 SoundSlots[slot].length = GameSounds[soundnum].length;
340 SoundSlots[slot].volume = fixmul(digi_volume, volume);
341 SoundSlots[slot].pan = pan;
342 SoundSlots[slot].position = 0;
343 SoundSlots[slot].looped = 0;
344 SoundSlots[slot].playing = 1;
346 //added on 980905 by adb to add sound kill system from original sos digi.c
347 reset_sounds_on_channel(slot);
348 SampleHandles[next_handle] = slot;
350 if ( next_handle >= digi_max_channels )
357 //added on 980905 by adb to add sound kill system from original sos digi.c
358 void reset_sounds_on_channel( int channel )
362 for (i=0; i<digi_max_channels; i++)
363 if (SampleHandles[i] == channel)
364 SampleHandles[i] = -1;
368 int digi_start_sound_object(int obj)
372 if (!digi_initialised) return -1;
373 slot = get_free_slot();
375 if (slot<0) return -1;
378 SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
379 SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
380 SoundSlots[slot].length = GameSounds[SoundObjects[obj].soundnum].length;
381 SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
382 SoundSlots[slot].pan = SoundObjects[obj].pan;
383 SoundSlots[slot].position = 0;
384 SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
385 SoundSlots[slot].playing = 1;
387 SoundObjects[obj].signature = next_signature++;
388 SoundObjects[obj].handle = slot;
390 SoundObjects[obj].flags |= SOF_PLAYING;
391 //added on 980905 by adb to add sound kill system from original sos digi.c
392 reset_sounds_on_channel(slot);
399 // Play the given sound number.
400 // Volume is max at F1_0.
401 void digi_play_sample( int soundno, fix max_volume )
404 if ( Newdemo_state == ND_STATE_RECORDING )
405 newdemo_record_sound( soundno );
407 soundno = digi_xlat_sound(soundno);
409 if (!digi_initialised) return;
411 if (soundno < 0 ) return;
413 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
416 // Play the given sound number. If the sound is already playing,
418 void digi_play_sample_once( int soundno, fix max_volume )
423 if ( Newdemo_state == ND_STATE_RECORDING )
424 newdemo_record_sound( soundno );
426 soundno = digi_xlat_sound(soundno);
428 if (!digi_initialised) return;
430 if (soundno < 0 ) return;
432 for (i=0; i < MAX_SOUND_SLOTS; i++)
433 if (SoundSlots[i].soundno == soundno)
434 SoundSlots[i].playing = 0;
435 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
439 void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff
444 if ( Newdemo_state == ND_STATE_RECORDING ) {
446 newdemo_record_sound_3d_once( soundno, angle, volume );
448 newdemo_record_sound_3d( soundno, angle, volume );
451 soundno = digi_xlat_sound(soundno);
453 if (!digi_initialised) return;
454 if (soundno < 0 ) return;
456 if (volume < MIN_VOLUME ) return;
457 digi_start_sound(soundno, volume, angle, 0, 0, 0, 0);
460 void digi_get_sound_loc( vms_matrix * listener, vms_vector * listener_pos, int listener_seg, vms_vector * sound_pos, int sound_seg, fix max_volume, int *volume, int *pan, fix max_distance )
462 vms_vector vector_to_sound;
463 fix angle_from_ear, cosang,sinang;
470 max_distance = (max_distance*5)/4; // Make all sounds travel 1.25 times as far.
472 // Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation.
473 distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos );
475 if (distance < max_distance ) {
476 int num_search_segs = f2i(max_distance/20);
477 if ( num_search_segs < 1 ) num_search_segs = 1;
479 path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG );
480 if ( path_distance > -1 ) {
481 *volume = max_volume - fixdiv(path_distance,max_distance);
482 //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume ));
484 angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec);
485 fix_sincos(angle_from_ear,&sinang,&cosang);
486 //mprintf( (0, "volume is %.2f\n", f2fl(*volume) ));
487 if (Config_channels_reversed) cosang *= -1;
488 *pan = (cosang + F1_0)/2;
496 int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance )
502 soundnum = digi_xlat_sound(org_soundnum);
504 if ( max_volume < 0 ) return -1;
505 // if ( max_volume > F1_0 ) max_volume = F1_0;
507 if (!digi_initialised) return -1;
508 if (soundnum < 0 ) return -1;
509 if (GameSounds[soundnum].data==NULL) {
513 if ((objnum<0)||(objnum>Highest_object_index))
517 // Hack to keep sounds from building up...
518 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance );
519 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
523 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
524 if (SoundObjects[i].flags==0)
527 if (i==MAX_SOUND_OBJECTS) {
528 mprintf((1, "Too many sound objects!\n" ));
532 SoundObjects[i].signature=next_signature++;
533 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ;
535 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
536 SoundObjects[i].lo_objnum = objnum;
537 SoundObjects[i].lo_objsignature = Objects[objnum].signature;
538 SoundObjects[i].max_volume = max_volume;
539 SoundObjects[i].max_distance = max_distance;
540 SoundObjects[i].volume = 0;
541 SoundObjects[i].pan = 0;
542 SoundObjects[i].soundnum = soundnum;
544 objp = &Objects[SoundObjects[i].lo_objnum];
545 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
546 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
547 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
549 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
550 digi_start_sound_object(i);
552 return SoundObjects[i].signature;
555 int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume )
556 { return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); }
558 int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance )
563 soundnum = digi_xlat_sound(org_soundnum);
565 if ( max_volume < 0 ) return -1;
566 // if ( max_volume > F1_0 ) max_volume = F1_0;
568 if (!digi_initialised) return -1;
569 if (soundnum < 0 ) return -1;
570 if (GameSounds[soundnum].data==NULL) {
575 if ((segnum<0)||(segnum>Highest_segment_index))
579 // Hack to keep sounds from building up...
580 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance );
581 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
585 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
586 if (SoundObjects[i].flags==0)
589 if (i==MAX_SOUND_OBJECTS) {
590 mprintf((1, "Too many sound objects!\n" ));
595 SoundObjects[i].signature=next_signature++;
596 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS;
598 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
599 SoundObjects[i].lp_segnum = segnum;
600 SoundObjects[i].lp_sidenum = sidenum;
601 SoundObjects[i].lp_position = *pos;
602 SoundObjects[i].soundnum = soundnum;
603 SoundObjects[i].max_volume = max_volume;
604 SoundObjects[i].max_distance = max_distance;
605 SoundObjects[i].volume = 0;
606 SoundObjects[i].pan = 0;
607 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
608 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
609 SoundObjects[i].max_volume,
610 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
612 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
613 digi_start_sound_object(i);
615 return SoundObjects[i].signature;
618 int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume )
620 return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 );
623 void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum )
627 soundnum = digi_xlat_sound(soundnum);
629 if (!digi_initialised) return;
633 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
634 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) ) {
635 if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
636 if ( SoundObjects[i].flags & SOF_PLAYING ) {
637 SoundSlots[SoundObjects[i].handle].playing = 0;
639 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
644 // If this assert happens, it means that there were 2 sounds
645 // that got deleted. Weird, get John.
647 mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum ));
651 void digi_kill_sound_linked_to_object( int objnum )
655 if (!digi_initialised) return;
659 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
660 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
661 if (SoundObjects[i].lo_objnum == objnum) {
662 if ( SoundObjects[i].flags & SOF_PLAYING ) {
663 SoundSlots[SoundObjects[i].handle].playing = 0;
665 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
670 // If this assert happens, it means that there were 2 sounds
671 // that got deleted. Weird, get John.
673 mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum ));
677 void digi_sync_sounds()
680 int oldvolume, oldpan;
682 if (!digi_initialised) return;
684 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
685 if ( SoundObjects[i].flags & SOF_USED ) {
686 oldvolume = SoundObjects[i].volume;
687 oldpan = SoundObjects[i].pan;
689 if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) ) {
690 // Check if its done.
691 if (SoundObjects[i].flags & SOF_PLAYING) {
692 if (!SoundSlots[SoundObjects[i].handle].playing) {
693 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
694 continue; // Go on to next sound...
699 if ( SoundObjects[i].flags & SOF_LINK_TO_POS ) {
700 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
701 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
702 SoundObjects[i].max_volume,
703 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
705 } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) {
708 objp = &Objects[SoundObjects[i].lo_objnum];
710 if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) {
711 // The object that this is linked to is dead, so just end this sound if it is looping.
712 if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
713 SoundSlots[SoundObjects[i].handle].playing = 0;
715 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
716 continue; // Go on to next sound...
718 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
719 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
720 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
724 if (oldvolume != SoundObjects[i].volume) {
725 if ( SoundObjects[i].volume < MIN_VOLUME ) {
726 // Sound is too far away, so stop it from playing.
727 if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
728 SoundSlots[SoundObjects[i].handle].playing = 0;
729 SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing
732 if (!(SoundObjects[i].flags & SOF_PLAYING)) {
733 digi_start_sound_object(i);
735 SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0);
740 if (oldpan != SoundObjects[i].pan) {
741 if (SoundObjects[i].flags & SOF_PLAYING)
742 SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan;
748 void digi_init_sounds()
752 if (!digi_initialised) return;
754 digi_reset_digi_sounds();
756 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
757 if (digi_sounds_initialized) {
758 if ( SoundObjects[i].flags & SOF_PLAYING ) {
759 SoundSlots[SoundObjects[i].handle].playing=0;
762 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
764 digi_sounds_initialized = 1;
767 //added on 980905 by adb from original source to make sfx volume work
768 void digi_set_digi_volume( int dvolume )
770 dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
771 if ( dvolume > SOUND_MAX_VOLUME )
772 digi_volume = SOUND_MAX_VOLUME;
773 else if ( dvolume < 0 )
776 digi_volume = dvolume;
778 if ( !digi_initialised ) return;
784 void digi_set_volume( int dvolume, int mvolume )
786 digi_set_digi_volume(dvolume);
787 digi_set_midi_volume(mvolume);
788 // mprintf(( 1, "Volume: 0x%x and 0x%x\n", digi_volume, midi_volume ));
791 int digi_is_sound_playing(int soundno)
795 soundno = digi_xlat_sound(soundno);
797 for (i = 0; i < MAX_SOUND_SLOTS; i++)
798 //changed on 980905 by adb: added SoundSlots[i].playing &&
799 if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno)
806 void digi_pause_all() { }
807 void digi_resume_all() { }
808 void digi_stop_all() {
810 // ... Ano. The lack of this was causing ambient sounds to crash.
811 // fixed, added digi_stop_all 07/19/01 - bluecow
813 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
814 if ( SoundObjects[i].flags & SOF_USED ) {
815 SoundSlots[SoundObjects[i].handle].playing = 0;
816 SoundObjects[i].flags = 0;
821 //added on 980905 by adb to make sound channel setting work
822 void digi_set_max_channels(int n) {
823 digi_max_channels = n;
825 if ( digi_max_channels < 1 )
826 digi_max_channels = 1;
827 if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) )
828 digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS);
830 if ( !digi_initialised ) return;
832 digi_reset_digi_sounds();
835 int digi_get_max_channels() {
836 return digi_max_channels;
840 void digi_reset_digi_sounds() {
843 for (i=0; i< MAX_SOUND_SLOTS; i++)
844 SoundSlots[i].playing=0;
846 //added on 980905 by adb to reset sound kill system
847 memset(SampleHandles, 255, sizeof(SampleHandles));
853 // MIDI stuff follows.
854 //added/killed on 11/25/98 by Matthew Mueller
855 //void digi_set_midi_volume( int mvolume ) { }
856 //void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {}
857 //void digi_stop_current_song()
866 //end this section kill - MM