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
26 #if defined(PLATFORM_UNIX)
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);
41 #if defined(PLATFORM_UNIX)
42 static unsigned char linear_to_ulaw(int);
43 static int ulaw_to_linear(unsigned char);
48 static void HPUX_Audio_Control();
51 #if defined(PLATFORM_MSDOS)
52 static void SoundServer_InsertNewSound(struct SoundControl);
53 static void SoundServer_StopSound(int);
54 static void SoundServer_StopAllSounds();
57 #if defined(PLATFORM_UNIX)
58 int OpenAudioDevice(char *audio_device_name)
62 /* check if desired audio device is accessible */
63 if (access(sound_device_name, W_OK) != 0)
66 /* try to open audio device in non-blocking mode */
67 if ((audio_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
70 /* re-open audio device in blocking mode */
72 audio_fd = open(audio_device_name, O_WRONLY);
77 void UnixOpenAudio(struct AudioSystemInfo *audio)
79 static char *audio_device_name[] =
87 /* look for available audio devices, starting with preferred ones */
88 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
89 if ((audio_fd = OpenAudioDevice(sound_device_name)) >= 0)
94 Error(ERR_WARN, "cannot open audio device - no sound");
100 audio->sound_available = TRUE;
103 audio->loops_available = TRUE;
107 void UnixCloseAudio(struct AudioSystemInfo *audio)
109 if (audio->device_fd)
110 close(audio->device_fd);
113 #endif /* PLATFORM_UNIX */
118 #if defined(PLATFORM_UNIX)
119 struct SoundControl snd_ctrl;
122 close(audio.soundserver_pipe[1]); /* no writing into pipe needed */
125 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
126 playlist[i] = emptySoundControl;
129 #if defined(PLATFORM_UNIX)
130 stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
131 for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
133 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
136 HPUX_Audio_Control();
139 FD_ZERO(&sound_fdset);
140 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
142 while(1) /* wait for sound playing commands from client */
144 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
145 select(audio.soundserver_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
146 if (!FD_ISSET(audio.soundserver_pipe[0], &sound_fdset))
148 if (read(audio.soundserver_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
150 Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
154 if (snd_ctrl.fade_sound)
159 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
160 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
161 playlist[i].fade_sound = TRUE;
163 else if (snd_ctrl.stop_all_sounds)
168 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
169 playlist[i]=emptySoundControl;
172 close(audio.device_fd);
174 else if (snd_ctrl.stop_sound)
179 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
180 if (playlist[i].nr == snd_ctrl.nr)
182 playlist[i]=emptySoundControl;
187 close(audio.device_fd);
190 if (playing_sounds || snd_ctrl.active)
192 struct timeval delay = { 0, 0 };
195 static long max_sample_size = 0;
196 static long fragment_size = 0;
197 /* Even if the stereo flag is used as being boolean, it must be
198 defined as an integer, else 'ioctl()' will fail! */
201 int sample_rate = 8000;
203 int sample_rate = 22050;
206 if (playing_sounds ||
207 (audio.device_fd = OpenAudioDevice(sound_device_name)) >= 0)
209 if (!playing_sounds) /* we just opened the audio device */
211 /* 2 buffers / 512 bytes, giving 1/16 second resolution */
212 /* (with stereo the effective buffer size will shrink to 256) */
213 fragment_size = 0x00020009;
215 if (ioctl(audio.device_fd,SNDCTL_DSP_SETFRAGMENT,&fragment_size) < 0)
216 Error(ERR_EXIT_SOUND_SERVER,
217 "cannot set fragment size of /dev/dsp - no sounds");
219 /* try if we can use stereo sound */
220 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
223 static boolean reported = FALSE;
227 Error(ERR_RETURN, "cannot get stereo sound on /dev/dsp");
234 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &sample_rate) < 0)
235 Error(ERR_EXIT_SOUND_SERVER,
236 "cannot set sample rate of /dev/dsp - no sounds");
238 /* get the real fragmentation size; this should return 512 */
239 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE,&fragment_size) < 0)
240 Error(ERR_EXIT_SOUND_SERVER,
241 "cannot get fragment size of /dev/dsp - no sounds");
243 max_sample_size = fragment_size / (stereo ? 2 : 1);
246 if (snd_ctrl.active) /* new sound has arrived */
247 SoundServer_InsertNewSound(snd_ctrl);
249 while(playing_sounds &&
250 select(audio.soundserver_pipe[0] + 1,
251 &sound_fdset, NULL, NULL, &delay) < 1)
253 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
255 /* first clear the last premixing buffer */
256 memset(premix_last_buffer,0,fragment_size*sizeof(int));
258 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
262 if (!playlist[i].active)
265 /* get pointer and size of the actual sound sample */
266 sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
268 MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
269 playlist[i].playingpos += sample_size;
271 /* fill the first mixing buffer with original sample */
272 memcpy(premix_first_buffer,sample_ptr,sample_size);
274 /* are we about to restart a looping sound? */
275 if (playlist[i].loop && sample_size<max_sample_size)
277 playlist[i].playingpos = max_sample_size-sample_size;
278 memcpy(premix_first_buffer+sample_size,
279 playlist[i].data_ptr,max_sample_size-sample_size);
280 sample_size = max_sample_size;
283 /* decrease volume if sound is fading out */
284 if (playlist[i].fade_sound &&
285 playlist[i].volume>=PSND_MAX_VOLUME/10)
286 playlist[i].volume-=PSND_MAX_VOLUME/20;
288 /* adjust volume of actual sound sample */
289 if (playlist[i].volume != PSND_MAX_VOLUME)
290 for(j=0;j<sample_size;j++)
291 premix_first_buffer[j] =
292 (playlist[i].volume * (int)premix_first_buffer[j])
293 >> PSND_MAX_VOLUME_BITS;
295 /* fill the last mixing buffer with stereo or mono sound */
298 int middle_pos = PSND_MAX_LEFT2RIGHT/2;
299 int left_volume = stereo_volume[middle_pos+playlist[i].stereo];
300 int right_volume = stereo_volume[middle_pos-playlist[i].stereo];
302 for(j=0;j<sample_size;j++)
304 premix_left_buffer[j] =
305 (left_volume * (int)premix_first_buffer[j])
306 >> PSND_MAX_LEFT2RIGHT_BITS;
307 premix_right_buffer[j] =
308 (right_volume * (int)premix_first_buffer[j])
309 >> PSND_MAX_LEFT2RIGHT_BITS;
310 premix_last_buffer[2*j+0] += premix_left_buffer[j];
311 premix_last_buffer[2*j+1] += premix_right_buffer[j];
316 for(j=0;j<sample_size;j++)
317 premix_last_buffer[j] += (int)premix_first_buffer[j];
320 /* delete completed sound entries from the playlist */
321 if (playlist[i].playingpos >= playlist[i].data_len)
323 if (playlist[i].loop)
324 playlist[i].playingpos = 0;
327 playlist[i] = emptySoundControl;
331 else if (playlist[i].volume <= PSND_MAX_VOLUME/10)
333 playlist[i] = emptySoundControl;
338 /* put last mixing buffer to final playing buffer */
339 for(i=0;i<fragment_size;i++)
341 if (premix_last_buffer[i]<-255)
342 playing_buffer[i] = 0;
343 else if (premix_last_buffer[i]>255)
344 playing_buffer[i] = 255;
346 playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80;
349 /* finally play the sound fragment */
350 write(audio.device_fd, playing_buffer,fragment_size);
353 /* if no sounds playing, free device for other sound programs */
355 close(audio.device_fd);
361 if (snd_ctrl.active && !snd_ctrl.loop)
363 struct timeval delay = { 0, 0 };
365 long sample_size, max_sample_size = SND_BLOCKSIZE;
366 long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
367 int wait_percent = 90; /* wait 90% of the real playing time */
370 if ((audio.device_fd = OpenAudioDevice(sound_device_name)) >= 0)
374 while(playing_sounds &&
375 select(audio.soundserver_pipe[0] + 1,
376 &sound_fdset, NULL, NULL, &delay) < 1)
378 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
380 /* get pointer and size of the actual sound sample */
381 sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
383 MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
384 snd_ctrl.playingpos += sample_size;
386 /* fill the first mixing buffer with original sample */
387 memcpy(premix_first_buffer,sample_ptr,sample_size);
390 /* adjust volume of actual sound sample */
391 if (snd_ctrl.volume != PSND_MAX_VOLUME)
392 for(i=0;i<sample_size;i++)
393 premix_first_buffer[i] =
394 (snd_ctrl.volume * (int)premix_first_buffer[i])
395 >> PSND_MAX_VOLUME_BITS;
397 for(i=0;i<sample_size;i++)
399 linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
401 if (snd_ctrl.playingpos >= snd_ctrl.data_len)
404 /* finally play the sound fragment */
405 write(audio.device_fd,playing_buffer,sample_size);
408 delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
410 close(audio.device_fd);
414 #endif /* !VOXWARE */
418 #endif /* PLATFORM_UNIX */
422 #if defined(PLATFORM_MSDOS)
423 static void sound_handler(struct SoundControl snd_ctrl)
427 if (snd_ctrl.fade_sound)
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)
436 playlist[i].fade_sound = TRUE;
437 if (voice_check(playlist[i].voice))
438 voice_ramp_volume(playlist[i].voice, 1000, 0);
439 playlist[i].loop = PSND_NO_LOOP;
442 else if (snd_ctrl.stop_all_sounds)
446 SoundServer_StopAllSounds();
448 else if (snd_ctrl.stop_sound)
452 SoundServer_StopSound(snd_ctrl.nr);
455 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
457 if (!playlist[i].active || playlist[i].loop)
460 playlist[i].playingpos = voice_get_position(playlist[i].voice);
461 playlist[i].volume = voice_get_volume(playlist[i].voice);
462 if (playlist[i].playingpos == -1 || !playlist[i].volume)
464 deallocate_voice(playlist[i].voice);
465 playlist[i] = emptySoundControl;
471 SoundServer_InsertNewSound(snd_ctrl);
473 #endif /* PLATFORM_MSDOS */
475 #if !defined(PLATFORM_WIN32)
476 static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
480 /* if playlist is full, remove oldest sound */
481 if (playing_sounds==MAX_SOUNDS_PLAYING)
483 int longest=0, longest_nr=0;
485 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
487 #if !defined(PLATFORM_MSDOS)
488 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
490 int actual = playlist[i].playingpos;
493 if (!playlist[i].loop && actual>longest)
499 #if defined(PLATFORM_MSDOS)
500 voice_set_volume(playlist[longest_nr].voice, 0);
501 deallocate_voice(playlist[longest_nr].voice);
503 playlist[longest_nr] = emptySoundControl;
507 /* check if sound is already being played (and how often) */
508 for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
510 if (playlist[i].nr == snd_ctrl.nr)
514 /* restart loop sounds only if they are just fading out */
515 if (k>=1 && snd_ctrl.loop)
517 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
519 if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
521 playlist[i].fade_sound = FALSE;
522 playlist[i].volume = PSND_MAX_VOLUME;
523 #if defined(PLATFORM_MSDOS)
524 playlist[i].loop = PSND_LOOP;
525 voice_stop_volumeramp(playlist[i].voice);
526 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
533 /* don't play sound more than n times simultaneously (with n == 2 for now) */
536 int longest=0, longest_nr=0;
538 /* look for oldest equal sound */
539 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
543 if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
546 #if !defined(PLATFORM_MSDOS)
547 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
549 actual = playlist[i].playingpos;
558 #if defined(PLATFORM_MSDOS)
559 voice_set_volume(playlist[longest_nr].voice, 0);
560 deallocate_voice(playlist[longest_nr].voice);
562 playlist[longest_nr] = emptySoundControl;
566 /* neuen Sound in Liste packen */
567 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
569 if (!playlist[i].active)
571 playlist[i] = snd_ctrl;
574 #if defined(PLATFORM_MSDOS)
575 playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
577 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
578 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
579 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
580 voice_start(playlist[i].voice);
586 #endif /* !PLATFORM_WIN32 */
589 void SoundServer_FadeSound(int nr)
596 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
597 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
598 playlist[i].fade_sound = TRUE;
602 #if !defined(PLATFORM_WIN32)
603 #if defined(PLATFORM_MSDOS)
604 static void SoundServer_StopSound(int nr)
611 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
612 if (playlist[i].nr == nr)
614 #if defined(PLATFORM_MSDOS)
615 voice_set_volume(playlist[i].voice, 0);
616 deallocate_voice(playlist[i].voice);
618 playlist[i] = emptySoundControl;
622 #if !defined(PLATFORM_MSDOS)
624 close(audio.device_fd);
628 static void SoundServer_StopAllSounds()
632 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
634 #if defined(PLATFORM_MSDOS)
635 voice_set_volume(playlist[i].voice, 0);
636 deallocate_voice(playlist[i].voice);
638 playlist[i]=emptySoundControl;
642 #if !defined(PLATFORM_MSDOS)
643 close(audio.device_fd);
646 #endif /* PLATFORM_MSDOS */
647 #endif /* !PLATFORM_WIN32 */
650 static void HPUX_Audio_Control()
652 struct audio_describe ainfo;
655 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
657 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl - no sounds");
659 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
660 Error(ERR_EXIT_SOUND_SERVER, "no audio info - no sounds");
662 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
663 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available - no sounds");
665 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
666 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
670 #endif /* HPUX_AUDIO */
672 #if !defined(VOXWARE) && defined(PLATFORM_UNIX)
674 /* these two are stolen from "sox"... :) */
677 ** This routine converts from linear to ulaw.
679 ** Craig Reese: IDA/Supercomputing Research Center
680 ** Joe Campbell: Department of Defense
684 ** 1) CCITT Recommendation G.711 (very difficult to follow)
685 ** 2) "A New Digital Technique for Implementation of Any
686 ** Continuous PCM Companding Law," Villeret, Michel,
687 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
688 ** 1973, pg. 11.12-11.17
689 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
690 ** for Analog-to_Digital Conversion Techniques,"
693 ** Input: Signed 16 bit linear sample
694 ** Output: 8 bit ulaw sample
697 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
698 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
701 static unsigned char linear_to_ulaw(int sample)
703 static int exp_lut[256] =
705 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
706 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
707 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
708 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
709 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
710 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
711 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
712 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
713 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
714 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
715 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
716 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
717 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
718 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
719 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
720 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
723 int sign, exponent, mantissa;
724 unsigned char ulawbyte;
726 /* Get the sample into sign-magnitude. */
727 sign = (sample >> 8) & 0x80; /* set aside the sign */
729 sample = -sample; /* get magnitude */
731 sample = CLIP; /* clip the magnitude */
733 /* Convert from 16 bit linear to ulaw. */
734 sample = sample + BIAS;
735 exponent = exp_lut[( sample >> 7 ) & 0xFF];
736 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
737 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
740 ulawbyte = 0x02; /* optional CCITT trap */
747 ** This routine converts from ulaw to 16 bit linear.
749 ** Craig Reese: IDA/Supercomputing Research Center
753 ** 1) CCITT Recommendation G.711 (very difficult to follow)
754 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
755 ** for Analog-to_Digital Conversion Techniques,"
758 ** Input: 8 bit ulaw sample
759 ** Output: signed 16 bit linear sample
762 static int ulaw_to_linear(unsigned char ulawbyte)
764 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
765 int sign, exponent, mantissa, sample;
767 ulawbyte = ~ ulawbyte;
768 sign = ( ulawbyte & 0x80 );
769 exponent = ( ulawbyte >> 4 ) & 0x07;
770 mantissa = ulawbyte & 0x0F;
771 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
777 #endif /* !VOXWARE && PLATFORM_UNIX */
779 /*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
781 /*===========================================================================*/
783 /*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/
785 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
786 #define WAV_HEADER_SIZE 20 /* size of WAV file header */
788 boolean LoadSound(struct SampleInfo *snd_info)
791 char *sound_ext = "wav";
792 #if !defined(TARGET_SDL)
793 #if !defined(PLATFORM_MSDOS)
794 byte sound_header_buffer[WAV_HEADER_SIZE];
795 char chunk[CHUNK_ID_LEN + 1];
796 int chunk_length, dummy;
802 sprintf(filename, "%s/%s/%s.%s",
803 options.ro_base_directory, SOUNDS_DIRECTORY,
804 snd_info->name, sound_ext);
806 #if defined(TARGET_SDL)
808 snd_info->mix_chunk = Mix_LoadWAV(filename);
809 if (snd_info->mix_chunk == NULL)
811 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
815 #else /* !TARGET_SDL */
817 #if !defined(PLATFORM_MSDOS)
819 if ((file = fopen(filename, "r")) == NULL)
821 Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
825 /* read chunk "RIFF" */
826 getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
827 if (strcmp(chunk, "RIFF") != 0)
829 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
834 /* read chunk "WAVE" */
835 getFileChunk(file, chunk, &dummy, BYTE_ORDER_LITTLE_ENDIAN);
836 if (strcmp(chunk, "WAVE") != 0)
838 Error(ERR_WARN, "missing 'WAVE' chunk of sound file '%s'", filename);
843 /* read header information */
844 for (i=0; i<WAV_HEADER_SIZE; i++)
845 sound_header_buffer[i] = fgetc(file);
847 /* read chunk "data" */
848 getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
849 if (strcmp(chunk, "data") != 0)
851 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
856 snd_info->data_len = chunk_length;
857 snd_info->data_ptr = checked_malloc(snd_info->data_len);
859 /* read sound data */
860 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
863 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
870 for (i=0; i<snd_info->data_len; i++)
871 snd_info->data_ptr[i] = snd_info->data_ptr[i] ^ 0x80;
873 #else /* PLATFORM_MSDOS */
875 snd_info->sample_ptr = load_sample(filename);
876 if (!snd_info->sample_ptr)
878 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
882 #endif /* PLATFORM_MSDOS */
883 #endif /* !TARGET_SDL */
888 void PlaySound(int nr)
890 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
893 void PlaySoundStereo(int nr, int stereo)
895 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
898 void PlaySoundLoop(int nr)
900 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
903 void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
905 struct SoundControl snd_ctrl = emptySoundControl;
907 if (!audio.sound_available || !setup.sound)
910 if (volume<PSND_MIN_VOLUME)
911 volume = PSND_MIN_VOLUME;
912 else if (volume>PSND_MAX_VOLUME)
913 volume = PSND_MAX_VOLUME;
915 if (stereo<PSND_MAX_LEFT)
916 stereo = PSND_MAX_LEFT;
917 else if (stereo>PSND_MAX_RIGHT)
918 stereo = PSND_MAX_RIGHT;
921 snd_ctrl.volume = volume;
922 snd_ctrl.stereo = stereo;
923 snd_ctrl.loop = loop;
924 snd_ctrl.active = TRUE;
925 snd_ctrl.data_ptr = Sound[nr].data_ptr;
926 snd_ctrl.data_len = Sound[nr].data_len;
928 #if defined(TARGET_SDL)
930 Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4);
931 Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4);
933 Mix_PlayChannel(-1, Sound[nr].mix_chunk, (loop ? -1 : 0));
936 #if !defined(PLATFORM_MSDOS)
937 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
939 Error(ERR_WARN, "cannot pipe to child process - no sounds");
940 audio.sound_available = FALSE;
944 sound_handler(snd_ctrl);
949 void FadeSound(int nr)
951 StopSoundExt(nr, SSND_FADE_SOUND);
956 StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
959 void StopSound(int nr)
961 StopSoundExt(nr, SSND_STOP_SOUND);
966 StopSoundExt(-1, SSND_STOP_ALL_SOUNDS);
969 void StopSoundExt(int nr, int method)
971 struct SoundControl snd_ctrl = emptySoundControl;
973 if (!audio.sound_available)
976 if (SSND_FADING(method))
977 snd_ctrl.fade_sound = TRUE;
979 if (SSND_ALL(method))
980 snd_ctrl.stop_all_sounds = TRUE;
984 snd_ctrl.stop_sound = TRUE;
987 #if defined(TARGET_SDL)
989 if (SSND_FADING(method))
991 Mix_FadeOutChannel(-1, 1000);
992 Mix_FadeOutMusic(1000);
1001 #if !defined(PLATFORM_MSDOS)
1002 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1004 Error(ERR_WARN, "cannot pipe to child process - no sounds");
1005 audio.sound_available = FALSE;
1009 sound_handler(snd_ctrl);
1014 void FreeSounds(int num_sounds)
1018 if (!audio.sound_available)
1021 for(i=0; i<num_sounds; i++)
1022 #if !defined(PLATFORM_MSDOS)
1023 free(Sound[i].data_ptr);
1025 destroy_sample(Sound[i].sample_ptr);
1029 /*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/