1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2001 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
31 struct ListNode *next;
33 typedef struct ListNode ListNode;
35 static ListNode *newListNode(void);
36 static void addNodeToList(ListNode **, char *, void *);
37 static void deleteNodeFromList(ListNode **, char *, void (*function)(void *));
38 static ListNode *getNodeFromKey(ListNode *, char *);
39 static int getNumNodes(ListNode *);
42 static struct SoundEffectInfo *sound_effect;
43 static ListNode *SoundFileList = NULL;
44 static SoundInfo **Sound = NULL;
45 static MusicInfo **Music = NULL;
46 static int num_sounds = 0, num_music = 0;
49 /* ========================================================================= */
50 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
52 static struct AudioFormatInfo afmt =
54 TRUE, 0, DEFAULT_AUDIO_SAMPLE_RATE, DEFAULT_AUDIO_FRAGMENT_SIZE
57 static int playing_sounds = 0;
58 static struct SoundControl playlist[NUM_MIXER_CHANNELS];
59 static struct SoundControl emptySoundControl =
62 FALSE, -1, 0, 0, FALSE, 0, 0, 0, NULL
64 -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, 0,0, 0,NULL
68 #if defined(PLATFORM_UNIX)
69 static int stereo_volume[PSND_MAX_LEFT2RIGHT + 1];
70 static short premix_first_buffer[SND_BLOCKSIZE];
71 #if defined(AUDIO_STREAMING_DSP)
72 static short premix_left_buffer[SND_BLOCKSIZE];
73 static short premix_right_buffer[SND_BLOCKSIZE];
74 static long premix_last_buffer[SND_BLOCKSIZE];
76 static byte playing_buffer[SND_BLOCKSIZE];
79 /* forward declaration of internal functions */
80 #if defined(AUDIO_STREAMING_DSP)
81 static void SoundServer_InsertNewSound(struct SoundControl);
82 static void InitAudioDevice_DSP(struct AudioFormatInfo *);
83 #elif defined(PLATFORM_HPUX)
84 static void InitAudioDevice_HPUX(struct AudioFormatInfo *);
85 #elif defined(PLATFORM_UNIX)
86 static unsigned char linear_to_ulaw(int);
87 static int ulaw_to_linear(unsigned char);
88 #elif defined(PLATFORM_MSDOS)
89 static void SoundServer_InsertNewSound(struct SoundControl);
90 static void SoundServer_StopSound(struct SoundControl);
91 static void SoundServer_StopAllSounds();
94 static void ReloadCustomSounds();
95 static void ReloadCustomMusic();
96 static void FreeSound(void *);
98 #if defined(PLATFORM_UNIX)
99 static int OpenAudioDevice(char *audio_device_name)
103 /* check if desired audio device is accessible */
104 if (access(audio_device_name, W_OK) != 0)
107 /* try to open audio device in non-blocking mode */
108 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
109 return audio_device_fd;
111 /* re-open audio device in blocking mode */
112 close(audio_device_fd);
113 audio_device_fd = open(audio_device_name, O_WRONLY);
115 return audio_device_fd;
118 static void CloseAudioDevice(int *audio_device_fd)
120 if (*audio_device_fd == 0)
123 close(*audio_device_fd);
124 *audio_device_fd = -1;
127 static boolean TestAudioDevices(void)
129 static char *audio_device_name[] =
134 int audio_device_fd = -1;
137 /* look for available audio devices, starting with preferred ones */
138 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
139 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
142 if (audio_device_fd < 0)
144 Error(ERR_WARN, "cannot open audio device -- no sound");
148 close(audio_device_fd);
150 audio.device_name = audio_device_name[i];
155 #if !defined(TARGET_SDL)
156 static boolean ForkAudioProcess(void)
158 if (pipe(audio.soundserver_pipe) < 0)
160 Error(ERR_WARN, "cannot create pipe -- no sounds");
164 if ((audio.soundserver_pid = fork()) < 0)
166 Error(ERR_WARN, "cannot create sound server process -- no sounds");
170 if (audio.soundserver_pid == 0) /* we are child process */
177 else /* we are parent */
178 close(audio.soundserver_pipe[0]); /* no reading from pipe needed */
184 void UnixOpenAudio(void)
186 if (!TestAudioDevices())
189 audio.sound_available = TRUE;
190 audio.sound_enabled = TRUE;
192 #if defined(AUDIO_STREAMING_DSP)
193 audio.music_available = TRUE;
194 audio.loops_available = TRUE;
198 void UnixCloseAudio(void)
201 close(audio.device_fd);
203 if (audio.soundserver_pid > 0) /* we are parent process */
204 kill(audio.soundserver_pid, SIGTERM);
206 #endif /* PLATFORM_UNIX */
208 void InitPlaylist(void)
212 for(i=0; i<NUM_MIXER_CHANNELS; i++)
213 playlist[i] = emptySoundControl;
218 static void PlaylistRemoveSound(int pos)
220 if (!playing_sounds || !playlist[pos].active)
223 playlist[pos] = emptySoundControl;
227 CloseAudioDevice(&audio.device_fd);
230 static void WriteReloadInfoToPipe(char *set_name, int type)
232 struct SoundControl snd_ctrl = emptySoundControl;
233 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
234 artwork.mus_current);
235 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
236 unsigned long str_size2 = strlen(ti->basepath) + 1;
237 unsigned long str_size3 = strlen(ti->fullpath) + 1;
239 snd_ctrl.state = type;
240 snd_ctrl.data_len = strlen(set_name) + 1;
242 if (write(audio.soundserver_pipe[1], &snd_ctrl,
243 sizeof(snd_ctrl)) < 0 ||
244 write(audio.soundserver_pipe[1], set_name,
245 snd_ctrl.data_len) < 0 ||
246 write(audio.soundserver_pipe[1], leveldir_current,
247 sizeof(TreeInfo)) < 0 ||
248 write(audio.soundserver_pipe[1], ti,
249 sizeof(TreeInfo)) < 0 ||
250 write(audio.soundserver_pipe[1], &str_size1,
251 sizeof(unsigned long)) < 0 ||
252 write(audio.soundserver_pipe[1], &str_size2,
253 sizeof(unsigned long)) < 0 ||
254 write(audio.soundserver_pipe[1], &str_size3,
255 sizeof(unsigned long)) < 0 ||
256 write(audio.soundserver_pipe[1], leveldir_current->fullpath,
258 write(audio.soundserver_pipe[1], ti->basepath,
260 write(audio.soundserver_pipe[1], ti->fullpath,
263 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
264 audio.sound_available = audio.sound_enabled = FALSE;
269 static void ReadReloadInfoFromPipe(struct SoundControl snd_ctrl)
271 TreeInfo **ti_ptr = ((snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS) ?
272 &artwork.snd_current : &artwork.mus_current);
273 TreeInfo *ti = *ti_ptr;
274 unsigned long str_size1, str_size2, str_size3;
275 static char *set_name = NULL;
280 set_name = checked_malloc(snd_ctrl.data_len);
282 if (leveldir_current == NULL)
283 leveldir_current = checked_calloc(sizeof(TreeInfo));
285 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
286 if (leveldir_current->fullpath != NULL)
287 free(leveldir_current->fullpath);
288 if (ti->basepath != NULL)
290 if (ti->fullpath != NULL)
293 if (read(audio.soundserver_pipe[0], set_name,
294 snd_ctrl.data_len) != snd_ctrl.data_len ||
295 read(audio.soundserver_pipe[0], leveldir_current,
296 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
297 read(audio.soundserver_pipe[0], ti,
298 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
299 read(audio.soundserver_pipe[0], &str_size1,
300 sizeof(unsigned long)) != sizeof(unsigned long) ||
301 read(audio.soundserver_pipe[0], &str_size2,
302 sizeof(unsigned long)) != sizeof(unsigned long) ||
303 read(audio.soundserver_pipe[0], &str_size3,
304 sizeof(unsigned long)) != sizeof(unsigned long))
305 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
307 leveldir_current->fullpath = checked_calloc(str_size1);
308 ti->basepath = checked_calloc(str_size2);
309 ti->fullpath = checked_calloc(str_size3);
311 if (read(audio.soundserver_pipe[0], leveldir_current->fullpath,
312 str_size1) != str_size1 ||
313 read(audio.soundserver_pipe[0], ti->basepath,
314 str_size2) != str_size2 ||
315 read(audio.soundserver_pipe[0], ti->fullpath,
316 str_size3) != str_size3)
317 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
319 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
320 artwork.sounds_set_current = set_name;
322 artwork.music_set_current = set_name;
325 static void HandleSoundRequest(struct SoundControl snd_ctrl)
329 if (IS_RELOADING(snd_ctrl))
331 ReadReloadInfoFromPipe(snd_ctrl);
333 CloseAudioDevice(&audio.device_fd);
335 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
336 ReloadCustomSounds();
340 else if (IS_FADING(snd_ctrl))
345 if (IS_MUSIC(snd_ctrl))
347 playlist[MUSIC_CHANNEL].state |= SND_CTRL_FADE;
351 for(i=FIRST_SOUND_CHANNEL; i<NUM_MIXER_CHANNELS; i++)
352 if (playlist[i].nr == snd_ctrl.nr || ALL_SOUNDS(snd_ctrl))
353 playlist[i].state |= SND_CTRL_FADE;
355 else if (IS_STOPPING(snd_ctrl))
360 if (IS_MUSIC(snd_ctrl))
362 PlaylistRemoveSound(MUSIC_CHANNEL);
366 for(i=FIRST_SOUND_CHANNEL; i<NUM_MIXER_CHANNELS; i++)
367 if (playlist[i].nr == snd_ctrl.nr || ALL_SOUNDS(snd_ctrl))
368 PlaylistRemoveSound(i);
373 void StartSoundserver(void)
375 if (!audio.sound_available)
378 #if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
379 if (!ForkAudioProcess())
380 audio.sound_available = FALSE;
384 #if defined(PLATFORM_UNIX)
385 void SoundServer(void)
389 struct SoundControl snd_ctrl;
392 close(audio.soundserver_pipe[1]); /* no writing into pipe needed */
396 stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
397 for(i=0; i<PSND_MAX_LEFT2RIGHT; i++)
399 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT * PSND_MAX_LEFT2RIGHT - i * i));
401 #if defined(PLATFORM_HPUX)
402 InitAudioDevice_HPUX(&afmt);
405 FD_ZERO(&sound_fdset);
406 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
408 while(1) /* wait for sound playing commands from client */
410 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
411 select(audio.soundserver_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
412 if (!FD_ISSET(audio.soundserver_pipe[0], &sound_fdset))
414 if (read(audio.soundserver_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
416 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
418 HandleSoundRequest(snd_ctrl);
420 if (IS_RELOADING(snd_ctrl))
423 #if defined(AUDIO_STREAMING_DSP)
425 if (playing_sounds || snd_ctrl.active)
427 if (playing_sounds ||
428 (audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
430 struct timeval delay = { 0, 0 };
432 if (!playing_sounds) /* we just opened the audio device */
433 InitAudioDevice_DSP(&afmt);
435 if (snd_ctrl.active) /* new sound has arrived */
436 SoundServer_InsertNewSound(snd_ctrl);
438 while (playing_sounds &&
439 select(audio.soundserver_pipe[0] + 1,
440 &sound_fdset, NULL, NULL, &delay) < 1)
443 int fragment_size = afmt.fragment_size;
444 int sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
445 boolean stereo = afmt.stereo;
447 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
449 max_sample_size = fragment_size / ((stereo ? 2 : 1) * sample_bytes);
451 /* first clear the last premixing buffer */
452 memset(premix_last_buffer, 0,
453 max_sample_size * (stereo ? 2 : 1) * sizeof(long));
455 for(i=0; i<NUM_MIXER_CHANNELS; i++)
463 if (!playlist[i].active)
466 /* pointer, lenght and actual playing position of sound sample */
467 sample_ptr = playlist[i].data_ptr;
468 sample_len = playlist[i].data_len;
469 sample_pos = playlist[i].playingpos;
470 sample_size = MIN(max_sample_size, sample_len - sample_pos);
471 playlist[i].playingpos += sample_size;
473 /* copy original sample to first mixing buffer */
474 if (playlist[i].format == AUDIO_FORMAT_U8)
475 for (j=0; j<sample_size; j++)
476 premix_first_buffer[j] =
477 ((short)(((byte *)sample_ptr)[sample_pos + j] ^ 0x80)) << 8;
478 else /* AUDIO_FORMAT_S16 */
479 for (j=0; j<sample_size; j++)
480 premix_first_buffer[j] =
481 ((short *)sample_ptr)[sample_pos + j];
483 /* are we about to restart a looping sound? */
484 if (IS_LOOP(playlist[i]) && sample_size < max_sample_size)
486 while (sample_size < max_sample_size)
488 int restarted_sample_size =
489 MIN(max_sample_size - sample_size, sample_len);
491 if (playlist[i].format == AUDIO_FORMAT_U8)
492 for (j=0; j<restarted_sample_size; j++)
493 premix_first_buffer[sample_size + j] =
494 ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
496 for (j=0; j<restarted_sample_size; j++)
497 premix_first_buffer[sample_size + j] =
498 ((short *)sample_ptr)[j];
500 playlist[i].playingpos = restarted_sample_size;
501 sample_size += restarted_sample_size;
505 /* decrease volume if sound is fading out */
506 if (IS_FADING(playlist[i]) &&
507 playlist[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
508 playlist[i].volume -= SOUND_FADING_VOLUME_STEP;
510 /* adjust volume of actual sound sample */
511 if (playlist[i].volume != PSND_MAX_VOLUME)
512 for(j=0; j<sample_size; j++)
513 premix_first_buffer[j] =
514 (playlist[i].volume * (long)premix_first_buffer[j])
515 >> PSND_MAX_VOLUME_BITS;
517 /* fill the last mixing buffer with stereo or mono sound */
520 int middle_pos = PSND_MAX_LEFT2RIGHT / 2;
521 int left_volume = stereo_volume[middle_pos + playlist[i].stereo];
522 int right_volume= stereo_volume[middle_pos - playlist[i].stereo];
524 for(j=0; j<sample_size; j++)
526 premix_left_buffer[j] =
527 (left_volume * premix_first_buffer[j])
528 >> PSND_MAX_LEFT2RIGHT_BITS;
529 premix_right_buffer[j] =
530 (right_volume * premix_first_buffer[j])
531 >> PSND_MAX_LEFT2RIGHT_BITS;
533 premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
534 premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
539 for(j=0; j<sample_size; j++)
540 premix_last_buffer[j] += premix_first_buffer[j];
543 /* delete completed sound entries from the playlist */
544 if (playlist[i].playingpos >= playlist[i].data_len)
546 if (IS_LOOP(playlist[i]))
547 playlist[i].playingpos = 0;
550 playlist[i] = emptySoundControl;
554 else if (playlist[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
556 playlist[i] = emptySoundControl;
561 /* prepare final playing buffer according to system audio format */
562 for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
564 /* cut off at 17 bit value */
565 if (premix_last_buffer[i] < -65535)
566 premix_last_buffer[i] = -65535;
567 else if (premix_last_buffer[i] > 65535)
568 premix_last_buffer[i] = 65535;
570 /* shift to 16 bit value */
571 premix_last_buffer[i] >>= 1;
573 if (afmt.format & AUDIO_FORMAT_U8)
575 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
577 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
579 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
580 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
582 else /* big endian */
584 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
585 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
589 /* finally play the sound fragment */
590 write(audio.device_fd, playing_buffer, fragment_size);
593 /* if no sounds playing, free device for other sound programs */
595 close(audio.device_fd);
599 #else /* !AUDIO_STREAMING_DSP */
601 if (snd_ctrl.active && !IS_LOOP(snd_ctrl))
603 struct timeval delay = { 0, 0 };
605 long sample_size, max_sample_size = SND_BLOCKSIZE;
606 long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
607 int wait_percent = 90; /* wait 90% of the real playing time */
610 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
614 while (playing_sounds &&
615 select(audio.soundserver_pipe[0] + 1,
616 &sound_fdset, NULL, NULL, &delay) < 1)
618 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
620 /* get pointer and size of the actual sound sample */
621 sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
623 MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
624 snd_ctrl.playingpos += sample_size;
626 /* fill the first mixing buffer with original sample */
627 memcpy(premix_first_buffer,sample_ptr,sample_size);
629 /* adjust volume of actual sound sample */
630 if (snd_ctrl.volume != PSND_MAX_VOLUME)
631 for(i=0;i<sample_size;i++)
632 premix_first_buffer[i] =
633 (snd_ctrl.volume * (int)premix_first_buffer[i])
634 >> PSND_MAX_VOLUME_BITS;
636 for(i=0;i<sample_size;i++)
638 linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
640 if (snd_ctrl.playingpos >= snd_ctrl.data_len)
643 /* finally play the sound fragment */
644 write(audio.device_fd,playing_buffer,sample_size);
647 delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
649 close(audio.device_fd);
652 #endif /* !AUDIO_STREAMING_DSP */
655 #endif /* PLATFORM_UNIX */
657 #if defined(PLATFORM_MSDOS)
658 static void sound_handler(struct SoundControl snd_ctrl)
662 if (snd_ctrl.fade_sound)
667 for (i=0; i<NUM_MIXER_CHANNELS; i++)
668 if ((snd_ctrl.stop_all_sounds ||
669 (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr) ||
670 (i == audio.music_channel && snd_ctrl.music)) &&
671 !playlist[i].fade_sound)
673 playlist[i].fade_sound = TRUE;
674 if (voice_check(playlist[i].voice))
675 voice_ramp_volume(playlist[i].voice, 1000, 0);
676 playlist[i].state &= ~SND_CTRL_IS_LOOP;
679 else if (snd_ctrl.stop_all_sounds)
683 SoundServer_StopAllSounds();
685 else if (snd_ctrl.stop_sound)
689 SoundServer_StopSound(snd_ctrl);
692 for (i=0; i<NUM_MIXER_CHANNELS; i++)
694 if (!playlist[i].active || playlist[i].loop)
697 playlist[i].playingpos = voice_get_position(playlist[i].voice);
698 playlist[i].volume = voice_get_volume(playlist[i].voice);
699 if (playlist[i].playingpos == -1 || !playlist[i].volume)
701 deallocate_voice(playlist[i].voice);
702 playlist[i] = emptySoundControl;
708 SoundServer_InsertNewSound(snd_ctrl);
710 #endif /* PLATFORM_MSDOS */
713 #if defined(TARGET_SDL)
714 static void sound_handler_SDL(struct SoundControl snd_ctrl)
716 /* copy sound_handler() here ... */
718 #endif /* TARGET_SDL */
721 #if !defined(PLATFORM_WIN32)
722 static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
728 printf("NEW SOUND %d HAS ARRIVED [%d]\n", snd_ctrl.nr, num_sounds);
731 if (IS_MUSIC(snd_ctrl))
732 snd_ctrl.nr = snd_ctrl.nr % num_music;
733 else if (snd_ctrl.nr >= num_sounds)
736 snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
737 if (snd_info == NULL)
740 printf("sound/music %d undefined\n", snd_ctrl.nr);
746 printf("-> %d\n", playing_sounds);
749 if (playing_sounds == NUM_MIXER_CHANNELS)
751 for (i=0; i<NUM_MIXER_CHANNELS; i++)
753 if (playlist[i].data_ptr == NULL)
756 printf("THIS SHOULD NEVER HAPPEN! [%d]\n", i);
759 playlist[i] = emptySoundControl;
765 /* if playlist is full, remove oldest sound */
766 if (playing_sounds == NUM_MIXER_CHANNELS)
768 int longest = 0, longest_nr = 0;
770 for (i=FIRST_SOUND_CHANNEL; i<NUM_MIXER_CHANNELS; i++)
772 #if !defined(PLATFORM_MSDOS)
773 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
775 int actual = playlist[i].playingpos;
778 if (!IS_LOOP(playlist[i]) && actual > longest)
784 #if defined(PLATFORM_MSDOS)
785 voice_set_volume(playlist[longest_nr].voice, 0);
786 deallocate_voice(playlist[longest_nr].voice);
788 playlist[longest_nr] = emptySoundControl;
792 /* check if sound is already being played (and how often) */
793 for (k=0, i=FIRST_SOUND_CHANNEL; i<NUM_MIXER_CHANNELS; i++)
794 if (playlist[i].nr == snd_ctrl.nr)
797 /* restart loop sounds only if they are just fading out */
798 if (k >= 1 && IS_LOOP(snd_ctrl))
800 for(i=FIRST_SOUND_CHANNEL; i<NUM_MIXER_CHANNELS; i++)
802 if (playlist[i].nr == snd_ctrl.nr && IS_FADING(playlist[i]))
804 playlist[i].state &= ~SND_CTRL_FADE;
805 playlist[i].volume = PSND_MAX_VOLUME;
806 #if defined(PLATFORM_MSDOS)
807 playlist[i].state |= SND_CTRL_LOOP;
808 voice_stop_volumeramp(playlist[i].voice);
809 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
817 /* don't play sound more than n times simultaneously (with n == 2 for now) */
820 int longest = 0, longest_nr = 0;
822 /* look for oldest equal sound */
823 for(i=FIRST_SOUND_CHANNEL; i<NUM_MIXER_CHANNELS; i++)
827 if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
830 #if !defined(PLATFORM_MSDOS)
831 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
833 actual = playlist[i].playingpos;
835 if (actual >= longest)
842 #if defined(PLATFORM_MSDOS)
843 voice_set_volume(playlist[longest_nr].voice, 0);
844 deallocate_voice(playlist[longest_nr].voice);
846 playlist[longest_nr] = emptySoundControl;
850 /* add new sound to playlist */
851 for(i=0; i<NUM_MIXER_CHANNELS; i++)
854 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
858 if (!playlist[i].active ||
859 (IS_MUSIC(snd_ctrl) && i == MUSIC_CHANNEL))
861 if ((i == MUSIC_CHANNEL && IS_MUSIC(snd_ctrl)) ||
862 (i != MUSIC_CHANNEL && !playlist[i].active))
864 snd_ctrl.data_ptr = snd_info->data_ptr;
865 snd_ctrl.data_len = snd_info->data_len;
866 snd_ctrl.format = snd_info->format;
869 if (snd_info->data_len == 0)
871 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
876 if (IS_MUSIC(snd_ctrl) && i == MUSIC_CHANNEL && playlist[i].active)
878 printf("THIS SHOULD NEVER HAPPEN! [adding music twice]\n");
881 playlist[i] = emptySoundControl;
887 playlist[i] = snd_ctrl;
891 printf("NEW SOUND %d ADDED TO PLAYLIST\n", snd_ctrl.nr);
894 #if defined(PLATFORM_MSDOS)
895 playlist[i].voice = allocate_voice((SAMPLE *)playlist[i].data_ptr);
898 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
900 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
901 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
902 voice_start(playlist[i].voice);
908 #endif /* !PLATFORM_WIN32 */
911 void SoundServer_FadeSound(int nr)
918 for(i=0;i<NUM_MIXER_CHANNELS;i++)
919 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
920 playlist[i].fade_sound = TRUE;
924 #if !defined(PLATFORM_WIN32)
925 #if defined(PLATFORM_MSDOS)
926 static void SoundServer_StopSound(struct SoundControl snd_ctrl)
928 int nr = snd_ctrl.nr;
934 for(i=0; i<NUM_MIXER_CHANNELS; i++)
936 if ((i == audio.music_channel && snd_ctrl.music) ||
937 (i != audio.music_channel && playlist[i].nr == nr))
939 #if defined(PLATFORM_MSDOS)
940 voice_set_volume(playlist[i].voice, 0);
941 deallocate_voice(playlist[i].voice);
943 playlist[i] = emptySoundControl;
948 #if !defined(PLATFORM_MSDOS)
950 close(audio.device_fd);
954 static void SoundServer_StopAllSounds()
958 for(i=0; i<NUM_MIXER_CHANNELS; i++)
960 #if defined(PLATFORM_MSDOS)
961 voice_set_volume(playlist[i].voice, 0);
962 deallocate_voice(playlist[i].voice);
964 playlist[i] = emptySoundControl;
968 #if !defined(PLATFORM_MSDOS)
969 close(audio.device_fd);
972 #endif /* PLATFORM_MSDOS */
973 #endif /* !PLATFORM_WIN32 */
976 /* ------------------------------------------------------------------------- */
977 /* platform dependant audio initialization code */
978 /* ------------------------------------------------------------------------- */
980 #if defined(AUDIO_LINUX_IOCTL)
981 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
983 /* "ioctl()" expects pointer to 'int' value for stereo flag
984 (boolean is defined as 'char', which will not work here) */
985 unsigned int fragment_spec = 0;
986 int fragment_size_query;
995 /* supported audio format in preferred order */
996 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
997 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
998 { AFMT_U8, AUDIO_FORMAT_U8 },
1003 /* determine logarithm (log2) of the fragment size */
1004 while ((1 << fragment_spec) < afmt->fragment_size)
1007 /* use two fragments (play one fragment, prepare the other);
1008 one fragment would result in interrupted audio output, more
1009 than two fragments would raise audio output latency to much */
1010 fragment_spec |= 0x00020000;
1012 /* Example for fragment specification:
1013 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
1014 - (with stereo the effective buffer size will shrink to 256)
1015 => fragment_size = 0x00020009 */
1017 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
1018 Error(ERR_EXIT_SOUND_SERVER,
1019 "cannot set fragment size of /dev/dsp -- no sounds");
1023 while (formats[i].format_result != -1)
1025 unsigned int audio_format = formats[i].format_ioctl;
1026 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
1028 afmt->format = formats[i].format_result;
1033 if (afmt->format == 0) /* no supported audio format found */
1034 Error(ERR_EXIT_SOUND_SERVER,
1035 "cannot set audio format of /dev/dsp -- no sounds");
1037 /* try if we can use stereo sound */
1038 afmt->stereo = TRUE;
1039 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
1040 afmt->stereo = FALSE;
1042 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
1043 Error(ERR_EXIT_SOUND_SERVER,
1044 "cannot set sample rate of /dev/dsp -- no sounds");
1046 /* get the real fragmentation size; this should return 512 */
1047 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
1048 Error(ERR_EXIT_SOUND_SERVER,
1049 "cannot get fragment size of /dev/dsp -- no sounds");
1050 if (fragment_size_query != afmt->fragment_size)
1051 Error(ERR_EXIT_SOUND_SERVER,
1052 "cannot set fragment size of /dev/dsp -- no sounds");
1054 #endif /* AUDIO_LINUX_IOCTL */
1056 #if defined(PLATFORM_NETBSD)
1057 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
1059 audio_info_t a_info;
1060 boolean stereo = TRUE;
1062 AUDIO_INITINFO(&a_info);
1063 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
1064 a_info.play.precision = 8;
1065 a_info.play.channels = 2;
1066 a_info.play.sample_rate = sample_rate;
1067 a_info.blocksize = fragment_size;
1069 afmt->format = AUDIO_FORMAT_U8;
1070 afmt->stereo = TRUE;
1072 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
1074 /* try to disable stereo */
1075 a_info.play.channels = 1;
1077 afmt->stereo = FALSE;
1079 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
1080 Error(ERR_EXIT_SOUND_SERVER,
1081 "cannot set sample rate of /dev/audio -- no sounds");
1084 #endif /* PLATFORM_NETBSD */
1086 #if defined(PLATFORM_HPUX)
1087 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
1089 struct audio_describe ainfo;
1092 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
1093 if (audio_ctl == -1)
1094 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl -- no sounds");
1096 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
1097 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
1099 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
1100 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
1102 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
1103 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
1105 afmt->format = AUDIO_FORMAT_U8;
1106 afmt->stereo = FALSE;
1107 afmt->sample_rate = 8000;
1111 #endif /* PLATFORM_HPUX */
1113 #if defined(PLATFORM_UNIX)
1114 static void InitAudioDevice_DSP(struct AudioFormatInfo *afmt)
1116 #if defined(AUDIO_LINUX_IOCTL)
1117 InitAudioDevice_Linux(afmt);
1118 #elif defined(PLATFORM_NETBSD)
1119 InitAudioDevice_NetBSD(afmt);
1120 #elif defined(PLATFORM_HPUX)
1121 InitAudioDevice_HPUX(afmt);
1124 #endif /* PLATFORM_UNIX */
1126 #if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
1128 /* these two are stolen from "sox"... :) */
1131 ** This routine converts from linear to ulaw.
1133 ** Craig Reese: IDA/Supercomputing Research Center
1134 ** Joe Campbell: Department of Defense
1135 ** 29 September 1989
1138 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1139 ** 2) "A New Digital Technique for Implementation of Any
1140 ** Continuous PCM Companding Law," Villeret, Michel,
1141 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1142 ** 1973, pg. 11.12-11.17
1143 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1144 ** for Analog-to_Digital Conversion Techniques,"
1147 ** Input: Signed 16 bit linear sample
1148 ** Output: 8 bit ulaw sample
1151 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1152 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1155 static unsigned char linear_to_ulaw(int sample)
1157 static int exp_lut[256] =
1159 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1160 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1161 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1162 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1163 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1164 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1165 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1166 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1167 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1168 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1169 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1170 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1171 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1172 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1173 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1174 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1177 int sign, exponent, mantissa;
1178 unsigned char ulawbyte;
1180 /* Get the sample into sign-magnitude. */
1181 sign = (sample >> 8) & 0x80; /* set aside the sign */
1183 sample = -sample; /* get magnitude */
1185 sample = CLIP; /* clip the magnitude */
1187 /* Convert from 16 bit linear to ulaw. */
1188 sample = sample + BIAS;
1189 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1190 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1191 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1194 ulawbyte = 0x02; /* optional CCITT trap */
1201 ** This routine converts from ulaw to 16 bit linear.
1203 ** Craig Reese: IDA/Supercomputing Research Center
1204 ** 29 September 1989
1207 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1208 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1209 ** for Analog-to_Digital Conversion Techniques,"
1212 ** Input: 8 bit ulaw sample
1213 ** Output: signed 16 bit linear sample
1216 static int ulaw_to_linear(unsigned char ulawbyte)
1218 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1219 int sign, exponent, mantissa, sample;
1221 ulawbyte = ~ ulawbyte;
1222 sign = ( ulawbyte & 0x80 );
1223 exponent = ( ulawbyte >> 4 ) & 0x07;
1224 mantissa = ulawbyte & 0x0F;
1225 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1231 #endif /* PLATFORM_UNIX && !AUDIO_STREAMING_DSP */
1234 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1235 /* ========================================================================= */
1236 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1238 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1239 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1241 static SoundInfo *Load_WAV(char *filename)
1243 SoundInfo *snd_info;
1244 #if !defined(TARGET_SDL) && !defined(PLATFORM_MSDOS)
1245 byte sound_header_buffer[WAV_HEADER_SIZE];
1246 char chunk_name[CHUNK_ID_LEN + 1];
1252 if (!audio.sound_available)
1256 printf("loading WAV file '%s'\n", filename);
1259 snd_info = checked_calloc(sizeof(SoundInfo));
1261 #if defined(TARGET_SDL)
1263 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1265 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1270 #elif defined(TARGET_ALLEGRO)
1272 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1274 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1279 #else /* PLATFORM_UNIX */
1281 if ((file = fopen(filename, MODE_READ)) == NULL)
1283 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1288 /* read chunk id "RIFF" */
1289 getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN);
1290 if (strcmp(chunk_name, "RIFF") != 0)
1292 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1298 /* read "RIFF" type id "WAVE" */
1299 getFileChunk(file, chunk_name, NULL, BYTE_ORDER_LITTLE_ENDIAN);
1300 if (strcmp(chunk_name, "WAVE") != 0)
1302 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1308 while (getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN))
1310 if (strcmp(chunk_name, "fmt ") == 0)
1312 /* read header information */
1313 for (i=0; i < MIN(chunk_size, WAV_HEADER_SIZE); i++)
1314 sound_header_buffer[i] = fgetc(file);
1316 if (chunk_size > WAV_HEADER_SIZE)
1317 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1319 else if (strcmp(chunk_name, "data") == 0)
1321 snd_info->data_len = chunk_size;
1322 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1324 /* read sound data */
1325 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1328 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1330 free(snd_info->data_ptr);
1335 /* check for odd number of sample bytes (data chunk is word aligned) */
1336 if ((chunk_size % 2) == 1)
1337 ReadUnusedBytesFromFile(file, 1);
1339 else /* unknown chunk -- ignore */
1340 ReadUnusedBytesFromFile(file, chunk_size);
1345 if (snd_info->data_ptr == NULL)
1347 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1352 snd_info->format = AUDIO_FORMAT_U8;
1354 #endif /* PLATFORM_UNIX */
1356 snd_info->type = SND_TYPE_WAV;
1357 snd_info->source_filename = getStringCopy(filename);
1362 static void deleteSoundEntry(SoundInfo **snd_info)
1366 char *filename = (*snd_info)->source_filename;
1369 printf("[decrementing reference counter of sound '%s']\n", filename);
1372 if (--(*snd_info)->num_references <= 0)
1375 printf("[deleting sound '%s']\n", filename);
1379 FreeSound(*snd_info);
1381 deleteNodeFromList(&SoundFileList, filename, FreeSound);
1388 static void replaceSoundEntry(SoundInfo **snd_info, char *filename)
1392 /* check if the old and the new sound file are the same */
1393 if (*snd_info && strcmp((*snd_info)->source_filename, filename) == 0)
1395 /* The old and new sound are the same (have the same filename and path).
1396 This usually means that this sound does not exist in this sound set
1397 and a fallback to the existing sound is done. */
1400 printf("[sound '%s' already exists (same list entry)]\n", filename);
1406 /* delete existing sound file entry */
1407 deleteSoundEntry(snd_info);
1409 /* check if the new sound file already exists in the list of sounds */
1410 if ((node = getNodeFromKey(SoundFileList, filename)) != NULL)
1413 printf("[sound '%s' already exists (other list entry)]\n", filename);
1416 *snd_info = (SoundInfo *)node->content;
1417 (*snd_info)->num_references++;
1419 else if ((*snd_info = Load_WAV(filename)) != NULL) /* load new sound */
1421 (*snd_info)->num_references = 1;
1422 addNodeToList(&SoundFileList, (*snd_info)->source_filename, *snd_info);
1426 static void LoadCustomSound(SoundInfo **snd_info, char *basename)
1428 char *filename = getCustomSoundFilename(basename);
1430 if (strcmp(basename, SND_FILE_UNDEFINED) == 0)
1432 deleteSoundEntry(snd_info);
1436 if (filename == NULL)
1438 Error(ERR_WARN, "cannot find sound file '%s'", basename);
1442 replaceSoundEntry(snd_info, filename);
1445 void InitSoundList(struct SoundEffectInfo *sounds_list, int num_list_entries)
1448 Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
1450 sound_effect = sounds_list;
1451 num_sounds = num_list_entries;
1454 void LoadSoundToList(char *basename, int list_pos)
1456 if (Sound == NULL || list_pos >= num_sounds)
1460 printf("loading sound '%s' ... [%d]\n",
1461 basename, getNumNodes(SoundFileList));
1464 LoadCustomSound(&Sound[list_pos], basename);
1467 printf("loading sound '%s' done [%d]\n",
1468 basename, getNumNodes(SoundFileList));
1472 static MusicInfo *Load_MOD(char *filename)
1474 #if defined(TARGET_SDL)
1475 MusicInfo *mod_info;
1477 if (!audio.sound_available)
1480 mod_info = checked_calloc(sizeof(MusicInfo));
1482 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1484 Error(ERR_WARN, "cannot read music file '%s'", filename);
1489 mod_info->type = MUS_TYPE_MOD;
1490 mod_info->source_filename = getStringCopy(filename);
1498 void LoadCustomMusic(void)
1500 char *music_directory = getCustomMusicDirectory();
1502 struct dirent *dir_entry;
1504 if (!audio.sound_available)
1507 if ((dir = opendir(music_directory)) == NULL)
1509 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1510 audio.music_available = FALSE;
1514 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1516 char *basename = dir_entry->d_name;
1517 char *filename = getPath2(music_directory, basename);
1518 MusicInfo *mus_info = NULL;
1520 if (FileIsSound(basename))
1521 mus_info = Load_WAV(filename);
1522 else if (FileIsMusic(basename))
1523 mus_info = Load_MOD(filename);
1530 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1531 Music[num_music -1] = mus_info;
1538 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1542 void PlayMusic(int nr)
1544 if (!audio.music_available)
1547 #if defined(TARGET_SDL)
1549 nr = nr % num_music;
1551 if (Music[nr]->type == MUS_TYPE_MOD)
1553 Mix_PlayMusic(Music[nr]->data_ptr, -1);
1554 Mix_VolumeMusic(SOUND_MAX_VOLUME); /* must be _after_ Mix_PlayMusic()! */
1556 else /* play WAV music loop */
1558 Mix_Volume(audio.music_channel, SOUND_MAX_VOLUME);
1559 Mix_PlayChannel(audio.music_channel, Music[nr]->data_ptr, -1);
1569 void PlaySound(int nr)
1571 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_SOUND);
1574 void PlaySoundStereo(int nr, int stereo)
1576 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, SND_CTRL_PLAY_SOUND);
1579 void PlaySoundLoop(int nr)
1581 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_LOOP);
1584 void PlaySoundMusic(int nr)
1586 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_MUSIC);
1589 void PlaySoundExt(int nr, int volume, int stereo, int state)
1591 struct SoundControl snd_ctrl = emptySoundControl;
1593 if (!audio.sound_available ||
1594 !audio.sound_enabled ||
1595 audio.sound_deactivated)
1598 if (volume < PSND_MIN_VOLUME)
1599 volume = PSND_MIN_VOLUME;
1600 else if (volume > PSND_MAX_VOLUME)
1601 volume = PSND_MAX_VOLUME;
1603 if (stereo < PSND_MAX_LEFT)
1604 stereo = PSND_MAX_LEFT;
1605 else if (stereo > PSND_MAX_RIGHT)
1606 stereo = PSND_MAX_RIGHT;
1608 snd_ctrl.active = TRUE;
1610 snd_ctrl.volume = volume;
1611 snd_ctrl.stereo = stereo;
1612 snd_ctrl.state = state;
1614 #if defined(TARGET_SDL)
1617 Mix_Volume(-1, SOUND_MAX_VOLUME);
1618 Mix_PlayChannel(-1, Sound[nr]->data_ptr, (state & SND_CTRL_LOOP ? -1 : 0));
1620 #elif defined(PLATFORM_UNIX)
1621 if (audio.soundserver_pid == 0) /* we are child process */
1624 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1626 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1627 audio.sound_available = audio.sound_enabled = FALSE;
1630 #elif defined(PLATFORM_MSDOS)
1631 sound_handler(snd_ctrl);
1635 void FadeMusic(void)
1637 if (!audio.sound_available)
1640 #if defined(TARGET_SDL)
1641 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
1642 Mix_FadeOutChannel(audio.music_channel, SOUND_FADING_INTERVAL);
1644 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
1648 void FadeSound(int nr)
1650 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
1656 StopSoundExt(-1, SND_CTRL_FADE_ALL);
1659 void StopMusic(void)
1661 #if defined(TARGET_SDL)
1662 if (!audio.sound_available)
1666 Mix_HaltChannel(audio.music_channel);
1668 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
1672 void StopSound(int nr)
1674 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
1680 StopSoundExt(-1, SND_CTRL_STOP_ALL);
1683 void StopSoundExt(int nr, int state)
1685 struct SoundControl snd_ctrl = emptySoundControl;
1687 if (!audio.sound_available)
1691 snd_ctrl.state = state;
1693 #if defined(TARGET_SDL)
1695 if (state & SND_CTRL_FADE)
1699 for (i=0; i<audio.channels; i++)
1700 if (i != audio.music_channel || snd_ctrl.music)
1701 Mix_FadeOutChannel(i, SOUND_FADING_INTERVAL);
1702 if (state & SND_CTRL_MUSIC)
1703 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
1709 for (i=0; i<audio.channels; i++)
1710 if (i != audio.music_channel || snd_ctrl.music)
1712 if (state & SND_CTRL_MUSIC)
1716 #elif !defined(PLATFORM_MSDOS)
1718 if (audio.soundserver_pid == 0) /* we are child process */
1721 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1723 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1724 audio.sound_available = audio.sound_enabled = FALSE;
1727 #else /* PLATFORM_MSDOS */
1728 sound_handler(snd_ctrl);
1732 ListNode *newListNode()
1734 return checked_calloc(sizeof(ListNode));
1737 void addNodeToList(ListNode **node_first, char *key, void *content)
1739 ListNode *node_new = newListNode();
1742 printf("LIST: adding node with key '%s'\n", key);
1745 node_new->key = getStringCopy(key);
1746 node_new->content = content;
1747 node_new->next = *node_first;
1748 *node_first = node_new;
1751 void deleteNodeFromList(ListNode **node_first, char *key,
1752 void (*destructor_function)(void *))
1754 if (node_first == NULL || *node_first == NULL)
1758 printf("[CHECKING LIST KEY '%s' == '%s']\n",
1759 (*node_first)->key, key);
1762 if (strcmp((*node_first)->key, key) == 0)
1765 printf("[DELETING LIST ENTRY]\n");
1768 free((*node_first)->key);
1769 if (destructor_function)
1770 destructor_function((*node_first)->content);
1771 *node_first = (*node_first)->next;
1774 deleteNodeFromList(&(*node_first)->next, key, destructor_function);
1777 ListNode *getNodeFromKey(ListNode *node_first, char *key)
1779 if (node_first == NULL)
1782 if (strcmp(node_first->key, key) == 0)
1785 return getNodeFromKey(node_first->next, key);
1788 int getNumNodes(ListNode *node_first)
1790 return (node_first ? 1 + getNumNodes(node_first->next) : 0);
1793 void dumpList(ListNode *node_first)
1795 ListNode *node = node_first;
1799 printf("['%s' (%d)]\n", node->key,
1800 ((SoundInfo *)node->content)->num_references);
1804 printf("[%d nodes]\n", getNumNodes(node_first));
1807 static void LoadSoundsInfo()
1809 char *filename = getCustomSoundConfigFilename();
1810 struct SetupFileList *setup_file_list;
1813 /* always start with reliable default values */
1814 for (i=0; i<num_sounds; i++)
1815 sound_effect[i].filename = NULL;
1817 if (filename == NULL)
1820 if ((setup_file_list = loadSetupFileList(filename)))
1822 for (i=0; i<num_sounds; i++)
1823 sound_effect[i].filename =
1824 getStringCopy(getTokenValue(setup_file_list, sound_effect[i].text));
1826 freeSetupFileList(setup_file_list);
1829 for (i=0; i<num_sounds; i++)
1831 printf("'%s' ", sound_effect[i].text);
1832 if (sound_effect[i].filename)
1833 printf("-> '%s'\n", sound_effect[i].filename);
1835 printf("-> UNDEFINED [-> '%s']\n", sound_effect[i].default_filename);
1841 static void ReloadCustomSounds()
1846 printf("DEBUG: reloading sounds '%s' ...\n", artwork.sounds_set_current);
1852 printf("DEBUG: reloading %d sounds ...\n", num_sounds);
1855 for(i=0; i<num_sounds; i++)
1857 if (sound_effect[i].filename)
1858 LoadSoundToList(sound_effect[i].filename, i);
1860 LoadSoundToList(sound_effect[i].default_filename, i);
1864 printf("list size == %d\n", getNumNodes(SoundFileList));
1868 dumpList(SoundFileList);
1872 static void ReloadCustomMusic()
1875 printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current);
1883 static void InitReloadSoundsOrMusic(char *set_name, int type)
1886 #if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
1887 struct SoundControl snd_ctrl = emptySoundControl;
1888 TreeInfo *ti = (state == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
1889 artwork.mus_current);
1890 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
1891 unsigned long str_size2 = strlen(ti->basepath) + 1;
1892 unsigned long str_size3 = strlen(ti->fullpath) + 1;
1896 if (!audio.sound_available)
1899 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
1900 if (type == SND_CTRL_RELOAD_SOUNDS)
1901 ReloadCustomSounds();
1903 ReloadCustomMusic();
1904 #elif defined(PLATFORM_UNIX)
1905 if (audio.soundserver_pid == 0) /* we are child process */
1908 if (leveldir_current == NULL) /* should never happen */
1909 Error(ERR_EXIT, "leveldir_current == NULL");
1912 WriteReloadInfoToPipe(set_name, type);
1915 snd_ctrl.state = type;
1916 snd_ctrl.data_len = strlen(set_name) + 1;
1918 if (write(audio.soundserver_pipe[1], &snd_ctrl,
1919 sizeof(snd_ctrl)) < 0 ||
1920 write(audio.soundserver_pipe[1], set_name,
1921 snd_ctrl.data_len) < 0 ||
1922 write(audio.soundserver_pipe[1], leveldir_current,
1923 sizeof(TreeInfo)) < 0 ||
1924 write(audio.soundserver_pipe[1], ti,
1925 sizeof(TreeInfo)) < 0 ||
1926 write(audio.soundserver_pipe[1], &str_size1,
1927 sizeof(unsigned long)) < 0 ||
1928 write(audio.soundserver_pipe[1], &str_size2,
1929 sizeof(unsigned long)) < 0 ||
1930 write(audio.soundserver_pipe[1], &str_size3,
1931 sizeof(unsigned long)) < 0 ||
1932 write(audio.soundserver_pipe[1], leveldir_current->fullpath,
1934 write(audio.soundserver_pipe[1], ti->basepath,
1936 write(audio.soundserver_pipe[1], ti->fullpath,
1939 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1940 audio.sound_available = audio.sound_enabled = FALSE;
1948 void InitReloadSounds(char *set_name)
1950 InitReloadSoundsOrMusic(set_name, SND_CTRL_RELOAD_SOUNDS);
1953 void InitReloadMusic(char *set_name)
1955 InitReloadSoundsOrMusic(set_name, SND_CTRL_RELOAD_MUSIC);
1958 void FreeSound(void *ptr)
1960 SoundInfo *sound = (SoundInfo *)ptr;
1965 if (sound->data_ptr)
1967 #if defined(TARGET_SDL)
1968 Mix_FreeChunk(sound->data_ptr);
1969 #elif defined(TARGET_ALLEGRO)
1970 destroy_sample(sound->data_ptr);
1971 #else /* PLATFORM_UNIX */
1972 free(sound->data_ptr);
1976 if (sound->source_filename)
1977 free(sound->source_filename);
1982 void FreeMusic(MusicInfo *music)
1987 if (music->data_ptr)
1989 #if defined(TARGET_SDL)
1990 if (music->type == MUS_TYPE_MOD)
1991 Mix_FreeMusic(music->data_ptr);
1993 Mix_FreeChunk(music->data_ptr);
1994 #elif defined(TARGET_ALLEGRO)
1995 destroy_sample(music->data_ptr);
1996 #else /* PLATFORM_UNIX */
1997 free(music->data_ptr);
2004 void FreeAllSounds()
2011 printf("%s: FREEING SOUNDS ...\n",
2012 audio.soundserver_pid == 0 ? "CHILD" : "PARENT");
2014 for(i=0; i<num_sounds; i++)
2015 deleteSoundEntry(&Sound[i]);
2017 FreeSound(Sound[i]);
2020 printf("%s: FREEING SOUNDS -- DONE\n",
2021 audio.soundserver_pid == 0 ? "CHILD" : "PARENT");
2036 for(i=0; i<num_music; i++)
2037 FreeMusic(Music[i]);
2045 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2046 /* ========================================================================= */