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[MAX_SOUNDS_PLAYING];
59 static struct SoundControl emptySoundControl =
61 -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, 0,0, 0,NULL
64 #if defined(PLATFORM_UNIX)
65 static int stereo_volume[PSND_MAX_LEFT2RIGHT + 1];
66 static short premix_first_buffer[SND_BLOCKSIZE];
67 #if defined(AUDIO_STREAMING_DSP)
68 static short premix_left_buffer[SND_BLOCKSIZE];
69 static short premix_right_buffer[SND_BLOCKSIZE];
70 static long premix_last_buffer[SND_BLOCKSIZE];
72 static byte playing_buffer[SND_BLOCKSIZE];
75 /* forward declaration of internal functions */
76 #if defined(AUDIO_STREAMING_DSP)
77 static void SoundServer_InsertNewSound(struct SoundControl);
78 static void InitAudioDevice_DSP(struct AudioFormatInfo *);
79 #elif defined(PLATFORM_HPUX)
80 static void InitAudioDevice_HPUX(struct AudioFormatInfo *);
81 #elif defined(PLATFORM_UNIX)
82 static unsigned char linear_to_ulaw(int);
83 static int ulaw_to_linear(unsigned char);
84 #elif defined(PLATFORM_MSDOS)
85 static void SoundServer_InsertNewSound(struct SoundControl);
86 static void SoundServer_StopSound(struct SoundControl);
87 static void SoundServer_StopAllSounds();
90 static void ReloadCustomSounds();
91 static void ReloadCustomMusic();
92 static void FreeSound(void *);
94 #if defined(PLATFORM_UNIX)
95 static int OpenAudioDevice(char *audio_device_name)
99 /* check if desired audio device is accessible */
100 if (access(audio_device_name, W_OK) != 0)
103 /* try to open audio device in non-blocking mode */
104 if ((audio_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
107 /* re-open audio device in blocking mode */
109 audio_fd = open(audio_device_name, O_WRONLY);
114 static boolean TestAudioDevices(void)
116 static char *audio_device_name[] =
124 /* look for available audio devices, starting with preferred ones */
125 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
126 if ((audio_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
131 Error(ERR_WARN, "cannot open audio device -- no sound");
137 audio.device_name = audio_device_name[i];
142 #if !defined(TARGET_SDL)
143 static boolean ForkAudioProcess(void)
145 if (pipe(audio.soundserver_pipe) < 0)
147 Error(ERR_WARN, "cannot create pipe -- no sounds");
151 if ((audio.soundserver_pid = fork()) < 0)
153 Error(ERR_WARN, "cannot create sound server process -- no sounds");
157 if (audio.soundserver_pid == 0) /* we are child process */
164 else /* we are parent */
165 close(audio.soundserver_pipe[0]); /* no reading from pipe needed */
171 void UnixOpenAudio(void)
173 if (!TestAudioDevices())
176 audio.sound_available = TRUE;
177 audio.sound_enabled = TRUE;
179 #if defined(AUDIO_STREAMING_DSP)
180 audio.music_available = TRUE;
181 audio.loops_available = TRUE;
185 void UnixCloseAudio(void)
188 close(audio.device_fd);
190 if (audio.soundserver_pid > 0) /* we are parent process */
191 kill(audio.soundserver_pid, SIGTERM);
193 #endif /* PLATFORM_UNIX */
195 void InitPlaylist(void)
199 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
200 playlist[i] = emptySoundControl;
204 void StartSoundserver(void)
206 if (!audio.sound_available)
209 #if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
210 if (!ForkAudioProcess())
211 audio.sound_available = FALSE;
215 #if defined(PLATFORM_UNIX)
216 void SoundServer(void)
220 struct SoundControl snd_ctrl;
223 close(audio.soundserver_pipe[1]); /* no writing into pipe needed */
227 stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
228 for(i=0; i<PSND_MAX_LEFT2RIGHT; i++)
230 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT * PSND_MAX_LEFT2RIGHT - i * i));
232 #if defined(PLATFORM_HPUX)
233 InitAudioDevice_HPUX(&afmt);
236 FD_ZERO(&sound_fdset);
237 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
239 while(1) /* wait for sound playing commands from client */
241 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
242 select(audio.soundserver_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
243 if (!FD_ISSET(audio.soundserver_pipe[0], &sound_fdset))
245 if (read(audio.soundserver_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
247 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
249 if (snd_ctrl.reload_sounds || snd_ctrl.reload_music)
251 char *set_name = checked_malloc(snd_ctrl.data_len);
253 (snd_ctrl.reload_sounds ? &artwork.snd_current : &artwork.mus_current);
254 TreeInfo *ti = *ti_ptr;
255 unsigned long str_size1, str_size2, str_size3;
257 if (leveldir_current == NULL)
258 leveldir_current = checked_calloc(sizeof(TreeInfo));
260 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
261 if (leveldir_current->fullpath != NULL)
262 free(leveldir_current->fullpath);
263 if (ti->basepath != NULL)
265 if (ti->fullpath != NULL)
268 if (read(audio.soundserver_pipe[0], set_name,
269 snd_ctrl.data_len) != snd_ctrl.data_len ||
270 read(audio.soundserver_pipe[0], leveldir_current,
271 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
272 read(audio.soundserver_pipe[0], ti,
273 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
274 read(audio.soundserver_pipe[0], &str_size1,
275 sizeof(unsigned long)) != sizeof(unsigned long) ||
276 read(audio.soundserver_pipe[0], &str_size2,
277 sizeof(unsigned long)) != sizeof(unsigned long) ||
278 read(audio.soundserver_pipe[0], &str_size3,
279 sizeof(unsigned long)) != sizeof(unsigned long))
280 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
282 leveldir_current->fullpath = checked_calloc(str_size1);
283 ti->basepath = checked_calloc(str_size2);
284 ti->fullpath = checked_calloc(str_size3);
286 if (read(audio.soundserver_pipe[0], leveldir_current->fullpath,
287 str_size1) != str_size1 ||
288 read(audio.soundserver_pipe[0], ti->basepath,
289 str_size2) != str_size2 ||
290 read(audio.soundserver_pipe[0], ti->fullpath,
291 str_size3) != str_size3)
292 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
296 close(audio.device_fd);
298 if (snd_ctrl.reload_sounds)
300 artwork.sounds_set_current = set_name;
301 ReloadCustomSounds();
305 artwork.music_set_current = set_name;
314 #if defined(AUDIO_STREAMING_DSP)
316 if (snd_ctrl.fade_sound)
322 playlist[audio.music_channel].fade_sound = TRUE;
324 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
325 if (snd_ctrl.stop_all_sounds ||
326 (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr))
327 playlist[i].fade_sound = TRUE;
329 else if (snd_ctrl.stop_all_sounds)
334 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
335 playlist[i] = emptySoundControl;
338 close(audio.device_fd);
340 else if (snd_ctrl.stop_sound)
347 playlist[audio.music_channel] = emptySoundControl;
351 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
353 if (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr)
355 playlist[i] = emptySoundControl;
361 close(audio.device_fd);
364 if (playing_sounds || snd_ctrl.active)
366 if (playing_sounds ||
367 (audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
369 struct timeval delay = { 0, 0 };
371 if (!playing_sounds) /* we just opened the audio device */
372 InitAudioDevice_DSP(&afmt);
374 if (snd_ctrl.active) /* new sound has arrived */
375 SoundServer_InsertNewSound(snd_ctrl);
377 while (playing_sounds &&
378 select(audio.soundserver_pipe[0] + 1,
379 &sound_fdset, NULL, NULL, &delay) < 1)
382 int fragment_size = afmt.fragment_size;
383 int sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
384 boolean stereo = afmt.stereo;
386 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
388 max_sample_size = fragment_size / ((stereo ? 2 : 1) * sample_bytes);
390 /* first clear the last premixing buffer */
391 memset(premix_last_buffer, 0,
392 max_sample_size * (stereo ? 2 : 1) * sizeof(long));
394 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
402 if (!playlist[i].active)
405 /* pointer, lenght and actual playing position of sound sample */
406 sample_ptr = playlist[i].data_ptr;
407 sample_len = playlist[i].data_len;
408 sample_pos = playlist[i].playingpos;
409 sample_size = MIN(max_sample_size, sample_len - sample_pos);
410 playlist[i].playingpos += sample_size;
412 /* copy original sample to first mixing buffer */
413 if (playlist[i].format == AUDIO_FORMAT_U8)
414 for (j=0; j<sample_size; j++)
415 premix_first_buffer[j] =
416 ((short)(((byte *)sample_ptr)[sample_pos + j] ^ 0x80)) << 8;
417 else /* AUDIO_FORMAT_S16 */
418 for (j=0; j<sample_size; j++)
419 premix_first_buffer[j] =
420 ((short *)sample_ptr)[sample_pos + j];
422 /* are we about to restart a looping sound? */
423 if (playlist[i].loop && sample_size < max_sample_size)
425 while (sample_size < max_sample_size)
427 int restarted_sample_size =
428 MIN(max_sample_size - sample_size, sample_len);
430 if (playlist[i].format == AUDIO_FORMAT_U8)
431 for (j=0; j<restarted_sample_size; j++)
432 premix_first_buffer[sample_size + j] =
433 ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
435 for (j=0; j<restarted_sample_size; j++)
436 premix_first_buffer[sample_size + j] =
437 ((short *)sample_ptr)[j];
439 playlist[i].playingpos = restarted_sample_size;
440 sample_size += restarted_sample_size;
444 /* decrease volume if sound is fading out */
445 if (playlist[i].fade_sound &&
446 playlist[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
447 playlist[i].volume -= SOUND_FADING_VOLUME_STEP;
449 /* adjust volume of actual sound sample */
450 if (playlist[i].volume != PSND_MAX_VOLUME)
451 for(j=0; j<sample_size; j++)
452 premix_first_buffer[j] =
453 (playlist[i].volume * (long)premix_first_buffer[j])
454 >> PSND_MAX_VOLUME_BITS;
456 /* fill the last mixing buffer with stereo or mono sound */
459 int middle_pos = PSND_MAX_LEFT2RIGHT / 2;
460 int left_volume = stereo_volume[middle_pos + playlist[i].stereo];
461 int right_volume= stereo_volume[middle_pos - playlist[i].stereo];
463 for(j=0; j<sample_size; j++)
465 premix_left_buffer[j] =
466 (left_volume * premix_first_buffer[j])
467 >> PSND_MAX_LEFT2RIGHT_BITS;
468 premix_right_buffer[j] =
469 (right_volume * premix_first_buffer[j])
470 >> PSND_MAX_LEFT2RIGHT_BITS;
472 premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
473 premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
478 for(j=0; j<sample_size; j++)
479 premix_last_buffer[j] += premix_first_buffer[j];
482 /* delete completed sound entries from the playlist */
483 if (playlist[i].playingpos >= playlist[i].data_len)
485 if (playlist[i].loop)
486 playlist[i].playingpos = 0;
489 playlist[i] = emptySoundControl;
493 else if (playlist[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
495 playlist[i] = emptySoundControl;
500 /* prepare final playing buffer according to system audio format */
501 for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
503 /* cut off at 17 bit value */
504 if (premix_last_buffer[i] < -65535)
505 premix_last_buffer[i] = -65535;
506 else if (premix_last_buffer[i] > 65535)
507 premix_last_buffer[i] = 65535;
509 /* shift to 16 bit value */
510 premix_last_buffer[i] >>= 1;
512 if (afmt.format & AUDIO_FORMAT_U8)
514 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
516 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
518 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
519 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
521 else /* big endian */
523 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
524 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
528 /* finally play the sound fragment */
529 write(audio.device_fd, playing_buffer, fragment_size);
532 /* if no sounds playing, free device for other sound programs */
534 close(audio.device_fd);
538 #else /* !AUDIO_STREAMING_DSP */
540 if (snd_ctrl.active && !snd_ctrl.loop)
542 struct timeval delay = { 0, 0 };
544 long sample_size, max_sample_size = SND_BLOCKSIZE;
545 long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
546 int wait_percent = 90; /* wait 90% of the real playing time */
549 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
553 while (playing_sounds &&
554 select(audio.soundserver_pipe[0] + 1,
555 &sound_fdset, NULL, NULL, &delay) < 1)
557 FD_SET(audio.soundserver_pipe[0], &sound_fdset);
559 /* get pointer and size of the actual sound sample */
560 sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
562 MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
563 snd_ctrl.playingpos += sample_size;
565 /* fill the first mixing buffer with original sample */
566 memcpy(premix_first_buffer,sample_ptr,sample_size);
568 /* adjust volume of actual sound sample */
569 if (snd_ctrl.volume != PSND_MAX_VOLUME)
570 for(i=0;i<sample_size;i++)
571 premix_first_buffer[i] =
572 (snd_ctrl.volume * (int)premix_first_buffer[i])
573 >> PSND_MAX_VOLUME_BITS;
575 for(i=0;i<sample_size;i++)
577 linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
579 if (snd_ctrl.playingpos >= snd_ctrl.data_len)
582 /* finally play the sound fragment */
583 write(audio.device_fd,playing_buffer,sample_size);
586 delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
588 close(audio.device_fd);
591 #endif /* !AUDIO_STREAMING_DSP */
594 #endif /* PLATFORM_UNIX */
596 #if defined(PLATFORM_MSDOS)
597 static void sound_handler(struct SoundControl snd_ctrl)
601 if (snd_ctrl.fade_sound)
606 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
607 if ((snd_ctrl.stop_all_sounds ||
608 (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr) ||
609 (i == audio.music_channel && snd_ctrl.music)) &&
610 !playlist[i].fade_sound)
612 playlist[i].fade_sound = TRUE;
613 if (voice_check(playlist[i].voice))
614 voice_ramp_volume(playlist[i].voice, 1000, 0);
615 playlist[i].loop = PSND_NO_LOOP;
618 else if (snd_ctrl.stop_all_sounds)
622 SoundServer_StopAllSounds();
624 else if (snd_ctrl.stop_sound)
628 SoundServer_StopSound(snd_ctrl);
631 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
633 if (!playlist[i].active || playlist[i].loop)
636 playlist[i].playingpos = voice_get_position(playlist[i].voice);
637 playlist[i].volume = voice_get_volume(playlist[i].voice);
638 if (playlist[i].playingpos == -1 || !playlist[i].volume)
640 deallocate_voice(playlist[i].voice);
641 playlist[i] = emptySoundControl;
647 SoundServer_InsertNewSound(snd_ctrl);
649 #endif /* PLATFORM_MSDOS */
651 #if !defined(PLATFORM_WIN32)
652 static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
658 snd_ctrl.nr = snd_ctrl.nr % num_music;
659 else if (snd_ctrl.nr >= num_sounds)
662 snd_info = (snd_ctrl.music ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
663 if (snd_info == NULL)
666 printf("sound/music %d undefined\n", snd_ctrl.nr);
671 /* if playlist is full, remove oldest sound */
672 if (playing_sounds == MAX_SOUNDS_PLAYING)
674 int longest = 0, longest_nr = 0;
676 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
678 #if !defined(PLATFORM_MSDOS)
679 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
681 int actual = playlist[i].playingpos;
684 if (i != audio.music_channel && !playlist[i].loop && actual > longest)
690 #if defined(PLATFORM_MSDOS)
691 voice_set_volume(playlist[longest_nr].voice, 0);
692 deallocate_voice(playlist[longest_nr].voice);
694 playlist[longest_nr] = emptySoundControl;
698 /* check if sound is already being played (and how often) */
699 for (k=0,i=0; i<MAX_SOUNDS_PLAYING; i++)
700 if (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr)
703 /* restart loop sounds only if they are just fading out */
704 if (k >= 1 && snd_ctrl.loop)
706 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
708 if (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr &&
709 playlist[i].fade_sound)
711 playlist[i].fade_sound = FALSE;
712 playlist[i].volume = PSND_MAX_VOLUME;
713 #if defined(PLATFORM_MSDOS)
714 playlist[i].loop = PSND_LOOP;
715 voice_stop_volumeramp(playlist[i].voice);
716 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
724 /* don't play sound more than n times simultaneously (with n == 2 for now) */
727 int longest = 0, longest_nr = 0;
729 /* look for oldest equal sound */
730 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
734 if (!playlist[i].active ||
735 i == audio.music_channel ||
736 playlist[i].nr != snd_ctrl.nr)
739 #if !defined(PLATFORM_MSDOS)
740 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
742 actual = playlist[i].playingpos;
744 if (actual >= longest)
751 #if defined(PLATFORM_MSDOS)
752 voice_set_volume(playlist[longest_nr].voice, 0);
753 deallocate_voice(playlist[longest_nr].voice);
755 playlist[longest_nr] = emptySoundControl;
759 /* add new sound to playlist */
760 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
762 if (!playlist[i].active ||
763 (snd_ctrl.music && i == audio.music_channel))
765 snd_ctrl.data_ptr = snd_info->data_ptr;
766 snd_ctrl.data_len = snd_info->data_len;
767 snd_ctrl.format = snd_info->format;
769 playlist[i] = snd_ctrl;
772 #if defined(PLATFORM_MSDOS)
773 playlist[i].voice = allocate_voice((SAMPLE *)playlist[i].data_ptr);
776 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
778 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
779 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
780 voice_start(playlist[i].voice);
786 #endif /* !PLATFORM_WIN32 */
789 void SoundServer_FadeSound(int nr)
796 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
797 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
798 playlist[i].fade_sound = TRUE;
802 #if !defined(PLATFORM_WIN32)
803 #if defined(PLATFORM_MSDOS)
804 static void SoundServer_StopSound(struct SoundControl snd_ctrl)
806 int nr = snd_ctrl.nr;
812 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
814 if ((i == audio.music_channel && snd_ctrl.music) ||
815 (i != audio.music_channel && playlist[i].nr == nr))
817 #if defined(PLATFORM_MSDOS)
818 voice_set_volume(playlist[i].voice, 0);
819 deallocate_voice(playlist[i].voice);
821 playlist[i] = emptySoundControl;
826 #if !defined(PLATFORM_MSDOS)
828 close(audio.device_fd);
832 static void SoundServer_StopAllSounds()
836 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
838 #if defined(PLATFORM_MSDOS)
839 voice_set_volume(playlist[i].voice, 0);
840 deallocate_voice(playlist[i].voice);
842 playlist[i]=emptySoundControl;
846 #if !defined(PLATFORM_MSDOS)
847 close(audio.device_fd);
850 #endif /* PLATFORM_MSDOS */
851 #endif /* !PLATFORM_WIN32 */
854 /* ------------------------------------------------------------------------- */
855 /* platform dependant audio initialization code */
856 /* ------------------------------------------------------------------------- */
858 #if defined(AUDIO_LINUX_IOCTL)
859 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
861 /* "ioctl()" expects pointer to 'int' value for stereo flag
862 (boolean is defined as 'char', which will not work here) */
863 unsigned int fragment_spec = 0;
864 int fragment_size_query;
873 /* supported audio format in preferred order */
874 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
875 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
876 { AFMT_U8, AUDIO_FORMAT_U8 },
881 /* determine logarithm (log2) of the fragment size */
882 while ((1 << fragment_spec) < afmt->fragment_size)
885 /* use two fragments (play one fragment, prepare the other);
886 one fragment would result in interrupted audio output, more
887 than two fragments would raise audio output latency to much */
888 fragment_spec |= 0x00020000;
890 /* Example for fragment specification:
891 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
892 - (with stereo the effective buffer size will shrink to 256)
893 => fragment_size = 0x00020009 */
895 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
896 Error(ERR_EXIT_SOUND_SERVER,
897 "cannot set fragment size of /dev/dsp -- no sounds");
901 while (formats[i].format_result != -1)
903 unsigned int audio_format = formats[i].format_ioctl;
904 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
906 afmt->format = formats[i].format_result;
911 if (afmt->format == 0) /* no supported audio format found */
912 Error(ERR_EXIT_SOUND_SERVER,
913 "cannot set audio format of /dev/dsp -- no sounds");
915 /* try if we can use stereo sound */
917 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
918 afmt->stereo = FALSE;
920 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
921 Error(ERR_EXIT_SOUND_SERVER,
922 "cannot set sample rate of /dev/dsp -- no sounds");
924 /* get the real fragmentation size; this should return 512 */
925 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
926 Error(ERR_EXIT_SOUND_SERVER,
927 "cannot get fragment size of /dev/dsp -- no sounds");
928 if (fragment_size_query != afmt->fragment_size)
929 Error(ERR_EXIT_SOUND_SERVER,
930 "cannot set fragment size of /dev/dsp -- no sounds");
932 #endif /* AUDIO_LINUX_IOCTL */
934 #if defined(PLATFORM_NETBSD)
935 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
938 boolean stereo = TRUE;
940 AUDIO_INITINFO(&a_info);
941 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
942 a_info.play.precision = 8;
943 a_info.play.channels = 2;
944 a_info.play.sample_rate = sample_rate;
945 a_info.blocksize = fragment_size;
947 afmt->format = AUDIO_FORMAT_U8;
950 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
952 /* try to disable stereo */
953 a_info.play.channels = 1;
955 afmt->stereo = FALSE;
957 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
958 Error(ERR_EXIT_SOUND_SERVER,
959 "cannot set sample rate of /dev/audio -- no sounds");
962 #endif /* PLATFORM_NETBSD */
964 #if defined(PLATFORM_HPUX)
965 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
967 struct audio_describe ainfo;
970 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
972 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl -- no sounds");
974 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
975 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
977 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
978 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
980 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
981 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
983 afmt->format = AUDIO_FORMAT_U8;
984 afmt->stereo = FALSE;
985 afmt->sample_rate = 8000;
989 #endif /* PLATFORM_HPUX */
991 #if defined(PLATFORM_UNIX)
992 static void InitAudioDevice_DSP(struct AudioFormatInfo *afmt)
994 #if defined(AUDIO_LINUX_IOCTL)
995 InitAudioDevice_Linux(afmt);
996 #elif defined(PLATFORM_NETBSD)
997 InitAudioDevice_NetBSD(afmt);
998 #elif defined(PLATFORM_HPUX)
999 InitAudioDevice_HPUX(afmt);
1002 #endif /* PLATFORM_UNIX */
1004 #if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
1006 /* these two are stolen from "sox"... :) */
1009 ** This routine converts from linear to ulaw.
1011 ** Craig Reese: IDA/Supercomputing Research Center
1012 ** Joe Campbell: Department of Defense
1013 ** 29 September 1989
1016 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1017 ** 2) "A New Digital Technique for Implementation of Any
1018 ** Continuous PCM Companding Law," Villeret, Michel,
1019 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1020 ** 1973, pg. 11.12-11.17
1021 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1022 ** for Analog-to_Digital Conversion Techniques,"
1025 ** Input: Signed 16 bit linear sample
1026 ** Output: 8 bit ulaw sample
1029 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1030 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1033 static unsigned char linear_to_ulaw(int sample)
1035 static int exp_lut[256] =
1037 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1038 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1039 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1040 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1041 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1042 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1043 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1044 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1045 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1046 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1047 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1048 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1049 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1050 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1051 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1052 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1055 int sign, exponent, mantissa;
1056 unsigned char ulawbyte;
1058 /* Get the sample into sign-magnitude. */
1059 sign = (sample >> 8) & 0x80; /* set aside the sign */
1061 sample = -sample; /* get magnitude */
1063 sample = CLIP; /* clip the magnitude */
1065 /* Convert from 16 bit linear to ulaw. */
1066 sample = sample + BIAS;
1067 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1068 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1069 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1072 ulawbyte = 0x02; /* optional CCITT trap */
1079 ** This routine converts from ulaw to 16 bit linear.
1081 ** Craig Reese: IDA/Supercomputing Research Center
1082 ** 29 September 1989
1085 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1086 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1087 ** for Analog-to_Digital Conversion Techniques,"
1090 ** Input: 8 bit ulaw sample
1091 ** Output: signed 16 bit linear sample
1094 static int ulaw_to_linear(unsigned char ulawbyte)
1096 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1097 int sign, exponent, mantissa, sample;
1099 ulawbyte = ~ ulawbyte;
1100 sign = ( ulawbyte & 0x80 );
1101 exponent = ( ulawbyte >> 4 ) & 0x07;
1102 mantissa = ulawbyte & 0x0F;
1103 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1109 #endif /* PLATFORM_UNIX && !AUDIO_STREAMING_DSP */
1112 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1113 /* ========================================================================= */
1114 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1116 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1117 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1119 static SoundInfo *Load_WAV(char *filename)
1121 SoundInfo *snd_info;
1122 #if !defined(TARGET_SDL) && !defined(PLATFORM_MSDOS)
1123 byte sound_header_buffer[WAV_HEADER_SIZE];
1124 char chunk_name[CHUNK_ID_LEN + 1];
1130 if (!audio.sound_available)
1134 printf("loading WAV file '%s'\n", filename);
1137 snd_info = checked_calloc(sizeof(SoundInfo));
1139 #if defined(TARGET_SDL)
1141 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1143 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1148 #elif defined(TARGET_ALLEGRO)
1150 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1152 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1157 #else /* PLATFORM_UNIX */
1159 if ((file = fopen(filename, MODE_READ)) == NULL)
1161 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1166 /* read chunk id "RIFF" */
1167 getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN);
1168 if (strcmp(chunk_name, "RIFF") != 0)
1170 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1176 /* read "RIFF" type id "WAVE" */
1177 getFileChunk(file, chunk_name, NULL, BYTE_ORDER_LITTLE_ENDIAN);
1178 if (strcmp(chunk_name, "WAVE") != 0)
1180 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1186 while (getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN))
1188 if (strcmp(chunk_name, "fmt ") == 0)
1190 /* read header information */
1191 for (i=0; i < MIN(chunk_size, WAV_HEADER_SIZE); i++)
1192 sound_header_buffer[i] = fgetc(file);
1194 if (chunk_size > WAV_HEADER_SIZE)
1195 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1197 else if (strcmp(chunk_name, "data") == 0)
1199 snd_info->data_len = chunk_size;
1200 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1202 /* read sound data */
1203 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1206 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1208 free(snd_info->data_ptr);
1213 /* check for odd number of sample bytes (data chunk is word aligned) */
1214 if ((chunk_size % 2) == 1)
1215 ReadUnusedBytesFromFile(file, 1);
1217 else /* unknown chunk -- ignore */
1218 ReadUnusedBytesFromFile(file, chunk_size);
1223 if (snd_info->data_ptr == NULL)
1225 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1230 snd_info->format = AUDIO_FORMAT_U8;
1232 #endif /* PLATFORM_UNIX */
1234 snd_info->type = SND_TYPE_WAV;
1235 snd_info->source_filename = getStringCopy(filename);
1240 static void deleteSoundEntry(SoundInfo **snd_info)
1244 char *filename = (*snd_info)->source_filename;
1247 printf("[decrementing reference counter of sound '%s']\n", filename);
1250 if (--(*snd_info)->num_references <= 0)
1253 printf("[deleting sound '%s']\n", filename);
1257 FreeSound(*snd_info);
1259 deleteNodeFromList(&SoundFileList, filename, FreeSound);
1266 static void replaceSoundEntry(SoundInfo **snd_info, char *filename)
1270 /* check if the old and the new sound file are the same */
1271 if (*snd_info && strcmp((*snd_info)->source_filename, filename) == 0)
1273 /* The old and new sound are the same (have the same filename and path).
1274 This usually means that this sound does not exist in this sound set
1275 and a fallback to the existing sound is done. */
1278 printf("[sound '%s' already exists (same list entry)]\n", filename);
1284 /* delete existing sound file entry */
1285 deleteSoundEntry(snd_info);
1287 /* check if the new sound file already exists in the list of sounds */
1288 if ((node = getNodeFromKey(SoundFileList, filename)) != NULL)
1291 printf("[sound '%s' already exists (other list entry)]\n", filename);
1294 *snd_info = (SoundInfo *)node->content;
1295 (*snd_info)->num_references++;
1297 else if ((*snd_info = Load_WAV(filename)) != NULL) /* load new sound */
1299 (*snd_info)->num_references = 1;
1300 addNodeToList(&SoundFileList, (*snd_info)->source_filename, *snd_info);
1304 static void LoadCustomSound(SoundInfo **snd_info, char *basename)
1306 char *filename = getCustomSoundFilename(basename);
1308 if (strcmp(basename, "NONE") == 0)
1310 deleteSoundEntry(snd_info);
1314 if (filename == NULL)
1316 Error(ERR_WARN, "cannot find sound file '%s'", basename);
1320 replaceSoundEntry(snd_info, filename);
1323 void InitSoundList(struct SoundEffectInfo *sounds_list, int num_list_entries)
1326 Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
1328 sound_effect = sounds_list;
1329 num_sounds = num_list_entries;
1332 void LoadSoundToList(char *basename, int list_pos)
1334 if (Sound == NULL || list_pos >= num_sounds)
1337 printf("loading sound '%s' ... [%d]\n",
1338 basename, getNumNodes(SoundFileList));
1340 LoadCustomSound(&Sound[list_pos], basename);
1342 printf("loading sound '%s' done [%d]\n",
1343 basename, getNumNodes(SoundFileList));
1346 static MusicInfo *Load_MOD(char *filename)
1348 #if defined(TARGET_SDL)
1349 MusicInfo *mod_info;
1351 if (!audio.sound_available)
1354 mod_info = checked_calloc(sizeof(MusicInfo));
1356 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1358 Error(ERR_WARN, "cannot read music file '%s'", filename);
1363 mod_info->type = MUS_TYPE_MOD;
1364 mod_info->source_filename = getStringCopy(filename);
1372 void LoadCustomMusic(void)
1374 char *music_directory = getCustomMusicDirectory();
1376 struct dirent *dir_entry;
1378 if (!audio.sound_available)
1381 if ((dir = opendir(music_directory)) == NULL)
1383 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1384 audio.music_available = FALSE;
1388 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1390 char *basename = dir_entry->d_name;
1391 char *filename = getPath2(music_directory, basename);
1392 MusicInfo *mus_info = NULL;
1394 if (FileIsSound(basename))
1395 mus_info = Load_WAV(filename);
1396 else if (FileIsMusic(basename))
1397 mus_info = Load_MOD(filename);
1404 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1405 Music[num_music -1] = mus_info;
1412 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1416 void PlayMusic(int nr)
1418 if (!audio.music_available)
1421 #if defined(TARGET_SDL)
1423 nr = nr % num_music;
1425 if (Music[nr]->type == MUS_TYPE_MOD)
1427 Mix_PlayMusic(Music[nr]->data_ptr, -1);
1428 Mix_VolumeMusic(SOUND_MAX_VOLUME); /* must be _after_ Mix_PlayMusic()! */
1430 else /* play WAV music loop */
1432 Mix_Volume(audio.music_channel, SOUND_MAX_VOLUME);
1433 Mix_PlayChannel(audio.music_channel, Music[nr]->data_ptr, -1);
1443 void PlaySound(int nr)
1445 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
1448 void PlaySoundStereo(int nr, int stereo)
1450 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
1453 void PlaySoundLoop(int nr)
1455 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
1458 void PlaySoundMusic(int nr)
1460 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_MUSIC);
1463 void PlaySoundExt(int nr, int volume, int stereo, boolean loop_type)
1465 struct SoundControl snd_ctrl = emptySoundControl;
1467 if (!audio.sound_available ||
1468 !audio.sound_enabled ||
1469 audio.sound_deactivated)
1472 if (volume < PSND_MIN_VOLUME)
1473 volume = PSND_MIN_VOLUME;
1474 else if (volume > PSND_MAX_VOLUME)
1475 volume = PSND_MAX_VOLUME;
1477 if (stereo < PSND_MAX_LEFT)
1478 stereo = PSND_MAX_LEFT;
1479 else if (stereo > PSND_MAX_RIGHT)
1480 stereo = PSND_MAX_RIGHT;
1483 snd_ctrl.volume = volume;
1484 snd_ctrl.stereo = stereo;
1485 snd_ctrl.loop = (loop_type != PSND_NO_LOOP);
1486 snd_ctrl.music = (loop_type == PSND_MUSIC);
1487 snd_ctrl.active = TRUE;
1490 /* now only used internally in sound server child process */
1491 snd_ctrl.data_ptr = Sound[nr].data_ptr;
1492 snd_ctrl.data_len = Sound[nr].data_len;
1495 #if defined(TARGET_SDL)
1496 Mix_Volume(-1, SOUND_MAX_VOLUME);
1497 Mix_PlayChannel(-1, Sound[nr]->data_ptr, (loop_type ? -1 : 0));
1498 #elif defined(PLATFORM_UNIX)
1499 if (audio.soundserver_pid == 0) /* we are child process */
1502 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1504 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1505 audio.sound_available = audio.sound_enabled = FALSE;
1508 #elif defined(PLATFORM_MSDOS)
1509 sound_handler(snd_ctrl);
1513 void FadeMusic(void)
1515 if (!audio.sound_available)
1518 #if defined(TARGET_SDL)
1519 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
1520 Mix_FadeOutChannel(audio.music_channel, SOUND_FADING_INTERVAL);
1522 StopSoundExt(-1, SSND_FADE_MUSIC);
1526 void FadeSound(int nr)
1528 StopSoundExt(nr, SSND_FADE_SOUND);
1534 StopSoundExt(-1, SSND_FADE_ALL);
1537 void StopMusic(void)
1539 #if defined(TARGET_SDL)
1540 if (!audio.sound_available)
1544 Mix_HaltChannel(audio.music_channel);
1546 StopSoundExt(-1, SSND_STOP_MUSIC);
1550 void StopSound(int nr)
1552 StopSoundExt(nr, SSND_STOP_SOUND);
1557 StopSoundExt(-1, SSND_STOP_ALL);
1560 void StopSoundExt(int nr, int method)
1562 struct SoundControl snd_ctrl = emptySoundControl;
1564 if (!audio.sound_available)
1567 if (method & SSND_FADING)
1568 snd_ctrl.fade_sound = TRUE;
1570 if (method & SSND_ALL)
1571 snd_ctrl.stop_all_sounds = TRUE;
1574 snd_ctrl.stop_sound = TRUE;
1578 if (method & SSND_MUSIC)
1579 snd_ctrl.music = TRUE;
1581 #if defined(TARGET_SDL)
1583 if (method & SSND_FADING)
1587 for (i=0; i<audio.channels; i++)
1588 if (i != audio.music_channel || snd_ctrl.music)
1589 Mix_FadeOutChannel(i, SOUND_FADING_INTERVAL);
1591 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
1597 for (i=0; i<audio.channels; i++)
1598 if (i != audio.music_channel || snd_ctrl.music)
1604 #elif !defined(PLATFORM_MSDOS)
1606 if (audio.soundserver_pid == 0) /* we are child process */
1609 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1611 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1612 audio.sound_available = audio.sound_enabled = FALSE;
1616 sound_handler(snd_ctrl);
1620 ListNode *newListNode()
1622 return checked_calloc(sizeof(ListNode));
1625 void addNodeToList(ListNode **node_first, char *key, void *content)
1627 ListNode *node_new = newListNode();
1630 printf("LIST: adding node with key '%s'\n", key);
1633 node_new->key = getStringCopy(key);
1634 node_new->content = content;
1635 node_new->next = *node_first;
1636 *node_first = node_new;
1639 void deleteNodeFromList(ListNode **node_first, char *key,
1640 void (*destructor_function)(void *))
1642 if (node_first == NULL || *node_first == NULL)
1645 printf("[CHECKING LIST KEY '%s' == '%s']\n",
1646 (*node_first)->key, key);
1648 if (strcmp((*node_first)->key, key) == 0)
1650 printf("[DELETING LIST ENTRY]\n");
1652 free((*node_first)->key);
1653 if (destructor_function)
1654 destructor_function((*node_first)->content);
1655 *node_first = (*node_first)->next;
1658 deleteNodeFromList(&(*node_first)->next, key, destructor_function);
1661 ListNode *getNodeFromKey(ListNode *node_first, char *key)
1663 if (node_first == NULL)
1666 if (strcmp(node_first->key, key) == 0)
1669 return getNodeFromKey(node_first->next, key);
1672 int getNumNodes(ListNode *node_first)
1674 return (node_first ? 1 + getNumNodes(node_first->next) : 0);
1677 void dumpList(ListNode *node_first)
1679 ListNode *node = node_first;
1683 printf("['%s' (%d)]\n", node->key,
1684 ((SoundInfo *)node->content)->num_references);
1688 printf("[%d nodes]\n", getNumNodes(node_first));
1691 static void LoadSoundsInfo()
1693 char *filename = getCustomSoundConfigFilename();
1694 struct SetupFileList *setup_file_list;
1697 /* always start with reliable default values */
1698 for (i=0; i<num_sounds; i++)
1699 sound_effect[i].filename = NULL;
1701 if (filename == NULL)
1704 if ((setup_file_list = loadSetupFileList(filename)))
1706 for (i=0; i<num_sounds; i++)
1707 sound_effect[i].filename =
1708 getStringCopy(getTokenValue(setup_file_list, sound_effect[i].text));
1710 freeSetupFileList(setup_file_list);
1713 for (i=0; i<num_sounds; i++)
1715 printf("'%s' ", sound_effect[i].text);
1716 if (sound_effect[i].filename)
1717 printf("-> '%s'\n", sound_effect[i].filename);
1719 printf("-> UNDEFINED [-> '%s']\n", sound_effect[i].default_filename);
1725 static void ReloadCustomSounds()
1730 printf("DEBUG: reloading sounds '%s' ...\n", artwork.sounds_set_current);
1735 for(i=0; i<num_sounds; i++)
1737 if (sound_effect[i].filename)
1738 LoadSoundToList(sound_effect[i].filename, i);
1740 LoadSoundToList(sound_effect[i].default_filename, i);
1744 printf("list size == %d\n", getNumNodes(SoundFileList));
1746 dumpList(SoundFileList);
1749 static void ReloadCustomMusic()
1752 printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current);
1760 static void InitReloadSoundsOrMusic(char *set_name, int type)
1762 #if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
1763 struct SoundControl snd_ctrl = emptySoundControl;
1765 (type == SND_RELOAD_SOUNDS ? artwork.snd_current : artwork.mus_current);
1766 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
1767 unsigned long str_size2 = strlen(ti->basepath) + 1;
1768 unsigned long str_size3 = strlen(ti->fullpath) + 1;
1771 if (!audio.sound_available)
1774 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
1775 if (type == SND_RELOAD_SOUNDS)
1776 audio.func_reload_sounds();
1778 audio.func_reload_music();
1779 #elif defined(PLATFORM_UNIX)
1780 if (audio.soundserver_pid == 0) /* we are child process */
1783 if (leveldir_current == NULL) /* should never happen */
1784 Error(ERR_EXIT, "leveldir_current == NULL");
1786 snd_ctrl.reload_sounds = (type == SND_RELOAD_SOUNDS);
1787 snd_ctrl.reload_music = (type == SND_RELOAD_MUSIC);
1788 snd_ctrl.data_len = strlen(set_name) + 1;
1790 if (write(audio.soundserver_pipe[1], &snd_ctrl,
1791 sizeof(snd_ctrl)) < 0 ||
1792 write(audio.soundserver_pipe[1], set_name,
1793 snd_ctrl.data_len) < 0 ||
1794 write(audio.soundserver_pipe[1], leveldir_current,
1795 sizeof(TreeInfo)) < 0 ||
1796 write(audio.soundserver_pipe[1], ti,
1797 sizeof(TreeInfo)) < 0 ||
1798 write(audio.soundserver_pipe[1], &str_size1,
1799 sizeof(unsigned long)) < 0 ||
1800 write(audio.soundserver_pipe[1], &str_size2,
1801 sizeof(unsigned long)) < 0 ||
1802 write(audio.soundserver_pipe[1], &str_size3,
1803 sizeof(unsigned long)) < 0 ||
1804 write(audio.soundserver_pipe[1], leveldir_current->fullpath,
1806 write(audio.soundserver_pipe[1], ti->basepath,
1808 write(audio.soundserver_pipe[1], ti->fullpath,
1811 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1812 audio.sound_available = audio.sound_enabled = FALSE;
1818 void InitReloadSounds(char *set_name)
1820 InitReloadSoundsOrMusic(set_name, SND_RELOAD_SOUNDS);
1823 void InitReloadMusic(char *set_name)
1825 InitReloadSoundsOrMusic(set_name, SND_RELOAD_MUSIC);
1828 void FreeSound(void *ptr)
1830 SoundInfo *sound = (SoundInfo *)ptr;
1835 if (sound->data_ptr)
1837 #if defined(TARGET_SDL)
1838 Mix_FreeChunk(sound->data_ptr);
1839 #elif defined(TARGET_ALLEGRO)
1840 destroy_sample(sound->data_ptr);
1841 #else /* PLATFORM_UNIX */
1842 free(sound->data_ptr);
1846 if (sound->source_filename)
1847 free(sound->source_filename);
1852 void FreeMusic(MusicInfo *music)
1857 if (music->data_ptr)
1859 #if defined(TARGET_SDL)
1860 if (music->type == MUS_TYPE_MOD)
1861 Mix_FreeMusic(music->data_ptr);
1863 Mix_FreeChunk(music->data_ptr);
1864 #elif defined(TARGET_ALLEGRO)
1865 destroy_sample(music->data_ptr);
1866 #else /* PLATFORM_UNIX */
1867 free(music->data_ptr);
1874 void FreeAllSounds()
1881 for(i=0; i<num_sounds; i++)
1882 FreeSound(Sound[i]);
1897 for(i=0; i<num_music; i++)
1898 FreeMusic(Music[i]);
1906 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
1907 /* ========================================================================= */