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)
657 snd_ctrl.nr = snd_ctrl.nr % num_music;
658 else if (snd_ctrl.nr >= num_sounds)
661 /* if playlist is full, remove oldest sound */
662 if (playing_sounds == MAX_SOUNDS_PLAYING)
664 int longest = 0, longest_nr = 0;
666 for (i=0; i<MAX_SOUNDS_PLAYING; i++)
668 #if !defined(PLATFORM_MSDOS)
669 int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
671 int actual = playlist[i].playingpos;
674 if (i != audio.music_channel && !playlist[i].loop && actual > longest)
680 #if defined(PLATFORM_MSDOS)
681 voice_set_volume(playlist[longest_nr].voice, 0);
682 deallocate_voice(playlist[longest_nr].voice);
684 playlist[longest_nr] = emptySoundControl;
688 /* check if sound is already being played (and how often) */
689 for (k=0,i=0; i<MAX_SOUNDS_PLAYING; i++)
690 if (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr)
693 /* restart loop sounds only if they are just fading out */
694 if (k >= 1 && snd_ctrl.loop)
696 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
698 if (i != audio.music_channel && playlist[i].nr == snd_ctrl.nr &&
699 playlist[i].fade_sound)
701 playlist[i].fade_sound = FALSE;
702 playlist[i].volume = PSND_MAX_VOLUME;
703 #if defined(PLATFORM_MSDOS)
704 playlist[i].loop = PSND_LOOP;
705 voice_stop_volumeramp(playlist[i].voice);
706 voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
714 /* don't play sound more than n times simultaneously (with n == 2 for now) */
717 int longest = 0, longest_nr = 0;
719 /* look for oldest equal sound */
720 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
724 if (!playlist[i].active ||
725 i == audio.music_channel ||
726 playlist[i].nr != snd_ctrl.nr)
729 #if !defined(PLATFORM_MSDOS)
730 actual = 100 * playlist[i].playingpos / playlist[i].data_len;
732 actual = playlist[i].playingpos;
734 if (actual >= longest)
741 #if defined(PLATFORM_MSDOS)
742 voice_set_volume(playlist[longest_nr].voice, 0);
743 deallocate_voice(playlist[longest_nr].voice);
745 playlist[longest_nr] = emptySoundControl;
749 /* add new sound to playlist */
750 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
752 if (!playlist[i].active ||
753 (snd_ctrl.music && i == audio.music_channel))
755 SoundInfo *snd_info =
756 (snd_ctrl.music ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
758 snd_ctrl.data_ptr = snd_info->data_ptr;
759 snd_ctrl.data_len = snd_info->data_len;
760 snd_ctrl.format = snd_info->format;
762 playlist[i] = snd_ctrl;
765 #if defined(PLATFORM_MSDOS)
766 playlist[i].voice = allocate_voice((SAMPLE *)playlist[i].data_ptr);
769 voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
771 voice_set_volume(playlist[i].voice, snd_ctrl.volume);
772 voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
773 voice_start(playlist[i].voice);
779 #endif /* !PLATFORM_WIN32 */
782 void SoundServer_FadeSound(int nr)
789 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
790 if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
791 playlist[i].fade_sound = TRUE;
795 #if !defined(PLATFORM_WIN32)
796 #if defined(PLATFORM_MSDOS)
797 static void SoundServer_StopSound(struct SoundControl snd_ctrl)
799 int nr = snd_ctrl.nr;
805 for(i=0; i<MAX_SOUNDS_PLAYING; i++)
807 if ((i == audio.music_channel && snd_ctrl.music) ||
808 (i != audio.music_channel && playlist[i].nr == nr))
810 #if defined(PLATFORM_MSDOS)
811 voice_set_volume(playlist[i].voice, 0);
812 deallocate_voice(playlist[i].voice);
814 playlist[i] = emptySoundControl;
819 #if !defined(PLATFORM_MSDOS)
821 close(audio.device_fd);
825 static void SoundServer_StopAllSounds()
829 for(i=0;i<MAX_SOUNDS_PLAYING;i++)
831 #if defined(PLATFORM_MSDOS)
832 voice_set_volume(playlist[i].voice, 0);
833 deallocate_voice(playlist[i].voice);
835 playlist[i]=emptySoundControl;
839 #if !defined(PLATFORM_MSDOS)
840 close(audio.device_fd);
843 #endif /* PLATFORM_MSDOS */
844 #endif /* !PLATFORM_WIN32 */
847 /* ------------------------------------------------------------------------- */
848 /* platform dependant audio initialization code */
849 /* ------------------------------------------------------------------------- */
851 #if defined(AUDIO_LINUX_IOCTL)
852 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
854 /* "ioctl()" expects pointer to 'int' value for stereo flag
855 (boolean is defined as 'char', which will not work here) */
856 unsigned int fragment_spec = 0;
857 int fragment_size_query;
866 /* supported audio format in preferred order */
867 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
868 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
869 { AFMT_U8, AUDIO_FORMAT_U8 },
874 /* determine logarithm (log2) of the fragment size */
875 while ((1 << fragment_spec) < afmt->fragment_size)
878 /* use two fragments (play one fragment, prepare the other);
879 one fragment would result in interrupted audio output, more
880 than two fragments would raise audio output latency to much */
881 fragment_spec |= 0x00020000;
883 /* Example for fragment specification:
884 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
885 - (with stereo the effective buffer size will shrink to 256)
886 => fragment_size = 0x00020009 */
888 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
889 Error(ERR_EXIT_SOUND_SERVER,
890 "cannot set fragment size of /dev/dsp -- no sounds");
894 while (formats[i].format_result != -1)
896 unsigned int audio_format = formats[i].format_ioctl;
897 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
899 afmt->format = formats[i].format_result;
904 if (afmt->format == 0) /* no supported audio format found */
905 Error(ERR_EXIT_SOUND_SERVER,
906 "cannot set audio format of /dev/dsp -- no sounds");
908 /* try if we can use stereo sound */
910 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
911 afmt->stereo = FALSE;
913 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
914 Error(ERR_EXIT_SOUND_SERVER,
915 "cannot set sample rate of /dev/dsp -- no sounds");
917 /* get the real fragmentation size; this should return 512 */
918 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
919 Error(ERR_EXIT_SOUND_SERVER,
920 "cannot get fragment size of /dev/dsp -- no sounds");
921 if (fragment_size_query != afmt->fragment_size)
922 Error(ERR_EXIT_SOUND_SERVER,
923 "cannot set fragment size of /dev/dsp -- no sounds");
925 #endif /* AUDIO_LINUX_IOCTL */
927 #if defined(PLATFORM_NETBSD)
928 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
931 boolean stereo = TRUE;
933 AUDIO_INITINFO(&a_info);
934 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
935 a_info.play.precision = 8;
936 a_info.play.channels = 2;
937 a_info.play.sample_rate = sample_rate;
938 a_info.blocksize = fragment_size;
940 afmt->format = AUDIO_FORMAT_U8;
943 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
945 /* try to disable stereo */
946 a_info.play.channels = 1;
948 afmt->stereo = FALSE;
950 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
951 Error(ERR_EXIT_SOUND_SERVER,
952 "cannot set sample rate of /dev/audio -- no sounds");
955 #endif /* PLATFORM_NETBSD */
957 #if defined(PLATFORM_HPUX)
958 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
960 struct audio_describe ainfo;
963 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
965 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl -- no sounds");
967 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
968 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
970 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
971 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
973 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
974 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
976 afmt->format = AUDIO_FORMAT_U8;
977 afmt->stereo = FALSE;
978 afmt->sample_rate = 8000;
982 #endif /* PLATFORM_HPUX */
984 #if defined(PLATFORM_UNIX)
985 static void InitAudioDevice_DSP(struct AudioFormatInfo *afmt)
987 #if defined(AUDIO_LINUX_IOCTL)
988 InitAudioDevice_Linux(afmt);
989 #elif defined(PLATFORM_NETBSD)
990 InitAudioDevice_NetBSD(afmt);
991 #elif defined(PLATFORM_HPUX)
992 InitAudioDevice_HPUX(afmt);
995 #endif /* PLATFORM_UNIX */
997 #if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
999 /* these two are stolen from "sox"... :) */
1002 ** This routine converts from linear to ulaw.
1004 ** Craig Reese: IDA/Supercomputing Research Center
1005 ** Joe Campbell: Department of Defense
1006 ** 29 September 1989
1009 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1010 ** 2) "A New Digital Technique for Implementation of Any
1011 ** Continuous PCM Companding Law," Villeret, Michel,
1012 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1013 ** 1973, pg. 11.12-11.17
1014 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1015 ** for Analog-to_Digital Conversion Techniques,"
1018 ** Input: Signed 16 bit linear sample
1019 ** Output: 8 bit ulaw sample
1022 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1023 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1026 static unsigned char linear_to_ulaw(int sample)
1028 static int exp_lut[256] =
1030 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1031 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1032 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1033 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1034 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1035 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1036 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1037 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1038 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1039 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1040 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1041 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1042 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1043 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1044 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1045 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1048 int sign, exponent, mantissa;
1049 unsigned char ulawbyte;
1051 /* Get the sample into sign-magnitude. */
1052 sign = (sample >> 8) & 0x80; /* set aside the sign */
1054 sample = -sample; /* get magnitude */
1056 sample = CLIP; /* clip the magnitude */
1058 /* Convert from 16 bit linear to ulaw. */
1059 sample = sample + BIAS;
1060 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1061 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1062 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1065 ulawbyte = 0x02; /* optional CCITT trap */
1072 ** This routine converts from ulaw to 16 bit linear.
1074 ** Craig Reese: IDA/Supercomputing Research Center
1075 ** 29 September 1989
1078 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1079 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1080 ** for Analog-to_Digital Conversion Techniques,"
1083 ** Input: 8 bit ulaw sample
1084 ** Output: signed 16 bit linear sample
1087 static int ulaw_to_linear(unsigned char ulawbyte)
1089 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1090 int sign, exponent, mantissa, sample;
1092 ulawbyte = ~ ulawbyte;
1093 sign = ( ulawbyte & 0x80 );
1094 exponent = ( ulawbyte >> 4 ) & 0x07;
1095 mantissa = ulawbyte & 0x0F;
1096 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1102 #endif /* PLATFORM_UNIX && !AUDIO_STREAMING_DSP */
1105 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1106 /* ========================================================================= */
1107 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1109 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1110 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1112 static SoundInfo *Load_WAV(char *filename)
1114 SoundInfo *snd_info;
1115 #if !defined(TARGET_SDL) && !defined(PLATFORM_MSDOS)
1116 byte sound_header_buffer[WAV_HEADER_SIZE];
1117 char chunk_name[CHUNK_ID_LEN + 1];
1123 if (!audio.sound_available)
1127 printf("loading WAV file '%s'\n", filename);
1130 snd_info = checked_calloc(sizeof(SoundInfo));
1132 #if defined(TARGET_SDL)
1134 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1136 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1141 #elif defined(TARGET_ALLEGRO)
1143 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1145 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1150 #else /* PLATFORM_UNIX */
1152 if ((file = fopen(filename, MODE_READ)) == NULL)
1154 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1159 /* read chunk id "RIFF" */
1160 getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN);
1161 if (strcmp(chunk_name, "RIFF") != 0)
1163 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1169 /* read "RIFF" type id "WAVE" */
1170 getFileChunk(file, chunk_name, NULL, BYTE_ORDER_LITTLE_ENDIAN);
1171 if (strcmp(chunk_name, "WAVE") != 0)
1173 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1179 while (getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN))
1181 if (strcmp(chunk_name, "fmt ") == 0)
1183 /* read header information */
1184 for (i=0; i < MIN(chunk_size, WAV_HEADER_SIZE); i++)
1185 sound_header_buffer[i] = fgetc(file);
1187 if (chunk_size > WAV_HEADER_SIZE)
1188 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1190 else if (strcmp(chunk_name, "data") == 0)
1192 snd_info->data_len = chunk_size;
1193 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1195 /* read sound data */
1196 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1199 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1201 free(snd_info->data_ptr);
1206 /* check for odd number of sample bytes (data chunk is word aligned) */
1207 if ((chunk_size % 2) == 1)
1208 ReadUnusedBytesFromFile(file, 1);
1210 else /* unknown chunk -- ignore */
1211 ReadUnusedBytesFromFile(file, chunk_size);
1216 if (snd_info->data_ptr == NULL)
1218 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1223 snd_info->format = AUDIO_FORMAT_U8;
1225 #endif /* PLATFORM_UNIX */
1227 snd_info->type = SND_TYPE_WAV;
1228 snd_info->source_filename = getStringCopy(filename);
1233 static void LoadCustomSound(SoundInfo **snd_info, char *basename)
1235 char *filename = getCustomSoundFilename(basename);
1237 if (filename == NULL) /* (should never happen) */
1239 Error(ERR_WARN, "cannot find sound file '%s'", basename);
1245 char *filename_old = (*snd_info)->source_filename;
1247 if (strcmp(filename, filename_old) == 0)
1249 /* The old and new sound are the same (have the same filename and path).
1250 This usually means that this sound does not exist in this sound set
1251 and a fallback to the existing sound is done. */
1254 printf("[sound '%s' already exists]\n", filename);
1260 if (--(*snd_info)->num_references <= 0)
1263 printf("[deleting sound '%s']\n", filename_old);
1267 FreeSound(*snd_info);
1269 deleteNodeFromList(&SoundFileList, filename_old, FreeSound);
1273 *snd_info = Load_WAV(filename);
1274 (*snd_info)->num_references = 1;
1276 addNodeToList(&SoundFileList, (*snd_info)->source_filename, *snd_info);
1279 void InitSoundList(struct SoundEffectInfo *sounds_list, int num_list_entries)
1282 Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
1284 sound_effect = sounds_list;
1285 num_sounds = num_list_entries;
1288 void LoadSoundToList(char *basename, int list_pos)
1290 if (Sound == NULL || list_pos >= num_sounds)
1293 printf("loading sound '%s' ... [%d]\n",
1294 basename, getNumNodes(SoundFileList));
1296 LoadCustomSound(&Sound[list_pos], basename);
1298 printf("loading sound '%s' done [%d]\n",
1299 basename, getNumNodes(SoundFileList));
1302 static MusicInfo *Load_MOD(char *filename)
1304 #if defined(TARGET_SDL)
1305 MusicInfo *mod_info;
1307 if (!audio.sound_available)
1310 mod_info = checked_calloc(sizeof(MusicInfo));
1312 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1314 Error(ERR_WARN, "cannot read music file '%s'", filename);
1319 mod_info->type = MUS_TYPE_MOD;
1320 mod_info->source_filename = getStringCopy(filename);
1328 void LoadCustomMusic(void)
1330 char *music_directory = getCustomMusicDirectory();
1332 struct dirent *dir_entry;
1334 if (!audio.sound_available)
1337 if ((dir = opendir(music_directory)) == NULL)
1339 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1340 audio.music_available = FALSE;
1344 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1346 char *basename = dir_entry->d_name;
1347 char *filename = getPath2(music_directory, basename);
1348 MusicInfo *mus_info = NULL;
1350 if (FileIsSound(basename))
1351 mus_info = Load_WAV(filename);
1352 else if (FileIsMusic(basename))
1353 mus_info = Load_MOD(filename);
1360 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1361 Music[num_music -1] = mus_info;
1368 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1372 void PlayMusic(int nr)
1374 if (!audio.music_available)
1377 #if defined(TARGET_SDL)
1379 nr = nr % num_music;
1381 if (Music[nr]->type == MUS_TYPE_MOD)
1383 Mix_PlayMusic(Music[nr]->data_ptr, -1);
1384 Mix_VolumeMusic(SOUND_MAX_VOLUME); /* must be _after_ Mix_PlayMusic()! */
1386 else /* play WAV music loop */
1388 Mix_Volume(audio.music_channel, SOUND_MAX_VOLUME);
1389 Mix_PlayChannel(audio.music_channel, Music[nr]->data_ptr, -1);
1399 void PlaySound(int nr)
1401 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
1404 void PlaySoundStereo(int nr, int stereo)
1406 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
1409 void PlaySoundLoop(int nr)
1411 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
1414 void PlaySoundMusic(int nr)
1416 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_MUSIC);
1419 void PlaySoundExt(int nr, int volume, int stereo, boolean loop_type)
1421 struct SoundControl snd_ctrl = emptySoundControl;
1423 if (!audio.sound_available ||
1424 !audio.sound_enabled ||
1425 audio.sound_deactivated)
1428 if (volume < PSND_MIN_VOLUME)
1429 volume = PSND_MIN_VOLUME;
1430 else if (volume > PSND_MAX_VOLUME)
1431 volume = PSND_MAX_VOLUME;
1433 if (stereo < PSND_MAX_LEFT)
1434 stereo = PSND_MAX_LEFT;
1435 else if (stereo > PSND_MAX_RIGHT)
1436 stereo = PSND_MAX_RIGHT;
1439 snd_ctrl.volume = volume;
1440 snd_ctrl.stereo = stereo;
1441 snd_ctrl.loop = (loop_type != PSND_NO_LOOP);
1442 snd_ctrl.music = (loop_type == PSND_MUSIC);
1443 snd_ctrl.active = TRUE;
1446 /* now only used internally in sound server child process */
1447 snd_ctrl.data_ptr = Sound[nr].data_ptr;
1448 snd_ctrl.data_len = Sound[nr].data_len;
1451 #if defined(TARGET_SDL)
1452 Mix_Volume(-1, SOUND_MAX_VOLUME);
1453 Mix_PlayChannel(-1, Sound[nr]->data_ptr, (loop_type ? -1 : 0));
1454 #elif defined(PLATFORM_UNIX)
1455 if (audio.soundserver_pid == 0) /* we are child process */
1458 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1460 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1461 audio.sound_available = audio.sound_enabled = FALSE;
1464 #elif defined(PLATFORM_MSDOS)
1465 sound_handler(snd_ctrl);
1469 void FadeMusic(void)
1471 if (!audio.sound_available)
1474 #if defined(TARGET_SDL)
1475 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
1476 Mix_FadeOutChannel(audio.music_channel, SOUND_FADING_INTERVAL);
1478 StopSoundExt(-1, SSND_FADE_MUSIC);
1482 void FadeSound(int nr)
1484 StopSoundExt(nr, SSND_FADE_SOUND);
1490 StopSoundExt(-1, SSND_FADE_ALL);
1493 void StopMusic(void)
1495 #if defined(TARGET_SDL)
1496 if (!audio.sound_available)
1500 Mix_HaltChannel(audio.music_channel);
1502 StopSoundExt(-1, SSND_STOP_MUSIC);
1506 void StopSound(int nr)
1508 StopSoundExt(nr, SSND_STOP_SOUND);
1513 StopSoundExt(-1, SSND_STOP_ALL);
1516 void StopSoundExt(int nr, int method)
1518 struct SoundControl snd_ctrl = emptySoundControl;
1520 if (!audio.sound_available)
1523 if (method & SSND_FADING)
1524 snd_ctrl.fade_sound = TRUE;
1526 if (method & SSND_ALL)
1527 snd_ctrl.stop_all_sounds = TRUE;
1530 snd_ctrl.stop_sound = TRUE;
1534 if (method & SSND_MUSIC)
1535 snd_ctrl.music = TRUE;
1537 #if defined(TARGET_SDL)
1539 if (method & SSND_FADING)
1543 for (i=0; i<audio.channels; i++)
1544 if (i != audio.music_channel || snd_ctrl.music)
1545 Mix_FadeOutChannel(i, SOUND_FADING_INTERVAL);
1547 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
1553 for (i=0; i<audio.channels; i++)
1554 if (i != audio.music_channel || snd_ctrl.music)
1560 #elif !defined(PLATFORM_MSDOS)
1562 if (audio.soundserver_pid == 0) /* we are child process */
1565 if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
1567 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1568 audio.sound_available = audio.sound_enabled = FALSE;
1572 sound_handler(snd_ctrl);
1576 ListNode *newListNode()
1578 return checked_calloc(sizeof(ListNode));
1581 void addNodeToList(ListNode **node_first, char *key, void *content)
1583 ListNode *node_new = newListNode();
1586 printf("LIST: adding node with key '%s'\n", key);
1589 node_new->key = getStringCopy(key);
1590 node_new->content = content;
1591 node_new->next = *node_first;
1592 *node_first = node_new;
1595 void deleteNodeFromList(ListNode **node_first, char *key,
1596 void (*destructor_function)(void *))
1598 if (node_first == NULL || *node_first == NULL)
1601 printf("[CHECKING LIST KEY '%s' == '%s']\n",
1602 (*node_first)->key, key);
1604 if (strcmp((*node_first)->key, key) == 0)
1606 printf("[DELETING LIST ENTRY]\n");
1608 free((*node_first)->key);
1609 if (destructor_function)
1610 destructor_function((*node_first)->content);
1611 *node_first = (*node_first)->next;
1614 deleteNodeFromList(&(*node_first)->next, key, destructor_function);
1617 ListNode *getNodeFromKey(ListNode *node_first, char *key)
1619 if (node_first == NULL)
1622 if (strcmp(node_first->key, key) == 0)
1625 return getNodeFromKey(node_first->next, key);
1628 int getNumNodes(ListNode *node_first)
1630 return (node_first ? 1 + getNumNodes(node_first->next) : 0);
1633 void dumpList(ListNode *node_first)
1635 ListNode *node = node_first;
1639 printf("['%s']\n", node->key);
1643 printf("[%d nodes]\n", getNumNodes(node_first));
1646 static void LoadSoundsInfo()
1648 char *filename = getCustomSoundConfigFilename();
1649 struct SetupFileList *setup_file_list;
1652 /* always start with reliable default values */
1653 for (i=0; i<num_sounds; i++)
1654 sound_effect[i].filename = NULL;
1656 if (filename == NULL)
1659 if ((setup_file_list = loadSetupFileList(filename)))
1661 for (i=0; i<num_sounds; i++)
1662 sound_effect[i].filename =
1663 getStringCopy(getTokenValue(setup_file_list, sound_effect[i].text));
1665 freeSetupFileList(setup_file_list);
1668 for (i=0; i<num_sounds; i++)
1670 printf("'%s' ", sound_effect[i].text);
1671 if (sound_effect[i].filename)
1672 printf("-> '%s'\n", sound_effect[i].filename);
1674 printf("-> UNDEFINED [-> '%s']\n", sound_effect[i].default_filename);
1680 static void ReloadCustomSounds()
1685 printf("DEBUG: reloading sounds '%s' ...\n", artwork.sounds_set_current);
1690 for(i=0; i<num_sounds; i++)
1692 if (sound_effect[i].filename)
1693 LoadSoundToList(sound_effect[i].filename, i);
1695 LoadSoundToList(sound_effect[i].default_filename, i);
1699 printf("list size == %d\n", getNumNodes(SoundFileList));
1701 dumpList(SoundFileList);
1704 static void ReloadCustomMusic()
1707 printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current);
1715 static void InitReloadSoundsOrMusic(char *set_name, int type)
1717 #if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
1718 struct SoundControl snd_ctrl = emptySoundControl;
1720 (type == SND_RELOAD_SOUNDS ? artwork.snd_current : artwork.mus_current);
1721 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
1722 unsigned long str_size2 = strlen(ti->basepath) + 1;
1723 unsigned long str_size3 = strlen(ti->fullpath) + 1;
1726 if (!audio.sound_available)
1729 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
1730 if (type == SND_RELOAD_SOUNDS)
1731 audio.func_reload_sounds();
1733 audio.func_reload_music();
1734 #elif defined(PLATFORM_UNIX)
1735 if (audio.soundserver_pid == 0) /* we are child process */
1738 if (leveldir_current == NULL) /* should never happen */
1739 Error(ERR_EXIT, "leveldir_current == NULL");
1741 snd_ctrl.reload_sounds = (type == SND_RELOAD_SOUNDS);
1742 snd_ctrl.reload_music = (type == SND_RELOAD_MUSIC);
1743 snd_ctrl.data_len = strlen(set_name) + 1;
1745 if (write(audio.soundserver_pipe[1], &snd_ctrl,
1746 sizeof(snd_ctrl)) < 0 ||
1747 write(audio.soundserver_pipe[1], set_name,
1748 snd_ctrl.data_len) < 0 ||
1749 write(audio.soundserver_pipe[1], leveldir_current,
1750 sizeof(TreeInfo)) < 0 ||
1751 write(audio.soundserver_pipe[1], ti,
1752 sizeof(TreeInfo)) < 0 ||
1753 write(audio.soundserver_pipe[1], &str_size1,
1754 sizeof(unsigned long)) < 0 ||
1755 write(audio.soundserver_pipe[1], &str_size2,
1756 sizeof(unsigned long)) < 0 ||
1757 write(audio.soundserver_pipe[1], &str_size3,
1758 sizeof(unsigned long)) < 0 ||
1759 write(audio.soundserver_pipe[1], leveldir_current->fullpath,
1761 write(audio.soundserver_pipe[1], ti->basepath,
1763 write(audio.soundserver_pipe[1], ti->fullpath,
1766 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
1767 audio.sound_available = audio.sound_enabled = FALSE;
1773 void InitReloadSounds(char *set_name)
1775 InitReloadSoundsOrMusic(set_name, SND_RELOAD_SOUNDS);
1778 void InitReloadMusic(char *set_name)
1780 InitReloadSoundsOrMusic(set_name, SND_RELOAD_MUSIC);
1783 void FreeSound(void *ptr)
1785 SoundInfo *sound = (SoundInfo *)ptr;
1790 if (sound->data_ptr)
1792 #if defined(TARGET_SDL)
1793 Mix_FreeChunk(sound->data_ptr);
1794 #elif defined(TARGET_ALLEGRO)
1795 destroy_sample(sound->data_ptr);
1796 #else /* PLATFORM_UNIX */
1797 free(sound->data_ptr);
1801 if (sound->source_filename)
1802 free(sound->source_filename);
1807 void FreeMusic(MusicInfo *music)
1812 if (music->data_ptr)
1814 #if defined(TARGET_SDL)
1815 if (music->type == MUS_TYPE_MOD)
1816 Mix_FreeMusic(music->data_ptr);
1818 Mix_FreeChunk(music->data_ptr);
1819 #elif defined(TARGET_ALLEGRO)
1820 destroy_sample(music->data_ptr);
1821 #else /* PLATFORM_UNIX */
1822 free(music->data_ptr);
1829 void FreeAllSounds()
1836 for(i=0; i<num_sounds; i++)
1837 FreeSound(Sound[i]);
1852 for(i=0; i<num_music; i++)
1853 FreeMusic(Music[i]);
1861 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
1862 /* ========================================================================= */