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 ***********************************************************/
24 #if defined(PLATFORM_LINUX)
25 #include <sys/ioctl.h>
26 #include <linux/soundcard.h>
27 #elif defined(PLATFORM_FREEBSD)
28 #include <machine/soundcard.h>
29 #elif defined(PLATFORM_NETBSD)
30 #include <sys/ioctl.h>
31 #include <sys/audioio.h>
32 #elif defined(PLATFORM_HPUX)
33 #include <sys/audio.h>
42 /* expiration time (in milliseconds) for sound loops */
43 #define SOUND_LOOP_EXPIRATION_TIME 200
45 #if defined(TARGET_SDL)
46 /* one second fading interval == 1000 ticks (milliseconds) */
47 #define SOUND_FADING_INTERVAL 1000
48 #define SOUND_MAX_VOLUME SDL_MIX_MAXVOLUME
51 #if defined(AUDIO_STREAMING_DSP)
52 #define SOUND_FADING_VOLUME_STEP (PSND_MAX_VOLUME / 40)
53 #define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2)
56 #if !defined(PLATFORM_HPUX)
57 #define SND_BLOCKSIZE 4096
59 #define SND_BLOCKSIZE 32768
62 #define SND_TYPE_NONE 0
63 #define SND_TYPE_WAV 1
65 #define MUS_TYPE_NONE 0
66 #define MUS_TYPE_WAV 1
67 #define MUS_TYPE_MOD 2
69 #define DEVICENAME_DSP "/dev/dsp"
70 #define DEVICENAME_AUDIO "/dev/audio"
71 #define DEVICENAME_AUDIOCTL "/dev/audioCtl"
75 struct SoundHeader_SUN
78 unsigned long hdr_size;
79 unsigned long data_size;
80 unsigned long encoding;
81 unsigned long sample_rate;
82 unsigned long channels;
85 struct SoundHeader_8SVX
88 unsigned long chunk_size;
93 struct AudioFormatInfo
95 boolean stereo; /* availability of stereo sound */
96 int format; /* size and endianess of sample data */
97 int sample_rate; /* sample frequency */
98 int fragment_size; /* audio device fragment size in bytes */
103 char *source_filename;
111 typedef struct SampleInfo SoundInfo;
112 typedef struct SampleInfo MusicInfo;
124 unsigned long playing_starttime;
125 unsigned long playing_pos;
132 #if defined(PLATFORM_MSDOS)
136 typedef struct SoundControl SoundControl;
142 struct ListNode *next;
144 typedef struct ListNode ListNode;
146 static ListNode *newListNode(void);
147 static void addNodeToList(ListNode **, char *, void *);
148 static void deleteNodeFromList(ListNode **, char *, void (*function)(void *));
149 static ListNode *getNodeFromKey(ListNode *, char *);
150 static int getNumNodes(ListNode *);
153 static struct SoundEffectInfo *sound_effect;
154 static ListNode *SoundFileList = NULL;
155 static SoundInfo **Sound = NULL;
156 static MusicInfo **Music = NULL;
157 static int num_sounds = 0, num_music = 0;
160 /* ========================================================================= */
161 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
163 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
164 static int mixer_active_channels = 0;
166 #if defined(AUDIO_UNIX_NATIVE)
167 static struct AudioFormatInfo afmt;
169 static void Mixer_Main(void);
170 #if !defined(AUDIO_STREAMING_DSP)
171 static unsigned char linear_to_ulaw(int);
172 static int ulaw_to_linear(unsigned char);
176 static void ReloadCustomSounds();
177 static void ReloadCustomMusic();
178 static void FreeSound(void *);
181 /* ------------------------------------------------------------------------- */
182 /* functions for native (non-SDL) Unix audio/mixer support */
183 /* ------------------------------------------------------------------------- */
185 #if defined(AUDIO_UNIX_NATIVE)
187 static int OpenAudioDevice(char *audio_device_name)
191 /* check if desired audio device is accessible */
192 if (access(audio_device_name, W_OK) != 0)
195 /* try to open audio device in non-blocking mode */
196 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
197 return audio_device_fd;
199 /* re-open audio device in blocking mode */
200 close(audio_device_fd);
201 audio_device_fd = open(audio_device_name, O_WRONLY);
203 return audio_device_fd;
206 static void CloseAudioDevice(int *audio_device_fd)
208 if (*audio_device_fd == 0)
211 close(*audio_device_fd);
212 *audio_device_fd = -1;
215 static boolean TestAudioDevices(void)
217 static char *audio_device_name[] =
222 int audio_device_fd = -1;
225 /* look for available audio devices, starting with preferred ones */
226 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
227 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
230 if (audio_device_fd < 0)
232 Error(ERR_WARN, "cannot open audio device -- no sound");
236 close(audio_device_fd);
238 audio.device_name = audio_device_name[i];
243 static boolean ForkAudioProcess(void)
245 if (pipe(audio.mixer_pipe) < 0)
247 Error(ERR_WARN, "cannot create pipe -- no sounds");
251 if ((audio.mixer_pid = fork()) < 0)
253 Error(ERR_WARN, "cannot create sound server process -- no sounds");
257 if (IS_CHILD_PROCESS(audio.mixer_pid))
258 Mixer_Main(); /* this function never returns */
260 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
265 void UnixOpenAudio(void)
267 if (!TestAudioDevices())
270 audio.sound_available = TRUE;
271 audio.sound_enabled = TRUE;
273 #if defined(AUDIO_STREAMING_DSP)
274 audio.music_available = TRUE;
275 audio.loops_available = TRUE;
278 audio.num_channels = NUM_MIXER_CHANNELS;
279 audio.music_channel = MUSIC_CHANNEL;
280 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
283 void UnixCloseAudio(void)
286 close(audio.device_fd);
288 if (IS_PARENT_PROCESS(audio.mixer_pid))
289 kill(audio.mixer_pid, SIGTERM);
293 /* ------------------------------------------------------------------------- */
294 /* functions for platform specific audio device initialization */
295 /* ------------------------------------------------------------------------- */
297 #if defined(AUDIO_LINUX_IOCTL)
298 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
300 /* "ioctl()" expects pointer to 'int' value for stereo flag
301 (boolean is defined as 'char', which will not work here) */
302 unsigned int fragment_spec = 0;
303 int fragment_size_query;
312 /* supported audio format in preferred order */
313 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
314 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
315 { AFMT_U8, AUDIO_FORMAT_U8 },
320 /* determine logarithm (log2) of the fragment size */
321 while ((1 << fragment_spec) < afmt->fragment_size)
324 /* use two fragments (play one fragment, prepare the other);
325 one fragment would result in interrupted audio output, more
326 than two fragments would raise audio output latency to much */
327 fragment_spec |= 0x00020000;
329 /* Example for fragment specification:
330 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
331 - (with stereo the effective buffer size will shrink to 256)
332 => fragment_size = 0x00020009 */
334 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
335 Error(ERR_EXIT_SOUND_SERVER,
336 "cannot set fragment size of /dev/dsp -- no sounds");
340 while (formats[i].format_result != -1)
342 unsigned int audio_format = formats[i].format_ioctl;
343 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
345 afmt->format = formats[i].format_result;
350 if (afmt->format == 0) /* no supported audio format found */
351 Error(ERR_EXIT_SOUND_SERVER,
352 "cannot set audio format of /dev/dsp -- no sounds");
354 /* try if we can use stereo sound */
356 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
357 afmt->stereo = FALSE;
359 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
360 Error(ERR_EXIT_SOUND_SERVER,
361 "cannot set sample rate of /dev/dsp -- no sounds");
363 /* get the real fragmentation size; this should return 512 */
364 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
365 Error(ERR_EXIT_SOUND_SERVER,
366 "cannot get fragment size of /dev/dsp -- no sounds");
367 if (fragment_size_query != afmt->fragment_size)
368 Error(ERR_EXIT_SOUND_SERVER,
369 "cannot set fragment size of /dev/dsp -- no sounds");
371 #endif /* AUDIO_LINUX_IOCTL */
373 #if defined(PLATFORM_NETBSD)
374 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
377 boolean stereo = TRUE;
379 AUDIO_INITINFO(&a_info);
380 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
381 a_info.play.precision = 8;
382 a_info.play.channels = 2;
383 a_info.play.sample_rate = sample_rate;
384 a_info.blocksize = fragment_size;
386 afmt->format = AUDIO_FORMAT_U8;
389 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
391 /* try to disable stereo */
392 a_info.play.channels = 1;
394 afmt->stereo = FALSE;
396 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
397 Error(ERR_EXIT_SOUND_SERVER,
398 "cannot set sample rate of /dev/audio -- no sounds");
401 #endif /* PLATFORM_NETBSD */
403 #if defined(PLATFORM_HPUX)
404 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
406 struct audio_describe ainfo;
409 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
411 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl -- no sounds");
413 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
414 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
416 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
417 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
419 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
420 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
422 afmt->format = AUDIO_FORMAT_U8;
423 afmt->stereo = FALSE;
424 afmt->sample_rate = 8000;
428 #endif /* PLATFORM_HPUX */
430 static void InitAudioDevice(struct AudioFormatInfo *afmt)
433 afmt->format = AUDIO_FORMAT_UNKNOWN;
434 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
435 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
437 #if defined(AUDIO_LINUX_IOCTL)
438 InitAudioDevice_Linux(afmt);
439 #elif defined(PLATFORM_NETBSD)
440 InitAudioDevice_NetBSD(afmt);
441 #elif defined(PLATFORM_HPUX)
442 InitAudioDevice_HPUX(afmt);
444 /* generic /dev/audio stuff might be placed here */
449 /* ------------------------------------------------------------------------- */
450 /* functions for communication between main process and sound mixer process */
451 /* ------------------------------------------------------------------------- */
453 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
455 if (IS_CHILD_PROCESS(audio.mixer_pid))
458 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
460 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
461 audio.sound_available = audio.sound_enabled = FALSE;
466 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
468 if (IS_PARENT_PROCESS(audio.mixer_pid))
471 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
472 != sizeof(SoundControl))
473 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
476 static void WriteReloadInfoToPipe(char *set_name, int type)
478 SoundControl snd_ctrl;
479 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
480 artwork.mus_current);
481 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
482 unsigned long str_size2 = strlen(ti->basepath) + 1;
483 unsigned long str_size3 = strlen(ti->fullpath) + 1;
485 if (IS_CHILD_PROCESS(audio.mixer_pid))
488 if (leveldir_current == NULL) /* should never happen */
489 Error(ERR_EXIT, "leveldir_current == NULL");
491 snd_ctrl.active = FALSE;
492 snd_ctrl.state = type;
493 snd_ctrl.data_len = strlen(set_name) + 1;
495 if (write(audio.mixer_pipe[1], &snd_ctrl,
496 sizeof(snd_ctrl)) < 0 ||
497 write(audio.mixer_pipe[1], set_name,
498 snd_ctrl.data_len) < 0 ||
499 write(audio.mixer_pipe[1], leveldir_current,
500 sizeof(TreeInfo)) < 0 ||
501 write(audio.mixer_pipe[1], ti,
502 sizeof(TreeInfo)) < 0 ||
503 write(audio.mixer_pipe[1], &str_size1,
504 sizeof(unsigned long)) < 0 ||
505 write(audio.mixer_pipe[1], &str_size2,
506 sizeof(unsigned long)) < 0 ||
507 write(audio.mixer_pipe[1], &str_size3,
508 sizeof(unsigned long)) < 0 ||
509 write(audio.mixer_pipe[1], leveldir_current->fullpath,
511 write(audio.mixer_pipe[1], ti->basepath,
513 write(audio.mixer_pipe[1], ti->fullpath,
516 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
517 audio.sound_available = audio.sound_enabled = FALSE;
522 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
524 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
525 &artwork.snd_current : &artwork.mus_current);
526 TreeInfo *ti = *ti_ptr;
527 unsigned long str_size1, str_size2, str_size3;
528 static char *set_name = NULL;
533 set_name = checked_malloc(snd_ctrl->data_len);
535 if (leveldir_current == NULL)
536 leveldir_current = checked_calloc(sizeof(TreeInfo));
538 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
539 if (leveldir_current->fullpath != NULL)
540 free(leveldir_current->fullpath);
541 if (ti->basepath != NULL)
543 if (ti->fullpath != NULL)
546 if (read(audio.mixer_pipe[0], set_name,
547 snd_ctrl->data_len) != snd_ctrl->data_len ||
548 read(audio.mixer_pipe[0], leveldir_current,
549 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
550 read(audio.mixer_pipe[0], ti,
551 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
552 read(audio.mixer_pipe[0], &str_size1,
553 sizeof(unsigned long)) != sizeof(unsigned long) ||
554 read(audio.mixer_pipe[0], &str_size2,
555 sizeof(unsigned long)) != sizeof(unsigned long) ||
556 read(audio.mixer_pipe[0], &str_size3,
557 sizeof(unsigned long)) != sizeof(unsigned long))
558 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
560 leveldir_current->fullpath = checked_calloc(str_size1);
561 ti->basepath = checked_calloc(str_size2);
562 ti->fullpath = checked_calloc(str_size3);
564 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
565 str_size1) != str_size1 ||
566 read(audio.mixer_pipe[0], ti->basepath,
567 str_size2) != str_size2 ||
568 read(audio.mixer_pipe[0], ti->fullpath,
569 str_size3) != str_size3)
570 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
572 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
573 artwork.sounds_set_current = set_name;
575 artwork.music_set_current = set_name;
578 #endif /* AUDIO_UNIX_NATIVE */
581 /* ------------------------------------------------------------------------- */
582 /* mixer functions */
583 /* ------------------------------------------------------------------------- */
585 void Mixer_InitChannels()
589 for(i=0; i<audio.num_channels; i++)
590 mixer[i].active = FALSE;
591 mixer_active_channels = 0;
594 static void Mixer_ResetChannelExpiration(int channel)
596 mixer[channel].playing_starttime = Counter();
598 #if defined(TARGET_SDL)
599 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
600 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
604 static boolean Mixer_ChannelExpired(int channel)
606 if (!mixer[channel].active)
609 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
610 DelayReached(&mixer[channel].playing_starttime,
611 SOUND_LOOP_EXPIRATION_TIME))
614 #if defined(TARGET_SDL)
616 if (!Mix_Playing(channel))
619 #elif defined(TARGET_ALLEGRO)
621 mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
622 mixer[channel].volume = voice_get_volume(mixer[channel].voice);
624 /* sound sample has completed playing or was completely faded out */
625 if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
628 #endif /* TARGET_ALLEGRO */
633 static void Mixer_PlayChannel(int channel)
635 /* start with inactive channel in case something goes wrong */
636 mixer[channel].active = FALSE;
638 if (mixer[channel].type != MUS_TYPE_WAV)
641 #if defined(TARGET_SDL)
642 Mix_Volume(channel, SOUND_MAX_VOLUME);
643 Mix_PlayChannel(channel, mixer[channel].data_ptr,
644 IS_LOOP(mixer[channel]) ? -1 : 0);
645 #elif defined(PLATFORM_MSDOS)
646 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
647 if (mixer[channel].voice < 0)
650 if (IS_LOOP(mixer[channel]))
651 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
653 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
654 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
655 voice_start(mixer[channel].voice);
658 Mixer_ResetChannelExpiration(channel);
660 mixer[channel].playing_pos = 0;
661 mixer[channel].active = TRUE;
662 mixer_active_channels++;
665 static void Mixer_PlayMusicChannel()
667 Mixer_PlayChannel(audio.music_channel);
669 #if defined(TARGET_SDL)
670 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
672 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
673 this looks like a bug in the SDL_mixer library */
674 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
675 Mix_VolumeMusic(SOUND_MAX_VOLUME);
680 static void Mixer_StopChannel(int channel)
682 if (!mixer[channel].active)
685 #if defined(TARGET_SDL)
686 Mix_HaltChannel(channel);
687 #elif defined(PLATFORM_MSDOS)
688 voice_set_volume(mixer[channel].voice, 0);
689 deallocate_voice(mixer[channel].voice);
692 mixer[channel].active = FALSE;
693 mixer_active_channels--;
696 static void Mixer_StopMusicChannel()
698 Mixer_StopChannel(audio.music_channel);
700 #if defined(TARGET_SDL)
705 static void Mixer_FadeChannel(int channel)
707 if (!mixer[channel].active)
710 mixer[channel].state |= SND_CTRL_FADE;
712 #if defined(TARGET_SDL)
713 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
714 #elif defined(PLATFORM_MSDOS)
715 if (voice_check(mixer[channel].voice))
716 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
720 static void Mixer_FadeMusicChannel()
722 Mixer_FadeChannel(audio.music_channel);
724 #if defined(TARGET_SDL)
725 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
729 static void Mixer_UnFadeChannel(int channel)
731 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
734 mixer[channel].state &= ~SND_CTRL_FADE;
735 mixer[channel].volume = PSND_MAX_VOLUME;
737 #if defined(TARGET_SDL)
738 Mix_ExpireChannel(channel, -1);
739 Mix_Volume(channel, SOUND_MAX_VOLUME);
740 #elif defined(TARGET_ALLEGRO)
741 voice_stop_volumeramp(mixer[channel].voice);
742 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
743 mixer[channel].volume);
747 static void Mixer_InsertSound(SoundControl snd_ctrl)
753 printf("NEW SOUND %d HAS ARRIVED [%d]\n", snd_ctrl.nr, num_sounds);
757 printf("%d ACTIVE CHANNELS\n", mixer_active_channels);
760 if (IS_MUSIC(snd_ctrl))
761 snd_ctrl.nr = snd_ctrl.nr % num_music;
762 else if (snd_ctrl.nr >= num_sounds)
765 snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
766 if (snd_info == NULL)
769 /* copy sound sample and format information */
770 snd_ctrl.type = snd_info->type;
771 snd_ctrl.format = snd_info->format;
772 snd_ctrl.data_ptr = snd_info->data_ptr;
773 snd_ctrl.data_len = snd_info->data_len;
775 /* play music samples on a dedicated music channel */
776 if (IS_MUSIC(snd_ctrl))
778 mixer[audio.music_channel] = snd_ctrl;
779 Mixer_PlayMusicChannel();
784 /* check if sound is already being played (and how often) */
785 for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
786 if (mixer[i].active && mixer[i].nr == snd_ctrl.nr)
790 printf("SOUND %d [CURRENTLY PLAYING %d TIMES]\n", snd_ctrl.nr, k);
793 /* reset expiration delay for already playing loop sounds */
794 if (k > 0 && IS_LOOP(snd_ctrl))
796 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
798 if (mixer[i].active && mixer[i].nr == snd_ctrl.nr)
801 printf("RESETTING EXPIRATION FOR SOUND %d\n", snd_ctrl.nr);
805 Mixer_ResetChannelExpiration(i);
807 if (IS_FADING(mixer[i]))
808 Mixer_UnFadeChannel(i);
815 /* don't play sound more than n times simultaneously (with n == 2 for now) */
818 unsigned long playing_current = Counter();
819 int longest = 0, longest_nr = audio.first_sound_channel;
821 /* look for oldest equal sound */
822 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
824 int playing_time = playing_current - mixer[i].playing_starttime;
827 if (!mixer[i].active || mixer[i].nr != snd_ctrl.nr)
830 actual = 1000 * playing_time / mixer[i].data_len;
832 if (actual >= longest)
839 Mixer_StopChannel(longest_nr);
842 /* If all (non-music) channels are active, stop the channel that has
843 played its sound sample most completely (in percent of the sample
844 length). As we cannot currently get the actual playing position
845 of the channel's sound sample when compiling with the SDL mixer
846 library, we use the current playing time (in milliseconds) instead. */
848 if (mixer_active_channels ==
849 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
851 unsigned long playing_current = Counter();
852 int longest = 0, longest_nr = audio.first_sound_channel;
854 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
856 int playing_time = playing_current - mixer[i].playing_starttime;
857 int actual = 1000 * playing_time / mixer[i].data_len;
859 if (!IS_LOOP(mixer[i]) && actual > longest)
866 Mixer_StopChannel(longest_nr);
869 /* add the new sound to the mixer */
870 for(i=0; i<audio.num_channels; i++)
873 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
877 if (!mixer[i].active ||
878 (IS_MUSIC(snd_ctrl) && i == audio.music_channel))
880 if ((i == audio.music_channel && IS_MUSIC(snd_ctrl)) ||
881 (i != audio.music_channel && !mixer[i].active))
884 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
888 #if defined(AUDIO_UNIX_NATIVE)
889 if (snd_info->data_len == 0)
891 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
897 if (IS_MUSIC(snd_ctrl) && i == audio.music_channel && mixer[i].active)
899 printf("THIS SHOULD NEVER HAPPEN! [adding music twice]\n");
902 Mixer_StopChannel(i);
908 Mixer_PlayChannel(i);
915 static void HandleSoundRequest(SoundControl snd_ctrl)
919 #if defined(AUDIO_UNIX_NATIVE)
920 if (IS_PARENT_PROCESS(audio.mixer_pid))
922 SendSoundControlToMixerProcess(&snd_ctrl);
927 /* deactivate channels that have expired since the last request */
928 for (i=0; i<audio.num_channels; i++)
929 if (mixer[i].active && Mixer_ChannelExpired(i))
930 Mixer_StopChannel(i);
932 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
934 Mixer_StopMusicChannel();
935 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
936 Mixer_StopChannel(i);
938 #if defined(AUDIO_UNIX_NATIVE)
939 CloseAudioDevice(&audio.device_fd);
940 ReadReloadInfoFromPipe(&snd_ctrl);
943 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
944 ReloadCustomSounds();
948 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
950 if (IS_MUSIC(snd_ctrl))
952 Mixer_FadeMusicChannel();
956 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
957 if (mixer[i].nr == snd_ctrl.nr || ALL_SOUNDS(snd_ctrl))
958 Mixer_FadeChannel(i);
960 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
962 if (IS_MUSIC(snd_ctrl))
964 Mixer_StopMusicChannel();
968 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
969 if (mixer[i].nr == snd_ctrl.nr || ALL_SOUNDS(snd_ctrl))
970 Mixer_StopChannel(i);
972 #if defined(AUDIO_UNIX_NATIVE)
973 if (!mixer_active_channels)
974 CloseAudioDevice(&audio.device_fd);
977 else if (snd_ctrl.active) /* add new sound to mixer */
979 Mixer_InsertSound(snd_ctrl);
983 void StartMixer(void)
986 SDL_version compile_version;
987 const SDL_version *link_version;
988 MIX_VERSION(&compile_version);
989 printf("compiled with SDL_mixer version: %d.%d.%d\n",
990 compile_version.major,
991 compile_version.minor,
992 compile_version.patch);
993 link_version = Mix_Linked_Version();
994 printf("running with SDL_mixer version: %d.%d.%d\n",
997 link_version->patch);
1000 if (!audio.sound_available)
1003 #if defined(AUDIO_UNIX_NATIVE)
1004 if (!ForkAudioProcess())
1005 audio.sound_available = FALSE;
1009 #if defined(AUDIO_UNIX_NATIVE)
1011 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1012 int sample_pos, int sample_size,
1015 void *sample_ptr = snd_ctrl->data_ptr;
1018 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1019 for (i=0; i<sample_size; i++)
1021 ((short)(((byte *)sample_ptr)[sample_pos + i] ^ 0x80)) << 8;
1022 else /* AUDIO_FORMAT_S16 */
1023 for (i=0; i<sample_size; i++)
1025 ((short *)sample_ptr)[sample_pos + i];
1028 #if defined(AUDIO_STREAMING_DSP)
1029 static void Mixer_Main_DSP()
1031 static int stereo_volume[PSND_MAX_LEFT2RIGHT + 1];
1032 static boolean stereo_volume_calculated = FALSE;
1033 static short premix_first_buffer[SND_BLOCKSIZE];
1034 static short premix_left_buffer[SND_BLOCKSIZE];
1035 static short premix_right_buffer[SND_BLOCKSIZE];
1036 static long premix_last_buffer[SND_BLOCKSIZE];
1037 static byte playing_buffer[SND_BLOCKSIZE];
1041 int max_sample_size;
1044 if (!stereo_volume_calculated)
1046 for(i=0; i<=PSND_MAX_LEFT2RIGHT; i++)
1048 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT * PSND_MAX_LEFT2RIGHT - i * i));
1050 stereo_volume_calculated = TRUE;
1053 if (!mixer_active_channels)
1056 if (audio.device_fd < 0)
1058 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1061 InitAudioDevice(&afmt);
1064 stereo = afmt.stereo;
1065 fragment_size = afmt.fragment_size;
1066 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1067 max_sample_size = fragment_size / ((stereo ? 2 : 1) * sample_bytes);
1069 /* first clear the last premixing buffer */
1070 memset(premix_last_buffer, 0,
1071 max_sample_size * (stereo ? 2 : 1) * sizeof(long));
1073 for(i=0; i<audio.num_channels; i++)
1080 if (!mixer[i].active)
1083 if (Mixer_ChannelExpired(i))
1085 Mixer_StopChannel(i);
1089 /* pointer, lenght and actual playing position of sound sample */
1090 sample_ptr = mixer[i].data_ptr;
1091 sample_len = mixer[i].data_len;
1092 sample_pos = mixer[i].playing_pos;
1093 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1094 mixer[i].playing_pos += sample_size;
1096 /* copy original sample to first mixing buffer */
1097 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1098 premix_first_buffer);
1100 /* are we about to restart a looping sound? */
1101 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1103 while (sample_size < max_sample_size)
1105 int restarted_sample_size =
1106 MIN(max_sample_size - sample_size, sample_len);
1108 if (mixer[i].format == AUDIO_FORMAT_U8)
1109 for (j=0; j<restarted_sample_size; j++)
1110 premix_first_buffer[sample_size + j] =
1111 ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
1113 for (j=0; j<restarted_sample_size; j++)
1114 premix_first_buffer[sample_size + j] =
1115 ((short *)sample_ptr)[j];
1117 mixer[i].playing_pos = restarted_sample_size;
1118 sample_size += restarted_sample_size;
1122 /* decrease volume if sound is fading out */
1123 if (IS_FADING(mixer[i]) &&
1124 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1125 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1127 /* adjust volume of actual sound sample */
1128 if (mixer[i].volume != PSND_MAX_VOLUME)
1129 for(j=0; j<sample_size; j++)
1130 premix_first_buffer[j] =
1131 (mixer[i].volume * (long)premix_first_buffer[j])
1132 >> PSND_MAX_VOLUME_BITS;
1134 /* fill the last mixing buffer with stereo or mono sound */
1137 int middle_pos = PSND_MAX_LEFT2RIGHT / 2;
1138 int left_volume = stereo_volume[middle_pos + mixer[i].stereo_position];
1139 int right_volume= stereo_volume[middle_pos - mixer[i].stereo_position];
1141 for(j=0; j<sample_size; j++)
1143 premix_left_buffer[j] =
1144 (left_volume * premix_first_buffer[j])
1145 >> PSND_MAX_LEFT2RIGHT_BITS;
1146 premix_right_buffer[j] =
1147 (right_volume * premix_first_buffer[j])
1148 >> PSND_MAX_LEFT2RIGHT_BITS;
1150 premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
1151 premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
1156 for(j=0; j<sample_size; j++)
1157 premix_last_buffer[j] += premix_first_buffer[j];
1160 /* delete completed sound entries from the mixer */
1161 if (mixer[i].playing_pos >= mixer[i].data_len)
1163 if (IS_LOOP(mixer[i]))
1164 mixer[i].playing_pos = 0;
1166 Mixer_StopChannel(i);
1168 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1169 Mixer_StopChannel(i);
1172 /* prepare final playing buffer according to system audio format */
1173 for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
1175 /* cut off at 17 bit value */
1176 if (premix_last_buffer[i] < -65535)
1177 premix_last_buffer[i] = -65535;
1178 else if (premix_last_buffer[i] > 65535)
1179 premix_last_buffer[i] = 65535;
1181 /* shift to 16 bit value */
1182 premix_last_buffer[i] >>= 1;
1184 if (afmt.format & AUDIO_FORMAT_U8)
1186 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1188 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1190 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1191 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1193 else /* big endian */
1195 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1196 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1200 /* finally play the sound fragment */
1201 write(audio.device_fd, playing_buffer, fragment_size);
1203 if (!mixer_active_channels)
1204 CloseAudioDevice(&audio.device_fd);
1207 #else /* !AUDIO_STREAMING_DSP */
1209 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1211 static short premix_first_buffer[SND_BLOCKSIZE];
1212 static byte playing_buffer[SND_BLOCKSIZE];
1213 int max_sample_size = SND_BLOCKSIZE;
1222 /* pointer, lenght and actual playing position of sound sample */
1223 sample_ptr = mixer[i].data_ptr;
1224 sample_len = mixer[i].data_len;
1225 sample_pos = mixer[i].playing_pos;
1226 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1227 mixer[i].playing_pos += sample_size;
1229 /* copy original sample to first mixing buffer */
1230 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1231 premix_first_buffer);
1233 /* adjust volume of actual sound sample */
1234 if (mixer[i].volume != PSND_MAX_VOLUME)
1235 for(j=0; j<sample_size; j++)
1236 premix_first_buffer[j] =
1237 (mixer[i].volume * (long)premix_first_buffer[j])
1238 >> PSND_MAX_VOLUME_BITS;
1240 /* might be needed for u-law /dev/audio */
1242 for(j=0; j<sample_size; j++)
1244 linear_to_ulaw(premix_first_buffer[j]);
1247 /* delete completed sound entries from the mixer */
1248 if (mixer[i].playing_pos >= mixer[i].data_len)
1249 Mixer_StopChannel(i);
1251 for(i=0; i<sample_size; i++)
1252 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1254 /* finally play the sound fragment */
1255 write(audio.device_fd, playing_buffer, sample_size);
1259 #endif /* !AUDIO_STREAMING_DSP */
1263 SoundControl snd_ctrl;
1266 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1268 Mixer_InitChannels();
1270 #if defined(PLATFORM_HPUX)
1271 InitAudioDevice(&afmt);
1274 FD_ZERO(&mixer_fdset);
1275 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1277 while(1) /* wait for sound playing commands from client */
1279 struct timeval delay = { 0, 0 };
1281 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1282 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1283 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1286 ReadSoundControlFromMainProcess(&snd_ctrl);
1288 HandleSoundRequest(snd_ctrl);
1290 #if defined(AUDIO_STREAMING_DSP)
1292 while (mixer_active_channels &&
1293 select(audio.mixer_pipe[0] + 1,
1294 &mixer_fdset, NULL, NULL, &delay) < 1)
1296 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1301 #else /* !AUDIO_STREAMING_DSP */
1303 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1304 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1307 InitAudioDevice(&afmt);
1312 while (mixer_active_channels &&
1313 select(audio.mixer_pipe[0] + 1,
1314 &mixer_fdset, NULL, NULL, &delay) < 1)
1316 int wait_percent = 90; /* wait 90% of the real playing time */
1319 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1321 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1325 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1328 CloseAudioDevice(&audio.device_fd);
1330 Mixer_InitChannels(); /* remove all sounds from mixer */
1332 #endif /* !AUDIO_STREAMING_DSP */
1335 #endif /* AUDIO_UNIX_NATIVE */
1338 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1340 /* these two are stolen from "sox"... :) */
1343 ** This routine converts from linear to ulaw.
1345 ** Craig Reese: IDA/Supercomputing Research Center
1346 ** Joe Campbell: Department of Defense
1347 ** 29 September 1989
1350 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1351 ** 2) "A New Digital Technique for Implementation of Any
1352 ** Continuous PCM Companding Law," Villeret, Michel,
1353 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1354 ** 1973, pg. 11.12-11.17
1355 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1356 ** for Analog-to_Digital Conversion Techniques,"
1359 ** Input: Signed 16 bit linear sample
1360 ** Output: 8 bit ulaw sample
1363 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1364 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1367 static unsigned char linear_to_ulaw(int sample)
1369 static int exp_lut[256] =
1371 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1372 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1373 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1374 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1375 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1376 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1377 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1378 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1379 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1380 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1381 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1382 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1383 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1384 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1385 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1386 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1389 int sign, exponent, mantissa;
1390 unsigned char ulawbyte;
1392 /* Get the sample into sign-magnitude. */
1393 sign = (sample >> 8) & 0x80; /* set aside the sign */
1395 sample = -sample; /* get magnitude */
1397 sample = CLIP; /* clip the magnitude */
1399 /* Convert from 16 bit linear to ulaw. */
1400 sample = sample + BIAS;
1401 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1402 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1403 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1406 ulawbyte = 0x02; /* optional CCITT trap */
1413 ** This routine converts from ulaw to 16 bit linear.
1415 ** Craig Reese: IDA/Supercomputing Research Center
1416 ** 29 September 1989
1419 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1420 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1421 ** for Analog-to_Digital Conversion Techniques,"
1424 ** Input: 8 bit ulaw sample
1425 ** Output: signed 16 bit linear sample
1428 static int ulaw_to_linear(unsigned char ulawbyte)
1430 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1431 int sign, exponent, mantissa, sample;
1433 ulawbyte = ~ ulawbyte;
1434 sign = ( ulawbyte & 0x80 );
1435 exponent = ( ulawbyte >> 4 ) & 0x07;
1436 mantissa = ulawbyte & 0x0F;
1437 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1443 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1446 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1447 /* ========================================================================= */
1448 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1450 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1451 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1453 static SoundInfo *Load_WAV(char *filename)
1455 SoundInfo *snd_info;
1456 #if !defined(TARGET_SDL) && !defined(PLATFORM_MSDOS)
1457 byte sound_header_buffer[WAV_HEADER_SIZE];
1458 char chunk_name[CHUNK_ID_LEN + 1];
1464 if (!audio.sound_available)
1468 printf("loading WAV file '%s'\n", filename);
1471 snd_info = checked_calloc(sizeof(SoundInfo));
1473 #if defined(TARGET_SDL)
1475 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1477 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1482 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1484 #elif defined(TARGET_ALLEGRO)
1486 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1488 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1493 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1495 #else /* AUDIO_UNIX_NATIVE */
1497 if ((file = fopen(filename, MODE_READ)) == NULL)
1499 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1504 /* read chunk id "RIFF" */
1505 getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN);
1506 if (strcmp(chunk_name, "RIFF") != 0)
1508 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1514 /* read "RIFF" type id "WAVE" */
1515 getFileChunk(file, chunk_name, NULL, BYTE_ORDER_LITTLE_ENDIAN);
1516 if (strcmp(chunk_name, "WAVE") != 0)
1518 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1524 while (getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN))
1526 if (strcmp(chunk_name, "fmt ") == 0)
1528 /* read header information */
1529 for (i=0; i < MIN(chunk_size, WAV_HEADER_SIZE); i++)
1530 sound_header_buffer[i] = fgetc(file);
1532 if (chunk_size > WAV_HEADER_SIZE)
1533 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1535 else if (strcmp(chunk_name, "data") == 0)
1537 snd_info->data_len = chunk_size;
1538 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1540 /* read sound data */
1541 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1544 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1546 free(snd_info->data_ptr);
1551 /* check for odd number of sample bytes (data chunk is word aligned) */
1552 if ((chunk_size % 2) == 1)
1553 ReadUnusedBytesFromFile(file, 1);
1555 else /* unknown chunk -- ignore */
1556 ReadUnusedBytesFromFile(file, chunk_size);
1561 if (snd_info->data_ptr == NULL)
1563 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1568 snd_info->format = AUDIO_FORMAT_U8;
1570 #endif /* AUDIO_UNIX_NATIVE */
1572 snd_info->type = SND_TYPE_WAV;
1573 snd_info->source_filename = getStringCopy(filename);
1578 static void deleteSoundEntry(SoundInfo **snd_info)
1582 char *filename = (*snd_info)->source_filename;
1585 printf("[decrementing reference counter of sound '%s']\n", filename);
1588 if (--(*snd_info)->num_references <= 0)
1591 printf("[deleting sound '%s']\n", filename);
1595 FreeSound(*snd_info);
1597 deleteNodeFromList(&SoundFileList, filename, FreeSound);
1604 static void replaceSoundEntry(SoundInfo **snd_info, char *filename)
1608 /* check if the old and the new sound file are the same */
1609 if (*snd_info && strcmp((*snd_info)->source_filename, filename) == 0)
1611 /* The old and new sound are the same (have the same filename and path).
1612 This usually means that this sound does not exist in this sound set
1613 and a fallback to the existing sound is done. */
1616 printf("[sound '%s' already exists (same list entry)]\n", filename);
1622 /* delete existing sound file entry */
1623 deleteSoundEntry(snd_info);
1625 /* check if the new sound file already exists in the list of sounds */
1626 if ((node = getNodeFromKey(SoundFileList, filename)) != NULL)
1629 printf("[sound '%s' already exists (other list entry)]\n", filename);
1632 *snd_info = (SoundInfo *)node->content;
1633 (*snd_info)->num_references++;
1635 else if ((*snd_info = Load_WAV(filename)) != NULL) /* load new sound */
1637 (*snd_info)->num_references = 1;
1638 addNodeToList(&SoundFileList, (*snd_info)->source_filename, *snd_info);
1642 static void LoadCustomSound(SoundInfo **snd_info, char *basename)
1644 char *filename = getCustomSoundFilename(basename);
1646 if (strcmp(basename, SND_FILE_UNDEFINED) == 0)
1648 deleteSoundEntry(snd_info);
1652 if (filename == NULL)
1654 Error(ERR_WARN, "cannot find sound file '%s'", basename);
1658 replaceSoundEntry(snd_info, filename);
1661 void InitSoundList(struct SoundEffectInfo *sounds_list, int num_list_entries)
1664 Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
1666 sound_effect = sounds_list;
1667 num_sounds = num_list_entries;
1670 void LoadSoundToList(char *basename, int list_pos)
1672 if (Sound == NULL || list_pos >= num_sounds)
1676 printf("loading sound '%s' ... [%d]\n",
1677 basename, getNumNodes(SoundFileList));
1680 LoadCustomSound(&Sound[list_pos], basename);
1683 printf("loading sound '%s' done [%d]\n",
1684 basename, getNumNodes(SoundFileList));
1688 static MusicInfo *Load_MOD(char *filename)
1690 #if defined(TARGET_SDL)
1691 MusicInfo *mod_info;
1693 if (!audio.sound_available)
1696 mod_info = checked_calloc(sizeof(MusicInfo));
1698 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1700 Error(ERR_WARN, "cannot read music file '%s'", filename);
1705 mod_info->type = MUS_TYPE_MOD;
1706 mod_info->source_filename = getStringCopy(filename);
1714 void LoadCustomMusic(void)
1716 char *music_directory = getCustomMusicDirectory();
1718 struct dirent *dir_entry;
1720 if (!audio.sound_available)
1723 if ((dir = opendir(music_directory)) == NULL)
1725 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1726 audio.music_available = FALSE;
1730 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1732 char *basename = dir_entry->d_name;
1733 char *filename = getPath2(music_directory, basename);
1734 MusicInfo *mus_info = NULL;
1736 if (FileIsSound(basename))
1737 mus_info = Load_WAV(filename);
1738 else if (FileIsMusic(basename))
1739 mus_info = Load_MOD(filename);
1746 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1747 Music[num_music -1] = mus_info;
1754 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1758 void PlayMusic(int nr)
1760 if (!audio.music_available)
1766 void PlaySound(int nr)
1768 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_SOUND);
1771 void PlaySoundStereo(int nr, int stereo_position)
1773 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
1776 void PlaySoundLoop(int nr)
1778 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_LOOP);
1781 void PlaySoundMusic(int nr)
1783 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_MUSIC);
1786 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
1788 SoundControl snd_ctrl;
1790 if (!audio.sound_available ||
1791 !audio.sound_enabled ||
1792 audio.sound_deactivated)
1795 if (volume < PSND_MIN_VOLUME)
1796 volume = PSND_MIN_VOLUME;
1797 else if (volume > PSND_MAX_VOLUME)
1798 volume = PSND_MAX_VOLUME;
1800 if (stereo_position < PSND_MAX_LEFT)
1801 stereo_position = PSND_MAX_LEFT;
1802 else if (stereo_position > PSND_MAX_RIGHT)
1803 stereo_position = PSND_MAX_RIGHT;
1805 snd_ctrl.active = TRUE;
1807 snd_ctrl.volume = volume;
1808 snd_ctrl.stereo_position = stereo_position;
1809 snd_ctrl.state = state;
1811 HandleSoundRequest(snd_ctrl);
1814 void FadeMusic(void)
1816 if (!audio.music_available)
1819 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
1822 void FadeSound(int nr)
1824 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
1830 StopSoundExt(-1, SND_CTRL_FADE_ALL);
1833 void StopMusic(void)
1835 if (!audio.music_available)
1838 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
1841 void StopSound(int nr)
1843 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
1849 StopSoundExt(-1, SND_CTRL_STOP_ALL);
1852 void StopSoundExt(int nr, int state)
1854 SoundControl snd_ctrl;
1856 if (!audio.sound_available)
1859 snd_ctrl.active = FALSE;
1861 snd_ctrl.state = state;
1863 HandleSoundRequest(snd_ctrl);
1866 ListNode *newListNode()
1868 return checked_calloc(sizeof(ListNode));
1871 void addNodeToList(ListNode **node_first, char *key, void *content)
1873 ListNode *node_new = newListNode();
1876 printf("LIST: adding node with key '%s'\n", key);
1879 node_new->key = getStringCopy(key);
1880 node_new->content = content;
1881 node_new->next = *node_first;
1882 *node_first = node_new;
1885 void deleteNodeFromList(ListNode **node_first, char *key,
1886 void (*destructor_function)(void *))
1888 if (node_first == NULL || *node_first == NULL)
1892 printf("[CHECKING LIST KEY '%s' == '%s']\n",
1893 (*node_first)->key, key);
1896 if (strcmp((*node_first)->key, key) == 0)
1899 printf("[DELETING LIST ENTRY]\n");
1902 free((*node_first)->key);
1903 if (destructor_function)
1904 destructor_function((*node_first)->content);
1905 *node_first = (*node_first)->next;
1908 deleteNodeFromList(&(*node_first)->next, key, destructor_function);
1911 ListNode *getNodeFromKey(ListNode *node_first, char *key)
1913 if (node_first == NULL)
1916 if (strcmp(node_first->key, key) == 0)
1919 return getNodeFromKey(node_first->next, key);
1922 int getNumNodes(ListNode *node_first)
1924 return (node_first ? 1 + getNumNodes(node_first->next) : 0);
1927 void dumpList(ListNode *node_first)
1929 ListNode *node = node_first;
1933 printf("['%s' (%d)]\n", node->key,
1934 ((SoundInfo *)node->content)->num_references);
1938 printf("[%d nodes]\n", getNumNodes(node_first));
1941 static void LoadSoundsInfo()
1943 char *filename = getCustomSoundConfigFilename();
1944 struct SetupFileList *setup_file_list;
1947 /* always start with reliable default values */
1948 for (i=0; i<num_sounds; i++)
1949 sound_effect[i].filename = NULL;
1951 if (filename == NULL)
1954 if ((setup_file_list = loadSetupFileList(filename)))
1956 for (i=0; i<num_sounds; i++)
1957 sound_effect[i].filename =
1958 getStringCopy(getTokenValue(setup_file_list, sound_effect[i].text));
1960 freeSetupFileList(setup_file_list);
1963 for (i=0; i<num_sounds; i++)
1965 printf("'%s' ", sound_effect[i].text);
1966 if (sound_effect[i].filename)
1967 printf("-> '%s'\n", sound_effect[i].filename);
1969 printf("-> UNDEFINED [-> '%s']\n", sound_effect[i].default_filename);
1975 static void ReloadCustomSounds()
1980 printf("DEBUG: reloading sounds '%s' ...\n", artwork.sounds_set_current);
1986 printf("DEBUG: reloading %d sounds ...\n", num_sounds);
1989 for(i=0; i<num_sounds; i++)
1991 if (sound_effect[i].filename)
1992 LoadSoundToList(sound_effect[i].filename, i);
1994 LoadSoundToList(sound_effect[i].default_filename, i);
1998 printf("list size == %d\n", getNumNodes(SoundFileList));
2002 dumpList(SoundFileList);
2006 static void ReloadCustomMusic()
2009 printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current);
2017 void InitReloadSounds(char *set_name)
2019 if (!audio.sound_available)
2022 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
2023 ReloadCustomSounds();
2024 #elif defined(AUDIO_UNIX_NATIVE)
2025 WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_SOUNDS);
2029 void InitReloadMusic(char *set_name)
2031 if (!audio.music_available)
2034 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
2035 ReloadCustomMusic();
2036 #elif defined(AUDIO_UNIX_NATIVE)
2037 WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_MUSIC);
2041 void FreeSound(void *ptr)
2043 SoundInfo *sound = (SoundInfo *)ptr;
2048 if (sound->data_ptr)
2050 #if defined(TARGET_SDL)
2051 Mix_FreeChunk(sound->data_ptr);
2052 #elif defined(TARGET_ALLEGRO)
2053 destroy_sample(sound->data_ptr);
2054 #else /* AUDIO_UNIX_NATIVE */
2055 free(sound->data_ptr);
2059 if (sound->source_filename)
2060 free(sound->source_filename);
2065 void FreeMusic(MusicInfo *music)
2070 if (music->data_ptr)
2072 #if defined(TARGET_SDL)
2073 if (music->type == MUS_TYPE_MOD)
2074 Mix_FreeMusic(music->data_ptr);
2076 Mix_FreeChunk(music->data_ptr);
2077 #elif defined(TARGET_ALLEGRO)
2078 destroy_sample(music->data_ptr);
2079 #else /* AUDIO_UNIX_NATIVE */
2080 free(music->data_ptr);
2087 void FreeAllSounds()
2094 printf("%s: FREEING SOUNDS ...\n",
2095 IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
2097 for(i=0; i<num_sounds; i++)
2098 deleteSoundEntry(&Sound[i]);
2100 FreeSound(Sound[i]);
2103 printf("%s: FREEING SOUNDS -- DONE\n",
2104 IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
2119 for(i=0; i<num_music; i++)
2120 FreeMusic(Music[i]);
2128 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2129 /* ========================================================================= */