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 ***********************************************************/
22 static int num_sounds = 0;
23 static struct SampleInfo *Sound = NULL;
26 /*** THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
28 static int playing_sounds = 0;
29 static struct SoundControl playlist[MAX_SOUNDS_PLAYING];
30 static struct SoundControl emptySoundControl =
32 -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE, 0,0L,0L,NULL
35 #if defined(PLATFORM_UNIX)
36 static int stereo_volume[PSND_MAX_LEFT2RIGHT+1];
37 static char premix_first_buffer[SND_BLOCKSIZE];
38 #if defined(AUDIO_STREAMING_DSP)
39 static char premix_left_buffer[SND_BLOCKSIZE];
40 static char premix_right_buffer[SND_BLOCKSIZE];
41 static int premix_last_buffer[SND_BLOCKSIZE];
43 static unsigned char playing_buffer[SND_BLOCKSIZE];
46 /* forward declaration of internal functions */
47 #if defined(AUDIO_STREAMING_DSP)
48 static void SoundServer_InsertNewSound(struct SoundControl);
49 #elif defined(PLATFORM_UNIX)
50 static unsigned char linear_to_ulaw(int);
51 static int ulaw_to_linear(unsigned char);
54 #if defined(PLATFORM_HPUX)
55 static void HPUX_Audio_Control();
58 #if defined(PLATFORM_MSDOS)
59 static void SoundServer_InsertNewSound(struct SoundControl);
60 static void SoundServer_StopSound(int);
61 static void SoundServer_StopAllSounds();
64 #if defined(PLATFORM_UNIX)
65 int OpenAudioDevice(char *audio_device_name)
69 /* check if desired audio device is accessible */
70 if (access(audio_device_name, W_OK) != 0)
73 /* try to open audio device in non-blocking mode */
74 if ((audio_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
77 /* re-open audio device in blocking mode */
79 audio_fd = open(audio_device_name, O_WRONLY);
84 void UnixOpenAudio(struct AudioSystemInfo *audio)
86 static char *audio_device_name[] =
94 /* look for available audio devices, starting with preferred ones */
95 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
96 if ((audio_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
101 Error(ERR_WARN, "cannot open audio device - no sound");
107 audio->device_name = audio_device_name[i];
108 audio->sound_available = TRUE;
109 audio->sound_enabled = TRUE;
111 #if defined(AUDIO_STREAMING_DSP)
112 audio->loops_available = TRUE;
116 void UnixCloseAudio(struct AudioSystemInfo *audio)
118 if (audio->device_fd)
119 close(audio->device_fd);
122 #endif /* PLATFORM_UNIX */
127 #if defined(PLATFORM_UNIX)
128 struct SoundControl snd_ctrl;
131 close(audio.soundserver_pipe[1]); /* no writing into pipe needed */
134 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
135 playlist[i] = emptySoundControl;
138 #if defined(PLATFORM_UNIX)
139 stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
140 for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
142 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
144 #if defined(PLATFORM_HPUX)
145 HPUX_Audio_Control();
148 FD_ZERO(&sound_fdset);
149 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
151 while(1) /* wait for sound playing commands from client */
153 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
154 select(audio.soundserver_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
155 if (!FD_ISSET(audio.soundserver_pipe[0], &sound_fdset))
157 if (read(audio.soundserver_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
159 Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
161 #if defined(AUDIO_STREAMING_DSP)
163 if (snd_ctrl.fade_sound)
168 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
169 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
170 playlist[i].fade_sound = TRUE;
172 else if (snd_ctrl.stop_all_sounds)
177 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
178 playlist[i]=emptySoundControl;
181 close(audio.device_fd);
183 else if (snd_ctrl.stop_sound)
188 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
189 if (playlist[i].nr == snd_ctrl.nr)
191 playlist[i]=emptySoundControl;
196 close(audio.device_fd);
199 if (playing_sounds || snd_ctrl.active)
201 struct timeval delay = { 0, 0 };
204 static long max_sample_size = 0;
205 static long fragment_size = 0;
206 /* Even if the stereo flag is used as being boolean, it must be
207 defined as an integer, else 'ioctl()' will fail! */
210 int sample_rate = 8000;
212 int sample_rate = 22050;
215 if (playing_sounds ||
216 (audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
218 if (!playing_sounds) /* we just opened the audio device */
220 /* 2 buffers / 512 bytes, giving 1/16 second resolution */
221 /* (with stereo the effective buffer size will shrink to 256) */
222 fragment_size = 0x00020009;
224 if (ioctl(audio.device_fd,SNDCTL_DSP_SETFRAGMENT,&fragment_size) < 0)
225 Error(ERR_EXIT_SOUND_SERVER,
226 "cannot set fragment size of /dev/dsp - no sounds");
228 /* try if we can use stereo sound */
229 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
232 static boolean reported = FALSE;
236 Error(ERR_RETURN, "cannot get stereo sound on /dev/dsp");
243 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &sample_rate) < 0)
244 Error(ERR_EXIT_SOUND_SERVER,
245 "cannot set sample rate of /dev/dsp - no sounds");
247 /* get the real fragmentation size; this should return 512 */
248 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE,&fragment_size) < 0)
249 Error(ERR_EXIT_SOUND_SERVER,
250 "cannot get fragment size of /dev/dsp - no sounds");
252 max_sample_size = fragment_size / (stereo ? 2 : 1);
255 if (snd_ctrl.active) /* new sound has arrived */
256 SoundServer_InsertNewSound(snd_ctrl);
258 while(playing_sounds &&
259 select(audio.soundserver_pipe[0] + 1,
260 &sound_fdset, NULL, NULL, &delay) < 1)
262 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
264 /* first clear the last premixing buffer */
265 memset(premix_last_buffer,0,fragment_size*sizeof(int));
267 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
271 if (!playlist[i].active)
274 /* get pointer and size of the actual sound sample */
275 sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
277 MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
278 playlist[i].playingpos += sample_size;
280 /* fill the first mixing buffer with original sample */
281 memcpy(premix_first_buffer,sample_ptr,sample_size);
283 /* are we about to restart a looping sound? */
284 if (playlist[i].loop && sample_size<max_sample_size)
286 playlist[i].playingpos = max_sample_size-sample_size;
287 memcpy(premix_first_buffer+sample_size,
288 playlist[i].data_ptr,max_sample_size-sample_size);
289 sample_size = max_sample_size;
292 /* decrease volume if sound is fading out */
293 if (playlist[i].fade_sound &&
294 playlist[i].volume>=PSND_MAX_VOLUME/10)
295 playlist[i].volume-=PSND_MAX_VOLUME/20;
297 /* adjust volume of actual sound sample */
298 if (playlist[i].volume != PSND_MAX_VOLUME)
299 for(j=0;j<sample_size;j++)
300 premix_first_buffer[j] =
301 (playlist[i].volume * (int)premix_first_buffer[j])
302 >> PSND_MAX_VOLUME_BITS;
304 /* fill the last mixing buffer with stereo or mono sound */
307 int middle_pos = PSND_MAX_LEFT2RIGHT/2;
308 int left_volume = stereo_volume[middle_pos+playlist[i].stereo];
309 int right_volume = stereo_volume[middle_pos-playlist[i].stereo];
311 for(j=0;j<sample_size;j++)
313 premix_left_buffer[j] =
314 (left_volume * (int)premix_first_buffer[j])
315 >> PSND_MAX_LEFT2RIGHT_BITS;
316 premix_right_buffer[j] =
317 (right_volume * (int)premix_first_buffer[j])
318 >> PSND_MAX_LEFT2RIGHT_BITS;
319 premix_last_buffer[2*j+0] += premix_left_buffer[j];
320 premix_last_buffer[2*j+1] += premix_right_buffer[j];
325 for(j=0;j<sample_size;j++)
326 premix_last_buffer[j] += (int)premix_first_buffer[j];
329 /* delete completed sound entries from the playlist */
330 if (playlist[i].playingpos >= playlist[i].data_len)
332 if (playlist[i].loop)
333 playlist[i].playingpos = 0;
336 playlist[i] = emptySoundControl;
340 else if (playlist[i].volume <= PSND_MAX_VOLUME/10)
342 playlist[i] = emptySoundControl;
347 /* put last mixing buffer to final playing buffer */
348 for(i=0;i<fragment_size;i++)
350 if (premix_last_buffer[i]<-255)
351 playing_buffer[i] = 0;
352 else if (premix_last_buffer[i]>255)
353 playing_buffer[i] = 255;
355 playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80;
358 /* finally play the sound fragment */
359 write(audio.device_fd, playing_buffer,fragment_size);
362 /* if no sounds playing, free device for other sound programs */
364 close(audio.device_fd);
368 #else /* !AUDIO_STREAMING_DSP */
370 if (snd_ctrl.active && !snd_ctrl.loop)
372 struct timeval delay = { 0, 0 };
374 long sample_size, max_sample_size = SND_BLOCKSIZE;
375 long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
376 int wait_percent = 90; /* wait 90% of the real playing time */
379 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
383 while(playing_sounds &&
384 select(audio.soundserver_pipe[0] + 1,
385 &sound_fdset, NULL, NULL, &delay) < 1)
387 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
389 /* get pointer and size of the actual sound sample */
390 sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
392 MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
393 snd_ctrl.playingpos += sample_size;
395 /* fill the first mixing buffer with original sample */
396 memcpy(premix_first_buffer,sample_ptr,sample_size);
399 /* adjust volume of actual sound sample */
400 if (snd_ctrl.volume != PSND_MAX_VOLUME)
401 for(i=0;i<sample_size;i++)
402 premix_first_buffer[i] =
403 (snd_ctrl.volume * (int)premix_first_buffer[i])
404 >> PSND_MAX_VOLUME_BITS;
406 for(i=0;i<sample_size;i++)
408 linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
410 if (snd_ctrl.playingpos >= snd_ctrl.data_len)
413 /* finally play the sound fragment */
414 write(audio.device_fd,playing_buffer,sample_size);
417 delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
419 close(audio.device_fd);
423 #endif /* !AUDIO_STREAMING_DSP */
427 #endif /* PLATFORM_UNIX */
431 #if defined(PLATFORM_MSDOS)
432 static void sound_handler(struct SoundControl snd_ctrl)
436 if (snd_ctrl.fade_sound)
441 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
442 if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) &&
443 !playlist[i].fade_sound)
445 playlist[i].fade_sound = TRUE;
446 if (voice_check(playlist[i].voice))
447 voice_ramp_volume(playlist[i].voice, 1000, 0);
448 playlist[i].loop = PSND_NO_LOOP;
451 else if (snd_ctrl.stop_all_sounds)
455 SoundServer_StopAllSounds();
457 else if (snd_ctrl.stop_sound)
461 SoundServer_StopSound(snd_ctrl.nr);
464 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
466 if (!playlist[i].active || playlist[i].loop)
469 playlist[i].playingpos = voice_get_position(playlist[i].voice);
470 playlist[i].volume = voice_get_volume(playlist[i].voice);
471 if (playlist[i].playingpos == -1 || !playlist[i].volume)
473 deallocate_voice(playlist[i].voice);
474 playlist[i] = emptySoundControl;
480 SoundServer_InsertNewSound(snd_ctrl);
482 #endif /* PLATFORM_MSDOS */
484 #if !defined(PLATFORM_WIN32)
485 static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
489 /* if playlist is full, remove oldest sound */
490 if (playing_sounds==MAX_SOUNDS_PLAYING)
492 int longest=0, longest_nr=0;
494 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
496 #if !defined(PLATFORM_MSDOS)
497 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
499 int actual = playlist[i].playingpos;
502 if (!playlist[i].loop && actual>longest)
508 #if defined(PLATFORM_MSDOS)
509 voice_set_volume(playlist[longest_nr].voice, 0);
510 deallocate_voice(playlist[longest_nr].voice);
512 playlist[longest_nr] = emptySoundControl;
516 /* check if sound is already being played (and how often) */
517 for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
519 if (playlist[i].nr == snd_ctrl.nr)
523 /* restart loop sounds only if they are just fading out */
524 if (k>=1 && snd_ctrl.loop)
526 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
528 if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
530 playlist[i].fade_sound = FALSE;
531 playlist[i].volume = PSND_MAX_VOLUME;
532 #if defined(PLATFORM_MSDOS)
533 playlist[i].loop = PSND_LOOP;
534 voice_stop_volumeramp(playlist[i].voice);
535 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
542 /* don't play sound more than n times simultaneously (with n == 2 for now) */
545 int longest=0, longest_nr=0;
547 /* look for oldest equal sound */
548 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
552 if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
555 #if !defined(PLATFORM_MSDOS)
556 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
558 actual = playlist[i].playingpos;
567 #if defined(PLATFORM_MSDOS)
568 voice_set_volume(playlist[longest_nr].voice, 0);
569 deallocate_voice(playlist[longest_nr].voice);
571 playlist[longest_nr] = emptySoundControl;
575 /* neuen Sound in Liste packen */
576 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
578 if (!playlist[i].active)
580 playlist[i] = snd_ctrl;
583 #if defined(PLATFORM_MSDOS)
584 playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
586 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
587 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
588 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
589 voice_start(playlist[i].voice);
595 #endif /* !PLATFORM_WIN32 */
598 void SoundServer_FadeSound(int nr)
605 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
606 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
607 playlist[i].fade_sound = TRUE;
611 #if !defined(PLATFORM_WIN32)
612 #if defined(PLATFORM_MSDOS)
613 static void SoundServer_StopSound(int nr)
620 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
621 if (playlist[i].nr == nr)
623 #if defined(PLATFORM_MSDOS)
624 voice_set_volume(playlist[i].voice, 0);
625 deallocate_voice(playlist[i].voice);
627 playlist[i] = emptySoundControl;
631 #if !defined(PLATFORM_MSDOS)
633 close(audio.device_fd);
637 static void SoundServer_StopAllSounds()
641 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
643 #if defined(PLATFORM_MSDOS)
644 voice_set_volume(playlist[i].voice, 0);
645 deallocate_voice(playlist[i].voice);
647 playlist[i]=emptySoundControl;
651 #if !defined(PLATFORM_MSDOS)
652 close(audio.device_fd);
655 #endif /* PLATFORM_MSDOS */
656 #endif /* !PLATFORM_WIN32 */
658 #if defined(PLATFORM_HPUX)
659 static void HPUX_Audio_Control()
661 struct audio_describe ainfo;
664 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
666 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl - no sounds");
668 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
669 Error(ERR_EXIT_SOUND_SERVER, "no audio info - no sounds");
671 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
672 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available - no sounds");
674 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
675 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
679 #endif /* PLATFORM_HPUX */
681 #if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
683 /* these two are stolen from "sox"... :) */
686 ** This routine converts from linear to ulaw.
688 ** Craig Reese: IDA/Supercomputing Research Center
689 ** Joe Campbell: Department of Defense
693 ** 1) CCITT Recommendation G.711 (very difficult to follow)
694 ** 2) "A New Digital Technique for Implementation of Any
695 ** Continuous PCM Companding Law," Villeret, Michel,
696 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
697 ** 1973, pg. 11.12-11.17
698 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
699 ** for Analog-to_Digital Conversion Techniques,"
702 ** Input: Signed 16 bit linear sample
703 ** Output: 8 bit ulaw sample
706 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
707 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
710 static unsigned char linear_to_ulaw(int sample)
712 static int exp_lut[256] =
714 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
715 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
716 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
717 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
718 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
719 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
720 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
721 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
722 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
723 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
724 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
725 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
726 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
727 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
728 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
729 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
732 int sign, exponent, mantissa;
733 unsigned char ulawbyte;
735 /* Get the sample into sign-magnitude. */
736 sign = (sample >> 8) & 0x80; /* set aside the sign */
738 sample = -sample; /* get magnitude */
740 sample = CLIP; /* clip the magnitude */
742 /* Convert from 16 bit linear to ulaw. */
743 sample = sample + BIAS;
744 exponent = exp_lut[( sample >> 7 ) & 0xFF];
745 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
746 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
749 ulawbyte = 0x02; /* optional CCITT trap */
756 ** This routine converts from ulaw to 16 bit linear.
758 ** Craig Reese: IDA/Supercomputing Research Center
762 ** 1) CCITT Recommendation G.711 (very difficult to follow)
763 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
764 ** for Analog-to_Digital Conversion Techniques,"
767 ** Input: 8 bit ulaw sample
768 ** Output: signed 16 bit linear sample
771 static int ulaw_to_linear(unsigned char ulawbyte)
773 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
774 int sign, exponent, mantissa, sample;
776 ulawbyte = ~ ulawbyte;
777 sign = ( ulawbyte & 0x80 );
778 exponent = ( ulawbyte >> 4 ) & 0x07;
779 mantissa = ulawbyte & 0x0F;
780 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
786 #endif /* PLATFORM_UNIX && !AUDIO_STREAMING_DSP */
788 /*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
790 /*===========================================================================*/
792 /*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/
794 void AllocSoundArray(int num)
797 Sound = checked_calloc(num_sounds * sizeof(struct SampleInfo));
800 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
801 #define WAV_HEADER_SIZE 20 /* size of WAV file header */
803 boolean LoadSound(int sound_nr, char *sound_name)
805 struct SampleInfo *snd_info = &Sound[sound_nr];
807 char *sound_ext = "wav";
808 #if !defined(TARGET_SDL)
809 #if !defined(PLATFORM_MSDOS)
810 byte sound_header_buffer[WAV_HEADER_SIZE];
811 char chunk[CHUNK_ID_LEN + 1];
812 int chunk_length, dummy;
818 snd_info->name = sound_name;
820 sprintf(filename, "%s/%s/%s.%s",
821 options.ro_base_directory, SOUNDS_DIRECTORY,
822 snd_info->name, sound_ext);
824 #if defined(TARGET_SDL)
826 snd_info->mix_chunk = Mix_LoadWAV(filename);
827 if (snd_info->mix_chunk == NULL)
829 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
833 #else /* !TARGET_SDL */
835 #if !defined(PLATFORM_MSDOS)
837 if ((file = fopen(filename, "r")) == NULL)
839 Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
843 /* read chunk "RIFF" */
844 getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
845 if (strcmp(chunk, "RIFF") != 0)
847 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
852 /* read chunk "WAVE" */
853 getFileChunk(file, chunk, &dummy, BYTE_ORDER_LITTLE_ENDIAN);
854 if (strcmp(chunk, "WAVE") != 0)
856 Error(ERR_WARN, "missing 'WAVE' chunk of sound file '%s'", filename);
861 /* read header information */
862 for (i=0; i<WAV_HEADER_SIZE; i++)
863 sound_header_buffer[i] = fgetc(file);
865 /* read chunk "data" */
866 getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
867 if (strcmp(chunk, "data") != 0)
869 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
874 snd_info->data_len = chunk_length;
875 snd_info->data_ptr = checked_malloc(snd_info->data_len);
877 /* read sound data */
878 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
881 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
888 for (i=0; i<snd_info->data_len; i++)
889 snd_info->data_ptr[i] = snd_info->data_ptr[i] ^ 0x80;
891 #else /* PLATFORM_MSDOS */
893 snd_info->sample_ptr = load_sample(filename);
894 if (!snd_info->sample_ptr)
896 Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
900 #endif /* PLATFORM_MSDOS */
901 #endif /* !TARGET_SDL */
906 void PlaySound(int nr)
908 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
911 void PlaySoundStereo(int nr, int stereo)
913 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
916 void PlaySoundLoop(int nr)
918 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
921 void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
923 struct SoundControl snd_ctrl = emptySoundControl;
925 if (!audio.sound_available || !audio.sound_enabled)
928 if (volume<PSND_MIN_VOLUME)
929 volume = PSND_MIN_VOLUME;
930 else if (volume>PSND_MAX_VOLUME)
931 volume = PSND_MAX_VOLUME;
933 if (stereo<PSND_MAX_LEFT)
934 stereo = PSND_MAX_LEFT;
935 else if (stereo>PSND_MAX_RIGHT)
936 stereo = PSND_MAX_RIGHT;
939 snd_ctrl.volume = volume;
940 snd_ctrl.stereo = stereo;
941 snd_ctrl.loop = loop;
942 snd_ctrl.active = TRUE;
943 snd_ctrl.data_ptr = Sound[nr].data_ptr;
944 snd_ctrl.data_len = Sound[nr].data_len;
946 #if defined(TARGET_SDL)
948 Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4);
949 Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4);
951 Mix_PlayChannel(-1, Sound[nr].mix_chunk, (loop ? -1 : 0));
954 #if !defined(PLATFORM_MSDOS)
955 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
957 Error(ERR_WARN, "cannot pipe to child process - no sounds");
958 audio.sound_available = audio.sound_enabled = FALSE;
962 sound_handler(snd_ctrl);
967 void FadeSound(int nr)
969 StopSoundExt(nr, SSND_FADE_SOUND);
974 StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
977 void StopSound(int nr)
979 StopSoundExt(nr, SSND_STOP_SOUND);
984 StopSoundExt(-1, SSND_STOP_ALL_SOUNDS);
987 void StopSoundExt(int nr, int method)
989 struct SoundControl snd_ctrl = emptySoundControl;
991 if (!audio.sound_available)
994 if (SSND_FADING(method))
995 snd_ctrl.fade_sound = TRUE;
997 if (SSND_ALL(method))
998 snd_ctrl.stop_all_sounds = TRUE;
1002 snd_ctrl.stop_sound = TRUE;
1005 #if defined(TARGET_SDL)
1007 if (SSND_FADING(method))
1009 Mix_FadeOutChannel(-1, 1000);
1010 Mix_FadeOutMusic(1000);
1014 Mix_HaltChannel(-1);
1019 #if !defined(PLATFORM_MSDOS)
1020 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1022 Error(ERR_WARN, "cannot pipe to child process - no sounds");
1023 audio.sound_available = audio.sound_enabled = FALSE;
1027 sound_handler(snd_ctrl);
1032 void FreeSounds(int num_sounds)
1036 if (!audio.sound_available)
1039 for(i=0; i<num_sounds; i++)
1040 #if !defined(PLATFORM_MSDOS)
1041 free(Sound[i].data_ptr);
1043 destroy_sample(Sound[i].sample_ptr);
1047 /*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/