1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2002 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
14 #include <sys/types.h>
25 #if defined(PLATFORM_LINUX)
26 #include <sys/ioctl.h>
27 #include <linux/soundcard.h>
28 #elif defined(PLATFORM_FREEBSD)
29 #include <machine/soundcard.h>
30 #elif defined(PLATFORM_NETBSD)
31 #include <sys/ioctl.h>
32 #include <sys/audioio.h>
33 #elif defined(PLATFORM_HPUX)
34 #include <sys/audio.h>
44 /* expiration time (in milliseconds) for sound loops */
45 #define SOUND_LOOP_EXPIRATION_TIME 200
47 /* one second fading interval == 1000 ticks (milliseconds) */
48 #define SOUND_FADING_INTERVAL 1000
50 #if defined(AUDIO_STREAMING_DSP)
51 #define SOUND_FADING_VOLUME_STEP (SOUND_MAX_VOLUME / 40)
52 #define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2)
55 #if !defined(PLATFORM_HPUX)
56 #define SND_BLOCKSIZE 4096
58 #define SND_BLOCKSIZE 32768
61 #define SND_TYPE_NONE 0
62 #define SND_TYPE_WAV 1
64 #define MUS_TYPE_NONE 0
65 #define MUS_TYPE_WAV 1
66 #define MUS_TYPE_MOD 2
68 #define DEVICENAME_DSP "/dev/dsp"
69 #define DEVICENAME_AUDIO "/dev/audio"
70 #define DEVICENAME_AUDIOCTL "/dev/audioCtl"
72 #define SOUND_VOLUME_LEFT(x) (stereo_volume[x])
73 #define SOUND_VOLUME_RIGHT(x) (stereo_volume[SOUND_MAX_LEFT2RIGHT-x])
75 #define SAME_SOUND_NR(x,y) ((x).nr == (y).nr)
76 #define SAME_SOUND_DATA(x,y) ((x).data_ptr == (y).data_ptr)
79 struct SoundHeader_SUN
82 unsigned long hdr_size;
83 unsigned long data_size;
84 unsigned long encoding;
85 unsigned long sample_rate;
86 unsigned long channels;
89 struct SoundHeader_8SVX
92 unsigned long chunk_size;
97 #if defined(AUDIO_UNIX_NATIVE)
98 struct SoundHeader_WAV
100 unsigned short compression_code;
101 unsigned short num_channels;
102 unsigned long sample_rate;
103 unsigned long bytes_per_second;
104 unsigned short block_align;
105 unsigned short bits_per_sample;
109 struct AudioFormatInfo
111 boolean stereo; /* availability of stereo sound */
112 int format; /* size and endianess of sample data */
113 int sample_rate; /* sample frequency */
114 int fragment_size; /* audio device fragment size in bytes */
119 char *source_filename;
124 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
125 long data_len; /* number of samples, NOT number of bytes */
127 typedef struct SampleInfo SoundInfo;
128 typedef struct SampleInfo MusicInfo;
140 unsigned long playing_starttime;
141 unsigned long playing_pos;
145 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
146 long data_len; /* number of samples, NOT number of bytes */
148 #if defined(TARGET_ALLEGRO)
152 typedef struct SoundControl SoundControl;
158 struct ListNode *next;
160 typedef struct ListNode ListNode;
162 static ListNode *newListNode(void);
163 static void addNodeToList(ListNode **, char *, void *);
164 static void deleteNodeFromList(ListNode **, char *, void (*function)(void *));
165 static ListNode *getNodeFromKey(ListNode *, char *);
166 static int getNumNodes(ListNode *);
169 static struct SoundEffectInfo *sound_effect;
170 static ListNode *SoundFileList = NULL;
171 static SoundInfo **Sound = NULL;
172 static MusicInfo **Music = NULL;
173 static int num_sounds = 0, num_music = 0;
174 static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
177 /* ========================================================================= */
178 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
180 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
181 static int mixer_active_channels = 0;
183 #if defined(AUDIO_UNIX_NATIVE)
184 static struct AudioFormatInfo afmt;
186 static void Mixer_Main(void);
187 #if !defined(AUDIO_STREAMING_DSP)
188 static unsigned char linear_to_ulaw(int);
189 static int ulaw_to_linear(unsigned char);
193 static void ReloadCustomSounds();
194 static void ReloadCustomMusic();
195 static void FreeSound(void *);
198 /* ------------------------------------------------------------------------- */
199 /* functions for native (non-SDL) Unix audio/mixer support */
200 /* ------------------------------------------------------------------------- */
202 #if defined(AUDIO_UNIX_NATIVE)
204 static int OpenAudioDevice(char *audio_device_name)
208 /* check if desired audio device is accessible */
209 if (access(audio_device_name, W_OK) != 0)
212 /* try to open audio device in non-blocking mode */
213 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
214 return audio_device_fd;
216 /* re-open audio device in blocking mode */
217 close(audio_device_fd);
218 audio_device_fd = open(audio_device_name, O_WRONLY);
220 return audio_device_fd;
223 static void CloseAudioDevice(int *audio_device_fd)
225 if (*audio_device_fd == 0)
228 close(*audio_device_fd);
229 *audio_device_fd = -1;
232 static boolean TestAudioDevices(void)
234 static char *audio_device_name[] =
239 int audio_device_fd = -1;
242 /* look for available audio devices, starting with preferred ones */
243 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
244 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
247 if (audio_device_fd < 0)
249 Error(ERR_WARN, "cannot open audio device -- no sound");
253 close(audio_device_fd);
255 audio.device_name = audio_device_name[i];
260 static boolean ForkAudioProcess(void)
262 if (pipe(audio.mixer_pipe) < 0)
264 Error(ERR_WARN, "cannot create pipe -- no sounds");
268 if ((audio.mixer_pid = fork()) < 0)
270 Error(ERR_WARN, "cannot create sound server process -- no sounds");
274 if (IS_CHILD_PROCESS(audio.mixer_pid))
275 Mixer_Main(); /* this function never returns */
277 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
282 void UnixOpenAudio(void)
284 if (!TestAudioDevices())
287 audio.sound_available = TRUE;
288 audio.sound_enabled = TRUE;
290 #if defined(AUDIO_STREAMING_DSP)
291 audio.music_available = TRUE;
292 audio.loops_available = TRUE;
295 audio.num_channels = NUM_MIXER_CHANNELS;
296 audio.music_channel = MUSIC_CHANNEL;
297 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
300 void UnixCloseAudio(void)
303 close(audio.device_fd);
305 if (IS_PARENT_PROCESS(audio.mixer_pid))
306 kill(audio.mixer_pid, SIGTERM);
310 /* ------------------------------------------------------------------------- */
311 /* functions for platform specific audio device initialization */
312 /* ------------------------------------------------------------------------- */
314 #if defined(AUDIO_LINUX_IOCTL)
315 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
317 /* "ioctl()" expects pointer to 'int' value for stereo flag
318 (boolean is defined as 'char', which will not work here) */
319 unsigned int fragment_spec = 0;
320 int fragment_size_query;
329 /* supported audio format in preferred order */
330 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
331 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
332 { AFMT_U8, AUDIO_FORMAT_U8 },
337 /* determine logarithm (log2) of the fragment size */
338 while ((1 << fragment_spec) < afmt->fragment_size)
341 /* use two fragments (play one fragment, prepare the other);
342 one fragment would result in interrupted audio output, more
343 than two fragments would raise audio output latency to much */
344 fragment_spec |= 0x00020000;
346 /* Example for fragment specification:
347 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
348 - (with stereo the effective buffer size will shrink to 256)
349 => fragment_size = 0x00020009 */
351 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
352 Error(ERR_EXIT_SOUND_SERVER,
353 "cannot set fragment size of /dev/dsp -- no sounds");
357 while (formats[i].format_result != -1)
359 unsigned int audio_format = formats[i].format_ioctl;
360 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
362 afmt->format = formats[i].format_result;
367 if (afmt->format == 0) /* no supported audio format found */
368 Error(ERR_EXIT_SOUND_SERVER,
369 "cannot set audio format of /dev/dsp -- no sounds");
371 /* try if we can use stereo sound */
373 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
374 afmt->stereo = FALSE;
376 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
377 Error(ERR_EXIT_SOUND_SERVER,
378 "cannot set sample rate of /dev/dsp -- no sounds");
380 /* get the real fragmentation size; this should return 512 */
381 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
382 Error(ERR_EXIT_SOUND_SERVER,
383 "cannot get fragment size of /dev/dsp -- no sounds");
384 if (fragment_size_query != afmt->fragment_size)
385 Error(ERR_EXIT_SOUND_SERVER,
386 "cannot set fragment size of /dev/dsp -- no sounds");
388 #endif /* AUDIO_LINUX_IOCTL */
390 #if defined(PLATFORM_NETBSD)
391 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
394 boolean stereo = TRUE;
396 AUDIO_INITINFO(&a_info);
397 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
398 a_info.play.precision = 8;
399 a_info.play.channels = 2;
400 a_info.play.sample_rate = sample_rate;
401 a_info.blocksize = fragment_size;
403 afmt->format = AUDIO_FORMAT_U8;
406 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
408 /* try to disable stereo */
409 a_info.play.channels = 1;
411 afmt->stereo = FALSE;
413 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
414 Error(ERR_EXIT_SOUND_SERVER,
415 "cannot set sample rate of /dev/audio -- no sounds");
418 #endif /* PLATFORM_NETBSD */
420 #if defined(PLATFORM_HPUX)
421 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
423 struct audio_describe ainfo;
426 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
428 Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl -- no sounds");
430 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
431 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
433 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
434 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
436 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
437 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
439 afmt->format = AUDIO_FORMAT_U8;
440 afmt->stereo = FALSE;
441 afmt->sample_rate = 8000;
445 #endif /* PLATFORM_HPUX */
447 static void InitAudioDevice(struct AudioFormatInfo *afmt)
450 afmt->format = AUDIO_FORMAT_UNKNOWN;
451 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
452 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
454 #if defined(AUDIO_LINUX_IOCTL)
455 InitAudioDevice_Linux(afmt);
456 #elif defined(PLATFORM_NETBSD)
457 InitAudioDevice_NetBSD(afmt);
458 #elif defined(PLATFORM_HPUX)
459 InitAudioDevice_HPUX(afmt);
461 /* generic /dev/audio stuff might be placed here */
466 /* ------------------------------------------------------------------------- */
467 /* functions for communication between main process and sound mixer process */
468 /* ------------------------------------------------------------------------- */
470 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
472 if (IS_CHILD_PROCESS(audio.mixer_pid))
475 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
477 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
478 audio.sound_available = audio.sound_enabled = FALSE;
483 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
485 if (IS_PARENT_PROCESS(audio.mixer_pid))
488 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
489 != sizeof(SoundControl))
490 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
493 static void WriteReloadInfoToPipe(char *set_name, int type)
495 SoundControl snd_ctrl;
496 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
497 artwork.mus_current);
498 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
499 unsigned long str_size2 = strlen(ti->basepath) + 1;
500 unsigned long str_size3 = strlen(ti->fullpath) + 1;
501 boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
502 setup.override_level_sounds :
503 setup.override_level_music);
505 if (IS_CHILD_PROCESS(audio.mixer_pid))
508 if (leveldir_current == NULL) /* should never happen */
509 Error(ERR_EXIT, "leveldir_current == NULL");
511 snd_ctrl.active = FALSE;
512 snd_ctrl.state = type;
513 snd_ctrl.data_len = strlen(set_name) + 1;
515 if (write(audio.mixer_pipe[1], &snd_ctrl,
516 sizeof(snd_ctrl)) < 0 ||
517 write(audio.mixer_pipe[1], set_name,
518 snd_ctrl.data_len) < 0 ||
519 write(audio.mixer_pipe[1], &override_level_artwork,
520 sizeof(boolean)) < 0 ||
521 write(audio.mixer_pipe[1], leveldir_current,
522 sizeof(TreeInfo)) < 0 ||
523 write(audio.mixer_pipe[1], ti,
524 sizeof(TreeInfo)) < 0 ||
525 write(audio.mixer_pipe[1], &str_size1,
526 sizeof(unsigned long)) < 0 ||
527 write(audio.mixer_pipe[1], &str_size2,
528 sizeof(unsigned long)) < 0 ||
529 write(audio.mixer_pipe[1], &str_size3,
530 sizeof(unsigned long)) < 0 ||
531 write(audio.mixer_pipe[1], leveldir_current->fullpath,
533 write(audio.mixer_pipe[1], ti->basepath,
535 write(audio.mixer_pipe[1], ti->fullpath,
538 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
539 audio.sound_available = audio.sound_enabled = FALSE;
544 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
546 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
547 &artwork.snd_current : &artwork.mus_current);
548 TreeInfo *ti = *ti_ptr;
549 unsigned long str_size1, str_size2, str_size3;
550 static char *set_name = NULL;
551 boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
552 &setup.override_level_sounds :
553 &setup.override_level_music);
558 set_name = checked_malloc(snd_ctrl->data_len);
560 if (leveldir_current == NULL)
561 leveldir_current = checked_calloc(sizeof(TreeInfo));
563 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
564 if (leveldir_current->fullpath != NULL)
565 free(leveldir_current->fullpath);
566 if (ti->basepath != NULL)
568 if (ti->fullpath != NULL)
571 if (read(audio.mixer_pipe[0], set_name,
572 snd_ctrl->data_len) != snd_ctrl->data_len ||
573 read(audio.mixer_pipe[0], override_level_artwork,
574 sizeof(boolean)) != sizeof(boolean) ||
575 read(audio.mixer_pipe[0], leveldir_current,
576 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
577 read(audio.mixer_pipe[0], ti,
578 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
579 read(audio.mixer_pipe[0], &str_size1,
580 sizeof(unsigned long)) != sizeof(unsigned long) ||
581 read(audio.mixer_pipe[0], &str_size2,
582 sizeof(unsigned long)) != sizeof(unsigned long) ||
583 read(audio.mixer_pipe[0], &str_size3,
584 sizeof(unsigned long)) != sizeof(unsigned long))
585 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
587 leveldir_current->fullpath = checked_calloc(str_size1);
588 ti->basepath = checked_calloc(str_size2);
589 ti->fullpath = checked_calloc(str_size3);
591 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
592 str_size1) != str_size1 ||
593 read(audio.mixer_pipe[0], ti->basepath,
594 str_size2) != str_size2 ||
595 read(audio.mixer_pipe[0], ti->fullpath,
596 str_size3) != str_size3)
597 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
599 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
600 artwork.sounds_set_current_name = set_name;
602 artwork.music_set_current_name = set_name;
605 #endif /* AUDIO_UNIX_NATIVE */
608 /* ------------------------------------------------------------------------- */
609 /* mixer functions */
610 /* ------------------------------------------------------------------------- */
612 void Mixer_InitChannels()
616 for(i=0; i<audio.num_channels; i++)
617 mixer[i].active = FALSE;
618 mixer_active_channels = 0;
621 static void Mixer_ResetChannelExpiration(int channel)
623 mixer[channel].playing_starttime = Counter();
625 #if defined(TARGET_SDL)
626 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
627 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
631 static boolean Mixer_ChannelExpired(int channel)
633 if (!mixer[channel].active)
636 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
637 DelayReached(&mixer[channel].playing_starttime,
638 SOUND_LOOP_EXPIRATION_TIME))
641 #if defined(TARGET_SDL)
643 if (!Mix_Playing(channel))
646 #elif defined(TARGET_ALLEGRO)
648 mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
649 mixer[channel].volume = voice_get_volume(mixer[channel].voice);
651 /* sound sample has completed playing or was completely faded out */
652 if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
655 #endif /* TARGET_ALLEGRO */
660 static boolean Mixer_AllocateChannel(int channel)
662 #if defined(TARGET_ALLEGRO)
663 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
664 if (mixer[channel].voice < 0)
671 static void Mixer_SetChannelProperties(int channel)
673 #if defined(TARGET_SDL)
674 Mix_Volume(channel, mixer[channel].volume);
675 Mix_SetPanning(channel,
676 SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
677 SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
678 #elif defined(TARGET_ALLEGRO)
679 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
680 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
684 static void Mixer_StartChannel(int channel)
686 #if defined(TARGET_SDL)
687 Mix_PlayChannel(channel, mixer[channel].data_ptr,
688 IS_LOOP(mixer[channel]) ? -1 : 0);
689 #elif defined(TARGET_ALLEGRO)
690 if (IS_LOOP(mixer[channel]))
691 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
693 voice_start(mixer[channel].voice);
697 static void Mixer_PlayChannel(int channel)
699 /* start with inactive channel in case something goes wrong */
700 mixer[channel].active = FALSE;
702 if (mixer[channel].type != MUS_TYPE_WAV)
705 if (!Mixer_AllocateChannel(channel))
708 Mixer_SetChannelProperties(channel);
709 Mixer_StartChannel(channel);
711 Mixer_ResetChannelExpiration(channel);
713 mixer[channel].playing_pos = 0;
714 mixer[channel].active = TRUE;
715 mixer_active_channels++;
718 static void Mixer_PlayMusicChannel()
720 Mixer_PlayChannel(audio.music_channel);
722 #if defined(TARGET_SDL)
723 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
725 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
726 this looks like a bug in the SDL_mixer library */
727 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
728 Mix_VolumeMusic(SOUND_MAX_VOLUME);
733 static void Mixer_StopChannel(int channel)
735 if (!mixer[channel].active)
738 #if defined(TARGET_SDL)
739 Mix_HaltChannel(channel);
740 #elif defined(TARGET_ALLEGRO)
741 voice_set_volume(mixer[channel].voice, 0);
742 deallocate_voice(mixer[channel].voice);
745 mixer[channel].active = FALSE;
746 mixer_active_channels--;
749 static void Mixer_StopMusicChannel()
751 Mixer_StopChannel(audio.music_channel);
753 #if defined(TARGET_SDL)
758 static void Mixer_FadeChannel(int channel)
760 if (!mixer[channel].active)
763 mixer[channel].state |= SND_CTRL_FADE;
765 #if defined(TARGET_SDL)
766 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
767 #elif defined(TARGET_ALLEGRO)
768 if (voice_check(mixer[channel].voice))
769 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
773 static void Mixer_FadeMusicChannel()
775 Mixer_FadeChannel(audio.music_channel);
777 #if defined(TARGET_SDL)
778 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
782 static void Mixer_UnFadeChannel(int channel)
784 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
787 mixer[channel].state &= ~SND_CTRL_FADE;
788 mixer[channel].volume = SOUND_MAX_VOLUME;
790 #if defined(TARGET_SDL)
791 Mix_ExpireChannel(channel, -1);
792 Mix_Volume(channel, mixer[channel].volume);
793 #elif defined(TARGET_ALLEGRO)
794 voice_stop_volumeramp(mixer[channel].voice);
795 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
796 mixer[channel].volume);
800 static void Mixer_InsertSound(SoundControl snd_ctrl)
806 printf("NEW SOUND %d ARRIVED [%d] [%d ACTIVE CHANNELS]\n",
807 snd_ctrl.nr, num_sounds, mixer_active_channels);
810 if (IS_MUSIC(snd_ctrl))
815 snd_ctrl.nr = snd_ctrl.nr % num_music;
817 else if (snd_ctrl.nr >= num_sounds)
820 snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
821 if (snd_info == NULL)
824 /* copy sound sample and format information */
825 snd_ctrl.type = snd_info->type;
826 snd_ctrl.format = snd_info->format;
827 snd_ctrl.data_ptr = snd_info->data_ptr;
828 snd_ctrl.data_len = snd_info->data_len;
830 /* play music samples on a dedicated music channel */
831 if (IS_MUSIC(snd_ctrl))
833 Mixer_StopMusicChannel();
835 mixer[audio.music_channel] = snd_ctrl;
836 Mixer_PlayMusicChannel();
841 /* check if (and how often) this sound sample is already playing */
842 for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
843 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
847 printf("SOUND %d [CURRENTLY PLAYING %d TIMES]\n", snd_ctrl.nr, k);
850 /* reset expiration delay for already playing loop sounds */
851 if (k > 0 && IS_LOOP(snd_ctrl))
853 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
855 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
858 printf("RESETTING EXPIRATION FOR SOUND %d\n", snd_ctrl.nr);
861 if (IS_FADING(mixer[i]))
862 Mixer_UnFadeChannel(i);
864 /* restore settings like volume and stereo position */
865 mixer[i].volume = snd_ctrl.volume;
866 mixer[i].stereo_position = snd_ctrl.stereo_position;
868 Mixer_SetChannelProperties(i);
869 Mixer_ResetChannelExpiration(i);
872 printf("RESETTING VOLUME/STEREO FOR SOUND %d TO %d/%d\n",
873 snd_ctrl.nr, snd_ctrl.volume, snd_ctrl.stereo_position);
882 printf("PLAYING NEW SOUND %d\n", snd_ctrl.nr);
885 /* don't play sound more than n times simultaneously (with n == 2 for now) */
888 unsigned long playing_current = Counter();
889 int longest = 0, longest_nr = audio.first_sound_channel;
891 /* look for oldest equal sound */
892 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
894 int playing_time = playing_current - mixer[i].playing_starttime;
897 if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
900 actual = 1000 * playing_time / mixer[i].data_len;
902 if (actual >= longest)
909 Mixer_StopChannel(longest_nr);
912 /* If all (non-music) channels are active, stop the channel that has
913 played its sound sample most completely (in percent of the sample
914 length). As we cannot currently get the actual playing position
915 of the channel's sound sample when compiling with the SDL mixer
916 library, we use the current playing time (in milliseconds) instead. */
919 /* Channel sanity check -- this should normally not be needed */
920 if (mixer_active_channels ==
921 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
923 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
925 if (!mixer[i].active)
927 Error(ERR_RETURN, "Mixer_InsertSound: Channel %d inactive", i);
928 Error(ERR_RETURN, "Mixer_InsertSound: This should never happen!");
930 mixer_active_channels--;
936 if (mixer_active_channels ==
937 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
939 unsigned long playing_current = Counter();
940 int longest = 0, longest_nr = audio.first_sound_channel;
942 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
944 Error(ERR_RETURN, "Mixer_InsertSound: %d [%d]: %ld (%ld)",
945 i, mixer[i].active, mixer[i].data_len, (long)mixer[i].data_ptr);
948 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
950 int playing_time = playing_current - mixer[i].playing_starttime;
951 int actual = 1000 * playing_time / mixer[i].data_len;
953 if (!IS_LOOP(mixer[i]) && actual > longest)
960 Mixer_StopChannel(longest_nr);
963 /* add the new sound to the mixer */
964 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
967 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
970 if (!mixer[i].active)
973 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
976 #if defined(AUDIO_UNIX_NATIVE)
977 if (snd_info->data_len == 0)
979 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
984 Mixer_PlayChannel(i);
991 static void HandleSoundRequest(SoundControl snd_ctrl)
995 #if defined(AUDIO_UNIX_NATIVE)
996 if (IS_PARENT_PROCESS(audio.mixer_pid))
998 SendSoundControlToMixerProcess(&snd_ctrl);
1003 /* deactivate channels that have expired since the last request */
1004 for (i=0; i<audio.num_channels; i++)
1005 if (mixer[i].active && Mixer_ChannelExpired(i))
1006 Mixer_StopChannel(i);
1008 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
1010 Mixer_StopMusicChannel();
1011 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1012 Mixer_StopChannel(i);
1014 #if defined(AUDIO_UNIX_NATIVE)
1015 CloseAudioDevice(&audio.device_fd);
1016 ReadReloadInfoFromPipe(&snd_ctrl);
1019 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
1020 ReloadCustomSounds();
1022 ReloadCustomMusic();
1024 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
1026 if (IS_MUSIC(snd_ctrl))
1028 Mixer_FadeMusicChannel();
1032 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1033 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1034 Mixer_FadeChannel(i);
1036 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
1038 if (IS_MUSIC(snd_ctrl))
1040 Mixer_StopMusicChannel();
1044 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1045 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1046 Mixer_StopChannel(i);
1048 #if defined(AUDIO_UNIX_NATIVE)
1049 if (!mixer_active_channels)
1050 CloseAudioDevice(&audio.device_fd);
1053 else if (snd_ctrl.active) /* add new sound to mixer */
1055 Mixer_InsertSound(snd_ctrl);
1059 void StartMixer(void)
1064 SDL_version compile_version;
1065 const SDL_version *link_version;
1066 MIX_VERSION(&compile_version);
1067 printf("compiled with SDL_mixer version: %d.%d.%d\n",
1068 compile_version.major,
1069 compile_version.minor,
1070 compile_version.patch);
1071 link_version = Mix_Linked_Version();
1072 printf("running with SDL_mixer version: %d.%d.%d\n",
1073 link_version->major,
1074 link_version->minor,
1075 link_version->patch);
1078 if (!audio.sound_available)
1081 /* initialize stereo position conversion information */
1082 for(i=0; i<=SOUND_MAX_LEFT2RIGHT; i++)
1084 (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1086 #if defined(AUDIO_UNIX_NATIVE)
1087 if (!ForkAudioProcess())
1088 audio.sound_available = FALSE;
1092 #if defined(AUDIO_UNIX_NATIVE)
1094 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1095 int sample_pos, int sample_size,
1098 void *sample_ptr = snd_ctrl->data_ptr;
1101 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1102 for (i=0; i<sample_size; i++)
1104 ((short)(((byte *)sample_ptr)[sample_pos + i] ^ 0x80)) << 8;
1105 else /* AUDIO_FORMAT_S16 */
1106 for (i=0; i<sample_size; i++)
1108 ((short *)sample_ptr)[sample_pos + i];
1111 #if defined(AUDIO_STREAMING_DSP)
1112 static void Mixer_Main_DSP()
1114 static short premix_first_buffer[SND_BLOCKSIZE];
1115 static short premix_left_buffer[SND_BLOCKSIZE];
1116 static short premix_right_buffer[SND_BLOCKSIZE];
1117 static long premix_last_buffer[SND_BLOCKSIZE];
1118 static byte playing_buffer[SND_BLOCKSIZE];
1122 int max_sample_size;
1125 if (!mixer_active_channels)
1128 if (audio.device_fd < 0)
1130 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1133 InitAudioDevice(&afmt);
1136 stereo = afmt.stereo;
1137 fragment_size = afmt.fragment_size;
1138 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1139 max_sample_size = fragment_size / ((stereo ? 2 : 1) * sample_bytes);
1141 /* first clear the last premixing buffer */
1142 memset(premix_last_buffer, 0,
1143 max_sample_size * (stereo ? 2 : 1) * sizeof(long));
1145 for(i=0; i<audio.num_channels; i++)
1152 if (!mixer[i].active)
1155 if (Mixer_ChannelExpired(i))
1157 Mixer_StopChannel(i);
1161 /* pointer, lenght and actual playing position of sound sample */
1162 sample_ptr = mixer[i].data_ptr;
1163 sample_len = mixer[i].data_len;
1164 sample_pos = mixer[i].playing_pos;
1165 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1166 mixer[i].playing_pos += sample_size;
1168 /* copy original sample to first mixing buffer */
1169 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1170 premix_first_buffer);
1172 /* are we about to restart a looping sound? */
1173 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1175 while (sample_size < max_sample_size)
1177 int restarted_sample_size =
1178 MIN(max_sample_size - sample_size, sample_len);
1180 if (mixer[i].format == AUDIO_FORMAT_U8)
1181 for (j=0; j<restarted_sample_size; j++)
1182 premix_first_buffer[sample_size + j] =
1183 ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
1185 for (j=0; j<restarted_sample_size; j++)
1186 premix_first_buffer[sample_size + j] =
1187 ((short *)sample_ptr)[j];
1189 mixer[i].playing_pos = restarted_sample_size;
1190 sample_size += restarted_sample_size;
1194 /* decrease volume if sound is fading out */
1195 if (IS_FADING(mixer[i]) &&
1196 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1197 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1199 /* adjust volume of actual sound sample */
1200 if (mixer[i].volume != SOUND_MAX_VOLUME)
1201 for(j=0; j<sample_size; j++)
1202 premix_first_buffer[j] =
1203 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1205 /* fill the last mixing buffer with stereo or mono sound */
1208 int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1209 int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1211 for(j=0; j<sample_size; j++)
1213 premix_left_buffer[j] =
1214 left_volume * premix_first_buffer[j] / SOUND_MAX_LEFT2RIGHT;
1215 premix_right_buffer[j] =
1216 right_volume * premix_first_buffer[j] / SOUND_MAX_LEFT2RIGHT;
1218 premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
1219 premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
1224 for(j=0; j<sample_size; j++)
1225 premix_last_buffer[j] += premix_first_buffer[j];
1228 /* delete completed sound entries from the mixer */
1229 if (mixer[i].playing_pos >= mixer[i].data_len)
1231 if (IS_LOOP(mixer[i]))
1232 mixer[i].playing_pos = 0;
1234 Mixer_StopChannel(i);
1236 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1237 Mixer_StopChannel(i);
1240 /* prepare final playing buffer according to system audio format */
1241 for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
1243 /* cut off at 17 bit value */
1244 if (premix_last_buffer[i] < -65535)
1245 premix_last_buffer[i] = -65535;
1246 else if (premix_last_buffer[i] > 65535)
1247 premix_last_buffer[i] = 65535;
1249 /* shift to 16 bit value */
1250 premix_last_buffer[i] >>= 1;
1252 if (afmt.format & AUDIO_FORMAT_U8)
1254 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1256 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1258 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1259 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1261 else /* big endian */
1263 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1264 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1268 /* finally play the sound fragment */
1269 write(audio.device_fd, playing_buffer, fragment_size);
1271 if (!mixer_active_channels)
1272 CloseAudioDevice(&audio.device_fd);
1275 #else /* !AUDIO_STREAMING_DSP */
1277 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1279 static short premix_first_buffer[SND_BLOCKSIZE];
1280 static byte playing_buffer[SND_BLOCKSIZE];
1281 int max_sample_size = SND_BLOCKSIZE;
1290 /* pointer, lenght and actual playing position of sound sample */
1291 sample_ptr = mixer[i].data_ptr;
1292 sample_len = mixer[i].data_len;
1293 sample_pos = mixer[i].playing_pos;
1294 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1295 mixer[i].playing_pos += sample_size;
1297 /* copy original sample to first mixing buffer */
1298 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1299 premix_first_buffer);
1301 /* adjust volume of actual sound sample */
1302 if (mixer[i].volume != SOUND_MAX_VOLUME)
1303 for(j=0; j<sample_size; j++)
1304 premix_first_buffer[j] =
1305 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1307 /* might be needed for u-law /dev/audio */
1309 for(j=0; j<sample_size; j++)
1311 linear_to_ulaw(premix_first_buffer[j]);
1314 /* delete completed sound entries from the mixer */
1315 if (mixer[i].playing_pos >= mixer[i].data_len)
1316 Mixer_StopChannel(i);
1318 for(i=0; i<sample_size; i++)
1319 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1321 /* finally play the sound fragment */
1322 write(audio.device_fd, playing_buffer, sample_size);
1326 #endif /* !AUDIO_STREAMING_DSP */
1330 SoundControl snd_ctrl;
1333 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1335 Mixer_InitChannels();
1337 #if defined(PLATFORM_HPUX)
1338 InitAudioDevice(&afmt);
1341 FD_ZERO(&mixer_fdset);
1342 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1344 while(1) /* wait for sound playing commands from client */
1346 struct timeval delay = { 0, 0 };
1348 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1349 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1350 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1353 ReadSoundControlFromMainProcess(&snd_ctrl);
1355 HandleSoundRequest(snd_ctrl);
1357 #if defined(AUDIO_STREAMING_DSP)
1359 while (mixer_active_channels &&
1360 select(audio.mixer_pipe[0] + 1,
1361 &mixer_fdset, NULL, NULL, &delay) < 1)
1363 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1368 #else /* !AUDIO_STREAMING_DSP */
1370 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1371 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1374 InitAudioDevice(&afmt);
1379 while (mixer_active_channels &&
1380 select(audio.mixer_pipe[0] + 1,
1381 &mixer_fdset, NULL, NULL, &delay) < 1)
1383 int wait_percent = 90; /* wait 90% of the real playing time */
1386 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1388 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1392 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1395 CloseAudioDevice(&audio.device_fd);
1397 Mixer_InitChannels(); /* remove all sounds from mixer */
1399 #endif /* !AUDIO_STREAMING_DSP */
1402 #endif /* AUDIO_UNIX_NATIVE */
1405 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1407 /* these two are stolen from "sox"... :) */
1410 ** This routine converts from linear to ulaw.
1412 ** Craig Reese: IDA/Supercomputing Research Center
1413 ** Joe Campbell: Department of Defense
1414 ** 29 September 1989
1417 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1418 ** 2) "A New Digital Technique for Implementation of Any
1419 ** Continuous PCM Companding Law," Villeret, Michel,
1420 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1421 ** 1973, pg. 11.12-11.17
1422 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1423 ** for Analog-to_Digital Conversion Techniques,"
1426 ** Input: Signed 16 bit linear sample
1427 ** Output: 8 bit ulaw sample
1430 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1431 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1434 static unsigned char linear_to_ulaw(int sample)
1436 static int exp_lut[256] =
1438 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1439 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1440 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1441 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1442 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1443 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1444 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1445 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1446 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1447 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1448 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1449 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1450 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1451 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1452 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1453 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1456 int sign, exponent, mantissa;
1457 unsigned char ulawbyte;
1459 /* Get the sample into sign-magnitude. */
1460 sign = (sample >> 8) & 0x80; /* set aside the sign */
1462 sample = -sample; /* get magnitude */
1464 sample = CLIP; /* clip the magnitude */
1466 /* Convert from 16 bit linear to ulaw. */
1467 sample = sample + BIAS;
1468 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1469 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1470 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1473 ulawbyte = 0x02; /* optional CCITT trap */
1480 ** This routine converts from ulaw to 16 bit linear.
1482 ** Craig Reese: IDA/Supercomputing Research Center
1483 ** 29 September 1989
1486 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1487 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1488 ** for Analog-to_Digital Conversion Techniques,"
1491 ** Input: 8 bit ulaw sample
1492 ** Output: signed 16 bit linear sample
1495 static int ulaw_to_linear(unsigned char ulawbyte)
1497 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1498 int sign, exponent, mantissa, sample;
1500 ulawbyte = ~ ulawbyte;
1501 sign = ( ulawbyte & 0x80 );
1502 exponent = ( ulawbyte >> 4 ) & 0x07;
1503 mantissa = ulawbyte & 0x0F;
1504 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1510 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1513 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1514 /* ========================================================================= */
1515 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1517 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1518 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1520 static SoundInfo *Load_WAV(char *filename)
1522 SoundInfo *snd_info;
1523 #if defined(AUDIO_UNIX_NATIVE)
1524 struct SoundHeader_WAV header;
1526 byte sound_header_buffer[WAV_HEADER_SIZE];
1529 char chunk_name[CHUNK_ID_LEN + 1];
1534 if (!audio.sound_available)
1538 printf("loading WAV file '%s'\n", filename);
1541 snd_info = checked_calloc(sizeof(SoundInfo));
1543 #if defined(TARGET_SDL)
1545 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1547 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1552 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1554 #elif defined(TARGET_ALLEGRO)
1556 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1558 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1563 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1565 #else /* AUDIO_UNIX_NATIVE */
1567 if ((file = fopen(filename, MODE_READ)) == NULL)
1569 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1574 /* read chunk id "RIFF" */
1575 getFileChunkLE(file, chunk_name, &chunk_size);
1576 if (strcmp(chunk_name, "RIFF") != 0)
1578 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1584 /* read "RIFF" type id "WAVE" */
1585 getFileChunkLE(file, chunk_name, NULL);
1586 if (strcmp(chunk_name, "WAVE") != 0)
1588 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1594 while (getFileChunkLE(file, chunk_name, &chunk_size))
1596 if (strcmp(chunk_name, "fmt ") == 0)
1598 if (chunk_size < WAV_HEADER_SIZE)
1600 Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1606 header.compression_code = getFile16BitLE(file);
1607 header.num_channels = getFile16BitLE(file);
1608 header.sample_rate = getFile32BitLE(file);
1609 header.bytes_per_second = getFile32BitLE(file);
1610 header.block_align = getFile16BitLE(file);
1611 header.bits_per_sample = getFile16BitLE(file);
1613 if (chunk_size > WAV_HEADER_SIZE)
1614 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1616 if (header.compression_code != 1)
1618 Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1619 filename, header.compression_code);
1625 if (header.num_channels != 1)
1627 Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
1628 filename, header.num_channels);
1634 if (header.bits_per_sample != 8 && header.bits_per_sample != 16)
1636 Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1637 filename, header.bits_per_sample);
1643 /* warn, but accept wrong sample rate (may be only slightly different) */
1644 if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1645 Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1646 filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1649 printf("WAV file: '%s'\n", filename);
1650 printf(" Compression code: %d'\n", header.compression_code);
1651 printf(" Number of channels: %d'\n", header.num_channels);
1652 printf(" Sample rate: %ld'\n", header.sample_rate);
1653 printf(" Average bytes per second: %ld'\n", header.bytes_per_second);
1654 printf(" Block align: %d'\n", header.block_align);
1655 printf(" Significant bits per sample: %d'\n", header.bits_per_sample);
1658 else if (strcmp(chunk_name, "data") == 0)
1660 snd_info->data_len = chunk_size;
1661 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1663 /* read sound data */
1664 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1667 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1669 free(snd_info->data_ptr);
1674 /* check for odd number of sample bytes (data chunk is word aligned) */
1675 if ((chunk_size % 2) == 1)
1676 ReadUnusedBytesFromFile(file, 1);
1678 else /* unknown chunk -- ignore */
1679 ReadUnusedBytesFromFile(file, chunk_size);
1684 if (snd_info->data_ptr == NULL)
1686 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1691 if (header.bits_per_sample == 8)
1692 snd_info->format = AUDIO_FORMAT_U8;
1693 else /* header.bits_per_sample == 16 */
1695 snd_info->format = AUDIO_FORMAT_S16;
1696 snd_info->data_len /= 2; /* correct number of samples */
1699 #endif /* AUDIO_UNIX_NATIVE */
1701 snd_info->type = SND_TYPE_WAV;
1702 snd_info->source_filename = getStringCopy(filename);
1707 static void deleteSoundEntry(SoundInfo **snd_info)
1711 char *filename = (*snd_info)->source_filename;
1714 printf("[decrementing reference counter of sound '%s']\n", filename);
1717 if (--(*snd_info)->num_references <= 0)
1720 printf("[deleting sound '%s']\n", filename);
1724 FreeSound(*snd_info);
1726 deleteNodeFromList(&SoundFileList, filename, FreeSound);
1733 static void replaceSoundEntry(SoundInfo **snd_info, char *filename)
1737 /* check if the old and the new sound file are the same */
1738 if (*snd_info && strcmp((*snd_info)->source_filename, filename) == 0)
1740 /* The old and new sound are the same (have the same filename and path).
1741 This usually means that this sound does not exist in this sound set
1742 and a fallback to the existing sound is done. */
1745 printf("[sound '%s' already exists (same list entry)]\n", filename);
1751 /* delete existing sound file entry */
1752 deleteSoundEntry(snd_info);
1754 /* check if the new sound file already exists in the list of sounds */
1755 if ((node = getNodeFromKey(SoundFileList, filename)) != NULL)
1758 printf("[sound '%s' already exists (other list entry)]\n", filename);
1761 *snd_info = (SoundInfo *)node->content;
1762 (*snd_info)->num_references++;
1764 else if ((*snd_info = Load_WAV(filename)) != NULL) /* load new sound */
1766 (*snd_info)->num_references = 1;
1767 addNodeToList(&SoundFileList, (*snd_info)->source_filename, *snd_info);
1771 static void LoadCustomSound(SoundInfo **snd_info, char *basename)
1773 char *filename = getCustomSoundFilename(basename);
1776 printf("GOT CUSTOM SOUND FILE '%s'\n", filename);
1779 if (strcmp(basename, SND_FILE_UNDEFINED) == 0)
1781 deleteSoundEntry(snd_info);
1785 if (filename == NULL)
1787 Error(ERR_WARN, "cannot find sound file '%s'", basename);
1791 replaceSoundEntry(snd_info, filename);
1794 void InitSoundList(struct SoundEffectInfo *sounds_list, int num_list_entries)
1797 Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
1799 sound_effect = sounds_list;
1800 num_sounds = num_list_entries;
1803 void LoadSoundToList(char *basename, int list_pos)
1805 if (Sound == NULL || list_pos >= num_sounds)
1809 printf("loading sound '%s' ... [%d]\n",
1810 basename, getNumNodes(SoundFileList));
1813 LoadCustomSound(&Sound[list_pos], basename);
1816 printf("loading sound '%s' done [%d]\n",
1817 basename, getNumNodes(SoundFileList));
1821 static MusicInfo *Load_MOD(char *filename)
1823 #if defined(TARGET_SDL)
1824 MusicInfo *mod_info;
1826 if (!audio.sound_available)
1829 mod_info = checked_calloc(sizeof(MusicInfo));
1831 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1833 Error(ERR_WARN, "cannot read music file '%s'", filename);
1838 mod_info->type = MUS_TYPE_MOD;
1839 mod_info->source_filename = getStringCopy(filename);
1847 void LoadCustomMusic(void)
1849 static boolean draw_init_text = TRUE; /* only draw at startup */
1850 static char *last_music_directory = NULL;
1851 char *music_directory = getCustomMusicDirectory();
1853 struct dirent *dir_entry;
1855 if (!audio.sound_available)
1858 if (last_music_directory != NULL &&
1859 strcmp(last_music_directory, music_directory) == 0)
1860 return; /* old and new music directory are the same */
1862 last_music_directory = music_directory;
1866 if ((dir = opendir(music_directory)) == NULL)
1868 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1869 audio.music_available = FALSE;
1874 DrawInitText("Loading music:", 120, FC_GREEN);
1876 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1878 char *basename = dir_entry->d_name;
1879 char *filename = getPath2(music_directory, basename);
1880 MusicInfo *mus_info = NULL;
1883 DrawInitText(basename, 150, FC_YELLOW);
1885 if (FileIsSound(basename))
1886 mus_info = Load_WAV(filename);
1887 else if (FileIsMusic(basename))
1888 mus_info = Load_MOD(filename);
1895 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1896 Music[num_music -1] = mus_info;
1902 draw_init_text = FALSE;
1905 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1909 void PlayMusic(int nr)
1911 if (!audio.music_available)
1917 void PlaySound(int nr)
1919 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
1922 void PlaySoundStereo(int nr, int stereo_position)
1924 PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
1927 void PlaySoundLoop(int nr)
1929 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
1932 void PlaySoundMusic(int nr)
1934 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
1937 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
1939 SoundControl snd_ctrl;
1941 if (!audio.sound_available ||
1942 !audio.sound_enabled ||
1943 audio.sound_deactivated)
1946 if (volume < SOUND_MIN_VOLUME)
1947 volume = SOUND_MIN_VOLUME;
1948 else if (volume > SOUND_MAX_VOLUME)
1949 volume = SOUND_MAX_VOLUME;
1951 if (stereo_position < SOUND_MAX_LEFT)
1952 stereo_position = SOUND_MAX_LEFT;
1953 else if (stereo_position > SOUND_MAX_RIGHT)
1954 stereo_position = SOUND_MAX_RIGHT;
1956 snd_ctrl.active = TRUE;
1958 snd_ctrl.volume = volume;
1959 snd_ctrl.stereo_position = stereo_position;
1960 snd_ctrl.state = state;
1962 HandleSoundRequest(snd_ctrl);
1965 void FadeMusic(void)
1967 if (!audio.music_available)
1970 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
1973 void FadeSound(int nr)
1975 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
1981 StopSoundExt(-1, SND_CTRL_FADE_ALL);
1984 void StopMusic(void)
1986 if (!audio.music_available)
1989 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
1992 void StopSound(int nr)
1994 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
2000 StopSoundExt(-1, SND_CTRL_STOP_ALL);
2003 void StopSoundExt(int nr, int state)
2005 SoundControl snd_ctrl;
2007 if (!audio.sound_available)
2010 snd_ctrl.active = FALSE;
2012 snd_ctrl.state = state;
2014 HandleSoundRequest(snd_ctrl);
2017 ListNode *newListNode()
2019 return checked_calloc(sizeof(ListNode));
2022 void addNodeToList(ListNode **node_first, char *key, void *content)
2024 ListNode *node_new = newListNode();
2027 printf("LIST: adding node with key '%s'\n", key);
2030 node_new->key = getStringCopy(key);
2031 node_new->content = content;
2032 node_new->next = *node_first;
2033 *node_first = node_new;
2036 void deleteNodeFromList(ListNode **node_first, char *key,
2037 void (*destructor_function)(void *))
2039 if (node_first == NULL || *node_first == NULL)
2043 printf("[CHECKING LIST KEY '%s' == '%s']\n",
2044 (*node_first)->key, key);
2047 if (strcmp((*node_first)->key, key) == 0)
2050 printf("[DELETING LIST ENTRY]\n");
2053 free((*node_first)->key);
2054 if (destructor_function)
2055 destructor_function((*node_first)->content);
2056 *node_first = (*node_first)->next;
2059 deleteNodeFromList(&(*node_first)->next, key, destructor_function);
2062 ListNode *getNodeFromKey(ListNode *node_first, char *key)
2064 if (node_first == NULL)
2067 if (strcmp(node_first->key, key) == 0)
2070 return getNodeFromKey(node_first->next, key);
2073 int getNumNodes(ListNode *node_first)
2075 return (node_first ? 1 + getNumNodes(node_first->next) : 0);
2078 void dumpList(ListNode *node_first)
2080 ListNode *node = node_first;
2084 printf("['%s' (%d)]\n", node->key,
2085 ((SoundInfo *)node->content)->num_references);
2089 printf("[%d nodes]\n", getNumNodes(node_first));
2092 static void LoadSoundsInfo()
2094 char *filename = getCustomSoundConfigFilename();
2095 struct SetupFileList *setup_file_list;
2099 printf("GOT CUSTOM SOUND CONFIG FILE '%s'\n", filename);
2102 /* always start with reliable default values */
2103 for (i=0; i<num_sounds; i++)
2104 sound_effect[i].filename = NULL;
2106 if (filename == NULL)
2109 if ((setup_file_list = loadSetupFileList(filename)))
2111 for (i=0; i<num_sounds; i++)
2112 sound_effect[i].filename =
2113 getStringCopy(getTokenValue(setup_file_list, sound_effect[i].text));
2115 freeSetupFileList(setup_file_list);
2118 for (i=0; i<num_sounds; i++)
2120 printf("'%s' ", sound_effect[i].text);
2121 if (sound_effect[i].filename)
2122 printf("-> '%s'\n", sound_effect[i].filename);
2124 printf("-> UNDEFINED [-> '%s']\n", sound_effect[i].default_filename);
2130 static void ReloadCustomSounds()
2132 static boolean draw_init_text = TRUE; /* only draw at startup */
2136 printf("DEBUG: reloading sounds '%s' ...\n",artwork.sounds_set_current_name);
2142 DrawInitText("Loading sounds:", 120, FC_GREEN);
2145 printf("DEBUG: reloading %d sounds ...\n", num_sounds);
2148 for(i=0; i<num_sounds; i++)
2151 DrawInitText(sound_effect[i].text, 150, FC_YELLOW);
2153 if (sound_effect[i].filename)
2154 LoadSoundToList(sound_effect[i].filename, i);
2156 LoadSoundToList(sound_effect[i].default_filename, i);
2159 draw_init_text = FALSE;
2162 printf("list size == %d\n", getNumNodes(SoundFileList));
2166 dumpList(SoundFileList);
2170 static void ReloadCustomMusic()
2173 printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current_name);
2177 /* this is done directly in LoadCustomMusic() now */
2184 void InitReloadSounds(char *set_name)
2186 if (!audio.sound_available)
2189 #if defined(AUDIO_UNIX_NATIVE)
2190 WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_SOUNDS);
2192 ReloadCustomSounds();
2196 void InitReloadMusic(char *set_name)
2198 if (!audio.music_available)
2201 #if defined(AUDIO_UNIX_NATIVE)
2202 WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_MUSIC);
2204 ReloadCustomMusic();
2208 void FreeSound(void *ptr)
2210 SoundInfo *sound = (SoundInfo *)ptr;
2215 if (sound->data_ptr)
2217 #if defined(TARGET_SDL)
2218 Mix_FreeChunk(sound->data_ptr);
2219 #elif defined(TARGET_ALLEGRO)
2220 destroy_sample(sound->data_ptr);
2221 #else /* AUDIO_UNIX_NATIVE */
2222 free(sound->data_ptr);
2226 if (sound->source_filename)
2227 free(sound->source_filename);
2232 void FreeMusic(MusicInfo *music)
2237 if (music->data_ptr)
2239 #if defined(TARGET_SDL)
2240 if (music->type == MUS_TYPE_MOD)
2241 Mix_FreeMusic(music->data_ptr);
2243 Mix_FreeChunk(music->data_ptr);
2244 #elif defined(TARGET_ALLEGRO)
2245 destroy_sample(music->data_ptr);
2246 #else /* AUDIO_UNIX_NATIVE */
2247 free(music->data_ptr);
2254 void FreeAllSounds()
2262 printf("%s: FREEING SOUNDS ...\n",
2263 IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
2266 for(i=0; i<num_sounds; i++)
2267 deleteSoundEntry(&Sound[i]);
2269 FreeSound(Sound[i]);
2273 printf("%s: FREEING SOUNDS -- DONE\n",
2274 IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
2290 for(i=0; i<num_music; i++)
2291 FreeMusic(Music[i]);
2299 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2300 /* ========================================================================= */