2 * $Source: /cvs/cvsroot/d2x/sound/sdl_digi.c,v $
5 * $Date: 2001-01-29 13:53:28 $
7 * SDL digital audio support
9 * $Log: not supported by cvs2svn $
21 #include <SDL/SDL_audio.h>
28 #include "gr.h" // needed for piggy.h
36 int digi_sample_rate=11025;
38 //edited 05/17/99 Matt Mueller - added ifndef NO_ASM
39 //added on 980905 by adb to add inline fixmul for mixer on i386
42 #define do_fixmul(x,y) \
45 asm("imull %2\n\tshrdl %3,%1,%0" \
46 : "=a"(_ax), "=d"(_dx) \
47 : "rm"(y), "i"(16), "0"(x)); \
50 extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); }
56 //changed on 980905 by adb to increase number of concurrent sounds
57 #define MAX_SOUND_SLOTS 32
59 #define SOUND_BUFFER_SIZE 512
63 /* This table is used to add two sound values together and pin
64 * the value to avoid overflow. (used with permission from ARDI)
65 * DPH: Taken from SDL/src/SDL_mixer.c.
67 static const Uint8 mix8[] =
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, 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, 0x01, 0x02, 0x03,
81 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
82 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
83 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
84 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
85 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
86 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
87 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
88 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
89 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
90 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
91 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
92 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
93 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
94 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
95 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
96 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
97 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
98 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
99 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
100 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
101 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
102 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
103 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 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, 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,
118 #define SOF_USED 1 // Set if this sample is used
119 #define SOF_PLAYING 2 // Set if this sample is playing on a channel
120 #define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits.
121 #define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos
122 #define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once
124 typedef struct sound_object {
125 short signature; // A unique signature to this sound
126 ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long.
127 fix max_volume; // Max volume that this sound is playing at
128 fix max_distance; // The max distance that this sound can be heard at...
129 int volume; // Volume that this sound is playing at
130 int pan; // Pan value that this sound is playing at
131 int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set.
132 short soundnum; // The sound number that is playing
135 short segnum; // Used if SOF_LINK_TO_POS field is used
140 short objnum; // Used if SOF_LINK_TO_OBJ field is used
145 #define lp_segnum link.pos.segnum
146 #define lp_sidenum link.pos.sidenum
147 #define lp_position link.pos.position
149 #define lo_objnum link.obj.objnum
150 #define lo_objsignature link.obj.objsignature
152 #define MAX_SOUND_OBJECTS 16
153 sound_object SoundObjects[MAX_SOUND_OBJECTS];
154 short next_signature=0;
156 //added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2
157 #define SOUND_MAX_VOLUME (F1_0 / 2)
159 int digi_volume = SOUND_MAX_VOLUME;
164 static int digi_initialised = 0;
168 int playing; // Is there a sample playing on this channel?
169 int looped; // Play this sample looped?
170 fix pan; // 0 = far left, 1 = far right
171 fix volume; // 0 = nothing, 1 = fully on
172 //changed on 980905 by adb from char * to unsigned char *
173 unsigned char *samples;
175 unsigned int length; // Length of the sample
176 unsigned int position; // Position we are at at the moment.
177 } SoundSlots[MAX_SOUND_SLOTS];
179 static SDL_AudioSpec WaveSpec;
180 static int digi_sounds_initialized = 0;
182 //added on 980905 by adb to add rotating/volume based sound kill system
183 static int digi_max_channels = 16;
184 static int next_handle = 0;
185 int SampleHandles[32];
186 void reset_sounds_on_channel(int channel);
189 void digi_reset_digi_sounds(void);
191 /* Audio mixing callback */
192 //changed on 980905 by adb to cleanup, add pan support and optimize mixer
193 static void audio_mixcallback(void *userdata, Uint8 *stream, int len)
195 Uint8 *streamend = stream + len;
196 struct sound_slot *sl;
198 for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++)
202 Uint8 *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length;
208 if ((x = sl->pan) & 0x8000)
210 vl = 0x20000 - x * 2;
218 vl = fixmul(vl, (x = sl->volume));
220 while (sp < streamend)
229 sldata = sl->samples;
231 v = *(sldata++) - 0x80;
232 *(sp++) = mix8[ *sp + fixmul(v, vl) + 0x80 ];
233 *(sp++) = mix8[ *sp + fixmul(v, vr) + 0x80 ];
235 sl->position = sldata - sl->samples;
241 /* Initialise audio devices. */
245 if (SDL_Init(SDL_INIT_AUDIO) < 0)
247 Warning("SDL library audio initialisation failed: %s.",SDL_GetError());
250 //added on 980905 by adb to init sound kill system
251 memset(SampleHandles, 255, sizeof(SampleHandles));
254 WaveSpec.freq = 11025;
255 //added/changed by Sam Lantinga on 12/01/98 for new SDL version
256 WaveSpec.format = AUDIO_U8;
257 WaveSpec.channels = 2;
258 //end this section addition/change - SL
259 WaveSpec.samples = SOUND_BUFFER_SIZE;
260 WaveSpec.callback = audio_mixcallback;
262 if ( SDL_OpenAudio(&WaveSpec, NULL) < 0 ) {
263 //edited on 10/05/98 by Matt Mueller - should keep running, just with no sound.
264 Warning("\nError: Couldn't open audio: %s\n", SDL_GetError());
272 digi_initialised = 1;
277 void digi_reset() { }
279 /* Shut down audio */
282 if (!digi_initialised) return;
283 digi_initialised = 0;
287 /* Find the sound which actually equates to a sound number */
288 int digi_xlat_sound(int soundno)
290 if ( soundno < 0 ) return -1;
293 soundno = AltSounds[soundno];
294 if ( soundno == 255 ) return -1;
296 return Sounds[soundno];
299 static int get_free_slot()
302 for (i=0; i<MAX_SOUND_SLOTS; i++)
304 if (!SoundSlots[i].playing) return i;
309 int digi_start_sound(int soundnum, fix volume, fix pan, int unknown1, int unknown2, int unknown3, int unknown4)
314 if (!digi_initialised) return -1;
316 //added on 980905 by adb from original source to add sound kill system
317 // play at most digi_max_channel samples, if possible kill sample with low volume
321 if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing) )
323 if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
325 //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
327 if ( next_handle >= digi_max_channels )
332 //mprintf(( 0, "[SS:%d]", next_handle ));
333 SoundSlots[SampleHandles[next_handle]].playing = 0;
334 SampleHandles[next_handle] = -1;
338 slot = get_free_slot();
339 if (slot<0) return -1;
341 SoundSlots[slot].soundno = soundnum;
342 SoundSlots[slot].samples = GameSounds[soundnum].data;
343 SoundSlots[slot].length = GameSounds[soundnum].length;
344 SoundSlots[slot].volume = fixmul(digi_volume, volume);
345 SoundSlots[slot].pan = pan;
346 SoundSlots[slot].position = 0;
347 SoundSlots[slot].looped = 0;
348 SoundSlots[slot].playing = 1;
350 //added on 980905 by adb to add sound kill system from original sos digi.c
351 reset_sounds_on_channel(slot);
352 SampleHandles[next_handle] = slot;
354 if ( next_handle >= digi_max_channels )
361 //added on 980905 by adb to add sound kill system from original sos digi.c
362 void reset_sounds_on_channel( int channel )
366 for (i=0; i<digi_max_channels; i++)
367 if (SampleHandles[i] == channel)
368 SampleHandles[i] = -1;
372 int digi_start_sound_object(int obj)
376 if (!digi_initialised) return -1;
377 slot = get_free_slot();
379 if (slot<0) return -1;
382 SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
383 SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
384 SoundSlots[slot].length = GameSounds[SoundObjects[obj].soundnum].length;
385 SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
386 SoundSlots[slot].pan = SoundObjects[obj].pan;
387 SoundSlots[slot].position = 0;
388 SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
389 SoundSlots[slot].playing = 1;
391 SoundObjects[obj].signature = next_signature++;
392 SoundObjects[obj].handle = slot;
394 SoundObjects[obj].flags |= SOF_PLAYING;
395 //added on 980905 by adb to add sound kill system from original sos digi.c
396 reset_sounds_on_channel(slot);
403 // Play the given sound number.
404 // Volume is max at F1_0.
405 void digi_play_sample( int soundno, fix max_volume )
408 if ( Newdemo_state == ND_STATE_RECORDING )
409 newdemo_record_sound( soundno );
411 soundno = digi_xlat_sound(soundno);
413 if (!digi_initialised) return;
415 if (soundno < 0 ) return;
417 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
420 // Play the given sound number. If the sound is already playing,
422 void digi_play_sample_once( int soundno, fix max_volume )
427 if ( Newdemo_state == ND_STATE_RECORDING )
428 newdemo_record_sound( soundno );
430 soundno = digi_xlat_sound(soundno);
432 if (!digi_initialised) return;
434 if (soundno < 0 ) return;
436 for (i=0; i < MAX_SOUND_SLOTS; i++)
437 if (SoundSlots[i].soundno == soundno)
438 SoundSlots[i].playing = 0;
439 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
443 void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff
448 if ( Newdemo_state == ND_STATE_RECORDING ) {
450 newdemo_record_sound_3d_once( soundno, angle, volume );
452 newdemo_record_sound_3d( soundno, angle, volume );
455 soundno = digi_xlat_sound(soundno);
457 if (!digi_initialised) return;
458 if (soundno < 0 ) return;
460 if (volume < MIN_VOLUME ) return;
461 digi_start_sound(soundno, volume, angle, 0, 0, 0, 0);
464 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 )
466 vms_vector vector_to_sound;
467 fix angle_from_ear, cosang,sinang;
474 max_distance = (max_distance*5)/4; // Make all sounds travel 1.25 times as far.
476 // Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation.
477 distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos );
479 if (distance < max_distance ) {
480 int num_search_segs = f2i(max_distance/20);
481 if ( num_search_segs < 1 ) num_search_segs = 1;
483 path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG );
484 if ( path_distance > -1 ) {
485 *volume = max_volume - fixdiv(path_distance,max_distance);
486 //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume ));
488 angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec);
489 fix_sincos(angle_from_ear,&sinang,&cosang);
490 //mprintf( (0, "volume is %.2f\n", f2fl(*volume) ));
491 if (Config_channels_reversed) cosang *= -1;
492 *pan = (cosang + F1_0)/2;
500 int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance )
506 soundnum = digi_xlat_sound(org_soundnum);
508 if ( max_volume < 0 ) return -1;
509 // if ( max_volume > F1_0 ) max_volume = F1_0;
511 if (!digi_initialised) return -1;
512 if (soundnum < 0 ) return -1;
513 if (GameSounds[soundnum].data==NULL) {
517 if ((objnum<0)||(objnum>Highest_object_index))
521 // Hack to keep sounds from building up...
522 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance );
523 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
527 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
528 if (SoundObjects[i].flags==0)
531 if (i==MAX_SOUND_OBJECTS) {
532 mprintf((1, "Too many sound objects!\n" ));
536 SoundObjects[i].signature=next_signature++;
537 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ;
539 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
540 SoundObjects[i].lo_objnum = objnum;
541 SoundObjects[i].lo_objsignature = Objects[objnum].signature;
542 SoundObjects[i].max_volume = max_volume;
543 SoundObjects[i].max_distance = max_distance;
544 SoundObjects[i].volume = 0;
545 SoundObjects[i].pan = 0;
546 SoundObjects[i].soundnum = soundnum;
548 objp = &Objects[SoundObjects[i].lo_objnum];
549 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
550 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
551 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
553 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
554 digi_start_sound_object(i);
556 return SoundObjects[i].signature;
559 int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume )
560 { return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); }
562 int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance )
567 soundnum = digi_xlat_sound(org_soundnum);
569 if ( max_volume < 0 ) return -1;
570 // if ( max_volume > F1_0 ) max_volume = F1_0;
572 if (!digi_initialised) return -1;
573 if (soundnum < 0 ) return -1;
574 if (GameSounds[soundnum].data==NULL) {
579 if ((segnum<0)||(segnum>Highest_segment_index))
583 // Hack to keep sounds from building up...
584 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance );
585 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
589 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
590 if (SoundObjects[i].flags==0)
593 if (i==MAX_SOUND_OBJECTS) {
594 mprintf((1, "Too many sound objects!\n" ));
599 SoundObjects[i].signature=next_signature++;
600 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS;
602 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
603 SoundObjects[i].lp_segnum = segnum;
604 SoundObjects[i].lp_sidenum = sidenum;
605 SoundObjects[i].lp_position = *pos;
606 SoundObjects[i].soundnum = soundnum;
607 SoundObjects[i].max_volume = max_volume;
608 SoundObjects[i].max_distance = max_distance;
609 SoundObjects[i].volume = 0;
610 SoundObjects[i].pan = 0;
611 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
612 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
613 SoundObjects[i].max_volume,
614 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
616 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
617 digi_start_sound_object(i);
619 return SoundObjects[i].signature;
622 int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume )
624 return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 );
627 void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum )
631 soundnum = digi_xlat_sound(soundnum);
633 if (!digi_initialised) return;
637 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
638 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) ) {
639 if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
640 if ( SoundObjects[i].flags & SOF_PLAYING ) {
641 SoundSlots[SoundObjects[i].handle].playing = 0;
643 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
648 // If this assert happens, it means that there were 2 sounds
649 // that got deleted. Weird, get John.
651 mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum ));
655 void digi_kill_sound_linked_to_object( int objnum )
659 if (!digi_initialised) return;
663 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
664 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
665 if (SoundObjects[i].lo_objnum == objnum) {
666 if ( SoundObjects[i].flags & SOF_PLAYING ) {
667 SoundSlots[SoundObjects[i].handle].playing = 0;
669 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
674 // If this assert happens, it means that there were 2 sounds
675 // that got deleted. Weird, get John.
677 mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum ));
681 void digi_sync_sounds()
684 int oldvolume, oldpan;
686 if (!digi_initialised) return;
688 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
689 if ( SoundObjects[i].flags & SOF_USED ) {
690 oldvolume = SoundObjects[i].volume;
691 oldpan = SoundObjects[i].pan;
693 if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) ) {
694 // Check if its done.
695 if (SoundObjects[i].flags & SOF_PLAYING) {
696 if (!SoundSlots[SoundObjects[i].handle].playing) {
697 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
698 continue; // Go on to next sound...
703 if ( SoundObjects[i].flags & SOF_LINK_TO_POS ) {
704 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
705 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
706 SoundObjects[i].max_volume,
707 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
709 } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) {
712 objp = &Objects[SoundObjects[i].lo_objnum];
714 if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) {
715 // The object that this is linked to is dead, so just end this sound if it is looping.
716 if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
717 SoundSlots[SoundObjects[i].handle].playing = 0;
719 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
720 continue; // Go on to next sound...
722 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
723 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
724 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
728 if (oldvolume != SoundObjects[i].volume) {
729 if ( SoundObjects[i].volume < MIN_VOLUME ) {
730 // Sound is too far away, so stop it from playing.
731 if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
732 SoundSlots[SoundObjects[i].handle].playing = 0;
733 SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing
736 if (!(SoundObjects[i].flags & SOF_PLAYING)) {
737 digi_start_sound_object(i);
739 SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0);
744 if (oldpan != SoundObjects[i].pan) {
745 if (SoundObjects[i].flags & SOF_PLAYING)
746 SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan;
752 void digi_init_sounds()
756 if (!digi_initialised) return;
758 digi_reset_digi_sounds();
760 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
761 if (digi_sounds_initialized) {
762 if ( SoundObjects[i].flags & SOF_PLAYING ) {
763 SoundSlots[SoundObjects[i].handle].playing=0;
766 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
768 digi_sounds_initialized = 1;
771 //added on 980905 by adb from original source to make sfx volume work
772 void digi_set_digi_volume( int dvolume )
774 dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
775 if ( dvolume > SOUND_MAX_VOLUME )
776 digi_volume = SOUND_MAX_VOLUME;
777 else if ( dvolume < 0 )
780 digi_volume = dvolume;
782 if ( !digi_initialised ) return;
788 void digi_set_volume( int dvolume, int mvolume ) { }
790 int digi_is_sound_playing(int soundno)
794 soundno = digi_xlat_sound(soundno);
796 for (i = 0; i < MAX_SOUND_SLOTS; i++)
797 //changed on 980905 by adb: added SoundSlots[i].playing &&
798 if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno)
805 void digi_pause_all() { }
806 void digi_resume_all() { }
807 void digi_stop_all() { }
809 //added on 980905 by adb to make sound channel setting work
810 void digi_set_max_channels(int n) {
811 digi_max_channels = n;
813 if ( digi_max_channels < 1 )
814 digi_max_channels = 1;
815 if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) )
816 digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS);
818 if ( !digi_initialised ) return;
820 digi_reset_digi_sounds();
823 int digi_get_max_channels() {
824 return digi_max_channels;
828 void digi_reset_digi_sounds() {
831 for (i=0; i< MAX_SOUND_SLOTS; i++)
832 SoundSlots[i].playing=0;
834 //added on 980905 by adb to reset sound kill system
835 memset(SampleHandles, 255, sizeof(SampleHandles));
841 // MIDI stuff follows.
842 //added/killed on 11/25/98 by Matthew Mueller
843 //void digi_set_midi_volume( int mvolume ) { }
844 //void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {}
845 //void digi_stop_current_song()
854 //end this section kill - MM