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 ***********************************************************/
27 #define IS_PARENT_PROCESS(pid) ((pid) > 0)
28 #define IS_CHILD_PROCESS(pid) ((pid) == 0)
34 struct ListNode *next;
36 typedef struct ListNode ListNode;
38 static ListNode *newListNode(void);
39 static void addNodeToList(ListNode **, char *, void *);
40 static void deleteNodeFromList(ListNode **, char *, void (*function)(void *));
41 static ListNode *getNodeFromKey(ListNode *, char *);
42 static int getNumNodes(ListNode *);
45 static struct SoundEffectInfo *sound_effect;
46 static ListNode *SoundFileList = NULL;
47 static SoundInfo **Sound = NULL;
48 static MusicInfo **Music = NULL;
49 static int num_sounds = 0, num_music = 0;
52 /* ========================================================================= */
53 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
55 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
56 static int mixer_active_channels = 0;
58 #if defined(AUDIO_UNIX_NATIVE)
59 static struct AudioFormatInfo afmt;
61 static void Mixer_Main(void);
62 #if !defined(AUDIO_STREAMING_DSP)
63 static unsigned char linear_to_ulaw(int);
64 static int ulaw_to_linear(unsigned char);
68 static void ReloadCustomSounds();
69 static void ReloadCustomMusic();
70 static void FreeSound(void *);
73 /* ------------------------------------------------------------------------- */
74 /* functions for native (non-SDL) Unix audio/mixer support */
75 /* ------------------------------------------------------------------------- */
77 #if defined(AUDIO_UNIX_NATIVE)
79 static int OpenAudioDevice(char *audio_device_name)
83 /* check if desired audio device is accessible */
84 if (access(audio_device_name, W_OK) != 0)
87 /* try to open audio device in non-blocking mode */
88 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
89 return audio_device_fd;
91 /* re-open audio device in blocking mode */
92 close(audio_device_fd);
93 audio_device_fd = open(audio_device_name, O_WRONLY);
95 return audio_device_fd;
98 static void CloseAudioDevice(int *audio_device_fd)
100 if (*audio_device_fd == 0)
103 close(*audio_device_fd);
104 *audio_device_fd = -1;
107 static boolean TestAudioDevices(void)
109 static char *audio_device_name[] =
114 int audio_device_fd = -1;
117 /* look for available audio devices, starting with preferred ones */
118 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
119 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
122 if (audio_device_fd < 0)
124 Error(ERR_WARN, "cannot open audio device -- no sound");
128 close(audio_device_fd);
130 audio.device_name = audio_device_name[i];
135 static boolean ForkAudioProcess(void)
137 if (pipe(audio.mixer_pipe) < 0)
139 Error(ERR_WARN, "cannot create pipe -- no sounds");
143 if ((audio.mixer_pid = fork()) < 0)
145 Error(ERR_WARN, "cannot create sound server process -- no sounds");
149 if (IS_CHILD_PROCESS(audio.mixer_pid))
150 Mixer_Main(); /* this function never returns */
152 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
157 void UnixOpenAudio(void)
159 if (!TestAudioDevices())
162 audio.sound_available = TRUE;
163 audio.sound_enabled = TRUE;
165 #if defined(AUDIO_STREAMING_DSP)
166 audio.music_available = TRUE;
167 audio.loops_available = TRUE;
170 audio.num_channels = NUM_MIXER_CHANNELS;
171 audio.music_channel = MUSIC_CHANNEL;
172 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
175 void UnixCloseAudio(void)
178 close(audio.device_fd);
180 if (IS_PARENT_PROCESS(audio.mixer_pid))
181 kill(audio.mixer_pid, SIGTERM);
185 /* ------------------------------------------------------------------------- */
186 /* functions for platform specific audio device initialization */
187 /* ------------------------------------------------------------------------- */
189 #if defined(AUDIO_LINUX_IOCTL)
190 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
192 /* "ioctl()" expects pointer to 'int' value for stereo flag
193 (boolean is defined as 'char', which will not work here) */
194 unsigned int fragment_spec = 0;
195 int fragment_size_query;
204 /* supported audio format in preferred order */
205 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
206 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
207 { AFMT_U8, AUDIO_FORMAT_U8 },
212 /* determine logarithm (log2) of the fragment size */
213 while ((1 << fragment_spec) < afmt->fragment_size)
216 /* use two fragments (play one fragment, prepare the other);
217 one fragment would result in interrupted audio output, more
218 than two fragments would raise audio output latency to much */
219 fragment_spec |= 0x00020000;
221 /* Example for fragment specification:
222 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
223 - (with stereo the effective buffer size will shrink to 256)
224 => fragment_size = 0x00020009 */
226 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
227 Error(ERR_EXIT_SOUND_SERVER,
228 "cannot set fragment size of /dev/dsp -- no sounds");
232 while (formats[i].format_result != -1)
234 unsigned int audio_format = formats[i].format_ioctl;
235 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
237 afmt->format = formats[i].format_result;
242 if (afmt->format == 0) /* no supported audio format found */
243 Error(ERR_EXIT_SOUND_SERVER,
244 "cannot set audio format of /dev/dsp -- no sounds");
246 /* try if we can use stereo sound */
248 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
249 afmt->stereo = FALSE;
251 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
252 Error(ERR_EXIT_SOUND_SERVER,
253 "cannot set sample rate of /dev/dsp -- no sounds");
255 /* get the real fragmentation size; this should return 512 */
256 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
257 Error(ERR_EXIT_SOUND_SERVER,
258 "cannot get fragment size of /dev/dsp -- no sounds");
259 if (fragment_size_query != afmt->fragment_size)
260 Error(ERR_EXIT_SOUND_SERVER,
261 "cannot set fragment size of /dev/dsp -- no sounds");
263 #endif /* AUDIO_LINUX_IOCTL */
265 #if defined(PLATFORM_NETBSD)
266 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
269 boolean stereo = TRUE;
271 AUDIO_INITINFO(&a_info);
272 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
273 a_info.play.precision = 8;
274 a_info.play.channels = 2;
275 a_info.play.sample_rate = sample_rate;
276 a_info.blocksize = fragment_size;
278 afmt->format = AUDIO_FORMAT_U8;
281 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
283 /* try to disable stereo */
284 a_info.play.channels = 1;
286 afmt->stereo = FALSE;
288 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
289 Error(ERR_EXIT_SOUND_SERVER,
290 "cannot set sample rate of /dev/audio -- no sounds");
293 #endif /* PLATFORM_NETBSD */
295 #if defined(PLATFORM_HPUX)
296 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
298 struct audio_describe ainfo;
301 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
303 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl -- no sounds");
305 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
306 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
308 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
309 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
311 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
312 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
314 afmt->format = AUDIO_FORMAT_U8;
315 afmt->stereo = FALSE;
316 afmt->sample_rate = 8000;
320 #endif /* PLATFORM_HPUX */
322 static void InitAudioDevice(struct AudioFormatInfo *afmt)
325 afmt->format = AUDIO_FORMAT_UNKNOWN;
326 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
327 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
329 #if defined(AUDIO_LINUX_IOCTL)
330 InitAudioDevice_Linux(afmt);
331 #elif defined(PLATFORM_NETBSD)
332 InitAudioDevice_NetBSD(afmt);
333 #elif defined(PLATFORM_HPUX)
334 InitAudioDevice_HPUX(afmt);
336 /* generic /dev/audio stuff might be placed here */
341 /* ------------------------------------------------------------------------- */
342 /* functions for communication between main process and sound mixer process */
343 /* ------------------------------------------------------------------------- */
345 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
347 if (IS_CHILD_PROCESS(audio.mixer_pid))
350 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
352 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
353 audio.sound_available = audio.sound_enabled = FALSE;
358 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
360 if (IS_PARENT_PROCESS(audio.mixer_pid))
363 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
364 != sizeof(SoundControl))
365 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
368 static void WriteReloadInfoToPipe(char *set_name, int type)
370 SoundControl snd_ctrl;
371 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
372 artwork.mus_current);
373 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
374 unsigned long str_size2 = strlen(ti->basepath) + 1;
375 unsigned long str_size3 = strlen(ti->fullpath) + 1;
377 if (IS_CHILD_PROCESS(audio.mixer_pid))
380 if (leveldir_current == NULL) /* should never happen */
381 Error(ERR_EXIT, "leveldir_current == NULL");
383 snd_ctrl.active = FALSE;
384 snd_ctrl.state = type;
385 snd_ctrl.data_len = strlen(set_name) + 1;
387 if (write(audio.mixer_pipe[1], &snd_ctrl,
388 sizeof(snd_ctrl)) < 0 ||
389 write(audio.mixer_pipe[1], set_name,
390 snd_ctrl.data_len) < 0 ||
391 write(audio.mixer_pipe[1], leveldir_current,
392 sizeof(TreeInfo)) < 0 ||
393 write(audio.mixer_pipe[1], ti,
394 sizeof(TreeInfo)) < 0 ||
395 write(audio.mixer_pipe[1], &str_size1,
396 sizeof(unsigned long)) < 0 ||
397 write(audio.mixer_pipe[1], &str_size2,
398 sizeof(unsigned long)) < 0 ||
399 write(audio.mixer_pipe[1], &str_size3,
400 sizeof(unsigned long)) < 0 ||
401 write(audio.mixer_pipe[1], leveldir_current->fullpath,
403 write(audio.mixer_pipe[1], ti->basepath,
405 write(audio.mixer_pipe[1], ti->fullpath,
408 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
409 audio.sound_available = audio.sound_enabled = FALSE;
414 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
416 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
417 &artwork.snd_current : &artwork.mus_current);
418 TreeInfo *ti = *ti_ptr;
419 unsigned long str_size1, str_size2, str_size3;
420 static char *set_name = NULL;
425 set_name = checked_malloc(snd_ctrl->data_len);
427 if (leveldir_current == NULL)
428 leveldir_current = checked_calloc(sizeof(TreeInfo));
430 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
431 if (leveldir_current->fullpath != NULL)
432 free(leveldir_current->fullpath);
433 if (ti->basepath != NULL)
435 if (ti->fullpath != NULL)
438 if (read(audio.mixer_pipe[0], set_name,
439 snd_ctrl->data_len) != snd_ctrl->data_len ||
440 read(audio.mixer_pipe[0], leveldir_current,
441 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
442 read(audio.mixer_pipe[0], ti,
443 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
444 read(audio.mixer_pipe[0], &str_size1,
445 sizeof(unsigned long)) != sizeof(unsigned long) ||
446 read(audio.mixer_pipe[0], &str_size2,
447 sizeof(unsigned long)) != sizeof(unsigned long) ||
448 read(audio.mixer_pipe[0], &str_size3,
449 sizeof(unsigned long)) != sizeof(unsigned long))
450 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
452 leveldir_current->fullpath = checked_calloc(str_size1);
453 ti->basepath = checked_calloc(str_size2);
454 ti->fullpath = checked_calloc(str_size3);
456 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
457 str_size1) != str_size1 ||
458 read(audio.mixer_pipe[0], ti->basepath,
459 str_size2) != str_size2 ||
460 read(audio.mixer_pipe[0], ti->fullpath,
461 str_size3) != str_size3)
462 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
464 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
465 artwork.sounds_set_current = set_name;
467 artwork.music_set_current = set_name;
470 #endif /* AUDIO_UNIX_NATIVE */
473 /* ------------------------------------------------------------------------- */
474 /* mixer functions */
475 /* ------------------------------------------------------------------------- */
477 void Mixer_InitChannels()
481 for(i=0; i<audio.num_channels; i++)
482 mixer[i].active = FALSE;
483 mixer_active_channels = 0;
486 static void Mixer_PlayChannel(int channel)
488 /* start with inactive channel in case something goes wrong */
489 mixer[channel].active = FALSE;
491 if (mixer[channel].type != MUS_TYPE_WAV)
494 mixer[channel].playing_pos = 0;
495 mixer[channel].playing_starttime = Counter();
497 #if defined(TARGET_SDL)
498 Mix_Volume(channel, SOUND_MAX_VOLUME);
499 Mix_PlayChannel(channel, mixer[channel].data_ptr,
500 IS_LOOP(mixer[channel]) ? -1 : 0);
501 #elif defined(PLATFORM_MSDOS)
502 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
503 if (mixer[channel].voice < 0)
506 if (IS_LOOP(mixer[channel]))
507 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
509 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
510 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
511 voice_start(mixer[channel].voice);
514 mixer[channel].active = TRUE;
515 mixer_active_channels++;
518 static void Mixer_PlayMusicChannel()
520 Mixer_PlayChannel(audio.music_channel);
522 #if defined(TARGET_SDL)
523 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
525 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
526 this looks like a bug in the SDL_mixer library */
527 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
528 Mix_VolumeMusic(SOUND_MAX_VOLUME);
533 static void Mixer_StopChannel(int channel)
536 #if defined(TARGET_SDL)
537 printf("----------> %d [%d]\n", Mix_Playing(channel), Mix_Playing(0));
541 if (!mixer[channel].active)
544 #if defined(TARGET_SDL)
545 Mix_HaltChannel(channel);
546 #elif defined(PLATFORM_MSDOS)
547 voice_set_volume(mixer[channel].voice, 0);
548 deallocate_voice(mixer[channel].voice);
551 mixer[channel].active = FALSE;
552 mixer_active_channels--;
555 static void Mixer_StopMusicChannel()
557 Mixer_StopChannel(audio.music_channel);
559 #if defined(TARGET_SDL)
564 static void Mixer_FadeChannel(int channel)
566 if (!mixer[channel].active)
569 mixer[channel].state |= SND_CTRL_FADE;
571 #if defined(TARGET_SDL)
572 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
573 #elif defined(PLATFORM_MSDOS)
574 if (voice_check(mixer[channel].voice))
575 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
579 static void Mixer_FadeMusicChannel()
581 Mixer_FadeChannel(audio.music_channel);
583 #if defined(TARGET_SDL)
584 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
588 static void Mixer_UnFadeChannel(int channel)
590 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
593 mixer[channel].state &= ~SND_CTRL_FADE;
594 mixer[channel].volume = PSND_MAX_VOLUME;
596 #if defined(TARGET_SDL)
597 Mix_ExpireChannel(channel, -1);
598 Mix_Volume(channel, SOUND_MAX_VOLUME);
599 #elif defined(TARGET_ALLEGRO)
600 voice_stop_volumeramp(mixer[channel].voice);
601 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
602 mixer[channel].volume);
606 static void Mixer_InsertSound(SoundControl snd_ctrl)
612 printf("NEW SOUND %d HAS ARRIVED [%d]\n", snd_ctrl.nr, num_sounds);
616 printf("%d ACTIVE CHANNELS\n", mixer_active_channels);
619 if (IS_MUSIC(snd_ctrl))
620 snd_ctrl.nr = snd_ctrl.nr % num_music;
621 else if (snd_ctrl.nr >= num_sounds)
624 snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
625 if (snd_info == NULL)
628 /* copy sound sample and format information */
629 snd_ctrl.type = snd_info->type;
630 snd_ctrl.format = snd_info->format;
631 snd_ctrl.data_ptr = snd_info->data_ptr;
632 snd_ctrl.data_len = snd_info->data_len;
634 /* play music samples on a dedicated music channel */
635 if (IS_MUSIC(snd_ctrl))
637 mixer[audio.music_channel] = snd_ctrl;
638 Mixer_PlayMusicChannel();
643 /* check if sound is already being played (and how often) */
644 for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
645 if (mixer[i].nr == snd_ctrl.nr)
648 /* restart loop sounds only if they are just fading out */
649 if (k >= 1 && IS_LOOP(snd_ctrl))
651 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
652 if (mixer[i].nr == snd_ctrl.nr && IS_FADING(mixer[i]))
653 Mixer_UnFadeChannel(i);
658 /* don't play sound more than n times simultaneously (with n == 2 for now) */
661 unsigned long playing_current = Counter();
662 int longest = 0, longest_nr = audio.first_sound_channel;
664 /* look for oldest equal sound */
665 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
667 int playing_time = playing_current - mixer[i].playing_starttime;
670 if (!mixer[i].active || mixer[i].nr != snd_ctrl.nr)
674 actual = 1000 * playing_time / mixer[i].data_len;
676 actual = 100 * mixer[i].playing_pos / mixer[i].data_len;
679 if (actual >= longest)
686 Mixer_StopChannel(longest_nr);
689 /* If all (non-music) channels are active, stop the channel that has
690 played its sound sample most completely (in percent of the sample
691 length). As we cannot currently get the actual playing position
692 of the channel's sound sample when compiling with the SDL mixer
693 library, we use the current playing time (in milliseconds) instead. */
695 if (mixer_active_channels ==
696 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
698 unsigned long playing_current = Counter();
699 int longest = 0, longest_nr = audio.first_sound_channel;
701 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
704 int playing_time = playing_current - mixer[i].playing_starttime;
705 int actual = 1000 * playing_time / mixer[i].data_len;
707 int actual = 100 * mixer[i].playing_pos / mixer[i].data_len;
710 if (!IS_LOOP(mixer[i]) && actual > longest)
717 Mixer_StopChannel(longest_nr);
720 /* add new sound to mixer */
721 for(i=0; i<audio.num_channels; i++)
724 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
728 if (!mixer[i].active ||
729 (IS_MUSIC(snd_ctrl) && i == audio.music_channel))
731 if ((i == audio.music_channel && IS_MUSIC(snd_ctrl)) ||
732 (i != audio.music_channel && !mixer[i].active))
735 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
739 #if defined(AUDIO_UNIX_NATIVE)
740 if (snd_info->data_len == 0)
742 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
748 if (IS_MUSIC(snd_ctrl) && i == audio.music_channel && mixer[i].active)
750 printf("THIS SHOULD NEVER HAPPEN! [adding music twice]\n");
753 Mixer_StopChannel(i);
759 Mixer_PlayChannel(i);
766 static void HandleSoundRequest(SoundControl snd_ctrl)
770 #if defined(AUDIO_UNIX_NATIVE)
771 if (IS_PARENT_PROCESS(audio.mixer_pid))
773 SendSoundControlToMixerProcess(&snd_ctrl);
776 #elif defined(TARGET_SDL)
777 for (i=0; i<audio.num_channels; i++)
779 Mixer_StopChannel(i);
780 #elif defined(TARGET_ALLEGRO)
781 for (i=0; i<audio.num_channels; i++)
783 if (!mixer[i].active || IS_LOOP(mixer[i]))
786 mixer[i].playing_pos = voice_get_position(mixer[i].voice);
787 mixer[i].volume = voice_get_volume(mixer[i].voice);
789 /* sound sample has completed playing or was completely faded out */
790 if (mixer[i].playing_pos == -1 || mixer[i].volume == 0)
791 Mixer_StopChannel(i);
793 #endif /* TARGET_ALLEGRO */
795 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
797 Mixer_StopMusicChannel();
798 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
799 Mixer_StopChannel(i);
801 #if defined(AUDIO_UNIX_NATIVE)
802 CloseAudioDevice(&audio.device_fd);
803 ReadReloadInfoFromPipe(&snd_ctrl);
806 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
807 ReloadCustomSounds();
811 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
813 if (IS_MUSIC(snd_ctrl))
815 Mixer_FadeMusicChannel();
819 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
820 if (mixer[i].nr == snd_ctrl.nr || ALL_SOUNDS(snd_ctrl))
821 Mixer_FadeChannel(i);
823 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
825 if (IS_MUSIC(snd_ctrl))
827 Mixer_StopMusicChannel();
831 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
832 if (mixer[i].nr == snd_ctrl.nr || ALL_SOUNDS(snd_ctrl))
833 Mixer_StopChannel(i);
835 #if defined(AUDIO_UNIX_NATIVE)
836 if (!mixer_active_channels)
837 CloseAudioDevice(&audio.device_fd);
840 else if (snd_ctrl.active) /* add new sound to mixer */
842 Mixer_InsertSound(snd_ctrl);
846 void StartMixer(void)
849 SDL_version compile_version;
850 const SDL_version *link_version;
851 MIX_VERSION(&compile_version);
852 printf("compiled with SDL_mixer version: %d.%d.%d\n",
853 compile_version.major,
854 compile_version.minor,
855 compile_version.patch);
856 link_version = Mix_Linked_Version();
857 printf("running with SDL_mixer version: %d.%d.%d\n",
860 link_version->patch);
863 if (!audio.sound_available)
866 #if defined(AUDIO_UNIX_NATIVE)
867 if (!ForkAudioProcess())
868 audio.sound_available = FALSE;
872 #if defined(AUDIO_UNIX_NATIVE)
874 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
875 int sample_pos, int sample_size,
878 void *sample_ptr = snd_ctrl->data_ptr;
881 if (snd_ctrl->format == AUDIO_FORMAT_U8)
882 for (i=0; i<sample_size; i++)
884 ((short)(((byte *)sample_ptr)[sample_pos + i] ^ 0x80)) << 8;
885 else /* AUDIO_FORMAT_S16 */
886 for (i=0; i<sample_size; i++)
888 ((short *)sample_ptr)[sample_pos + i];
891 #if defined(AUDIO_STREAMING_DSP)
892 static void Mixer_Main_DSP()
894 static int stereo_volume[PSND_MAX_LEFT2RIGHT + 1];
895 static boolean stereo_volume_calculated = FALSE;
896 static short premix_first_buffer[SND_BLOCKSIZE];
897 static short premix_left_buffer[SND_BLOCKSIZE];
898 static short premix_right_buffer[SND_BLOCKSIZE];
899 static long premix_last_buffer[SND_BLOCKSIZE];
900 static byte playing_buffer[SND_BLOCKSIZE];
907 if (!stereo_volume_calculated)
909 for(i=0; i<=PSND_MAX_LEFT2RIGHT; i++)
911 (int)sqrt((float)(PSND_MAX_LEFT2RIGHT * PSND_MAX_LEFT2RIGHT - i * i));
913 stereo_volume_calculated = TRUE;
916 if (!mixer_active_channels)
919 if (audio.device_fd < 0)
921 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
924 InitAudioDevice(&afmt);
927 stereo = afmt.stereo;
928 fragment_size = afmt.fragment_size;
929 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
930 max_sample_size = fragment_size / ((stereo ? 2 : 1) * sample_bytes);
932 /* first clear the last premixing buffer */
933 memset(premix_last_buffer, 0,
934 max_sample_size * (stereo ? 2 : 1) * sizeof(long));
936 for(i=0; i<audio.num_channels; i++)
943 if (!mixer[i].active)
946 /* pointer, lenght and actual playing position of sound sample */
947 sample_ptr = mixer[i].data_ptr;
948 sample_len = mixer[i].data_len;
949 sample_pos = mixer[i].playing_pos;
950 sample_size = MIN(max_sample_size, sample_len - sample_pos);
951 mixer[i].playing_pos += sample_size;
953 /* copy original sample to first mixing buffer */
954 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
955 premix_first_buffer);
957 /* are we about to restart a looping sound? */
958 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
960 while (sample_size < max_sample_size)
962 int restarted_sample_size =
963 MIN(max_sample_size - sample_size, sample_len);
965 if (mixer[i].format == AUDIO_FORMAT_U8)
966 for (j=0; j<restarted_sample_size; j++)
967 premix_first_buffer[sample_size + j] =
968 ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
970 for (j=0; j<restarted_sample_size; j++)
971 premix_first_buffer[sample_size + j] =
972 ((short *)sample_ptr)[j];
974 mixer[i].playing_pos = restarted_sample_size;
975 sample_size += restarted_sample_size;
979 /* decrease volume if sound is fading out */
980 if (IS_FADING(mixer[i]) &&
981 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
982 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
984 /* adjust volume of actual sound sample */
985 if (mixer[i].volume != PSND_MAX_VOLUME)
986 for(j=0; j<sample_size; j++)
987 premix_first_buffer[j] =
988 (mixer[i].volume * (long)premix_first_buffer[j])
989 >> PSND_MAX_VOLUME_BITS;
991 /* fill the last mixing buffer with stereo or mono sound */
994 int middle_pos = PSND_MAX_LEFT2RIGHT / 2;
995 int left_volume = stereo_volume[middle_pos + mixer[i].stereo_position];
996 int right_volume= stereo_volume[middle_pos - mixer[i].stereo_position];
998 for(j=0; j<sample_size; j++)
1000 premix_left_buffer[j] =
1001 (left_volume * premix_first_buffer[j])
1002 >> PSND_MAX_LEFT2RIGHT_BITS;
1003 premix_right_buffer[j] =
1004 (right_volume * premix_first_buffer[j])
1005 >> PSND_MAX_LEFT2RIGHT_BITS;
1007 premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
1008 premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
1013 for(j=0; j<sample_size; j++)
1014 premix_last_buffer[j] += premix_first_buffer[j];
1017 /* delete completed sound entries from the mixer */
1018 if (mixer[i].playing_pos >= mixer[i].data_len)
1020 if (IS_LOOP(mixer[i]))
1021 mixer[i].playing_pos = 0;
1023 Mixer_StopChannel(i);
1025 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1026 Mixer_StopChannel(i);
1029 /* prepare final playing buffer according to system audio format */
1030 for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
1032 /* cut off at 17 bit value */
1033 if (premix_last_buffer[i] < -65535)
1034 premix_last_buffer[i] = -65535;
1035 else if (premix_last_buffer[i] > 65535)
1036 premix_last_buffer[i] = 65535;
1038 /* shift to 16 bit value */
1039 premix_last_buffer[i] >>= 1;
1041 if (afmt.format & AUDIO_FORMAT_U8)
1043 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1045 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1047 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1048 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1050 else /* big endian */
1052 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1053 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1057 /* finally play the sound fragment */
1058 write(audio.device_fd, playing_buffer, fragment_size);
1060 if (!mixer_active_channels)
1061 CloseAudioDevice(&audio.device_fd);
1064 #else /* !AUDIO_STREAMING_DSP */
1066 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1068 static short premix_first_buffer[SND_BLOCKSIZE];
1069 static byte playing_buffer[SND_BLOCKSIZE];
1070 int max_sample_size = SND_BLOCKSIZE;
1079 /* pointer, lenght and actual playing position of sound sample */
1080 sample_ptr = mixer[i].data_ptr;
1081 sample_len = mixer[i].data_len;
1082 sample_pos = mixer[i].playing_pos;
1083 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1084 mixer[i].playing_pos += sample_size;
1086 /* copy original sample to first mixing buffer */
1087 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1088 premix_first_buffer);
1090 /* adjust volume of actual sound sample */
1091 if (mixer[i].volume != PSND_MAX_VOLUME)
1092 for(j=0; j<sample_size; j++)
1093 premix_first_buffer[j] =
1094 (mixer[i].volume * (long)premix_first_buffer[j])
1095 >> PSND_MAX_VOLUME_BITS;
1097 /* might be needed for u-law /dev/audio */
1099 for(j=0; j<sample_size; j++)
1101 linear_to_ulaw(premix_first_buffer[j]);
1104 /* delete completed sound entries from the mixer */
1105 if (mixer[i].playing_pos >= mixer[i].data_len)
1106 Mixer_StopChannel(i);
1108 for(i=0; i<sample_size; i++)
1109 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1111 /* finally play the sound fragment */
1112 write(audio.device_fd, playing_buffer, sample_size);
1116 #endif /* !AUDIO_STREAMING_DSP */
1120 SoundControl snd_ctrl;
1123 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1125 Mixer_InitChannels();
1127 #if defined(PLATFORM_HPUX)
1128 InitAudioDevice(&afmt);
1131 FD_ZERO(&mixer_fdset);
1132 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1134 while(1) /* wait for sound playing commands from client */
1136 struct timeval delay = { 0, 0 };
1138 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1139 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1140 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1143 ReadSoundControlFromMainProcess(&snd_ctrl);
1145 HandleSoundRequest(snd_ctrl);
1147 #if defined(AUDIO_STREAMING_DSP)
1149 while (mixer_active_channels &&
1150 select(audio.mixer_pipe[0] + 1,
1151 &mixer_fdset, NULL, NULL, &delay) < 1)
1153 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1158 #else /* !AUDIO_STREAMING_DSP */
1160 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1161 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1164 InitAudioDevice(&afmt);
1169 while (mixer_active_channels &&
1170 select(audio.mixer_pipe[0] + 1,
1171 &mixer_fdset, NULL, NULL, &delay) < 1)
1173 int wait_percent = 90; /* wait 90% of the real playing time */
1176 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1178 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1182 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1185 CloseAudioDevice(&audio.device_fd);
1187 Mixer_InitChannels(); /* remove all sounds from mixer */
1189 #endif /* !AUDIO_STREAMING_DSP */
1192 #endif /* AUDIO_UNIX_NATIVE */
1195 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1197 /* these two are stolen from "sox"... :) */
1200 ** This routine converts from linear to ulaw.
1202 ** Craig Reese: IDA/Supercomputing Research Center
1203 ** Joe Campbell: Department of Defense
1204 ** 29 September 1989
1207 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1208 ** 2) "A New Digital Technique for Implementation of Any
1209 ** Continuous PCM Companding Law," Villeret, Michel,
1210 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1211 ** 1973, pg. 11.12-11.17
1212 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1213 ** for Analog-to_Digital Conversion Techniques,"
1216 ** Input: Signed 16 bit linear sample
1217 ** Output: 8 bit ulaw sample
1220 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1221 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1224 static unsigned char linear_to_ulaw(int sample)
1226 static int exp_lut[256] =
1228 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1229 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1230 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1231 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1232 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1233 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1234 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1235 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1236 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1237 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1238 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1239 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1240 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1241 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1242 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1243 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1246 int sign, exponent, mantissa;
1247 unsigned char ulawbyte;
1249 /* Get the sample into sign-magnitude. */
1250 sign = (sample >> 8) & 0x80; /* set aside the sign */
1252 sample = -sample; /* get magnitude */
1254 sample = CLIP; /* clip the magnitude */
1256 /* Convert from 16 bit linear to ulaw. */
1257 sample = sample + BIAS;
1258 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1259 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1260 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1263 ulawbyte = 0x02; /* optional CCITT trap */
1270 ** This routine converts from ulaw to 16 bit linear.
1272 ** Craig Reese: IDA/Supercomputing Research Center
1273 ** 29 September 1989
1276 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1277 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1278 ** for Analog-to_Digital Conversion Techniques,"
1281 ** Input: 8 bit ulaw sample
1282 ** Output: signed 16 bit linear sample
1285 static int ulaw_to_linear(unsigned char ulawbyte)
1287 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1288 int sign, exponent, mantissa, sample;
1290 ulawbyte = ~ ulawbyte;
1291 sign = ( ulawbyte & 0x80 );
1292 exponent = ( ulawbyte >> 4 ) & 0x07;
1293 mantissa = ulawbyte & 0x0F;
1294 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1300 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1303 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1304 /* ========================================================================= */
1305 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1307 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1308 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1310 static SoundInfo *Load_WAV(char *filename)
1312 SoundInfo *snd_info;
1313 #if !defined(TARGET_SDL) && !defined(PLATFORM_MSDOS)
1314 byte sound_header_buffer[WAV_HEADER_SIZE];
1315 char chunk_name[CHUNK_ID_LEN + 1];
1321 if (!audio.sound_available)
1325 printf("loading WAV file '%s'\n", filename);
1328 snd_info = checked_calloc(sizeof(SoundInfo));
1330 #if defined(TARGET_SDL)
1332 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1334 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1339 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1341 #elif defined(TARGET_ALLEGRO)
1343 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1345 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1350 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1352 #else /* AUDIO_UNIX_NATIVE */
1354 if ((file = fopen(filename, MODE_READ)) == NULL)
1356 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1361 /* read chunk id "RIFF" */
1362 getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN);
1363 if (strcmp(chunk_name, "RIFF") != 0)
1365 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1371 /* read "RIFF" type id "WAVE" */
1372 getFileChunk(file, chunk_name, NULL, BYTE_ORDER_LITTLE_ENDIAN);
1373 if (strcmp(chunk_name, "WAVE") != 0)
1375 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1381 while (getFileChunk(file, chunk_name, &chunk_size, BYTE_ORDER_LITTLE_ENDIAN))
1383 if (strcmp(chunk_name, "fmt ") == 0)
1385 /* read header information */
1386 for (i=0; i < MIN(chunk_size, WAV_HEADER_SIZE); i++)
1387 sound_header_buffer[i] = fgetc(file);
1389 if (chunk_size > WAV_HEADER_SIZE)
1390 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1392 else if (strcmp(chunk_name, "data") == 0)
1394 snd_info->data_len = chunk_size;
1395 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1397 /* read sound data */
1398 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1401 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1403 free(snd_info->data_ptr);
1408 /* check for odd number of sample bytes (data chunk is word aligned) */
1409 if ((chunk_size % 2) == 1)
1410 ReadUnusedBytesFromFile(file, 1);
1412 else /* unknown chunk -- ignore */
1413 ReadUnusedBytesFromFile(file, chunk_size);
1418 if (snd_info->data_ptr == NULL)
1420 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1425 snd_info->format = AUDIO_FORMAT_U8;
1427 #endif /* AUDIO_UNIX_NATIVE */
1429 snd_info->type = SND_TYPE_WAV;
1430 snd_info->source_filename = getStringCopy(filename);
1435 static void deleteSoundEntry(SoundInfo **snd_info)
1439 char *filename = (*snd_info)->source_filename;
1442 printf("[decrementing reference counter of sound '%s']\n", filename);
1445 if (--(*snd_info)->num_references <= 0)
1448 printf("[deleting sound '%s']\n", filename);
1452 FreeSound(*snd_info);
1454 deleteNodeFromList(&SoundFileList, filename, FreeSound);
1461 static void replaceSoundEntry(SoundInfo **snd_info, char *filename)
1465 /* check if the old and the new sound file are the same */
1466 if (*snd_info && strcmp((*snd_info)->source_filename, filename) == 0)
1468 /* The old and new sound are the same (have the same filename and path).
1469 This usually means that this sound does not exist in this sound set
1470 and a fallback to the existing sound is done. */
1473 printf("[sound '%s' already exists (same list entry)]\n", filename);
1479 /* delete existing sound file entry */
1480 deleteSoundEntry(snd_info);
1482 /* check if the new sound file already exists in the list of sounds */
1483 if ((node = getNodeFromKey(SoundFileList, filename)) != NULL)
1486 printf("[sound '%s' already exists (other list entry)]\n", filename);
1489 *snd_info = (SoundInfo *)node->content;
1490 (*snd_info)->num_references++;
1492 else if ((*snd_info = Load_WAV(filename)) != NULL) /* load new sound */
1494 (*snd_info)->num_references = 1;
1495 addNodeToList(&SoundFileList, (*snd_info)->source_filename, *snd_info);
1499 static void LoadCustomSound(SoundInfo **snd_info, char *basename)
1501 char *filename = getCustomSoundFilename(basename);
1503 if (strcmp(basename, SND_FILE_UNDEFINED) == 0)
1505 deleteSoundEntry(snd_info);
1509 if (filename == NULL)
1511 Error(ERR_WARN, "cannot find sound file '%s'", basename);
1515 replaceSoundEntry(snd_info, filename);
1518 void InitSoundList(struct SoundEffectInfo *sounds_list, int num_list_entries)
1521 Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
1523 sound_effect = sounds_list;
1524 num_sounds = num_list_entries;
1527 void LoadSoundToList(char *basename, int list_pos)
1529 if (Sound == NULL || list_pos >= num_sounds)
1533 printf("loading sound '%s' ... [%d]\n",
1534 basename, getNumNodes(SoundFileList));
1537 LoadCustomSound(&Sound[list_pos], basename);
1540 printf("loading sound '%s' done [%d]\n",
1541 basename, getNumNodes(SoundFileList));
1545 static MusicInfo *Load_MOD(char *filename)
1547 #if defined(TARGET_SDL)
1548 MusicInfo *mod_info;
1550 if (!audio.sound_available)
1553 mod_info = checked_calloc(sizeof(MusicInfo));
1555 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1557 Error(ERR_WARN, "cannot read music file '%s'", filename);
1562 mod_info->type = MUS_TYPE_MOD;
1563 mod_info->source_filename = getStringCopy(filename);
1571 void LoadCustomMusic(void)
1573 char *music_directory = getCustomMusicDirectory();
1575 struct dirent *dir_entry;
1577 if (!audio.sound_available)
1580 if ((dir = opendir(music_directory)) == NULL)
1582 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1583 audio.music_available = FALSE;
1587 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1589 char *basename = dir_entry->d_name;
1590 char *filename = getPath2(music_directory, basename);
1591 MusicInfo *mus_info = NULL;
1593 if (FileIsSound(basename))
1594 mus_info = Load_WAV(filename);
1595 else if (FileIsMusic(basename))
1596 mus_info = Load_MOD(filename);
1603 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1604 Music[num_music -1] = mus_info;
1611 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1615 void PlayMusic(int nr)
1617 if (!audio.music_available)
1623 void PlaySound(int nr)
1625 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_SOUND);
1628 void PlaySoundStereo(int nr, int stereo_position)
1630 PlaySoundExt(nr, PSND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
1633 void PlaySoundLoop(int nr)
1635 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_LOOP);
1638 void PlaySoundMusic(int nr)
1640 PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, SND_CTRL_PLAY_MUSIC);
1643 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
1645 SoundControl snd_ctrl;
1647 if (!audio.sound_available ||
1648 !audio.sound_enabled ||
1649 audio.sound_deactivated)
1652 if (volume < PSND_MIN_VOLUME)
1653 volume = PSND_MIN_VOLUME;
1654 else if (volume > PSND_MAX_VOLUME)
1655 volume = PSND_MAX_VOLUME;
1657 if (stereo_position < PSND_MAX_LEFT)
1658 stereo_position = PSND_MAX_LEFT;
1659 else if (stereo_position > PSND_MAX_RIGHT)
1660 stereo_position = PSND_MAX_RIGHT;
1662 snd_ctrl.active = TRUE;
1664 snd_ctrl.volume = volume;
1665 snd_ctrl.stereo_position = stereo_position;
1666 snd_ctrl.state = state;
1668 HandleSoundRequest(snd_ctrl);
1671 void FadeMusic(void)
1673 if (!audio.music_available)
1676 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
1679 void FadeSound(int nr)
1681 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
1687 StopSoundExt(-1, SND_CTRL_FADE_ALL);
1690 void StopMusic(void)
1692 if (!audio.music_available)
1695 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
1698 void StopSound(int nr)
1700 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
1706 StopSoundExt(-1, SND_CTRL_STOP_ALL);
1709 void StopSoundExt(int nr, int state)
1711 SoundControl snd_ctrl;
1713 if (!audio.sound_available)
1716 snd_ctrl.active = FALSE;
1718 snd_ctrl.state = state;
1720 HandleSoundRequest(snd_ctrl);
1723 ListNode *newListNode()
1725 return checked_calloc(sizeof(ListNode));
1728 void addNodeToList(ListNode **node_first, char *key, void *content)
1730 ListNode *node_new = newListNode();
1733 printf("LIST: adding node with key '%s'\n", key);
1736 node_new->key = getStringCopy(key);
1737 node_new->content = content;
1738 node_new->next = *node_first;
1739 *node_first = node_new;
1742 void deleteNodeFromList(ListNode **node_first, char *key,
1743 void (*destructor_function)(void *))
1745 if (node_first == NULL || *node_first == NULL)
1749 printf("[CHECKING LIST KEY '%s' == '%s']\n",
1750 (*node_first)->key, key);
1753 if (strcmp((*node_first)->key, key) == 0)
1756 printf("[DELETING LIST ENTRY]\n");
1759 free((*node_first)->key);
1760 if (destructor_function)
1761 destructor_function((*node_first)->content);
1762 *node_first = (*node_first)->next;
1765 deleteNodeFromList(&(*node_first)->next, key, destructor_function);
1768 ListNode *getNodeFromKey(ListNode *node_first, char *key)
1770 if (node_first == NULL)
1773 if (strcmp(node_first->key, key) == 0)
1776 return getNodeFromKey(node_first->next, key);
1779 int getNumNodes(ListNode *node_first)
1781 return (node_first ? 1 + getNumNodes(node_first->next) : 0);
1784 void dumpList(ListNode *node_first)
1786 ListNode *node = node_first;
1790 printf("['%s' (%d)]\n", node->key,
1791 ((SoundInfo *)node->content)->num_references);
1795 printf("[%d nodes]\n", getNumNodes(node_first));
1798 static void LoadSoundsInfo()
1800 char *filename = getCustomSoundConfigFilename();
1801 struct SetupFileList *setup_file_list;
1804 /* always start with reliable default values */
1805 for (i=0; i<num_sounds; i++)
1806 sound_effect[i].filename = NULL;
1808 if (filename == NULL)
1811 if ((setup_file_list = loadSetupFileList(filename)))
1813 for (i=0; i<num_sounds; i++)
1814 sound_effect[i].filename =
1815 getStringCopy(getTokenValue(setup_file_list, sound_effect[i].text));
1817 freeSetupFileList(setup_file_list);
1820 for (i=0; i<num_sounds; i++)
1822 printf("'%s' ", sound_effect[i].text);
1823 if (sound_effect[i].filename)
1824 printf("-> '%s'\n", sound_effect[i].filename);
1826 printf("-> UNDEFINED [-> '%s']\n", sound_effect[i].default_filename);
1832 static void ReloadCustomSounds()
1837 printf("DEBUG: reloading sounds '%s' ...\n", artwork.sounds_set_current);
1843 printf("DEBUG: reloading %d sounds ...\n", num_sounds);
1846 for(i=0; i<num_sounds; i++)
1848 if (sound_effect[i].filename)
1849 LoadSoundToList(sound_effect[i].filename, i);
1851 LoadSoundToList(sound_effect[i].default_filename, i);
1855 printf("list size == %d\n", getNumNodes(SoundFileList));
1859 dumpList(SoundFileList);
1863 static void ReloadCustomMusic()
1866 printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current);
1874 void InitReloadSounds(char *set_name)
1876 if (!audio.sound_available)
1879 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
1880 ReloadCustomSounds();
1881 #elif defined(AUDIO_UNIX_NATIVE)
1882 WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_SOUNDS);
1886 void InitReloadMusic(char *set_name)
1888 if (!audio.music_available)
1891 #if defined(TARGET_SDL) || defined(TARGET_ALLEGRO)
1892 ReloadCustomMusic();
1893 #elif defined(AUDIO_UNIX_NATIVE)
1894 WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_MUSIC);
1898 void FreeSound(void *ptr)
1900 SoundInfo *sound = (SoundInfo *)ptr;
1905 if (sound->data_ptr)
1907 #if defined(TARGET_SDL)
1908 Mix_FreeChunk(sound->data_ptr);
1909 #elif defined(TARGET_ALLEGRO)
1910 destroy_sample(sound->data_ptr);
1911 #else /* AUDIO_UNIX_NATIVE */
1912 free(sound->data_ptr);
1916 if (sound->source_filename)
1917 free(sound->source_filename);
1922 void FreeMusic(MusicInfo *music)
1927 if (music->data_ptr)
1929 #if defined(TARGET_SDL)
1930 if (music->type == MUS_TYPE_MOD)
1931 Mix_FreeMusic(music->data_ptr);
1933 Mix_FreeChunk(music->data_ptr);
1934 #elif defined(TARGET_ALLEGRO)
1935 destroy_sample(music->data_ptr);
1936 #else /* AUDIO_UNIX_NATIVE */
1937 free(music->data_ptr);
1944 void FreeAllSounds()
1951 printf("%s: FREEING SOUNDS ...\n",
1952 IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
1954 for(i=0; i<num_sounds; i++)
1955 deleteSoundEntry(&Sound[i]);
1957 FreeSound(Sound[i]);
1960 printf("%s: FREEING SOUNDS -- DONE\n",
1961 IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
1976 for(i=0; i<num_music; i++)
1977 FreeMusic(Music[i]);
1985 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
1986 /* ========================================================================= */