2 * $Source: /cvs/cvsroot/d2x/sound/sdl_digi.c,v $
5 * $Date: 2001-10-12 06:36:55 $
7 * SDL digital audio support
9 * $Log: not supported by cvs2svn $
10 * Revision 1.2 2001/01/29 13:53:28 bradleyb
11 * Fixed build, minor fixes
24 #include <SDL/SDL_audio.h>
31 #include "gr.h" // needed for piggy.h
39 int digi_sample_rate=11025;
41 //edited 05/17/99 Matt Mueller - added ifndef NO_ASM
42 //added on 980905 by adb to add inline fixmul for mixer on i386
45 #define do_fixmul(x,y) \
48 asm("imull %2\n\tshrdl %3,%1,%0" \
49 : "=a"(_ax), "=d"(_dx) \
50 : "rm"(y), "i"(16), "0"(x)); \
53 extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); }
59 //changed on 980905 by adb to increase number of concurrent sounds
60 #define MAX_SOUND_SLOTS 32
62 #define SOUND_BUFFER_SIZE 512
66 /* This table is used to add two sound values together and pin
67 * the value to avoid overflow. (used with permission from ARDI)
68 * DPH: Taken from SDL/src/SDL_mixer.c.
70 static const Uint8 mix8[] =
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, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
84 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
85 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
86 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
87 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
88 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
89 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
90 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
91 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
92 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
93 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
94 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
95 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
96 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
97 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
98 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
99 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
100 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
101 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
102 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
103 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
104 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
105 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
106 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
113 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
114 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
115 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
116 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
117 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
118 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
121 #define SOF_USED 1 // Set if this sample is used
122 #define SOF_PLAYING 2 // Set if this sample is playing on a channel
123 #define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits.
124 #define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos
125 #define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once
127 typedef struct sound_object {
128 short signature; // A unique signature to this sound
129 ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long.
130 fix max_volume; // Max volume that this sound is playing at
131 fix max_distance; // The max distance that this sound can be heard at...
132 int volume; // Volume that this sound is playing at
133 int pan; // Pan value that this sound is playing at
134 int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set.
135 short soundnum; // The sound number that is playing
138 short segnum; // Used if SOF_LINK_TO_POS field is used
143 short objnum; // Used if SOF_LINK_TO_OBJ field is used
148 #define lp_segnum link.pos.segnum
149 #define lp_sidenum link.pos.sidenum
150 #define lp_position link.pos.position
152 #define lo_objnum link.obj.objnum
153 #define lo_objsignature link.obj.objsignature
155 #define MAX_SOUND_OBJECTS 16
156 sound_object SoundObjects[MAX_SOUND_OBJECTS];
157 short next_signature=0;
159 //added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2
160 #define SOUND_MAX_VOLUME (F1_0 / 2)
162 int digi_volume = SOUND_MAX_VOLUME;
167 static int digi_initialised = 0;
171 int playing; // Is there a sample playing on this channel?
172 int looped; // Play this sample looped?
173 fix pan; // 0 = far left, 1 = far right
174 fix volume; // 0 = nothing, 1 = fully on
175 //changed on 980905 by adb from char * to unsigned char *
176 unsigned char *samples;
178 unsigned int length; // Length of the sample
179 unsigned int position; // Position we are at at the moment.
180 } SoundSlots[MAX_SOUND_SLOTS];
182 static SDL_AudioSpec WaveSpec;
183 static int digi_sounds_initialized = 0;
185 //added on 980905 by adb to add rotating/volume based sound kill system
186 static int digi_max_channels = 16;
187 static int next_handle = 0;
188 int SampleHandles[32];
189 void reset_sounds_on_channel(int channel);
192 void digi_reset_digi_sounds(void);
194 /* Audio mixing callback */
195 //changed on 980905 by adb to cleanup, add pan support and optimize mixer
196 static void audio_mixcallback(void *userdata, Uint8 *stream, int len)
198 Uint8 *streamend = stream + len;
199 struct sound_slot *sl;
201 for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++)
205 Uint8 *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length;
206 Uint8 *sp = stream, s;
211 if ((x = sl->pan) & 0x8000)
213 vl = 0x20000 - x * 2;
221 vl = fixmul(vl, (x = sl->volume));
223 while (sp < streamend)
232 sldata = sl->samples;
234 v = *(sldata++) - 0x80;
236 *(sp++) = mix8[ s + fixmul(v, vl) + 0x80 ];
238 *(sp++) = mix8[ s + fixmul(v, vr) + 0x80 ];
240 sl->position = sldata - sl->samples;
246 /* Initialise audio devices. */
249 if (SDL_InitSubSystem(SDL_INIT_AUDIO)<0){
250 Error("SDL audio initialisation failed: %s.",SDL_GetError());
252 //added on 980905 by adb to init sound kill system
253 memset(SampleHandles, 255, sizeof(SampleHandles));
256 WaveSpec.freq = 11025;
257 //added/changed by Sam Lantinga on 12/01/98 for new SDL version
258 WaveSpec.format = AUDIO_U8;
259 WaveSpec.channels = 2;
260 //end this section addition/change - SL
261 WaveSpec.samples = SOUND_BUFFER_SIZE;
262 WaveSpec.callback = audio_mixcallback;
264 if ( SDL_OpenAudio(&WaveSpec, NULL) < 0 ) {
265 //edited on 10/05/98 by Matt Mueller - should keep running, just with no sound.
266 Warning("\nError: Couldn't open audio: %s\n", SDL_GetError());
274 digi_initialised = 1;
279 void digi_reset() { }
281 /* Shut down audio */
284 if (!digi_initialised) return;
285 digi_initialised = 0;
289 /* Find the sound which actually equates to a sound number */
290 int digi_xlat_sound(int soundno)
292 if ( soundno < 0 ) return -1;
295 soundno = AltSounds[soundno];
296 if ( soundno == 255 ) return -1;
298 return Sounds[soundno];
301 static int get_free_slot()
304 for (i=0; i<MAX_SOUND_SLOTS; i++)
306 if (!SoundSlots[i].playing) return i;
311 int digi_start_sound(int soundnum, fix volume, fix pan, int unknown1, int unknown2, int unknown3, int unknown4)
316 if (!digi_initialised) return -1;
318 //added on 980905 by adb from original source to add sound kill system
319 // play at most digi_max_channel samples, if possible kill sample with low volume
323 if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing) )
325 if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
327 //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
329 if ( next_handle >= digi_max_channels )
334 //mprintf(( 0, "[SS:%d]", next_handle ));
335 SoundSlots[SampleHandles[next_handle]].playing = 0;
336 SampleHandles[next_handle] = -1;
340 slot = get_free_slot();
341 if (slot<0) return -1;
343 SoundSlots[slot].soundno = soundnum;
344 SoundSlots[slot].samples = GameSounds[soundnum].data;
345 SoundSlots[slot].length = GameSounds[soundnum].length;
346 SoundSlots[slot].volume = fixmul(digi_volume, volume);
347 SoundSlots[slot].pan = pan;
348 SoundSlots[slot].position = 0;
349 SoundSlots[slot].looped = 0;
350 SoundSlots[slot].playing = 1;
352 //added on 980905 by adb to add sound kill system from original sos digi.c
353 reset_sounds_on_channel(slot);
354 SampleHandles[next_handle] = slot;
356 if ( next_handle >= digi_max_channels )
363 //added on 980905 by adb to add sound kill system from original sos digi.c
364 void reset_sounds_on_channel( int channel )
368 for (i=0; i<digi_max_channels; i++)
369 if (SampleHandles[i] == channel)
370 SampleHandles[i] = -1;
374 int digi_start_sound_object(int obj)
378 if (!digi_initialised) return -1;
379 slot = get_free_slot();
381 if (slot<0) return -1;
384 SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
385 SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
386 SoundSlots[slot].length = GameSounds[SoundObjects[obj].soundnum].length;
387 SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
388 SoundSlots[slot].pan = SoundObjects[obj].pan;
389 SoundSlots[slot].position = 0;
390 SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
391 SoundSlots[slot].playing = 1;
393 SoundObjects[obj].signature = next_signature++;
394 SoundObjects[obj].handle = slot;
396 SoundObjects[obj].flags |= SOF_PLAYING;
397 //added on 980905 by adb to add sound kill system from original sos digi.c
398 reset_sounds_on_channel(slot);
405 // Play the given sound number.
406 // Volume is max at F1_0.
407 void digi_play_sample( int soundno, fix max_volume )
410 if ( Newdemo_state == ND_STATE_RECORDING )
411 newdemo_record_sound( soundno );
413 soundno = digi_xlat_sound(soundno);
415 if (!digi_initialised) return;
417 if (soundno < 0 ) return;
419 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
422 // Play the given sound number. If the sound is already playing,
424 void digi_play_sample_once( int soundno, fix max_volume )
429 if ( Newdemo_state == ND_STATE_RECORDING )
430 newdemo_record_sound( soundno );
432 soundno = digi_xlat_sound(soundno);
434 if (!digi_initialised) return;
436 if (soundno < 0 ) return;
438 for (i=0; i < MAX_SOUND_SLOTS; i++)
439 if (SoundSlots[i].soundno == soundno)
440 SoundSlots[i].playing = 0;
441 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
445 void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff
450 if ( Newdemo_state == ND_STATE_RECORDING ) {
452 newdemo_record_sound_3d_once( soundno, angle, volume );
454 newdemo_record_sound_3d( soundno, angle, volume );
457 soundno = digi_xlat_sound(soundno);
459 if (!digi_initialised) return;
460 if (soundno < 0 ) return;
462 if (volume < MIN_VOLUME ) return;
463 digi_start_sound(soundno, volume, angle, 0, 0, 0, 0);
466 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 )
468 vms_vector vector_to_sound;
469 fix angle_from_ear, cosang,sinang;
476 max_distance = (max_distance*5)/4; // Make all sounds travel 1.25 times as far.
478 // Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation.
479 distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos );
481 if (distance < max_distance ) {
482 int num_search_segs = f2i(max_distance/20);
483 if ( num_search_segs < 1 ) num_search_segs = 1;
485 path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG );
486 if ( path_distance > -1 ) {
487 *volume = max_volume - fixdiv(path_distance,max_distance);
488 //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume ));
490 angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec);
491 fix_sincos(angle_from_ear,&sinang,&cosang);
492 //mprintf( (0, "volume is %.2f\n", f2fl(*volume) ));
493 if (Config_channels_reversed) cosang *= -1;
494 *pan = (cosang + F1_0)/2;
502 int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance )
508 soundnum = digi_xlat_sound(org_soundnum);
510 if ( max_volume < 0 ) return -1;
511 // if ( max_volume > F1_0 ) max_volume = F1_0;
513 if (!digi_initialised) return -1;
514 if (soundnum < 0 ) return -1;
515 if (GameSounds[soundnum].data==NULL) {
519 if ((objnum<0)||(objnum>Highest_object_index))
523 // Hack to keep sounds from building up...
524 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance );
525 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
529 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
530 if (SoundObjects[i].flags==0)
533 if (i==MAX_SOUND_OBJECTS) {
534 mprintf((1, "Too many sound objects!\n" ));
538 SoundObjects[i].signature=next_signature++;
539 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ;
541 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
542 SoundObjects[i].lo_objnum = objnum;
543 SoundObjects[i].lo_objsignature = Objects[objnum].signature;
544 SoundObjects[i].max_volume = max_volume;
545 SoundObjects[i].max_distance = max_distance;
546 SoundObjects[i].volume = 0;
547 SoundObjects[i].pan = 0;
548 SoundObjects[i].soundnum = soundnum;
550 objp = &Objects[SoundObjects[i].lo_objnum];
551 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
552 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
553 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
555 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
556 digi_start_sound_object(i);
558 return SoundObjects[i].signature;
561 int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume )
562 { return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); }
564 int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance )
569 soundnum = digi_xlat_sound(org_soundnum);
571 if ( max_volume < 0 ) return -1;
572 // if ( max_volume > F1_0 ) max_volume = F1_0;
574 if (!digi_initialised) return -1;
575 if (soundnum < 0 ) return -1;
576 if (GameSounds[soundnum].data==NULL) {
581 if ((segnum<0)||(segnum>Highest_segment_index))
585 // Hack to keep sounds from building up...
586 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance );
587 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
591 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
592 if (SoundObjects[i].flags==0)
595 if (i==MAX_SOUND_OBJECTS) {
596 mprintf((1, "Too many sound objects!\n" ));
601 SoundObjects[i].signature=next_signature++;
602 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS;
604 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
605 SoundObjects[i].lp_segnum = segnum;
606 SoundObjects[i].lp_sidenum = sidenum;
607 SoundObjects[i].lp_position = *pos;
608 SoundObjects[i].soundnum = soundnum;
609 SoundObjects[i].max_volume = max_volume;
610 SoundObjects[i].max_distance = max_distance;
611 SoundObjects[i].volume = 0;
612 SoundObjects[i].pan = 0;
613 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
614 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
615 SoundObjects[i].max_volume,
616 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
618 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
619 digi_start_sound_object(i);
621 return SoundObjects[i].signature;
624 int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume )
626 return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 );
629 void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum )
633 soundnum = digi_xlat_sound(soundnum);
635 if (!digi_initialised) return;
639 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
640 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) ) {
641 if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
642 if ( SoundObjects[i].flags & SOF_PLAYING ) {
643 SoundSlots[SoundObjects[i].handle].playing = 0;
645 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
650 // If this assert happens, it means that there were 2 sounds
651 // that got deleted. Weird, get John.
653 mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum ));
657 void digi_kill_sound_linked_to_object( int objnum )
661 if (!digi_initialised) return;
665 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
666 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
667 if (SoundObjects[i].lo_objnum == objnum) {
668 if ( SoundObjects[i].flags & SOF_PLAYING ) {
669 SoundSlots[SoundObjects[i].handle].playing = 0;
671 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
676 // If this assert happens, it means that there were 2 sounds
677 // that got deleted. Weird, get John.
679 mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum ));
683 void digi_sync_sounds()
686 int oldvolume, oldpan;
688 if (!digi_initialised) return;
690 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
691 if ( SoundObjects[i].flags & SOF_USED ) {
692 oldvolume = SoundObjects[i].volume;
693 oldpan = SoundObjects[i].pan;
695 if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) ) {
696 // Check if its done.
697 if (SoundObjects[i].flags & SOF_PLAYING) {
698 if (!SoundSlots[SoundObjects[i].handle].playing) {
699 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
700 continue; // Go on to next sound...
705 if ( SoundObjects[i].flags & SOF_LINK_TO_POS ) {
706 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
707 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
708 SoundObjects[i].max_volume,
709 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
711 } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) {
714 objp = &Objects[SoundObjects[i].lo_objnum];
716 if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) {
717 // The object that this is linked to is dead, so just end this sound if it is looping.
718 if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
719 SoundSlots[SoundObjects[i].handle].playing = 0;
721 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
722 continue; // Go on to next sound...
724 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
725 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
726 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
730 if (oldvolume != SoundObjects[i].volume) {
731 if ( SoundObjects[i].volume < MIN_VOLUME ) {
732 // Sound is too far away, so stop it from playing.
733 if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
734 SoundSlots[SoundObjects[i].handle].playing = 0;
735 SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing
738 if (!(SoundObjects[i].flags & SOF_PLAYING)) {
739 digi_start_sound_object(i);
741 SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0);
746 if (oldpan != SoundObjects[i].pan) {
747 if (SoundObjects[i].flags & SOF_PLAYING)
748 SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan;
754 void digi_init_sounds()
758 if (!digi_initialised) return;
760 digi_reset_digi_sounds();
762 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
763 if (digi_sounds_initialized) {
764 if ( SoundObjects[i].flags & SOF_PLAYING ) {
765 SoundSlots[SoundObjects[i].handle].playing=0;
768 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
770 digi_sounds_initialized = 1;
773 //added on 980905 by adb from original source to make sfx volume work
774 void digi_set_digi_volume( int dvolume )
776 dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
777 if ( dvolume > SOUND_MAX_VOLUME )
778 digi_volume = SOUND_MAX_VOLUME;
779 else if ( dvolume < 0 )
782 digi_volume = dvolume;
784 if ( !digi_initialised ) return;
790 void digi_set_volume( int dvolume, int mvolume ) { }
792 int digi_is_sound_playing(int soundno)
796 soundno = digi_xlat_sound(soundno);
798 for (i = 0; i < MAX_SOUND_SLOTS; i++)
799 //changed on 980905 by adb: added SoundSlots[i].playing &&
800 if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno)
807 void digi_pause_all() { }
808 void digi_resume_all() { }
809 void digi_stop_all() {
811 // ... Ano. The lack of this was causing ambient sounds to crash.
812 // fixed, added digi_stop_all 07/19/01 - bluecow
814 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
815 if ( SoundObjects[i].flags & SOF_USED ) {
816 SoundSlots[SoundObjects[i].handle].playing = 0;
817 SoundObjects[i].flags = 0;
822 //added on 980905 by adb to make sound channel setting work
823 void digi_set_max_channels(int n) {
824 digi_max_channels = n;
826 if ( digi_max_channels < 1 )
827 digi_max_channels = 1;
828 if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) )
829 digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS);
831 if ( !digi_initialised ) return;
833 digi_reset_digi_sounds();
836 int digi_get_max_channels() {
837 return digi_max_channels;
841 void digi_reset_digi_sounds() {
844 for (i=0; i< MAX_SOUND_SLOTS; i++)
845 SoundSlots[i].playing=0;
847 //added on 980905 by adb to reset sound kill system
848 memset(SampleHandles, 255, sizeof(SampleHandles));
854 // MIDI stuff follows.
855 //added/killed on 11/25/98 by Matthew Mueller
856 //void digi_set_midi_volume( int mvolume ) { }
857 //void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {}
858 //void digi_stop_current_song()
867 //end this section kill - MM