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 ***********************************************************/
17 /*** THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
19 static int playing_sounds = 0;
20 static struct SoundControl playlist[MAX_SOUNDS_PLAYING];
21 static struct SoundControl emptySoundControl =
23 -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE, 0,0L,0L,NULL
27 static int stereo_volume[PSND_MAX_LEFT2RIGHT+1];
28 static char premix_first_buffer[SND_BLOCKSIZE];
30 static char premix_left_buffer[SND_BLOCKSIZE];
31 static char premix_right_buffer[SND_BLOCKSIZE];
32 static int premix_last_buffer[SND_BLOCKSIZE];
34 static unsigned char playing_buffer[SND_BLOCKSIZE];
37 /* forward declaration of internal functions */
39 static void SoundServer_InsertNewSound(struct SoundControl);
43 static unsigned char linear_to_ulaw(int);
44 static int ulaw_to_linear(unsigned char);
48 static void HPUX_Audio_Control();
51 static void SoundServer_InsertNewSound(struct SoundControl);
52 static void SoundServer_StopSound(int);
53 static void SoundServer_StopAllSounds();
60 struct SoundControl snd_ctrl;
63 close(sound_pipe[1]); /* no writing into pipe needed */
66 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
67 playlist[i] = emptySoundControl;
71 stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
72 for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
74 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
80 FD_ZERO(&sound_fdset);
81 FD_SET(sound_pipe[0], &sound_fdset);
83 while(1) /* wait for sound playing commands from client */
85 FD_SET(sound_pipe[0], &sound_fdset);
86 select(sound_pipe[0]+1, &sound_fdset, NULL, NULL, NULL);
87 if (!FD_ISSET(sound_pipe[0], &sound_fdset))
89 if (read(sound_pipe[0], &snd_ctrl, sizeof(snd_ctrl)) != sizeof(snd_ctrl))
90 Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
94 if (snd_ctrl.fade_sound)
99 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
100 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
101 playlist[i].fade_sound = TRUE;
103 else if (snd_ctrl.stop_all_sounds)
108 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
109 playlist[i]=emptySoundControl;
114 else if (snd_ctrl.stop_sound)
119 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
120 if (playlist[i].nr == snd_ctrl.nr)
122 playlist[i]=emptySoundControl;
130 if (playing_sounds || snd_ctrl.active)
132 struct timeval delay = { 0, 0 };
135 static long max_sample_size = 0;
136 static long fragment_size = 0;
137 /* Even if the stereo flag is used as being boolean, it must be
138 defined as an integer, else 'ioctl()' will fail! */
140 int sample_rate = 8000;
142 if (playing_sounds || (sound_device=open(sound_device_name,O_WRONLY))>=0)
144 if (!playing_sounds) /* we just opened the audio device */
146 /* 2 buffers / 512 bytes, giving 1/16 second resolution */
147 /* (with stereo the effective buffer size will shrink to 256) */
148 fragment_size = 0x00020009;
150 if (ioctl(sound_device, SNDCTL_DSP_SETFRAGMENT, &fragment_size) < 0)
151 Error(ERR_EXIT_SOUND_SERVER,
152 "cannot set fragment size of /dev/dsp - no sounds");
154 /* try if we can use stereo sound */
155 if (ioctl(sound_device, SNDCTL_DSP_STEREO, &stereo) < 0)
158 static boolean reported = FALSE;
162 Error(ERR_RETURN, "cannot get stereo sound on /dev/dsp");
169 if (ioctl(sound_device, SNDCTL_DSP_SPEED, &sample_rate) < 0)
170 Error(ERR_EXIT_SOUND_SERVER,
171 "cannot set sample rate of /dev/dsp - no sounds");
173 /* get the real fragmentation size; this should return 512 */
174 if (ioctl(sound_device, SNDCTL_DSP_GETBLKSIZE, &fragment_size) < 0)
175 Error(ERR_EXIT_SOUND_SERVER,
176 "cannot get fragment size of /dev/dsp - no sounds");
178 max_sample_size = fragment_size / (stereo ? 2 : 1);
181 if (snd_ctrl.active) /* new sound has arrived */
182 SoundServer_InsertNewSound(snd_ctrl);
184 while(playing_sounds &&
185 select(sound_pipe[0]+1,&sound_fdset,NULL,NULL,&delay)<1)
187 FD_SET(sound_pipe[0], &sound_fdset);
189 /* first clear the last premixing buffer */
190 memset(premix_last_buffer,0,fragment_size*sizeof(int));
192 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
196 if (!playlist[i].active)
199 /* get pointer and size of the actual sound sample */
200 sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
202 MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
203 playlist[i].playingpos += sample_size;
205 /* fill the first mixing buffer with original sample */
206 memcpy(premix_first_buffer,sample_ptr,sample_size);
208 /* are we about to restart a looping sound? */
209 if (playlist[i].loop && sample_size<max_sample_size)
211 playlist[i].playingpos = max_sample_size-sample_size;
212 memcpy(premix_first_buffer+sample_size,
213 playlist[i].data_ptr,max_sample_size-sample_size);
214 sample_size = max_sample_size;
217 /* decrease volume if sound is fading out */
218 if (playlist[i].fade_sound &&
219 playlist[i].volume>=PSND_MAX_VOLUME/10)
220 playlist[i].volume-=PSND_MAX_VOLUME/20;
222 /* adjust volume of actual sound sample */
223 if (playlist[i].volume != PSND_MAX_VOLUME)
224 for(j=0;j<sample_size;j++)
225 premix_first_buffer[j] =
226 (playlist[i].volume * (int)premix_first_buffer[j])
227 >> PSND_MAX_VOLUME_BITS;
229 /* fill the last mixing buffer with stereo or mono sound */
232 int middle_pos = PSND_MAX_LEFT2RIGHT/2;
233 int left_volume = stereo_volume[middle_pos+playlist[i].stereo];
234 int right_volume = stereo_volume[middle_pos-playlist[i].stereo];
236 for(j=0;j<sample_size;j++)
238 premix_left_buffer[j] =
239 (left_volume * (int)premix_first_buffer[j])
240 >> PSND_MAX_LEFT2RIGHT_BITS;
241 premix_right_buffer[j] =
242 (right_volume * (int)premix_first_buffer[j])
243 >> PSND_MAX_LEFT2RIGHT_BITS;
244 premix_last_buffer[2*j+0] += premix_left_buffer[j];
245 premix_last_buffer[2*j+1] += premix_right_buffer[j];
250 for(j=0;j<sample_size;j++)
251 premix_last_buffer[j] += (int)premix_first_buffer[j];
254 /* delete completed sound entries from the playlist */
255 if (playlist[i].playingpos >= playlist[i].data_len)
257 if (playlist[i].loop)
258 playlist[i].playingpos = 0;
261 playlist[i] = emptySoundControl;
265 else if (playlist[i].volume <= PSND_MAX_VOLUME/10)
267 playlist[i] = emptySoundControl;
272 /* put last mixing buffer to final playing buffer */
273 for(i=0;i<fragment_size;i++)
275 if (premix_last_buffer[i]<-255)
276 playing_buffer[i] = 0;
277 else if (premix_last_buffer[i]>255)
278 playing_buffer[i] = 255;
280 playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80;
283 /* finally play the sound fragment */
284 write(sound_device,playing_buffer,fragment_size);
287 /* if no sounds playing, free device for other sound programs */
295 if (snd_ctrl.active && !snd_ctrl.loop)
297 struct timeval delay = { 0, 0 };
299 long sample_size, max_sample_size = SND_BLOCKSIZE;
300 long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
301 int wait_percent = 90; /* wait 90% of the real playing time */
304 if ((sound_device=open(sound_device_name,O_WRONLY))>=0)
308 while(playing_sounds &&
309 select(sound_pipe[0]+1,&sound_fdset,NULL,NULL,&delay)<1)
311 FD_SET(sound_pipe[0], &sound_fdset);
313 /* get pointer and size of the actual sound sample */
314 sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
316 MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
317 snd_ctrl.playingpos += sample_size;
319 /* fill the first mixing buffer with original sample */
320 memcpy(premix_first_buffer,sample_ptr,sample_size);
323 /* adjust volume of actual sound sample */
324 if (snd_ctrl.volume != PSND_MAX_VOLUME)
325 for(i=0;i<sample_size;i++)
326 premix_first_buffer[i] =
327 (snd_ctrl.volume * (int)premix_first_buffer[i])
328 >> PSND_MAX_VOLUME_BITS;
330 for(i=0;i<sample_size;i++)
332 linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
334 if (snd_ctrl.playingpos >= snd_ctrl.data_len)
337 /* finally play the sound fragment */
338 write(sound_device,playing_buffer,sample_size);
341 delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
347 #endif /* !VOXWARE */
354 static void sound_handler(struct SoundControl snd_ctrl)
358 if (snd_ctrl.fade_sound)
363 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
364 if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) &&
365 !playlist[i].fade_sound)
367 playlist[i].fade_sound = TRUE;
368 if (voice_check(playlist[i].voice))
369 voice_ramp_volume(playlist[i].voice, 1000, 0);
370 playlist[i].loop = PSND_NO_LOOP;
373 else if (snd_ctrl.stop_all_sounds)
377 SoundServer_StopAllSounds();
379 else if (snd_ctrl.stop_sound)
383 SoundServer_StopSound(snd_ctrl.nr);
386 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
388 if (!playlist[i].active || playlist[i].loop)
391 playlist[i].playingpos = voice_get_position(playlist[i].voice);
392 playlist[i].volume = voice_get_volume(playlist[i].voice);
393 if (playlist[i].playingpos == -1 || !playlist[i].volume)
395 deallocate_voice(playlist[i].voice);
396 playlist[i] = emptySoundControl;
402 SoundServer_InsertNewSound(snd_ctrl);
406 static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
410 /* if playlist is full, remove oldest sound */
411 if (playing_sounds==MAX_SOUNDS_PLAYING)
413 int longest=0, longest_nr=0;
415 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
418 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
420 int actual = playlist[i].playingpos;
423 if (!playlist[i].loop && actual>longest)
430 voice_set_volume(playlist[longest_nr].voice, 0);
431 deallocate_voice(playlist[longest_nr].voice);
433 playlist[longest_nr] = emptySoundControl;
437 /* check if sound is already being played (and how often) */
438 for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
440 if (playlist[i].nr == snd_ctrl.nr)
444 /* restart loop sounds only if they are just fading out */
445 if (k>=1 && snd_ctrl.loop)
447 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
449 if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
451 playlist[i].fade_sound = FALSE;
452 playlist[i].volume = PSND_MAX_VOLUME;
454 playlist[i].loop = PSND_LOOP;
455 voice_stop_volumeramp(playlist[i].voice);
456 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
463 /* don't play sound more than n times simultaneously (with n == 2 for now) */
466 int longest=0, longest_nr=0;
468 /* look for oldest equal sound */
469 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
473 if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
477 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
479 actual = playlist[i].playingpos;
488 voice_set_volume(playlist[longest_nr].voice, 0);
489 deallocate_voice(playlist[longest_nr].voice);
491 playlist[longest_nr] = emptySoundControl;
495 /* neuen Sound in Liste packen */
496 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
498 if (!playlist[i].active)
500 playlist[i] = snd_ctrl;
503 playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
505 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
506 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
507 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
508 voice_start(playlist[i].voice);
516 void SoundServer_FadeSound(int nr)
523 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
524 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
525 playlist[i].fade_sound = TRUE;
530 static void SoundServer_StopSound(int nr)
537 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
538 if (playlist[i].nr == nr)
541 voice_set_volume(playlist[i].voice, 0);
542 deallocate_voice(playlist[i].voice);
544 playlist[i] = emptySoundControl;
554 static void SoundServer_StopAllSounds()
558 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
561 voice_set_volume(playlist[i].voice, 0);
562 deallocate_voice(playlist[i].voice);
564 playlist[i]=emptySoundControl;
575 static void HPUX_Audio_Control()
577 struct audio_describe ainfo;
580 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
582 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl - no sounds");
584 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
585 Error(ERR_EXIT_SOUND_SERVER, "no audio info - no sounds");
587 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
588 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available - no sounds");
590 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
591 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
595 #endif /* HPUX_AUDIO */
599 /* these two are stolen from "sox"... :) */
602 ** This routine converts from linear to ulaw.
604 ** Craig Reese: IDA/Supercomputing Research Center
605 ** Joe Campbell: Department of Defense
609 ** 1) CCITT Recommendation G.711 (very difficult to follow)
610 ** 2) "A New Digital Technique for Implementation of Any
611 ** Continuous PCM Companding Law," Villeret, Michel,
612 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
613 ** 1973, pg. 11.12-11.17
614 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
615 ** for Analog-to_Digital Conversion Techniques,"
618 ** Input: Signed 16 bit linear sample
619 ** Output: 8 bit ulaw sample
622 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
623 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
626 static unsigned char linear_to_ulaw(int sample)
628 static int exp_lut[256] =
630 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
631 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
632 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
633 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
634 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
635 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
636 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
637 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
638 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
639 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
640 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
641 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
642 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
643 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
644 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
645 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
648 int sign, exponent, mantissa;
649 unsigned char ulawbyte;
651 /* Get the sample into sign-magnitude. */
652 sign = (sample >> 8) & 0x80; /* set aside the sign */
654 sample = -sample; /* get magnitude */
656 sample = CLIP; /* clip the magnitude */
658 /* Convert from 16 bit linear to ulaw. */
659 sample = sample + BIAS;
660 exponent = exp_lut[( sample >> 7 ) & 0xFF];
661 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
662 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
665 ulawbyte = 0x02; /* optional CCITT trap */
672 ** This routine converts from ulaw to 16 bit linear.
674 ** Craig Reese: IDA/Supercomputing Research Center
678 ** 1) CCITT Recommendation G.711 (very difficult to follow)
679 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
680 ** for Analog-to_Digital Conversion Techniques,"
683 ** Input: 8 bit ulaw sample
684 ** Output: signed 16 bit linear sample
687 static int ulaw_to_linear(unsigned char ulawbyte)
689 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
690 int sign, exponent, mantissa, sample;
692 ulawbyte = ~ ulawbyte;
693 sign = ( ulawbyte & 0x80 );
694 exponent = ( ulawbyte >> 4 ) & 0x07;
695 mantissa = ulawbyte & 0x0F;
696 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
703 #endif /* !VOXWARE */
705 /*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
707 /*===========================================================================*/
709 /*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/
711 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
712 #define WAV_HEADER_SIZE 20 /* size of WAV file header */
714 boolean LoadSound(struct SoundInfo *snd_info)
717 char *sound_ext = "wav";
719 byte sound_header_buffer[WAV_HEADER_SIZE];
720 char chunk[CHUNK_ID_LEN + 1];
721 int chunk_length, dummy;
726 sprintf(filename, "%s/%s/%s.%s",
727 options.ro_base_directory, SOUNDS_DIRECTORY,
728 snd_info->name, sound_ext);
732 if ((file = fopen(filename, "r")) == NULL)
734 Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
738 /* read chunk "RIFF" */
739 getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
740 if (strcmp(chunk, "RIFF") != 0)
742 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
747 /* read chunk "WAVE" */
748 getFileChunk(file, chunk, &dummy, BYTE_ORDER_LITTLE_ENDIAN);
749 if (strcmp(chunk, "WAVE") != 0)
751 Error(ERR_WARN, "missing 'WAVE' chunk of sound file '%s'", filename);
756 /* read header information */
757 for (i=0; i<WAV_HEADER_SIZE; i++)
758 sound_header_buffer[i] = fgetc(file);
760 /* read chunk "data" */
761 getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
762 if (strcmp(chunk, "data") != 0)
764 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
769 snd_info->data_len = chunk_length;
770 snd_info->data_ptr = checked_malloc(snd_info->data_len);
772 /* read sound data */
773 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
776 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
783 for (i=0; i<snd_info->data_len; i++)
784 snd_info->data_ptr[i] = snd_info->data_ptr[i] ^ 0x80;
788 snd_info->sample_ptr = load_sample(filename);
789 if (!snd_info->sample_ptr)
791 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
800 void PlaySound(int nr)
802 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
805 void PlaySoundStereo(int nr, int stereo)
807 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
810 void PlaySoundLoop(int nr)
812 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
815 void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
817 struct SoundControl snd_ctrl = emptySoundControl;
819 if (sound_status==SOUND_OFF || !setup.sound)
822 if (volume<PSND_MIN_VOLUME)
823 volume = PSND_MIN_VOLUME;
824 else if (volume>PSND_MAX_VOLUME)
825 volume = PSND_MAX_VOLUME;
827 if (stereo<PSND_MAX_LEFT)
828 stereo = PSND_MAX_LEFT;
829 else if (stereo>PSND_MAX_RIGHT)
830 stereo = PSND_MAX_RIGHT;
833 snd_ctrl.volume = volume;
834 snd_ctrl.stereo = stereo;
835 snd_ctrl.loop = loop;
836 snd_ctrl.active = TRUE;
837 snd_ctrl.data_ptr = Sound[nr].data_ptr;
838 snd_ctrl.data_len = Sound[nr].data_len;
841 if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
843 Error(ERR_WARN, "cannot pipe to child process - no sounds");
844 sound_status = SOUND_OFF;
848 sound_handler(snd_ctrl);
852 void FadeSound(int nr)
854 StopSoundExt(nr, SSND_FADE_SOUND);
859 StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
862 void StopSound(int nr)
864 StopSoundExt(nr, SSND_STOP_SOUND);
869 StopSoundExt(-1, SSND_STOP_ALL_SOUNDS);
872 void StopSoundExt(int nr, int method)
874 struct SoundControl snd_ctrl = emptySoundControl;
876 if (sound_status==SOUND_OFF)
879 if (SSND_FADING(method))
880 snd_ctrl.fade_sound = TRUE;
882 if (SSND_ALL(method))
883 snd_ctrl.stop_all_sounds = TRUE;
887 snd_ctrl.stop_sound = TRUE;
891 if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
893 Error(ERR_WARN, "cannot pipe to child process - no sounds");
894 sound_status = SOUND_OFF;
898 sound_handler(snd_ctrl);
902 void FreeSounds(int num_sounds)
906 if (sound_status == SOUND_OFF)
909 for(i=0; i<num_sounds; i++)
911 free(Sound[i].data_ptr);
913 destroy_sample(Sound[i].sample_ptr);
917 /*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/