1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-98 Artsoft Entertainment *
8 * phone: ++49 +521 290471 *
9 * email: aeglos@valinor.owl.de *
10 *----------------------------------------------------------*
12 ***********************************************************/
18 extern void sound_handler(struct SoundControl);
21 /*** THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
24 static struct SoundControl playlist[MAX_SOUNDS_PLAYING];
25 static struct SoundControl emptySoundControl =
27 -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE, 0,0L,0L,NULL
29 static int stereo_volume[PSND_MAX_LEFT2RIGHT+1];
30 static char premix_first_buffer[SND_BLOCKSIZE];
32 static char premix_left_buffer[SND_BLOCKSIZE];
33 static char premix_right_buffer[SND_BLOCKSIZE];
34 static int premix_last_buffer[SND_BLOCKSIZE];
36 static unsigned char playing_buffer[SND_BLOCKSIZE];
37 static int playing_sounds = 0;
39 struct SoundControl playlist[MAX_SOUNDS_PLAYING];
40 struct SoundControl emptySoundControl;
48 struct SoundControl snd_ctrl;
51 close(sound_pipe[1]); /* no writing into pipe needed */
54 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
55 playlist[i] = emptySoundControl;
59 stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
60 for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
62 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
68 FD_ZERO(&sound_fdset);
69 FD_SET(sound_pipe[0], &sound_fdset);
71 for(;;) /* wait for calls from PlaySound(), StopSound(), ... */
73 FD_SET(sound_pipe[0], &sound_fdset);
74 select(sound_pipe[0]+1, &sound_fdset, NULL, NULL, NULL);
75 if (!FD_ISSET(sound_pipe[0], &sound_fdset))
77 if (read(sound_pipe[0], &snd_ctrl, sizeof(snd_ctrl)) != sizeof(snd_ctrl))
78 Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
82 if (snd_ctrl.fade_sound)
87 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
88 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
89 playlist[i].fade_sound = TRUE;
91 else if (snd_ctrl.stop_all_sounds)
96 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
97 playlist[i]=emptySoundControl;
102 else if (snd_ctrl.stop_sound)
107 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
108 if (playlist[i].nr == snd_ctrl.nr)
110 playlist[i]=emptySoundControl;
118 if (playing_sounds || snd_ctrl.active)
120 struct timeval delay = { 0, 0 };
123 long max_sample_size; /* MIGHT BE USED UNINITIALIZED! TO BE FIXED! */
127 if (playing_sounds || (sound_device=open(sound_device_name,O_WRONLY))>=0)
129 if (!playing_sounds) /* we just opened the audio device */
131 /* 2 buffers / 512 bytes, giving 1/16 second resolution */
132 /* (with stereo the effective buffer size will shrink to 256) */
133 fragment_size = 0x00020009;
134 ioctl(sound_device, SNDCTL_DSP_SETFRAGMENT, &fragment_size);
135 /* try if we can use stereo sound */
137 ioctl(sound_device, SNDCTL_DSP_STEREO, &stereo);
138 /* get the real fragmentation size; this should return 512 */
139 ioctl(sound_device, SNDCTL_DSP_GETBLKSIZE, &fragment_size);
140 max_sample_size = fragment_size / (stereo ? 2 : 1);
143 if (snd_ctrl.active) /* new sound has arrived */
144 SoundServer_InsertNewSound(snd_ctrl);
146 while(playing_sounds &&
147 select(sound_pipe[0]+1,&sound_fdset,NULL,NULL,&delay)<1)
149 FD_SET(sound_pipe[0], &sound_fdset);
151 /* first clear the last premixing buffer */
152 memset(premix_last_buffer,0,fragment_size*sizeof(int));
154 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
158 if (!playlist[i].active)
161 /* get pointer and size of the actual sound sample */
162 sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
164 MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
165 playlist[i].playingpos += sample_size;
167 /* fill the first mixing buffer with original sample */
168 memcpy(premix_first_buffer,sample_ptr,sample_size);
170 /* are we about to restart a looping sound? */
171 if (playlist[i].loop && sample_size<max_sample_size)
173 playlist[i].playingpos = max_sample_size-sample_size;
174 memcpy(premix_first_buffer+sample_size,
175 playlist[i].data_ptr,max_sample_size-sample_size);
176 sample_size = max_sample_size;
179 /* decrease volume if sound is fading out */
180 if (playlist[i].fade_sound &&
181 playlist[i].volume>=PSND_MAX_VOLUME/10)
182 playlist[i].volume-=PSND_MAX_VOLUME/20;
184 /* adjust volume of actual sound sample */
185 if (playlist[i].volume != PSND_MAX_VOLUME)
186 for(j=0;j<sample_size;j++)
187 premix_first_buffer[j] =
188 (playlist[i].volume * (int)premix_first_buffer[j])
189 >> PSND_MAX_VOLUME_BITS;
191 /* fill the last mixing buffer with stereo or mono sound */
194 int middle_pos = PSND_MAX_LEFT2RIGHT/2;
195 int left_volume = stereo_volume[middle_pos+playlist[i].stereo];
196 int right_volume = stereo_volume[middle_pos-playlist[i].stereo];
198 for(j=0;j<sample_size;j++)
200 premix_left_buffer[j] =
201 (left_volume * (int)premix_first_buffer[j])
202 >> PSND_MAX_LEFT2RIGHT_BITS;
203 premix_right_buffer[j] =
204 (right_volume * (int)premix_first_buffer[j])
205 >> PSND_MAX_LEFT2RIGHT_BITS;
206 premix_last_buffer[2*j+0] += premix_left_buffer[j];
207 premix_last_buffer[2*j+1] += premix_right_buffer[j];
212 for(j=0;j<sample_size;j++)
213 premix_last_buffer[j] += (int)premix_first_buffer[j];
216 /* delete completed sound entries from the playlist */
217 if (playlist[i].playingpos >= playlist[i].data_len)
219 if (playlist[i].loop)
220 playlist[i].playingpos = 0;
223 playlist[i] = emptySoundControl;
227 else if (playlist[i].volume <= PSND_MAX_VOLUME/10)
229 playlist[i] = emptySoundControl;
234 /* put last mixing buffer to final playing buffer */
235 for(i=0;i<fragment_size;i++)
237 if (premix_last_buffer[i]<-255)
238 playing_buffer[i] = 0;
239 else if (premix_last_buffer[i]>255)
240 playing_buffer[i] = 255;
242 playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80;
245 /* finally play the sound fragment */
246 write(sound_device,playing_buffer,fragment_size);
249 /* if no sounds playing, free device for other sound programs */
257 if (snd_ctrl.active && !snd_ctrl.loop)
259 struct timeval delay = { 0, 0 };
261 long sample_size, max_sample_size = SND_BLOCKSIZE;
262 long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
263 int wait_percent = 90; /* wait 90% of the real playing time */
266 if ((sound_device=open(sound_device_name,O_WRONLY))>=0)
270 while(playing_sounds &&
271 select(sound_pipe[0]+1,&sound_fdset,NULL,NULL,&delay)<1)
273 FD_SET(sound_pipe[0], &sound_fdset);
275 /* get pointer and size of the actual sound sample */
276 sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
278 MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
279 snd_ctrl.playingpos += sample_size;
281 /* fill the first mixing buffer with original sample */
282 memcpy(premix_first_buffer,sample_ptr,sample_size);
285 /* adjust volume of actual sound sample */
286 if (snd_ctrl.volume != PSND_MAX_VOLUME)
287 for(i=0;i<sample_size;i++)
288 premix_first_buffer[i] =
289 (snd_ctrl.volume * (int)premix_first_buffer[i])
290 >> PSND_MAX_VOLUME_BITS;
292 for(i=0;i<sample_size;i++)
294 linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
296 if (snd_ctrl.playingpos >= snd_ctrl.data_len)
299 /* finally play the sound fragment */
300 write(sound_device,playing_buffer,sample_size);
303 delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
309 #endif /* !VOXWARE */
315 void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
319 /* wenn voll, ältesten Sound 'rauswerfen */
320 if (playing_sounds==MAX_SOUNDS_PLAYING)
322 int longest=0, longest_nr=0;
324 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
327 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
329 int actual = playlist[i].playingpos;
332 if (!playlist[i].loop && actual>longest)
339 voice_set_volume(playlist[longest_nr].voice, 0);
340 deallocate_voice(playlist[longest_nr].voice);
342 playlist[longest_nr] = emptySoundControl;
346 /* nachsehen, ob (und ggf. wie oft) Sound bereits gespielt wird */
347 for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
349 if (playlist[i].nr == snd_ctrl.nr)
353 /* falls Sound-Loop: nur neu beginnen, wenn Sound gerade ausklingt */
354 if (k>=1 && snd_ctrl.loop)
356 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
358 if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
360 playlist[i].fade_sound = FALSE;
361 playlist[i].volume = PSND_MAX_VOLUME;
363 playlist[i].loop = PSND_LOOP;
364 voice_stop_volumeramp(playlist[i].voice);
365 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
372 /* keinen Sound mehr als n mal gleichzeitig spielen (momentan n==2) */
375 int longest=0, longest_nr=0;
377 /* den bereits am längsten gespielten (gleichen) Sound suchen */
378 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
382 if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
386 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
388 actual = playlist[i].playingpos;
397 voice_set_volume(playlist[longest_nr].voice, 0);
398 deallocate_voice(playlist[longest_nr].voice);
400 playlist[longest_nr] = emptySoundControl;
404 /* neuen Sound in Liste packen */
405 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
407 if (!playlist[i].active)
409 playlist[i] = snd_ctrl;
412 playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
414 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
415 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
416 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
417 voice_start(playlist[i].voice);
425 void SoundServer_FadeSound(int nr)
432 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
433 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
434 playlist[i].fade_sound = TRUE;
438 void SoundServer_StopSound(int nr)
445 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
446 if (playlist[i].nr == nr)
449 voice_set_volume(playlist[i].voice, 0);
450 deallocate_voice(playlist[i].voice);
452 playlist[i] = emptySoundControl;
462 void SoundServer_StopAllSounds()
466 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
469 voice_set_volume(playlist[i].voice, 0);
470 deallocate_voice(playlist[i].voice);
472 playlist[i]=emptySoundControl;
482 void HPUX_Audio_Control()
484 struct audio_describe ainfo;
487 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
489 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl - no sounds");
491 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
492 Error(ERR_EXIT_SOUND_SERVER, "no audio info - no sounds");
494 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
495 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available - no sounds");
497 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
498 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
502 #endif /* HPUX_AUDIO */
504 /* these two are stolen from "sox"... :) */
507 ** This routine converts from linear to ulaw.
509 ** Craig Reese: IDA/Supercomputing Research Center
510 ** Joe Campbell: Department of Defense
514 ** 1) CCITT Recommendation G.711 (very difficult to follow)
515 ** 2) "A New Digital Technique for Implementation of Any
516 ** Continuous PCM Companding Law," Villeret, Michel,
517 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
518 ** 1973, pg. 11.12-11.17
519 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
520 ** for Analog-to_Digital Conversion Techniques,"
523 ** Input: Signed 16 bit linear sample
524 ** Output: 8 bit ulaw sample
527 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
528 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
531 unsigned char linear_to_ulaw(int sample)
533 static int exp_lut[256] =
535 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
536 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
537 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
538 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
539 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
540 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
541 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
542 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
543 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
544 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
545 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
546 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
547 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
548 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
549 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
550 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
553 int sign, exponent, mantissa;
554 unsigned char ulawbyte;
556 /* Get the sample into sign-magnitude. */
557 sign = (sample >> 8) & 0x80; /* set aside the sign */
559 sample = -sample; /* get magnitude */
561 sample = CLIP; /* clip the magnitude */
563 /* Convert from 16 bit linear to ulaw. */
564 sample = sample + BIAS;
565 exponent = exp_lut[( sample >> 7 ) & 0xFF];
566 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
567 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
570 ulawbyte = 0x02; /* optional CCITT trap */
577 ** This routine converts from ulaw to 16 bit linear.
579 ** Craig Reese: IDA/Supercomputing Research Center
583 ** 1) CCITT Recommendation G.711 (very difficult to follow)
584 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
585 ** for Analog-to_Digital Conversion Techniques,"
588 ** Input: 8 bit ulaw sample
589 ** Output: signed 16 bit linear sample
592 int ulaw_to_linear(unsigned char ulawbyte)
594 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
595 int sign, exponent, mantissa, sample;
597 ulawbyte = ~ ulawbyte;
598 sign = ( ulawbyte & 0x80 );
599 exponent = ( ulawbyte >> 4 ) & 0x07;
600 mantissa = ulawbyte & 0x0F;
601 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
608 /*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
610 /*===========================================================================*/
612 /*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/
615 static unsigned long be2long(unsigned long *be) /* big-endian -> longword */
617 unsigned char *ptr = (unsigned char *)be;
619 return(ptr[0]<<24 | ptr[1]<<16 | ptr[2]<<8 | ptr[3]);
622 static unsigned long le2long(unsigned long *be) /* little-endian -> longword */
624 unsigned char *ptr = (unsigned char *)be;
626 return(ptr[3]<<24 | ptr[2]<<16 | ptr[1]<<8 | ptr[0]);
630 boolean LoadSound(struct SoundInfo *snd_info)
634 char *sound_ext = "wav";
636 struct SoundHeader_WAV *sound_header;
640 sprintf(filename, "%s/%s/%s.%s",
641 options.base_directory, SOUNDS_DIRECTORY, snd_info->name, sound_ext);
644 if ((file = fopen(filename, "r")) == NULL)
646 Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
650 if (fseek(file, 0, SEEK_END) < 0)
652 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
657 snd_info->file_len = ftell(file);
660 snd_info->file_ptr = checked_malloc(snd_info->file_len);
662 if (fread(snd_info->file_ptr, 1, snd_info->file_len, file) !=
665 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
672 sound_header = (struct SoundHeader_WAV *)snd_info->file_ptr;
674 if (strncmp(sound_header->magic_RIFF, "RIFF", 4) ||
675 snd_info->file_len != le2long(&sound_header->header_size) + 8 ||
676 strncmp(sound_header->magic_WAVE, "WAVE", 4) ||
677 strncmp(sound_header->magic_DATA, "data", 4) ||
678 snd_info->file_len != le2long(&sound_header->data_size) + 44)
680 Error(ERR_WARN, "'%s' is not a RIFF/WAVE file or broken - no sounds",
685 snd_info->data_ptr = snd_info->file_ptr + 44;
686 snd_info->data_len = le2long(&sound_header->data_size);
688 for (i=0; i<snd_info->data_len; i++)
689 snd_info->data_ptr[i] = snd_info->data_ptr[i]^0x80;
693 snd_info->sample_ptr = load_sample(filename);
694 if (!snd_info->sample_ptr)
696 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
705 boolean LoadSound_8SVX(struct SoundInfo *snd_info)
710 struct SoundHeader_8SVX *sound_header;
712 char *sound_ext = "8svx";
714 char *sound_ext = "wav";
717 sprintf(filename, "%s/%s/%s.%s",
718 options.base_directory, SOUNDS_DIRECTORY, snd_info->name, sound_ext);
721 if (!(file=fopen(filename,"r")))
723 Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
727 if (fseek(file,0,SEEK_END)<0)
729 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
734 snd_info->file_len = ftell(file);
737 if (!(snd_info->file_ptr=malloc(snd_info->file_len)))
739 Error(ERR_WARN, "out of memory (this shouldn't happen :) - no sounds");
744 if (fread(snd_info->file_ptr,1,snd_info->file_len,file)!=snd_info->file_len)
746 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
753 sound_header = (struct SoundHeader_8SVX *)snd_info->file_ptr;
755 if (strncmp(sound_header->magic_FORM,"FORM",4) ||
756 snd_info->file_len != be2long(&sound_header->chunk_size)+8 ||
757 strncmp(sound_header->magic_8SVX,"8SVX",4))
759 Error(ERR_WARN, "'%s' is not an IFF/8SVX file or broken - no sounds",
764 ptr = (char *)snd_info->file_ptr + 12;
766 while(ptr < (char *)(snd_info->file_ptr + snd_info->file_len))
768 if (!strncmp(ptr,"VHDR",4))
770 ptr += be2long((unsigned long *)(ptr + 4)) + 8;
773 else if (!strncmp(ptr,"ANNO",4))
775 ptr += be2long((unsigned long *)(ptr + 4)) + 8;
778 else if (!strncmp(ptr,"CHAN",4))
780 ptr += be2long((unsigned long *)(ptr + 4)) + 8;
783 else if (!strncmp(ptr,"BODY",4))
785 snd_info->data_ptr = (byte *)ptr + 8;
786 snd_info->data_len = be2long((unsigned long *)(ptr + 4));
791 /* other chunk not recognized here */
792 ptr += be2long((unsigned long *)(ptr + 4)) + 8;
799 snd_info->sample_ptr = load_sample(filename);
800 if(!snd_info->sample_ptr)
802 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
810 void PlaySound(int nr)
812 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
815 void PlaySoundStereo(int nr, int stereo)
817 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
820 void PlaySoundLoop(int nr)
822 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
825 void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
827 struct SoundControl snd_ctrl = emptySoundControl;
829 if (sound_status==SOUND_OFF || !setup.sound)
832 if (volume<PSND_MIN_VOLUME)
833 volume = PSND_MIN_VOLUME;
834 else if (volume>PSND_MAX_VOLUME)
835 volume = PSND_MAX_VOLUME;
837 if (stereo<PSND_MAX_LEFT)
838 stereo = PSND_MAX_LEFT;
839 else if (stereo>PSND_MAX_RIGHT)
840 stereo = PSND_MAX_RIGHT;
843 snd_ctrl.volume = volume;
844 snd_ctrl.stereo = stereo;
845 snd_ctrl.loop = loop;
846 snd_ctrl.active = TRUE;
847 snd_ctrl.data_ptr = Sound[nr].data_ptr;
848 snd_ctrl.data_len = Sound[nr].data_len;
851 if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
853 Error(ERR_WARN, "cannot pipe to child process - no sounds");
854 sound_status = SOUND_OFF;
858 sound_handler(snd_ctrl);
862 void FadeSound(int nr)
864 StopSoundExt(nr, SSND_FADE_SOUND);
869 StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
872 void StopSound(int nr)
874 StopSoundExt(nr, SSND_STOP_SOUND);
879 StopSoundExt(-1, SSND_STOP_ALL_SOUNDS);
882 void StopSoundExt(int nr, int method)
884 struct SoundControl snd_ctrl = emptySoundControl;
886 if (sound_status==SOUND_OFF)
889 if (SSND_FADING(method))
890 snd_ctrl.fade_sound = TRUE;
892 if (SSND_ALL(method))
893 snd_ctrl.stop_all_sounds = TRUE;
897 snd_ctrl.stop_sound = TRUE;
901 if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
903 Error(ERR_WARN, "cannot pipe to child process - no sounds");
904 sound_status = SOUND_OFF;
908 sound_handler(snd_ctrl);
912 void FreeSounds(int max)
916 if (sound_status==SOUND_OFF)
921 free(Sound[i].file_ptr);
923 destroy_sample(Sound[i].sample_ptr);
927 /*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/