2 * $Source: /cvs/cvsroot/d2x/arch/sdl/digi.c,v $
5 * $Date: 2001-10-25 08:25:34 $
7 * SDL digital audio support
9 * $Log: not supported by cvs2svn $
10 * Revision 1.3 2001/10/12 06:36:55 bradleyb
11 * Fix a gcc 3.0 warning, couple updates from d1x
13 * Revision 1.2 2001/01/29 13:53:28 bradleyb
14 * Fixed build, minor fixes
27 #include <SDL/SDL_audio.h>
34 #include "gr.h" // needed for piggy.h
42 int digi_sample_rate=11025;
44 //edited 05/17/99 Matt Mueller - added ifndef NO_ASM
45 //added on 980905 by adb to add inline fixmul for mixer on i386
48 #define do_fixmul(x,y) \
51 asm("imull %2\n\tshrdl %3,%1,%0" \
52 : "=a"(_ax), "=d"(_dx) \
53 : "rm"(y), "i"(16), "0"(x)); \
56 extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); }
62 //changed on 980905 by adb to increase number of concurrent sounds
63 #define MAX_SOUND_SLOTS 32
65 #define SOUND_BUFFER_SIZE 512
69 /* This table is used to add two sound values together and pin
70 * the value to avoid overflow. (used with permission from ARDI)
71 * DPH: Taken from SDL/src/SDL_mixer.c.
73 static const Uint8 mix8[] =
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, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03,
87 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
88 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
89 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
90 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
91 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
92 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
93 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
94 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
95 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
96 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
97 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
98 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
99 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
100 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
101 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
102 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
103 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
104 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
105 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
106 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
107 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
108 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
109 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 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, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
119 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
120 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
121 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
124 #define SOF_USED 1 // Set if this sample is used
125 #define SOF_PLAYING 2 // Set if this sample is playing on a channel
126 #define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits.
127 #define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos
128 #define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once
130 typedef struct sound_object {
131 short signature; // A unique signature to this sound
132 ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long.
133 fix max_volume; // Max volume that this sound is playing at
134 fix max_distance; // The max distance that this sound can be heard at...
135 int volume; // Volume that this sound is playing at
136 int pan; // Pan value that this sound is playing at
137 int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set.
138 short soundnum; // The sound number that is playing
141 short segnum; // Used if SOF_LINK_TO_POS field is used
146 short objnum; // Used if SOF_LINK_TO_OBJ field is used
151 #define lp_segnum link.pos.segnum
152 #define lp_sidenum link.pos.sidenum
153 #define lp_position link.pos.position
155 #define lo_objnum link.obj.objnum
156 #define lo_objsignature link.obj.objsignature
158 #define MAX_SOUND_OBJECTS 16
159 sound_object SoundObjects[MAX_SOUND_OBJECTS];
160 short next_signature=0;
162 //added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2
163 #define SOUND_MAX_VOLUME (F1_0 / 2)
165 int digi_volume = SOUND_MAX_VOLUME;
170 static int digi_initialised = 0;
174 int playing; // Is there a sample playing on this channel?
175 int looped; // Play this sample looped?
176 fix pan; // 0 = far left, 1 = far right
177 fix volume; // 0 = nothing, 1 = fully on
178 //changed on 980905 by adb from char * to unsigned char *
179 unsigned char *samples;
181 unsigned int length; // Length of the sample
182 unsigned int position; // Position we are at at the moment.
183 } SoundSlots[MAX_SOUND_SLOTS];
185 static SDL_AudioSpec WaveSpec;
186 static int digi_sounds_initialized = 0;
188 //added on 980905 by adb to add rotating/volume based sound kill system
189 static int digi_max_channels = 16;
190 static int next_handle = 0;
191 int SampleHandles[32];
192 void reset_sounds_on_channel(int channel);
195 void digi_reset_digi_sounds(void);
197 /* Audio mixing callback */
198 //changed on 980905 by adb to cleanup, add pan support and optimize mixer
199 static void audio_mixcallback(void *userdata, Uint8 *stream, int len)
201 Uint8 *streamend = stream + len;
202 struct sound_slot *sl;
204 for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++)
208 Uint8 *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length;
209 Uint8 *sp = stream, s;
214 if ((x = sl->pan) & 0x8000)
216 vl = 0x20000 - x * 2;
224 vl = fixmul(vl, (x = sl->volume));
226 while (sp < streamend)
235 sldata = sl->samples;
237 v = *(sldata++) - 0x80;
239 *(sp++) = mix8[ s + fixmul(v, vl) + 0x80 ];
241 *(sp++) = mix8[ s + fixmul(v, vr) + 0x80 ];
243 sl->position = sldata - sl->samples;
249 /* Initialise audio devices. */
252 if (SDL_InitSubSystem(SDL_INIT_AUDIO)<0){
253 Error("SDL audio initialisation failed: %s.",SDL_GetError());
255 //added on 980905 by adb to init sound kill system
256 memset(SampleHandles, 255, sizeof(SampleHandles));
259 WaveSpec.freq = 11025;
260 //added/changed by Sam Lantinga on 12/01/98 for new SDL version
261 WaveSpec.format = AUDIO_U8;
262 WaveSpec.channels = 2;
263 //end this section addition/change - SL
264 WaveSpec.samples = SOUND_BUFFER_SIZE;
265 WaveSpec.callback = audio_mixcallback;
267 if ( SDL_OpenAudio(&WaveSpec, NULL) < 0 ) {
268 //edited on 10/05/98 by Matt Mueller - should keep running, just with no sound.
269 Warning("\nError: Couldn't open audio: %s\n", SDL_GetError());
277 digi_initialised = 1;
282 void digi_reset() { }
284 /* Shut down audio */
287 if (!digi_initialised) return;
288 digi_initialised = 0;
292 /* Find the sound which actually equates to a sound number */
293 int digi_xlat_sound(int soundno)
295 if ( soundno < 0 ) return -1;
298 soundno = AltSounds[soundno];
299 if ( soundno == 255 ) return -1;
301 return Sounds[soundno];
304 static int get_free_slot()
307 for (i=0; i<MAX_SOUND_SLOTS; i++)
309 if (!SoundSlots[i].playing) return i;
314 int digi_start_sound(int soundnum, fix volume, fix pan, int unknown1, int unknown2, int unknown3, int unknown4)
319 if (!digi_initialised) return -1;
321 //added on 980905 by adb from original source to add sound kill system
322 // play at most digi_max_channel samples, if possible kill sample with low volume
326 if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing) )
328 if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
330 //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
332 if ( next_handle >= digi_max_channels )
337 //mprintf(( 0, "[SS:%d]", next_handle ));
338 SoundSlots[SampleHandles[next_handle]].playing = 0;
339 SampleHandles[next_handle] = -1;
343 slot = get_free_slot();
344 if (slot<0) return -1;
346 SoundSlots[slot].soundno = soundnum;
347 SoundSlots[slot].samples = GameSounds[soundnum].data;
348 SoundSlots[slot].length = GameSounds[soundnum].length;
349 SoundSlots[slot].volume = fixmul(digi_volume, volume);
350 SoundSlots[slot].pan = pan;
351 SoundSlots[slot].position = 0;
352 SoundSlots[slot].looped = 0;
353 SoundSlots[slot].playing = 1;
355 //added on 980905 by adb to add sound kill system from original sos digi.c
356 reset_sounds_on_channel(slot);
357 SampleHandles[next_handle] = slot;
359 if ( next_handle >= digi_max_channels )
366 //added on 980905 by adb to add sound kill system from original sos digi.c
367 void reset_sounds_on_channel( int channel )
371 for (i=0; i<digi_max_channels; i++)
372 if (SampleHandles[i] == channel)
373 SampleHandles[i] = -1;
377 int digi_start_sound_object(int obj)
381 if (!digi_initialised) return -1;
382 slot = get_free_slot();
384 if (slot<0) return -1;
387 SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
388 SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
389 SoundSlots[slot].length = GameSounds[SoundObjects[obj].soundnum].length;
390 SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
391 SoundSlots[slot].pan = SoundObjects[obj].pan;
392 SoundSlots[slot].position = 0;
393 SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
394 SoundSlots[slot].playing = 1;
396 SoundObjects[obj].signature = next_signature++;
397 SoundObjects[obj].handle = slot;
399 SoundObjects[obj].flags |= SOF_PLAYING;
400 //added on 980905 by adb to add sound kill system from original sos digi.c
401 reset_sounds_on_channel(slot);
408 // Play the given sound number.
409 // Volume is max at F1_0.
410 void digi_play_sample( int soundno, fix max_volume )
413 if ( Newdemo_state == ND_STATE_RECORDING )
414 newdemo_record_sound( soundno );
416 soundno = digi_xlat_sound(soundno);
418 if (!digi_initialised) return;
420 if (soundno < 0 ) return;
422 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
425 // Play the given sound number. If the sound is already playing,
427 void digi_play_sample_once( int soundno, fix max_volume )
432 if ( Newdemo_state == ND_STATE_RECORDING )
433 newdemo_record_sound( soundno );
435 soundno = digi_xlat_sound(soundno);
437 if (!digi_initialised) return;
439 if (soundno < 0 ) return;
441 for (i=0; i < MAX_SOUND_SLOTS; i++)
442 if (SoundSlots[i].soundno == soundno)
443 SoundSlots[i].playing = 0;
444 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
448 void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff
453 if ( Newdemo_state == ND_STATE_RECORDING ) {
455 newdemo_record_sound_3d_once( soundno, angle, volume );
457 newdemo_record_sound_3d( soundno, angle, volume );
460 soundno = digi_xlat_sound(soundno);
462 if (!digi_initialised) return;
463 if (soundno < 0 ) return;
465 if (volume < MIN_VOLUME ) return;
466 digi_start_sound(soundno, volume, angle, 0, 0, 0, 0);
469 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 )
471 vms_vector vector_to_sound;
472 fix angle_from_ear, cosang,sinang;
479 max_distance = (max_distance*5)/4; // Make all sounds travel 1.25 times as far.
481 // Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation.
482 distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos );
484 if (distance < max_distance ) {
485 int num_search_segs = f2i(max_distance/20);
486 if ( num_search_segs < 1 ) num_search_segs = 1;
488 path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG );
489 if ( path_distance > -1 ) {
490 *volume = max_volume - fixdiv(path_distance,max_distance);
491 //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume ));
493 angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec);
494 fix_sincos(angle_from_ear,&sinang,&cosang);
495 //mprintf( (0, "volume is %.2f\n", f2fl(*volume) ));
496 if (Config_channels_reversed) cosang *= -1;
497 *pan = (cosang + F1_0)/2;
505 int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance )
511 soundnum = digi_xlat_sound(org_soundnum);
513 if ( max_volume < 0 ) return -1;
514 // if ( max_volume > F1_0 ) max_volume = F1_0;
516 if (!digi_initialised) return -1;
517 if (soundnum < 0 ) return -1;
518 if (GameSounds[soundnum].data==NULL) {
522 if ((objnum<0)||(objnum>Highest_object_index))
526 // Hack to keep sounds from building up...
527 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance );
528 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
532 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
533 if (SoundObjects[i].flags==0)
536 if (i==MAX_SOUND_OBJECTS) {
537 mprintf((1, "Too many sound objects!\n" ));
541 SoundObjects[i].signature=next_signature++;
542 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ;
544 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
545 SoundObjects[i].lo_objnum = objnum;
546 SoundObjects[i].lo_objsignature = Objects[objnum].signature;
547 SoundObjects[i].max_volume = max_volume;
548 SoundObjects[i].max_distance = max_distance;
549 SoundObjects[i].volume = 0;
550 SoundObjects[i].pan = 0;
551 SoundObjects[i].soundnum = soundnum;
553 objp = &Objects[SoundObjects[i].lo_objnum];
554 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
555 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
556 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
558 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
559 digi_start_sound_object(i);
561 return SoundObjects[i].signature;
564 int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume )
565 { return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); }
567 int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance )
572 soundnum = digi_xlat_sound(org_soundnum);
574 if ( max_volume < 0 ) return -1;
575 // if ( max_volume > F1_0 ) max_volume = F1_0;
577 if (!digi_initialised) return -1;
578 if (soundnum < 0 ) return -1;
579 if (GameSounds[soundnum].data==NULL) {
584 if ((segnum<0)||(segnum>Highest_segment_index))
588 // Hack to keep sounds from building up...
589 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance );
590 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
594 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
595 if (SoundObjects[i].flags==0)
598 if (i==MAX_SOUND_OBJECTS) {
599 mprintf((1, "Too many sound objects!\n" ));
604 SoundObjects[i].signature=next_signature++;
605 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS;
607 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
608 SoundObjects[i].lp_segnum = segnum;
609 SoundObjects[i].lp_sidenum = sidenum;
610 SoundObjects[i].lp_position = *pos;
611 SoundObjects[i].soundnum = soundnum;
612 SoundObjects[i].max_volume = max_volume;
613 SoundObjects[i].max_distance = max_distance;
614 SoundObjects[i].volume = 0;
615 SoundObjects[i].pan = 0;
616 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
617 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
618 SoundObjects[i].max_volume,
619 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
621 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
622 digi_start_sound_object(i);
624 return SoundObjects[i].signature;
627 int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume )
629 return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 );
632 void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum )
636 soundnum = digi_xlat_sound(soundnum);
638 if (!digi_initialised) return;
642 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
643 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) ) {
644 if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
645 if ( SoundObjects[i].flags & SOF_PLAYING ) {
646 SoundSlots[SoundObjects[i].handle].playing = 0;
648 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
653 // If this assert happens, it means that there were 2 sounds
654 // that got deleted. Weird, get John.
656 mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum ));
660 void digi_kill_sound_linked_to_object( int objnum )
664 if (!digi_initialised) return;
668 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
669 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
670 if (SoundObjects[i].lo_objnum == objnum) {
671 if ( SoundObjects[i].flags & SOF_PLAYING ) {
672 SoundSlots[SoundObjects[i].handle].playing = 0;
674 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
679 // If this assert happens, it means that there were 2 sounds
680 // that got deleted. Weird, get John.
682 mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum ));
686 void digi_sync_sounds()
689 int oldvolume, oldpan;
691 if (!digi_initialised) return;
693 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
694 if ( SoundObjects[i].flags & SOF_USED ) {
695 oldvolume = SoundObjects[i].volume;
696 oldpan = SoundObjects[i].pan;
698 if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) ) {
699 // Check if its done.
700 if (SoundObjects[i].flags & SOF_PLAYING) {
701 if (!SoundSlots[SoundObjects[i].handle].playing) {
702 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
703 continue; // Go on to next sound...
708 if ( SoundObjects[i].flags & SOF_LINK_TO_POS ) {
709 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
710 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
711 SoundObjects[i].max_volume,
712 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
714 } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) {
717 objp = &Objects[SoundObjects[i].lo_objnum];
719 if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) {
720 // The object that this is linked to is dead, so just end this sound if it is looping.
721 if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
722 SoundSlots[SoundObjects[i].handle].playing = 0;
724 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
725 continue; // Go on to next sound...
727 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
728 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
729 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
733 if (oldvolume != SoundObjects[i].volume) {
734 if ( SoundObjects[i].volume < MIN_VOLUME ) {
735 // Sound is too far away, so stop it from playing.
736 if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
737 SoundSlots[SoundObjects[i].handle].playing = 0;
738 SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing
741 if (!(SoundObjects[i].flags & SOF_PLAYING)) {
742 digi_start_sound_object(i);
744 SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0);
749 if (oldpan != SoundObjects[i].pan) {
750 if (SoundObjects[i].flags & SOF_PLAYING)
751 SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan;
757 void digi_init_sounds()
761 if (!digi_initialised) return;
763 digi_reset_digi_sounds();
765 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
766 if (digi_sounds_initialized) {
767 if ( SoundObjects[i].flags & SOF_PLAYING ) {
768 SoundSlots[SoundObjects[i].handle].playing=0;
771 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
773 digi_sounds_initialized = 1;
776 //added on 980905 by adb from original source to make sfx volume work
777 void digi_set_digi_volume( int dvolume )
779 dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
780 if ( dvolume > SOUND_MAX_VOLUME )
781 digi_volume = SOUND_MAX_VOLUME;
782 else if ( dvolume < 0 )
785 digi_volume = dvolume;
787 if ( !digi_initialised ) return;
793 void digi_set_volume( int dvolume, int mvolume ) { }
795 int digi_is_sound_playing(int soundno)
799 soundno = digi_xlat_sound(soundno);
801 for (i = 0; i < MAX_SOUND_SLOTS; i++)
802 //changed on 980905 by adb: added SoundSlots[i].playing &&
803 if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno)
810 void digi_pause_all() { }
811 void digi_resume_all() { }
812 void digi_stop_all() {
814 // ... Ano. The lack of this was causing ambient sounds to crash.
815 // fixed, added digi_stop_all 07/19/01 - bluecow
817 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
818 if ( SoundObjects[i].flags & SOF_USED ) {
819 SoundSlots[SoundObjects[i].handle].playing = 0;
820 SoundObjects[i].flags = 0;
825 //added on 980905 by adb to make sound channel setting work
826 void digi_set_max_channels(int n) {
827 digi_max_channels = n;
829 if ( digi_max_channels < 1 )
830 digi_max_channels = 1;
831 if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) )
832 digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS);
834 if ( !digi_initialised ) return;
836 digi_reset_digi_sounds();
839 int digi_get_max_channels() {
840 return digi_max_channels;
844 void digi_reset_digi_sounds() {
847 for (i=0; i< MAX_SOUND_SLOTS; i++)
848 SoundSlots[i].playing=0;
850 //added on 980905 by adb to reset sound kill system
851 memset(SampleHandles, 255, sizeof(SampleHandles));
857 // MIDI stuff follows.
858 //added/killed on 11/25/98 by Matthew Mueller
859 //void digi_set_midi_volume( int mvolume ) { }
860 //void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {}
861 //void digi_stop_current_song()
870 //end this section kill - MM