1 // SDL digital audio support
11 #include <SDL/SDL_audio.h>
18 #include "gr.h" // needed for piggy.h
26 int digi_sample_rate=11025;
28 //edited 05/17/99 Matt Mueller - added ifndef NO_ASM
29 //added on 980905 by adb to add inline fixmul for mixer on i386
32 #define do_fixmul(x,y) \
35 asm("imull %2\n\tshrdl %3,%1,%0" \
36 : "=a"(_ax), "=d"(_dx) \
37 : "rm"(y), "i"(16), "0"(x)); \
40 extern inline fix fixmul(fix x, fix y) { return do_fixmul(x,y); }
46 //changed on 980905 by adb to increase number of concurrent sounds
47 #define MAX_SOUND_SLOTS 32
49 #define SOUND_BUFFER_SIZE 512
53 /* This table is used to add two sound values together and pin
54 * the value to avoid overflow. (used with permission from ARDI)
55 * DPH: Taken from SDL/src/SDL_mixer.c.
57 static const Uint8 mix8[] =
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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, 0x01, 0x02, 0x03,
71 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
72 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
73 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
74 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
75 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
76 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
77 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
78 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B,
79 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
80 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
81 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C,
82 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
83 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92,
84 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,
85 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
86 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3,
87 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
88 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9,
89 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
90 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
91 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA,
92 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5,
93 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF,
94 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
95 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
96 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
97 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
98 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
99 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
100 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 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,
108 #define SOF_USED 1 // Set if this sample is used
109 #define SOF_PLAYING 2 // Set if this sample is playing on a channel
110 #define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits.
111 #define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos
112 #define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once
114 typedef struct sound_object {
115 short signature; // A unique signature to this sound
116 ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long.
117 fix max_volume; // Max volume that this sound is playing at
118 fix max_distance; // The max distance that this sound can be heard at...
119 int volume; // Volume that this sound is playing at
120 int pan; // Pan value that this sound is playing at
121 int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set.
122 short soundnum; // The sound number that is playing
125 short segnum; // Used if SOF_LINK_TO_POS field is used
130 short objnum; // Used if SOF_LINK_TO_OBJ field is used
135 #define lp_segnum link.pos.segnum
136 #define lp_sidenum link.pos.sidenum
137 #define lp_position link.pos.position
139 #define lo_objnum link.obj.objnum
140 #define lo_objsignature link.obj.objsignature
142 #define MAX_SOUND_OBJECTS 16
143 sound_object SoundObjects[MAX_SOUND_OBJECTS];
144 short next_signature=0;
146 //added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2
147 #define SOUND_MAX_VOLUME (F1_0 / 2)
149 int digi_volume = SOUND_MAX_VOLUME;
154 static int digi_initialised = 0;
158 int playing; // Is there a sample playing on this channel?
159 int looped; // Play this sample looped?
160 fix pan; // 0 = far left, 1 = far right
161 fix volume; // 0 = nothing, 1 = fully on
162 //changed on 980905 by adb from char * to unsigned char *
163 unsigned char *samples;
165 unsigned int length; // Length of the sample
166 unsigned int position; // Position we are at at the moment.
167 } SoundSlots[MAX_SOUND_SLOTS];
169 static SDL_AudioSpec WaveSpec;
170 static int digi_sounds_initialized = 0;
172 //added on 980905 by adb to add rotating/volume based sound kill system
173 static int digi_max_channels = 16;
174 static int next_handle = 0;
175 int SampleHandles[32];
176 void reset_sounds_on_channel(int channel);
179 void digi_reset_digi_sounds(void);
181 /* Audio mixing callback */
182 //changed on 980905 by adb to cleanup, add pan support and optimize mixer
183 static void audio_mixcallback(void *userdata, Uint8 *stream, int len)
185 Uint8 *streamend = stream + len;
186 struct sound_slot *sl;
188 for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++)
192 Uint8 *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length;
198 if ((x = sl->pan) & 0x8000)
200 vl = 0x20000 - x * 2;
208 vl = fixmul(vl, (x = sl->volume));
210 while (sp < streamend)
219 sldata = sl->samples;
221 v = *(sldata++) - 0x80;
222 *(sp++) = mix8[ *sp + fixmul(v, vl) + 0x80 ];
223 *(sp++) = mix8[ *sp + fixmul(v, vr) + 0x80 ];
225 sl->position = sldata - sl->samples;
231 /* Initialise audio devices. */
235 if (SDL_Init(SDL_INIT_AUDIO) < 0)
237 Warning("SDL library audio initialisation failed: %s.",SDL_GetError());
240 //added on 980905 by adb to init sound kill system
241 memset(SampleHandles, 255, sizeof(SampleHandles));
244 WaveSpec.freq = 11025;
245 //added/changed by Sam Lantinga on 12/01/98 for new SDL version
246 WaveSpec.format = AUDIO_U8;
247 WaveSpec.channels = 2;
248 //end this section addition/change - SL
249 WaveSpec.samples = SOUND_BUFFER_SIZE;
250 WaveSpec.callback = audio_mixcallback;
252 if ( SDL_OpenAudio(&WaveSpec, NULL) < 0 ) {
253 //edited on 10/05/98 by Matt Mueller - should keep running, just with no sound.
254 Warning("\nError: Couldn't open audio: %s\n", SDL_GetError());
262 digi_initialised = 1;
267 void digi_reset() { }
269 /* Shut down audio */
272 if (!digi_initialised) return;
273 digi_initialised = 0;
277 /* Find the sound which actually equates to a sound number */
278 int digi_xlat_sound(int soundno)
280 if ( soundno < 0 ) return -1;
283 soundno = AltSounds[soundno];
284 if ( soundno == 255 ) return -1;
286 return Sounds[soundno];
289 static int get_free_slot()
292 for (i=0; i<MAX_SOUND_SLOTS; i++)
294 if (!SoundSlots[i].playing) return i;
299 int digi_start_sound(int soundnum, fix volume, fix pan, int unknown1, int unknown2, int unknown3, int unknown4)
304 if (!digi_initialised) return -1;
306 //added on 980905 by adb from original source to add sound kill system
307 // play at most digi_max_channel samples, if possible kill sample with low volume
311 if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing) )
313 if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
315 //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
317 if ( next_handle >= digi_max_channels )
322 //mprintf(( 0, "[SS:%d]", next_handle ));
323 SoundSlots[SampleHandles[next_handle]].playing = 0;
324 SampleHandles[next_handle] = -1;
328 slot = get_free_slot();
329 if (slot<0) return -1;
331 SoundSlots[slot].soundno = soundnum;
332 SoundSlots[slot].samples = GameSounds[soundnum].data;
333 SoundSlots[slot].length = GameSounds[soundnum].length;
334 SoundSlots[slot].volume = fixmul(digi_volume, volume);
335 SoundSlots[slot].pan = pan;
336 SoundSlots[slot].position = 0;
337 SoundSlots[slot].looped = 0;
338 SoundSlots[slot].playing = 1;
340 //added on 980905 by adb to add sound kill system from original sos digi.c
341 reset_sounds_on_channel(slot);
342 SampleHandles[next_handle] = slot;
344 if ( next_handle >= digi_max_channels )
351 //added on 980905 by adb to add sound kill system from original sos digi.c
352 void reset_sounds_on_channel( int channel )
356 for (i=0; i<digi_max_channels; i++)
357 if (SampleHandles[i] == channel)
358 SampleHandles[i] = -1;
362 int digi_start_sound_object(int obj)
366 if (!digi_initialised) return -1;
367 slot = get_free_slot();
369 if (slot<0) return -1;
372 SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
373 SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
374 SoundSlots[slot].length = GameSounds[SoundObjects[obj].soundnum].length;
375 SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume);
376 SoundSlots[slot].pan = SoundObjects[obj].pan;
377 SoundSlots[slot].position = 0;
378 SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER);
379 SoundSlots[slot].playing = 1;
381 SoundObjects[obj].signature = next_signature++;
382 SoundObjects[obj].handle = slot;
384 SoundObjects[obj].flags |= SOF_PLAYING;
385 //added on 980905 by adb to add sound kill system from original sos digi.c
386 reset_sounds_on_channel(slot);
393 // Play the given sound number.
394 // Volume is max at F1_0.
395 void digi_play_sample( int soundno, fix max_volume )
398 if ( Newdemo_state == ND_STATE_RECORDING )
399 newdemo_record_sound( soundno );
401 soundno = digi_xlat_sound(soundno);
403 if (!digi_initialised) return;
405 if (soundno < 0 ) return;
407 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
410 // Play the given sound number. If the sound is already playing,
412 void digi_play_sample_once( int soundno, fix max_volume )
417 if ( Newdemo_state == ND_STATE_RECORDING )
418 newdemo_record_sound( soundno );
420 soundno = digi_xlat_sound(soundno);
422 if (!digi_initialised) return;
424 if (soundno < 0 ) return;
426 for (i=0; i < MAX_SOUND_SLOTS; i++)
427 if (SoundSlots[i].soundno == soundno)
428 SoundSlots[i].playing = 0;
429 digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
433 void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff
438 if ( Newdemo_state == ND_STATE_RECORDING ) {
440 newdemo_record_sound_3d_once( soundno, angle, volume );
442 newdemo_record_sound_3d( soundno, angle, volume );
445 soundno = digi_xlat_sound(soundno);
447 if (!digi_initialised) return;
448 if (soundno < 0 ) return;
450 if (volume < MIN_VOLUME ) return;
451 digi_start_sound(soundno, volume, angle, 0, 0, 0, 0);
454 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 )
456 vms_vector vector_to_sound;
457 fix angle_from_ear, cosang,sinang;
464 max_distance = (max_distance*5)/4; // Make all sounds travel 1.25 times as far.
466 // Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation.
467 distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos );
469 if (distance < max_distance ) {
470 int num_search_segs = f2i(max_distance/20);
471 if ( num_search_segs < 1 ) num_search_segs = 1;
473 path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG );
474 if ( path_distance > -1 ) {
475 *volume = max_volume - fixdiv(path_distance,max_distance);
476 //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume ));
478 angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec);
479 fix_sincos(angle_from_ear,&sinang,&cosang);
480 //mprintf( (0, "volume is %.2f\n", f2fl(*volume) ));
481 if (Config_channels_reversed) cosang *= -1;
482 *pan = (cosang + F1_0)/2;
490 int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance )
496 soundnum = digi_xlat_sound(org_soundnum);
498 if ( max_volume < 0 ) return -1;
499 // if ( max_volume > F1_0 ) max_volume = F1_0;
501 if (!digi_initialised) return -1;
502 if (soundnum < 0 ) return -1;
503 if (GameSounds[soundnum].data==NULL) {
507 if ((objnum<0)||(objnum>Highest_object_index))
511 // Hack to keep sounds from building up...
512 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance );
513 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
517 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
518 if (SoundObjects[i].flags==0)
521 if (i==MAX_SOUND_OBJECTS) {
522 mprintf((1, "Too many sound objects!\n" ));
526 SoundObjects[i].signature=next_signature++;
527 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ;
529 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
530 SoundObjects[i].lo_objnum = objnum;
531 SoundObjects[i].lo_objsignature = Objects[objnum].signature;
532 SoundObjects[i].max_volume = max_volume;
533 SoundObjects[i].max_distance = max_distance;
534 SoundObjects[i].volume = 0;
535 SoundObjects[i].pan = 0;
536 SoundObjects[i].soundnum = soundnum;
538 objp = &Objects[SoundObjects[i].lo_objnum];
539 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
540 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
541 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
543 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
544 digi_start_sound_object(i);
546 return SoundObjects[i].signature;
549 int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume )
550 { return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); }
552 int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance )
557 soundnum = digi_xlat_sound(org_soundnum);
559 if ( max_volume < 0 ) return -1;
560 // if ( max_volume > F1_0 ) max_volume = F1_0;
562 if (!digi_initialised) return -1;
563 if (soundnum < 0 ) return -1;
564 if (GameSounds[soundnum].data==NULL) {
569 if ((segnum<0)||(segnum>Highest_segment_index))
573 // Hack to keep sounds from building up...
574 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance );
575 digi_play_sample_3d( org_soundnum, pan, volume, 0 );
579 for (i=0; i<MAX_SOUND_OBJECTS; i++ )
580 if (SoundObjects[i].flags==0)
583 if (i==MAX_SOUND_OBJECTS) {
584 mprintf((1, "Too many sound objects!\n" ));
589 SoundObjects[i].signature=next_signature++;
590 SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS;
592 SoundObjects[i].flags |= SOF_PLAY_FOREVER;
593 SoundObjects[i].lp_segnum = segnum;
594 SoundObjects[i].lp_sidenum = sidenum;
595 SoundObjects[i].lp_position = *pos;
596 SoundObjects[i].soundnum = soundnum;
597 SoundObjects[i].max_volume = max_volume;
598 SoundObjects[i].max_distance = max_distance;
599 SoundObjects[i].volume = 0;
600 SoundObjects[i].pan = 0;
601 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
602 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
603 SoundObjects[i].max_volume,
604 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
606 if (!forever || SoundObjects[i].volume >= MIN_VOLUME)
607 digi_start_sound_object(i);
609 return SoundObjects[i].signature;
612 int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume )
614 return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 );
617 void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum )
621 soundnum = digi_xlat_sound(soundnum);
623 if (!digi_initialised) return;
627 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
628 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) ) {
629 if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
630 if ( SoundObjects[i].flags & SOF_PLAYING ) {
631 SoundSlots[SoundObjects[i].handle].playing = 0;
633 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
638 // If this assert happens, it means that there were 2 sounds
639 // that got deleted. Weird, get John.
641 mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum ));
645 void digi_kill_sound_linked_to_object( int objnum )
649 if (!digi_initialised) return;
653 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
654 if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
655 if (SoundObjects[i].lo_objnum == objnum) {
656 if ( SoundObjects[i].flags & SOF_PLAYING ) {
657 SoundSlots[SoundObjects[i].handle].playing = 0;
659 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
664 // If this assert happens, it means that there were 2 sounds
665 // that got deleted. Weird, get John.
667 mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum ));
671 void digi_sync_sounds()
674 int oldvolume, oldpan;
676 if (!digi_initialised) return;
678 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
679 if ( SoundObjects[i].flags & SOF_USED ) {
680 oldvolume = SoundObjects[i].volume;
681 oldpan = SoundObjects[i].pan;
683 if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) ) {
684 // Check if its done.
685 if (SoundObjects[i].flags & SOF_PLAYING) {
686 if (!SoundSlots[SoundObjects[i].handle].playing) {
687 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
688 continue; // Go on to next sound...
693 if ( SoundObjects[i].flags & SOF_LINK_TO_POS ) {
694 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
695 &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum,
696 SoundObjects[i].max_volume,
697 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
699 } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) {
702 objp = &Objects[SoundObjects[i].lo_objnum];
704 if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) {
705 // The object that this is linked to is dead, so just end this sound if it is looping.
706 if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
707 SoundSlots[SoundObjects[i].handle].playing = 0;
709 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
710 continue; // Go on to next sound...
712 digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum,
713 &objp->pos, objp->segnum, SoundObjects[i].max_volume,
714 &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance );
718 if (oldvolume != SoundObjects[i].volume) {
719 if ( SoundObjects[i].volume < MIN_VOLUME ) {
720 // Sound is too far away, so stop it from playing.
721 if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) {
722 SoundSlots[SoundObjects[i].handle].playing = 0;
723 SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing
726 if (!(SoundObjects[i].flags & SOF_PLAYING)) {
727 digi_start_sound_object(i);
729 SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0);
734 if (oldpan != SoundObjects[i].pan) {
735 if (SoundObjects[i].flags & SOF_PLAYING)
736 SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan;
742 void digi_init_sounds()
746 if (!digi_initialised) return;
748 digi_reset_digi_sounds();
750 for (i=0; i<MAX_SOUND_OBJECTS; i++ ) {
751 if (digi_sounds_initialized) {
752 if ( SoundObjects[i].flags & SOF_PLAYING ) {
753 SoundSlots[SoundObjects[i].handle].playing=0;
756 SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound
758 digi_sounds_initialized = 1;
761 //added on 980905 by adb from original source to make sfx volume work
762 void digi_set_digi_volume( int dvolume )
764 dvolume = fixmuldiv( dvolume, SOUND_MAX_VOLUME, 0x7fff);
765 if ( dvolume > SOUND_MAX_VOLUME )
766 digi_volume = SOUND_MAX_VOLUME;
767 else if ( dvolume < 0 )
770 digi_volume = dvolume;
772 if ( !digi_initialised ) return;
778 void digi_set_volume( int dvolume, int mvolume ) { }
780 int digi_is_sound_playing(int soundno)
784 soundno = digi_xlat_sound(soundno);
786 for (i = 0; i < MAX_SOUND_SLOTS; i++)
787 //changed on 980905 by adb: added SoundSlots[i].playing &&
788 if (SoundSlots[i].playing && SoundSlots[i].soundno == soundno)
795 void digi_pause_all() { }
796 void digi_resume_all() { }
797 void digi_stop_all() { }
799 //added on 980905 by adb to make sound channel setting work
800 void digi_set_max_channels(int n) {
801 digi_max_channels = n;
803 if ( digi_max_channels < 1 )
804 digi_max_channels = 1;
805 if ( digi_max_channels > (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) )
806 digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS);
808 if ( !digi_initialised ) return;
810 digi_reset_digi_sounds();
813 int digi_get_max_channels() {
814 return digi_max_channels;
818 void digi_reset_digi_sounds() {
821 for (i=0; i< MAX_SOUND_SLOTS; i++)
822 SoundSlots[i].playing=0;
824 //added on 980905 by adb to reset sound kill system
825 memset(SampleHandles, 255, sizeof(SampleHandles));
831 // MIDI stuff follows.
832 //added/killed on 11/25/98 by Matthew Mueller
833 //void digi_set_midi_volume( int mvolume ) { }
834 //void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {}
835 //void digi_stop_current_song()
844 //end this section kill - MM