1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2006 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
14 #include <sys/types.h>
26 #if defined(PLATFORM_LINUX)
27 #include <sys/ioctl.h>
28 #include <linux/soundcard.h>
29 #elif defined(PLATFORM_FREEBSD)
30 #include <machine/soundcard.h>
31 #elif defined(PLATFORM_NETBSD)
32 #include <sys/ioctl.h>
33 #include <sys/audioio.h>
34 #elif defined(PLATFORM_HPUX)
35 #include <sys/audio.h>
45 /* expiration time (in milliseconds) for sound loops */
46 #define SOUND_LOOP_EXPIRATION_TIME 200
48 /* one second fading interval == 1000 ticks (milliseconds) */
49 #define SOUND_FADING_INTERVAL 1000
51 #if defined(AUDIO_STREAMING_DSP)
52 #define SOUND_FADING_VOLUME_STEP (SOUND_MAX_VOLUME / 40)
53 #define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2)
56 #define SND_TYPE_NONE 0
57 #define SND_TYPE_WAV 1
59 #define MUS_TYPE_NONE 0
60 #define MUS_TYPE_WAV 1
61 #define MUS_TYPE_MOD 2
63 #define DEVICENAME_DSP "/dev/dsp"
64 #define DEVICENAME_SOUND_DSP "/dev/sound/dsp"
65 #define DEVICENAME_AUDIO "/dev/audio"
66 #define DEVICENAME_AUDIOCTL "/dev/audioCtl"
68 #define SOUND_VOLUME_LEFT(x) (stereo_volume[x])
69 #define SOUND_VOLUME_RIGHT(x) (stereo_volume[SOUND_MAX_LEFT2RIGHT-x])
71 #define SAME_SOUND_NR(x,y) ((x).nr == (y).nr)
72 #define SAME_SOUND_DATA(x,y) ((x).data_ptr == (y).data_ptr)
74 #define SOUND_VOLUME_FROM_PERCENT(v,p) ((p) < 0 ? SOUND_MIN_VOLUME : \
78 #define SOUND_VOLUME_SIMPLE(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_simple)
79 #define SOUND_VOLUME_LOOPS(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_loops)
80 #define SOUND_VOLUME_MUSIC(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_music)
82 #define SETUP_SOUND_VOLUME(v,s) ((s) == SND_CTRL_PLAY_MUSIC ? \
83 SOUND_VOLUME_MUSIC(v) : \
84 (s) == SND_CTRL_PLAY_LOOP ? \
85 SOUND_VOLUME_LOOPS(v) : \
86 SOUND_VOLUME_SIMPLE(v))
89 #if defined(AUDIO_UNIX_NATIVE)
90 struct SoundHeader_WAV
92 unsigned short compression_code;
93 unsigned short num_channels;
94 unsigned int sample_rate;
95 unsigned int bytes_per_second;
96 unsigned short block_align;
97 unsigned short bits_per_sample;
101 struct AudioFormatInfo
103 boolean stereo; /* availability of stereo sound */
104 int format; /* size and endianess of sample data */
105 int sample_rate; /* sample frequency */
106 int fragment_size; /* audio device fragment size in bytes */
111 char *source_filename;
116 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
117 int data_len; /* number of samples, NOT number of bytes */
118 int num_channels; /* mono: 1 channel, stereo: 2 channels */
120 typedef struct SampleInfo SoundInfo;
121 typedef struct SampleInfo MusicInfo;
133 unsigned int playing_starttime;
134 unsigned int playing_pos;
138 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
139 int data_len; /* number of samples, NOT number of bytes */
140 int num_channels; /* mono: 1 channel, stereo: 2 channels */
142 typedef struct SoundControl SoundControl;
144 static struct ArtworkListInfo *sound_info = NULL;
145 static struct ArtworkListInfo *music_info = NULL;
147 static MusicInfo **Music_NoConf = NULL;
149 static int num_music_noconf = 0;
150 static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
153 /* ========================================================================= */
154 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
156 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
157 static int mixer_active_channels = 0;
159 #if defined(AUDIO_UNIX_NATIVE)
160 static struct AudioFormatInfo afmt;
162 static void Mixer_Main(void);
163 #if !defined(AUDIO_STREAMING_DSP)
164 static unsigned char linear_to_ulaw(int);
165 static int ulaw_to_linear(unsigned char);
169 static void ReloadCustomSounds();
170 static void ReloadCustomMusic();
171 static void FreeSound(void *);
172 static void FreeMusic(void *);
173 static void FreeAllMusic_NoConf();
175 static SoundInfo *getSoundInfoEntryFromSoundID(int);
176 static MusicInfo *getMusicInfoEntryFromMusicID(int);
179 /* ------------------------------------------------------------------------- */
180 /* functions for native (non-SDL) Unix audio/mixer support */
181 /* ------------------------------------------------------------------------- */
183 #if defined(AUDIO_UNIX_NATIVE)
185 static int OpenAudioDevice(char *audio_device_name)
189 /* check if desired audio device is accessible */
190 if (access(audio_device_name, W_OK) != 0)
193 /* try to open audio device in non-blocking mode */
194 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
195 return audio_device_fd;
197 /* re-open audio device in blocking mode */
198 close(audio_device_fd);
199 audio_device_fd = open(audio_device_name, O_WRONLY);
201 return audio_device_fd;
204 static void CloseAudioDevice(int *audio_device_fd)
206 if (*audio_device_fd == 0)
209 close(*audio_device_fd);
210 *audio_device_fd = -1;
213 static boolean TestAudioDevices(void)
215 static char *audio_device_name[] =
218 DEVICENAME_SOUND_DSP,
221 int audio_device_fd = -1;
224 /* look for available audio devices, starting with preferred ones */
225 for (i = 0; i < sizeof(audio_device_name)/sizeof(char *); i++)
226 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
229 if (audio_device_fd < 0)
231 Error(ERR_WARN, "cannot open audio device -- no sound");
235 close(audio_device_fd);
237 audio.device_name = audio_device_name[i];
242 static boolean ForkAudioProcess(void)
244 if (pipe(audio.mixer_pipe) < 0)
246 Error(ERR_WARN, "cannot create pipe -- no sounds");
250 if ((audio.mixer_pid = fork()) < 0)
252 Error(ERR_WARN, "cannot create sound server process -- no sounds");
256 if (audio.mixer_pid == 0) /* we are the child process */
257 audio.mixer_pid = getpid();
259 if (IS_CHILD_PROCESS())
260 Mixer_Main(); /* this function never returns */
262 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
267 void UnixOpenAudio(void)
269 if (!TestAudioDevices())
272 audio.sound_available = TRUE;
273 audio.sound_enabled = TRUE;
275 #if defined(AUDIO_STREAMING_DSP)
276 audio.music_available = TRUE;
277 audio.loops_available = TRUE;
280 audio.num_channels = NUM_MIXER_CHANNELS;
281 audio.music_channel = MUSIC_CHANNEL;
282 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
285 void UnixCloseAudio(void)
288 close(audio.device_fd);
290 if (IS_PARENT_PROCESS() && HAS_CHILD_PROCESS())
291 kill(audio.mixer_pid, SIGTERM);
295 /* ------------------------------------------------------------------------- */
296 /* functions for platform specific audio device initialization */
297 /* ------------------------------------------------------------------------- */
299 #if defined(AUDIO_LINUX_IOCTL)
300 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
302 /* "ioctl()" expects pointer to 'int' value for stereo flag
303 (boolean is defined as 'char', which will not work here) */
304 unsigned int fragment_spec = 0;
305 int fragment_size_query = -1;
314 /* supported audio format in preferred order */
315 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
316 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
317 { AFMT_U8, AUDIO_FORMAT_U8 },
322 /* determine logarithm (log2) of the fragment size */
323 while ((1 << fragment_spec) < afmt->fragment_size)
326 /* use two fragments (play one fragment, prepare the other);
327 one fragment would result in interrupted audio output, more
328 than two fragments would raise audio output latency to much */
329 fragment_spec |= 0x00020000;
331 /* Example for fragment specification:
332 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
333 - (with stereo the effective buffer size will shrink to 256)
334 => fragment_size = 0x00020009 */
336 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
337 Error(ERR_EXIT_SOUND_SERVER,
338 "cannot set fragment size of audio device -- no sounds");
342 while (formats[i].format_result != -1)
344 unsigned int audio_format = formats[i].format_ioctl;
345 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
347 afmt->format = formats[i].format_result;
352 if (afmt->format == 0) /* no supported audio format found */
353 Error(ERR_EXIT_SOUND_SERVER,
354 "cannot set audio format of audio device -- no sounds");
356 /* try if we can use stereo sound */
358 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
359 afmt->stereo = FALSE;
361 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
362 Error(ERR_EXIT_SOUND_SERVER,
363 "cannot set sample rate of audio device -- no sounds");
365 /* get the real fragmentation size; this should return 512 */
366 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
367 Error(ERR_EXIT_SOUND_SERVER,
368 "cannot get fragment size of audio device -- no sounds");
369 if (fragment_size_query != afmt->fragment_size)
370 Error(ERR_EXIT_SOUND_SERVER,
371 "cannot set fragment size of audio device -- no sounds");
373 #endif /* AUDIO_LINUX_IOCTL */
375 #if defined(PLATFORM_NETBSD)
376 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
379 boolean stereo = TRUE;
381 AUDIO_INITINFO(&a_info);
382 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
383 a_info.play.precision = 8;
384 a_info.play.channels = 2;
385 a_info.play.sample_rate = afmt->sample_rate;
386 a_info.blocksize = afmt->fragment_size;
388 afmt->format = AUDIO_FORMAT_U8;
391 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
393 /* try to disable stereo */
394 a_info.play.channels = 1;
396 afmt->stereo = FALSE;
398 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
399 Error(ERR_EXIT_SOUND_SERVER,
400 "cannot set sample rate of audio device -- no sounds");
403 #endif /* PLATFORM_NETBSD */
405 #if defined(PLATFORM_HPUX)
406 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
408 struct audio_describe ainfo;
411 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
413 Error(ERR_EXIT_SOUND_SERVER, "cannot open audio device -- no sounds");
415 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
416 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
418 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
419 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
421 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
422 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
424 afmt->format = AUDIO_FORMAT_U8;
425 afmt->stereo = FALSE;
426 afmt->sample_rate = 8000;
430 #endif /* PLATFORM_HPUX */
432 static void InitAudioDevice(struct AudioFormatInfo *afmt)
435 afmt->format = AUDIO_FORMAT_UNKNOWN;
436 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
437 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
439 #if defined(AUDIO_LINUX_IOCTL)
440 InitAudioDevice_Linux(afmt);
441 #elif defined(PLATFORM_NETBSD)
442 InitAudioDevice_NetBSD(afmt);
443 #elif defined(PLATFORM_HPUX)
444 InitAudioDevice_HPUX(afmt);
446 /* generic /dev/audio stuff might be placed here */
451 /* ------------------------------------------------------------------------- */
452 /* functions for communication between main process and sound mixer process */
453 /* ------------------------------------------------------------------------- */
455 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
457 if (IS_CHILD_PROCESS())
460 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
462 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
463 audio.sound_available = audio.sound_enabled = FALSE;
468 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
470 if (IS_PARENT_PROCESS())
473 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
474 != sizeof(SoundControl))
475 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
478 static void WriteReloadInfoToPipe(char *set_identifier, int type)
480 SoundControl snd_ctrl;
481 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
482 artwork.mus_current);
483 unsigned int str_size1 = strlen(leveldir_current->fullpath) + 1;
484 unsigned int str_size2 = strlen(leveldir_current->sounds_path) + 1;
485 unsigned int str_size3 = strlen(leveldir_current->music_path) + 1;
486 unsigned int str_size4 = strlen(ti->basepath) + 1;
487 unsigned int str_size5 = strlen(ti->fullpath) + 1;
488 boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
489 gfx.override_level_sounds :
490 gfx.override_level_music);
492 if (IS_CHILD_PROCESS())
495 if (leveldir_current == NULL) /* should never happen */
496 Error(ERR_EXIT, "leveldir_current == NULL");
498 clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */
500 snd_ctrl.active = FALSE;
501 snd_ctrl.state = type;
502 snd_ctrl.data_len = strlen(set_identifier) + 1;
504 if (write(audio.mixer_pipe[1], &snd_ctrl,
505 sizeof(snd_ctrl)) < 0 ||
506 write(audio.mixer_pipe[1], set_identifier,
507 snd_ctrl.data_len) < 0 ||
508 write(audio.mixer_pipe[1], &override_level_artwork,
509 sizeof(boolean)) < 0 ||
510 write(audio.mixer_pipe[1], leveldir_current,
511 sizeof(TreeInfo)) < 0 ||
512 write(audio.mixer_pipe[1], ti,
513 sizeof(TreeInfo)) < 0 ||
514 write(audio.mixer_pipe[1], &str_size1,
515 sizeof(unsigned int)) < 0 ||
516 write(audio.mixer_pipe[1], &str_size2,
517 sizeof(unsigned int)) < 0 ||
518 write(audio.mixer_pipe[1], &str_size3,
519 sizeof(unsigned int)) < 0 ||
520 write(audio.mixer_pipe[1], &str_size4,
521 sizeof(unsigned int)) < 0 ||
522 write(audio.mixer_pipe[1], &str_size5,
523 sizeof(unsigned int)) < 0 ||
524 write(audio.mixer_pipe[1], leveldir_current->fullpath,
526 write(audio.mixer_pipe[1], leveldir_current->sounds_path,
528 write(audio.mixer_pipe[1], leveldir_current->music_path,
530 write(audio.mixer_pipe[1], ti->basepath,
532 write(audio.mixer_pipe[1], ti->fullpath,
535 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
536 audio.sound_available = audio.sound_enabled = FALSE;
541 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
543 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
544 &artwork.snd_current : &artwork.mus_current);
545 TreeInfo *ti = *ti_ptr;
546 unsigned int str_size1, str_size2, str_size3, str_size4, str_size5;
547 static char *set_identifier = NULL;
548 boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
549 &gfx.override_level_sounds :
550 &gfx.override_level_music);
552 checked_free(set_identifier);
554 set_identifier = checked_malloc(snd_ctrl->data_len);
556 if (leveldir_current == NULL)
557 leveldir_current = checked_calloc(sizeof(TreeInfo));
560 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
562 checked_free(leveldir_current->fullpath);
563 checked_free(leveldir_current->sounds_path);
564 checked_free(leveldir_current->music_path);
565 checked_free(ti->basepath);
566 checked_free(ti->fullpath);
568 if (read(audio.mixer_pipe[0], set_identifier,
569 snd_ctrl->data_len) != snd_ctrl->data_len ||
570 read(audio.mixer_pipe[0], override_level_artwork,
571 sizeof(boolean)) != sizeof(boolean) ||
572 read(audio.mixer_pipe[0], leveldir_current,
573 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
574 read(audio.mixer_pipe[0], ti,
575 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
576 read(audio.mixer_pipe[0], &str_size1,
577 sizeof(unsigned int)) != sizeof(unsigned int) ||
578 read(audio.mixer_pipe[0], &str_size2,
579 sizeof(unsigned int)) != sizeof(unsigned int) ||
580 read(audio.mixer_pipe[0], &str_size3,
581 sizeof(unsigned int)) != sizeof(unsigned int) ||
582 read(audio.mixer_pipe[0], &str_size4,
583 sizeof(unsigned int)) != sizeof(unsigned int) ||
584 read(audio.mixer_pipe[0], &str_size5,
585 sizeof(unsigned int)) != sizeof(unsigned int))
586 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
588 leveldir_current->fullpath = checked_calloc(str_size1);
589 leveldir_current->sounds_path = checked_calloc(str_size2);
590 leveldir_current->music_path = checked_calloc(str_size3);
591 ti->basepath = checked_calloc(str_size4);
592 ti->fullpath = checked_calloc(str_size5);
594 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
595 str_size1) != str_size1 ||
596 read(audio.mixer_pipe[0], leveldir_current->sounds_path,
597 str_size2) != str_size2 ||
598 read(audio.mixer_pipe[0], leveldir_current->music_path,
599 str_size3) != str_size3 ||
600 read(audio.mixer_pipe[0], ti->basepath,
601 str_size4) != str_size4 ||
602 read(audio.mixer_pipe[0], ti->fullpath,
603 str_size5) != str_size5)
604 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
606 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
607 artwork.snd_current_identifier = set_identifier;
609 artwork.mus_current_identifier = set_identifier;
612 #endif /* AUDIO_UNIX_NATIVE */
615 /* ------------------------------------------------------------------------- */
616 /* mixer functions */
617 /* ------------------------------------------------------------------------- */
619 void Mixer_InitChannels()
623 for (i = 0; i < audio.num_channels; i++)
624 mixer[i].active = FALSE;
625 mixer_active_channels = 0;
628 static void Mixer_ResetChannelExpiration(int channel)
630 mixer[channel].playing_starttime = Counter();
632 #if defined(TARGET_SDL)
633 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
634 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
638 static boolean Mixer_ChannelExpired(int channel)
640 if (!mixer[channel].active)
643 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
644 DelayReached(&mixer[channel].playing_starttime,
645 SOUND_LOOP_EXPIRATION_TIME))
648 #if defined(TARGET_SDL)
649 if (!Mix_Playing(channel))
656 static boolean Mixer_AllocateChannel(int channel)
661 static void Mixer_SetChannelProperties(int channel)
663 #if defined(TARGET_SDL)
664 Mix_Volume(channel, mixer[channel].volume);
665 Mix_SetPanning(channel,
666 SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
667 SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
671 static void Mixer_StartChannel(int channel)
673 #if defined(TARGET_SDL)
674 Mix_PlayChannel(channel, mixer[channel].data_ptr,
675 IS_LOOP(mixer[channel]) ? -1 : 0);
679 static void Mixer_PlayChannel(int channel)
681 /* start with inactive channel in case something goes wrong */
682 mixer[channel].active = FALSE;
684 if (mixer[channel].type != MUS_TYPE_WAV)
687 if (!Mixer_AllocateChannel(channel))
690 Mixer_SetChannelProperties(channel);
691 Mixer_StartChannel(channel);
693 Mixer_ResetChannelExpiration(channel);
695 mixer[channel].playing_pos = 0;
696 mixer[channel].active = TRUE;
697 mixer_active_channels++;
700 static void Mixer_PlayMusicChannel()
702 Mixer_PlayChannel(audio.music_channel);
704 #if defined(TARGET_SDL)
705 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
707 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
708 this looks like a bug in the SDL_mixer library */
709 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
710 Mix_VolumeMusic(mixer[audio.music_channel].volume);
715 static void Mixer_StopChannel(int channel)
717 if (!mixer[channel].active)
720 #if defined(TARGET_SDL)
721 Mix_HaltChannel(channel);
724 mixer[channel].active = FALSE;
725 mixer_active_channels--;
728 static void Mixer_StopMusicChannel()
730 Mixer_StopChannel(audio.music_channel);
732 #if defined(TARGET_SDL)
737 static void Mixer_FadeChannel(int channel)
739 if (!mixer[channel].active)
742 mixer[channel].state |= SND_CTRL_FADE;
744 #if defined(TARGET_SDL)
745 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
749 static void Mixer_FadeMusicChannel()
751 Mixer_FadeChannel(audio.music_channel);
753 #if defined(TARGET_SDL)
754 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
758 static void Mixer_UnFadeChannel(int channel)
760 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
763 mixer[channel].state &= ~SND_CTRL_FADE;
764 mixer[channel].volume = SOUND_MAX_VOLUME;
766 #if defined(TARGET_SDL)
767 Mix_ExpireChannel(channel, -1);
768 Mix_Volume(channel, mixer[channel].volume);
772 static void Mixer_InsertSound(SoundControl snd_ctrl)
776 int num_sounds = getSoundListSize();
777 int num_music = getMusicListSize();
779 if (IS_MUSIC(snd_ctrl))
781 if (snd_ctrl.nr >= num_music) /* invalid music */
784 if (snd_ctrl.nr < 0) /* undefined music */
786 if (num_music_noconf == 0) /* no fallback music available */
789 snd_ctrl.nr = UNMAP_NOCONF_MUSIC(snd_ctrl.nr) % num_music_noconf;
790 snd_info = Music_NoConf[snd_ctrl.nr];
793 snd_info = getMusicInfoEntryFromMusicID(snd_ctrl.nr);
797 if (snd_ctrl.nr < 0 || snd_ctrl.nr >= num_sounds)
800 snd_info = getSoundInfoEntryFromSoundID(snd_ctrl.nr);
803 if (snd_info == NULL)
806 /* copy sound sample and format information */
807 snd_ctrl.type = snd_info->type;
808 snd_ctrl.format = snd_info->format;
809 snd_ctrl.data_ptr = snd_info->data_ptr;
810 snd_ctrl.data_len = snd_info->data_len;
811 snd_ctrl.num_channels = snd_info->num_channels;
813 /* play music samples on a dedicated music channel */
814 if (IS_MUSIC(snd_ctrl))
816 Mixer_StopMusicChannel();
818 mixer[audio.music_channel] = snd_ctrl;
819 Mixer_PlayMusicChannel();
824 /* check if (and how often) this sound sample is already playing */
825 for (k = 0, i = audio.first_sound_channel; i < audio.num_channels; i++)
826 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
829 /* reset expiration delay for already playing loop sounds */
830 if (k > 0 && IS_LOOP(snd_ctrl))
832 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
834 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
836 if (IS_FADING(mixer[i]))
837 Mixer_UnFadeChannel(i);
839 /* restore settings like volume and stereo position */
840 mixer[i].volume = snd_ctrl.volume;
841 mixer[i].stereo_position = snd_ctrl.stereo_position;
843 Mixer_SetChannelProperties(i);
844 Mixer_ResetChannelExpiration(i);
851 /* don't play sound more than n times simultaneously (with n == 2 for now) */
854 unsigned int playing_current = Counter();
855 int longest = 0, longest_nr = audio.first_sound_channel;
857 /* look for oldest equal sound */
858 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
860 int playing_time = playing_current - mixer[i].playing_starttime;
863 if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
866 actual = 1000 * playing_time / mixer[i].data_len;
868 if (actual >= longest)
875 Mixer_StopChannel(longest_nr);
878 /* If all (non-music) channels are active, stop the channel that has
879 played its sound sample most completely (in percent of the sample
880 length). As we cannot currently get the actual playing position
881 of the channel's sound sample when compiling with the SDL mixer
882 library, we use the current playing time (in milliseconds) instead. */
885 /* channel allocation sanity check -- should not be needed */
886 if (mixer_active_channels ==
887 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
889 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
891 if (!mixer[i].active)
893 Error(ERR_INFO, "Mixer_InsertSound: Channel %d inactive", i);
894 Error(ERR_INFO, "Mixer_InsertSound: This should never happen!");
896 mixer_active_channels--;
902 if (mixer_active_channels ==
903 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
905 unsigned int playing_current = Counter();
906 int longest = 0, longest_nr = audio.first_sound_channel;
910 /* print some debugging information about audio channel usage */
911 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
913 Error(ERR_INFO, "Mixer_InsertSound: %d [%d]: %d (%d)",
914 i, mixer[i].active, mixer[i].data_len, (int)mixer[i].data_ptr);
919 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
921 int playing_time = playing_current - mixer[i].playing_starttime;
922 int actual = 1000 * playing_time / mixer[i].data_len;
924 if (!IS_LOOP(mixer[i]) && actual > longest)
931 Mixer_StopChannel(longest_nr);
934 /* add the new sound to the mixer */
935 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
937 if (!mixer[i].active)
939 #if defined(AUDIO_UNIX_NATIVE)
940 if (snd_info->data_len == 0)
942 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
947 Mixer_PlayChannel(i);
954 static void HandleSoundRequest(SoundControl snd_ctrl)
958 #if defined(AUDIO_UNIX_NATIVE)
959 if (IS_PARENT_PROCESS())
961 SendSoundControlToMixerProcess(&snd_ctrl);
966 /* deactivate channels that have expired since the last request */
967 for (i = 0; i < audio.num_channels; i++)
968 if (mixer[i].active && Mixer_ChannelExpired(i))
969 Mixer_StopChannel(i);
971 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
973 Mixer_StopMusicChannel();
974 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
975 Mixer_StopChannel(i);
977 #if defined(AUDIO_UNIX_NATIVE)
978 CloseAudioDevice(&audio.device_fd);
979 ReadReloadInfoFromPipe(&snd_ctrl);
982 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
983 ReloadCustomSounds();
987 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
989 if (IS_MUSIC(snd_ctrl))
991 Mixer_FadeMusicChannel();
995 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
996 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
997 Mixer_FadeChannel(i);
999 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
1001 if (IS_MUSIC(snd_ctrl))
1003 Mixer_StopMusicChannel();
1007 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1008 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1009 Mixer_StopChannel(i);
1011 #if defined(AUDIO_UNIX_NATIVE)
1012 if (!mixer_active_channels)
1013 CloseAudioDevice(&audio.device_fd);
1016 else if (snd_ctrl.active) /* add new sound to mixer */
1018 Mixer_InsertSound(snd_ctrl);
1022 void StartMixer(void)
1027 SDL_version compile_version;
1028 const SDL_version *link_version;
1029 MIX_VERSION(&compile_version);
1030 printf("compiled with SDL_mixer version: %d.%d.%d\n",
1031 compile_version.major,
1032 compile_version.minor,
1033 compile_version.patch);
1034 link_version = Mix_Linked_Version();
1035 printf("running with SDL_mixer version: %d.%d.%d\n",
1036 link_version->major,
1037 link_version->minor,
1038 link_version->patch);
1041 if (!audio.sound_available)
1044 /* initialize stereo position conversion information */
1045 for (i = 0; i <= SOUND_MAX_LEFT2RIGHT; i++)
1047 (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1049 #if defined(AUDIO_UNIX_NATIVE)
1050 if (!ForkAudioProcess())
1051 audio.sound_available = FALSE;
1055 #if defined(AUDIO_UNIX_NATIVE)
1057 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1058 int sample_pos, int sample_size,
1059 short *buffer_base_ptr, int buffer_pos,
1060 int num_output_channels)
1062 short *buffer_ptr = buffer_base_ptr + num_output_channels * buffer_pos;
1063 int num_channels = snd_ctrl->num_channels;
1064 int stepsize = num_channels;
1065 int output_stepsize = num_output_channels;
1068 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1070 byte *sample_ptr = (byte *)snd_ctrl->data_ptr + num_channels * sample_pos;
1072 for (i = 0; i < num_output_channels; i++)
1074 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1076 for (j = 0; j < sample_size; j++)
1077 buffer_ptr[output_stepsize * j + i] =
1078 ((short)(sample_ptr[stepsize * j + offset] ^ 0x80)) << 8;
1081 else /* AUDIO_FORMAT_S16 */
1083 short *sample_ptr= (short *)snd_ctrl->data_ptr + num_channels * sample_pos;
1085 for (i = 0; i < num_output_channels; i++)
1087 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1089 for (j = 0; j < sample_size; j++)
1090 buffer_ptr[output_stepsize * j + i] =
1091 sample_ptr[stepsize * j + offset];
1096 #if defined(AUDIO_STREAMING_DSP)
1097 static void Mixer_Main_DSP()
1099 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1100 static int premix_last_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1101 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1105 int max_sample_size;
1106 int num_output_channels;
1109 if (!mixer_active_channels)
1112 if (audio.device_fd < 0)
1114 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1117 InitAudioDevice(&afmt);
1120 stereo = afmt.stereo;
1121 fragment_size = afmt.fragment_size;
1122 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1123 num_output_channels = (stereo ? 2 : 1);
1124 max_sample_size = fragment_size / (num_output_channels * sample_bytes);
1126 /* first clear the last premixing buffer */
1127 clear_mem(premix_last_buffer,
1128 max_sample_size * num_output_channels * sizeof(int));
1130 for (i = 0; i < audio.num_channels; i++)
1132 // void *sample_ptr;
1137 if (!mixer[i].active)
1140 if (Mixer_ChannelExpired(i))
1142 Mixer_StopChannel(i);
1146 /* pointer, lenght and actual playing position of sound sample */
1147 // sample_ptr = mixer[i].data_ptr;
1148 sample_len = mixer[i].data_len;
1149 sample_pos = mixer[i].playing_pos;
1150 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1151 mixer[i].playing_pos += sample_size;
1153 /* copy original sample to first mixing buffer */
1154 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1155 premix_first_buffer, 0, num_output_channels);
1157 /* are we about to restart a looping sound? */
1158 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1160 while (sample_size < max_sample_size)
1162 int restarted_sample_size =
1163 MIN(max_sample_size - sample_size, sample_len);
1165 CopySampleToMixingBuffer(&mixer[i], 0, restarted_sample_size,
1166 premix_first_buffer, sample_size,
1167 num_output_channels);
1169 mixer[i].playing_pos = restarted_sample_size;
1170 sample_size += restarted_sample_size;
1174 /* decrease volume if sound is fading out */
1175 if (IS_FADING(mixer[i]) &&
1176 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1177 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1179 /* adjust volume of actual sound sample */
1180 if (mixer[i].volume != SOUND_MAX_VOLUME)
1181 for (j = 0; j < sample_size * num_output_channels; j++)
1182 premix_first_buffer[j] =
1183 mixer[i].volume * (int)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1185 /* adjust left and right channel volume due to stereo sound position */
1188 int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1189 int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1191 for (j = 0; j < sample_size; j++)
1193 premix_first_buffer[2 * j + 0] =
1194 left_volume * premix_first_buffer[2 * j + 0] / SOUND_MAX_LEFT2RIGHT;
1195 premix_first_buffer[2 * j + 1] =
1196 right_volume * premix_first_buffer[2 * j + 1] / SOUND_MAX_LEFT2RIGHT;
1200 /* fill the last mixing buffer with stereo or mono sound */
1201 for (j = 0; j < sample_size * num_output_channels; j++)
1202 premix_last_buffer[j] += premix_first_buffer[j];
1204 /* delete completed sound entries from the mixer */
1205 if (mixer[i].playing_pos >= mixer[i].data_len)
1207 if (IS_LOOP(mixer[i]))
1208 mixer[i].playing_pos = 0;
1210 Mixer_StopChannel(i);
1212 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1213 Mixer_StopChannel(i);
1216 /* prepare final playing buffer according to system audio format */
1217 for (i = 0; i < max_sample_size * num_output_channels; i++)
1219 /* cut off at 17 bit value */
1220 if (premix_last_buffer[i] < -65535)
1221 premix_last_buffer[i] = -65535;
1222 else if (premix_last_buffer[i] > 65535)
1223 premix_last_buffer[i] = 65535;
1225 /* shift to 16 bit value */
1226 premix_last_buffer[i] >>= 1;
1228 if (afmt.format & AUDIO_FORMAT_U8)
1230 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1232 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1234 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1235 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1237 else /* big endian */
1239 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1240 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1244 /* finally play the sound fragment */
1245 if (write(audio.device_fd, playing_buffer, fragment_size) == -1)
1246 Error(ERR_WARN, "write() failed; %s", strerror(errno));
1248 if (!mixer_active_channels)
1249 CloseAudioDevice(&audio.device_fd);
1252 #else /* !AUDIO_STREAMING_DSP */
1254 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1256 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1257 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1258 int max_sample_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
1259 int num_output_channels = 1;
1268 /* pointer, lenght and actual playing position of sound sample */
1269 sample_ptr = mixer[i].data_ptr;
1270 sample_len = mixer[i].data_len;
1271 sample_pos = mixer[i].playing_pos;
1272 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1273 mixer[i].playing_pos += sample_size;
1275 /* copy original sample to first mixing buffer */
1276 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1277 premix_first_buffer, 0, num_output_channels);
1279 /* adjust volume of actual sound sample */
1280 if (mixer[i].volume != SOUND_MAX_VOLUME)
1281 for (j = 0; j < sample_size; j++)
1282 premix_first_buffer[j] =
1283 mixer[i].volume * (int)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1285 /* might be needed for u-law /dev/audio */
1286 for (j = 0; j < sample_size; j++)
1288 linear_to_ulaw(premix_first_buffer[j]);
1290 /* delete completed sound entries from the mixer */
1291 if (mixer[i].playing_pos >= mixer[i].data_len)
1292 Mixer_StopChannel(i);
1294 for (i = 0; i < sample_size; i++)
1295 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1297 /* finally play the sound fragment */
1298 write(audio.device_fd, playing_buffer, sample_size);
1302 #endif /* !AUDIO_STREAMING_DSP */
1306 SoundControl snd_ctrl;
1309 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1311 Mixer_InitChannels();
1313 #if defined(PLATFORM_HPUX)
1314 InitAudioDevice(&afmt);
1317 FD_ZERO(&mixer_fdset);
1318 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1320 while (1) /* wait for sound playing commands from client */
1322 struct timeval delay = { 0, 0 };
1324 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1325 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1326 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1329 ReadSoundControlFromMainProcess(&snd_ctrl);
1331 HandleSoundRequest(snd_ctrl);
1333 #if defined(AUDIO_STREAMING_DSP)
1335 while (mixer_active_channels &&
1336 select(audio.mixer_pipe[0] + 1,
1337 &mixer_fdset, NULL, NULL, &delay) < 1)
1339 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1344 #else /* !AUDIO_STREAMING_DSP */
1346 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1347 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1350 InitAudioDevice(&afmt);
1355 while (mixer_active_channels &&
1356 select(audio.mixer_pipe[0] + 1,
1357 &mixer_fdset, NULL, NULL, &delay) < 1)
1359 int wait_percent = 90; /* wait 90% of the real playing time */
1362 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1364 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1368 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1371 CloseAudioDevice(&audio.device_fd);
1373 Mixer_InitChannels(); /* remove all sounds from mixer */
1375 #endif /* !AUDIO_STREAMING_DSP */
1378 #endif /* AUDIO_UNIX_NATIVE */
1381 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1383 /* these two are stolen from "sox"... :) */
1386 ** This routine converts from linear to ulaw.
1388 ** Craig Reese: IDA/Supercomputing Research Center
1389 ** Joe Campbell: Department of Defense
1390 ** 29 September 1989
1393 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1394 ** 2) "A New Digital Technique for Implementation of Any
1395 ** Continuous PCM Companding Law," Villeret, Michel,
1396 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1397 ** 1973, pg. 11.12-11.17
1398 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1399 ** for Analog-to_Digital Conversion Techniques,"
1402 ** Input: Signed 16 bit linear sample
1403 ** Output: 8 bit ulaw sample
1406 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1407 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1410 static unsigned char linear_to_ulaw(int sample)
1412 static int exp_lut[256] =
1414 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1415 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1416 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1417 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1418 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1419 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1420 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1421 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1422 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1423 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1424 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1425 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1426 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1427 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1428 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1429 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1432 int sign, exponent, mantissa;
1433 unsigned char ulawbyte;
1435 /* Get the sample into sign-magnitude. */
1436 sign = (sample >> 8) & 0x80; /* set aside the sign */
1438 sample = -sample; /* get magnitude */
1440 sample = CLIP; /* clip the magnitude */
1442 /* Convert from 16 bit linear to ulaw. */
1443 sample = sample + BIAS;
1444 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1445 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1446 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1449 ulawbyte = 0x02; /* optional CCITT trap */
1456 ** This routine converts from ulaw to 16 bit linear.
1458 ** Craig Reese: IDA/Supercomputing Research Center
1459 ** 29 September 1989
1462 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1463 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1464 ** for Analog-to_Digital Conversion Techniques,"
1467 ** Input: 8 bit ulaw sample
1468 ** Output: signed 16 bit linear sample
1471 static int ulaw_to_linear(unsigned char ulawbyte)
1473 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1474 int sign, exponent, mantissa, sample;
1476 ulawbyte = ~ ulawbyte;
1477 sign = ( ulawbyte & 0x80 );
1478 exponent = ( ulawbyte >> 4 ) & 0x07;
1479 mantissa = ulawbyte & 0x0F;
1480 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1486 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1489 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1490 /* ========================================================================= */
1491 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1493 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1494 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1496 static void *Load_WAV(char *filename)
1498 SoundInfo *snd_info;
1499 #if defined(AUDIO_UNIX_NATIVE)
1500 struct SoundHeader_WAV header;
1502 byte sound_header_buffer[WAV_HEADER_SIZE];
1505 char chunk_name[CHUNK_ID_LEN + 1];
1511 if (!audio.sound_available)
1514 snd_info = checked_calloc(sizeof(SoundInfo));
1516 #if defined(TARGET_SDL)
1518 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1520 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1525 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1527 #else /* AUDIO_UNIX_NATIVE */
1529 clear_mem(&header, sizeof(struct SoundHeader_WAV)); /* to make gcc happy */
1531 if ((file = fopen(filename, MODE_READ)) == NULL)
1533 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1538 /* read chunk id "RIFF" */
1539 getFileChunkLE(file, chunk_name, &chunk_size);
1540 if (!strEqual(chunk_name, "RIFF"))
1542 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1548 /* read "RIFF" type id "WAVE" */
1549 getFileChunkLE(file, chunk_name, NULL);
1550 if (!strEqual(chunk_name, "WAVE"))
1552 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1558 while (getFileChunkLE(file, chunk_name, &chunk_size))
1560 if (strEqual(chunk_name, "fmt "))
1562 if (chunk_size < WAV_HEADER_SIZE)
1564 Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1570 header.compression_code = getFile16BitLE(file);
1571 header.num_channels = getFile16BitLE(file);
1572 header.sample_rate = getFile32BitLE(file);
1573 header.bytes_per_second = getFile32BitLE(file);
1574 header.block_align = getFile16BitLE(file);
1575 header.bits_per_sample = getFile16BitLE(file);
1577 if (chunk_size > WAV_HEADER_SIZE)
1578 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1580 if (header.compression_code != 1)
1582 Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1583 filename, header.compression_code);
1589 if (header.num_channels != 1 &&
1590 header.num_channels != 2)
1592 Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
1593 filename, header.num_channels);
1599 if (header.bits_per_sample != 8 &&
1600 header.bits_per_sample != 16)
1602 Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1603 filename, header.bits_per_sample);
1609 /* warn, but accept wrong sample rate (may be only slightly different) */
1610 if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1611 Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1612 filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1615 printf("WAV file: '%s'\n", filename);
1616 printf(" Compression code: %d'\n", header.compression_code);
1617 printf(" Number of channels: %d'\n", header.num_channels);
1618 printf(" Sample rate: %d'\n", header.sample_rate);
1619 printf(" Average bytes per second: %d'\n", header.bytes_per_second);
1620 printf(" Block align: %d'\n", header.block_align);
1621 printf(" Significant bits per sample: %d'\n", header.bits_per_sample);
1624 else if (strEqual(chunk_name, "data"))
1626 data_byte_len = chunk_size;
1628 snd_info->data_len = data_byte_len;
1629 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1631 /* read sound data */
1632 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1635 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1637 free(snd_info->data_ptr);
1642 /* check for odd number of data bytes (data chunk is word aligned) */
1643 if ((data_byte_len % 2) == 1)
1644 ReadUnusedBytesFromFile(file, 1);
1646 else /* unknown chunk -- ignore */
1647 ReadUnusedBytesFromFile(file, chunk_size);
1652 if (snd_info->data_ptr == NULL)
1654 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1659 if (header.bits_per_sample == 8)
1660 snd_info->format = AUDIO_FORMAT_U8;
1661 else /* header.bits_per_sample == 16 */
1663 snd_info->format = AUDIO_FORMAT_S16;
1664 snd_info->data_len /= 2; /* correct number of samples */
1667 snd_info->num_channels = header.num_channels;
1668 if (header.num_channels == 2)
1669 snd_info->data_len /= 2; /* correct number of samples */
1672 if (header.num_channels == 1) /* convert mono sound to stereo */
1674 void *buffer_ptr = checked_malloc(data_byte_len * 2);
1675 void *sample_ptr = snd_info->data_ptr;
1676 int sample_size = snd_info->data_len;
1679 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1680 for (i = 0; i < sample_size; i++)
1682 ((short)(((byte *)sample_ptr)[i] ^ 0x80)) << 8;
1683 else /* AUDIO_FORMAT_S16 */
1684 for (i = 0; i < sample_size; i++)
1686 ((short *)sample_ptr)[i];
1690 #endif /* AUDIO_UNIX_NATIVE */
1692 snd_info->type = SND_TYPE_WAV;
1693 snd_info->source_filename = getStringCopy(filename);
1698 static void *Load_MOD(char *filename)
1700 #if defined(TARGET_SDL)
1701 MusicInfo *mod_info;
1703 if (!audio.sound_available)
1706 mod_info = checked_calloc(sizeof(MusicInfo));
1708 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1710 Error(ERR_WARN, "cannot read music file '%s'", filename);
1715 mod_info->type = MUS_TYPE_MOD;
1716 mod_info->source_filename = getStringCopy(filename);
1724 static void *Load_WAV_or_MOD(char *filename)
1727 if (FileIsMusic(filename))
1728 return Load_MOD(filename);
1729 else if (FileIsSound(filename))
1730 return Load_WAV(filename);
1734 if (FileIsSound(filename))
1735 return Load_WAV(filename);
1736 else if (FileIsMusic(filename))
1737 return Load_MOD(filename);
1745 void LoadCustomMusic_NoConf(void)
1747 static boolean draw_init_text = TRUE; /* only draw at startup */
1748 static char *last_music_directory = NULL;
1749 char *music_directory = getCustomMusicDirectory();
1751 DirectoryEntry *dir_entry;
1752 int num_music = getMusicListSize();
1754 if (!audio.sound_available)
1757 if (last_music_directory != NULL &&
1758 strEqual(last_music_directory, music_directory))
1759 return; /* old and new music directory are the same */
1761 if (last_music_directory != NULL)
1762 free(last_music_directory);
1763 last_music_directory = getStringCopy(music_directory);
1765 FreeAllMusic_NoConf();
1767 if ((dir = openDirectory(music_directory)) == NULL)
1769 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1771 audio.music_available = FALSE;
1777 DrawInitText("Loading music", 120, FC_GREEN);
1779 while ((dir_entry = readDirectory(dir)) != NULL) /* loop all entries */
1781 char *basename = dir_entry->basename;
1782 char *filename = NULL;
1783 MusicInfo *mus_info = NULL;
1784 boolean music_already_used = FALSE;
1787 /* skip all music files that are configured in music config file */
1788 for (i = 0; i < num_music; i++)
1790 struct FileInfo *music = getMusicListEntry(i);
1792 if (strEqual(basename, music->filename))
1794 music_already_used = TRUE;
1799 if (music_already_used)
1803 DrawInitText(basename, 150, FC_YELLOW);
1805 filename = getPath2(music_directory, basename);
1807 if (FileIsMusic(basename))
1808 mus_info = Load_WAV_or_MOD(filename);
1815 Music_NoConf = checked_realloc(Music_NoConf,
1816 num_music_noconf * sizeof(MusicInfo *));
1817 Music_NoConf[num_music_noconf - 1] = mus_info;
1821 closeDirectory(dir);
1823 draw_init_text = FALSE;
1828 void LoadCustomMusic_NoConf(void)
1830 static boolean draw_init_text = TRUE; /* only draw at startup */
1831 static char *last_music_directory = NULL;
1832 char *music_directory = getCustomMusicDirectory();
1834 struct dirent *dir_entry;
1835 int num_music = getMusicListSize();
1837 if (!audio.sound_available)
1840 if (last_music_directory != NULL &&
1841 strEqual(last_music_directory, music_directory))
1842 return; /* old and new music directory are the same */
1844 if (last_music_directory != NULL)
1845 free(last_music_directory);
1846 last_music_directory = getStringCopy(music_directory);
1848 FreeAllMusic_NoConf();
1850 if ((dir = opendir(music_directory)) == NULL)
1852 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1854 audio.music_available = FALSE;
1860 DrawInitText("Loading music", 120, FC_GREEN);
1862 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1864 char *basename = dir_entry->d_name;
1865 char *filename = NULL;
1866 MusicInfo *mus_info = NULL;
1867 boolean music_already_used = FALSE;
1870 /* skip all music files that are configured in music config file */
1871 for (i = 0; i < num_music; i++)
1873 struct FileInfo *music = getMusicListEntry(i);
1875 if (strEqual(basename, music->filename))
1877 music_already_used = TRUE;
1882 if (music_already_used)
1886 DrawInitText(basename, 150, FC_YELLOW);
1888 filename = getPath2(music_directory, basename);
1890 if (FileIsMusic(basename))
1891 mus_info = Load_WAV_or_MOD(filename);
1898 Music_NoConf = checked_realloc(Music_NoConf,
1899 num_music_noconf * sizeof(MusicInfo *));
1900 Music_NoConf[num_music_noconf - 1] = mus_info;
1906 draw_init_text = FALSE;
1911 int getSoundListSize()
1913 return (sound_info->num_file_list_entries +
1914 sound_info->num_dynamic_file_list_entries);
1917 int getMusicListSize()
1919 return (music_info->num_file_list_entries +
1920 music_info->num_dynamic_file_list_entries);
1923 struct FileInfo *getSoundListEntry(int pos)
1925 int num_list_entries = sound_info->num_file_list_entries;
1926 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1928 return (pos < num_list_entries ? &sound_info->file_list[list_pos] :
1929 &sound_info->dynamic_file_list[list_pos]);
1932 struct FileInfo *getMusicListEntry(int pos)
1934 int num_list_entries = music_info->num_file_list_entries;
1935 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1937 return (pos < num_list_entries ? &music_info->file_list[list_pos] :
1938 &music_info->dynamic_file_list[list_pos]);
1941 static SoundInfo *getSoundInfoEntryFromSoundID(int pos)
1943 int num_list_entries = sound_info->num_file_list_entries;
1944 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1945 SoundInfo **snd_info =
1946 (SoundInfo **)(pos < num_list_entries ? sound_info->artwork_list :
1947 sound_info->dynamic_artwork_list);
1949 return snd_info[list_pos];
1952 static MusicInfo *getMusicInfoEntryFromMusicID(int pos)
1954 int num_list_entries = music_info->num_file_list_entries;
1955 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1956 MusicInfo **mus_info =
1957 (MusicInfo **)(pos < num_list_entries ? music_info->artwork_list :
1958 music_info->dynamic_artwork_list);
1960 return mus_info[list_pos];
1963 int getSoundListPropertyMappingSize()
1965 return sound_info->num_property_mapping_entries;
1968 int getMusicListPropertyMappingSize()
1970 return music_info->num_property_mapping_entries;
1973 struct PropertyMapping *getSoundListPropertyMapping()
1975 return sound_info->property_mapping;
1978 struct PropertyMapping *getMusicListPropertyMapping()
1980 return music_info->property_mapping;
1983 void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
1984 struct ConfigTypeInfo *config_suffix_list,
1985 char **base_prefixes, char **ext1_suffixes,
1986 char **ext2_suffixes, char **ext3_suffixes,
1987 char **ignore_tokens)
1991 sound_info = checked_calloc(sizeof(struct ArtworkListInfo));
1992 sound_info->type = ARTWORK_TYPE_SOUNDS;
1994 /* ---------- initialize file list and suffix lists ---------- */
1996 sound_info->num_file_list_entries = num_file_list_entries;
1997 sound_info->num_dynamic_file_list_entries = 0;
1999 sound_info->file_list =
2000 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
2001 num_file_list_entries);
2002 sound_info->dynamic_file_list = NULL;
2004 sound_info->num_suffix_list_entries = 0;
2005 for (i = 0; config_suffix_list[i].token != NULL; i++)
2006 sound_info->num_suffix_list_entries++;
2008 sound_info->suffix_list = config_suffix_list;
2010 /* ---------- initialize base prefix and suffixes lists ---------- */
2012 sound_info->num_base_prefixes = 0;
2013 for (i = 0; base_prefixes[i] != NULL; i++)
2014 sound_info->num_base_prefixes++;
2016 sound_info->num_ext1_suffixes = 0;
2017 for (i = 0; ext1_suffixes[i] != NULL; i++)
2018 sound_info->num_ext1_suffixes++;
2020 sound_info->num_ext2_suffixes = 0;
2021 for (i = 0; ext2_suffixes[i] != NULL; i++)
2022 sound_info->num_ext2_suffixes++;
2024 sound_info->num_ext3_suffixes = 0;
2025 for (i = 0; ext3_suffixes[i] != NULL; i++)
2026 sound_info->num_ext3_suffixes++;
2028 sound_info->num_ignore_tokens = 0;
2029 for (i = 0; ignore_tokens[i] != NULL; i++)
2030 sound_info->num_ignore_tokens++;
2032 sound_info->base_prefixes = base_prefixes;
2033 sound_info->ext1_suffixes = ext1_suffixes;
2034 sound_info->ext2_suffixes = ext2_suffixes;
2035 sound_info->ext3_suffixes = ext3_suffixes;
2036 sound_info->ignore_tokens = ignore_tokens;
2038 sound_info->num_property_mapping_entries = 0;
2040 sound_info->property_mapping = NULL;
2042 /* ---------- initialize artwork reference and content lists ---------- */
2044 sound_info->sizeof_artwork_list_entry = sizeof(SoundInfo *);
2046 sound_info->artwork_list =
2047 checked_calloc(num_file_list_entries * sizeof(SoundInfo *));
2048 sound_info->dynamic_artwork_list = NULL;
2050 sound_info->content_list = NULL;
2052 /* ---------- initialize artwork loading/freeing functions ---------- */
2054 sound_info->load_artwork = Load_WAV;
2055 sound_info->free_artwork = FreeSound;
2058 void InitMusicList(struct ConfigInfo *config_list, int num_file_list_entries,
2059 struct ConfigTypeInfo *config_suffix_list,
2060 char **base_prefixes, char **ext1_suffixes,
2061 char **ext2_suffixes, char **ext3_suffixes,
2062 char **ignore_tokens)
2066 music_info = checked_calloc(sizeof(struct ArtworkListInfo));
2067 music_info->type = ARTWORK_TYPE_MUSIC;
2069 /* ---------- initialize file list and suffix lists ---------- */
2071 music_info->num_file_list_entries = num_file_list_entries;
2072 music_info->num_dynamic_file_list_entries = 0;
2074 music_info->file_list =
2075 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
2076 num_file_list_entries);
2077 music_info->dynamic_file_list = NULL;
2079 music_info->num_suffix_list_entries = 0;
2080 for (i = 0; config_suffix_list[i].token != NULL; i++)
2081 music_info->num_suffix_list_entries++;
2083 music_info->suffix_list = config_suffix_list;
2085 /* ---------- initialize base prefix and suffixes lists ---------- */
2087 music_info->num_base_prefixes = 0;
2088 for (i = 0; base_prefixes[i] != NULL; i++)
2089 music_info->num_base_prefixes++;
2091 music_info->num_ext1_suffixes = 0;
2092 for (i = 0; ext1_suffixes[i] != NULL; i++)
2093 music_info->num_ext1_suffixes++;
2095 music_info->num_ext2_suffixes = 0;
2096 for (i = 0; ext2_suffixes[i] != NULL; i++)
2097 music_info->num_ext2_suffixes++;
2099 music_info->num_ext3_suffixes = 0;
2100 for (i = 0; ext3_suffixes[i] != NULL; i++)
2101 music_info->num_ext3_suffixes++;
2103 music_info->num_ignore_tokens = 0;
2104 for (i = 0; ignore_tokens[i] != NULL; i++)
2105 music_info->num_ignore_tokens++;
2107 music_info->base_prefixes = base_prefixes;
2108 music_info->ext1_suffixes = ext1_suffixes;
2109 music_info->ext2_suffixes = ext2_suffixes;
2110 music_info->ext3_suffixes = ext3_suffixes;
2111 music_info->ignore_tokens = ignore_tokens;
2113 music_info->num_property_mapping_entries = 0;
2115 music_info->property_mapping = NULL;
2117 /* ---------- initialize artwork reference and content lists ---------- */
2119 music_info->sizeof_artwork_list_entry = sizeof(MusicInfo *);
2121 music_info->artwork_list =
2122 checked_calloc(num_file_list_entries * sizeof(MusicInfo *));
2123 music_info->dynamic_artwork_list = NULL;
2125 music_info->content_list = NULL;
2127 /* ---------- initialize artwork loading/freeing functions ---------- */
2129 music_info->load_artwork = Load_WAV_or_MOD;
2130 music_info->free_artwork = FreeMusic;
2133 void PlayMusic(int nr)
2135 if (!audio.music_available)
2141 void PlaySound(int nr)
2143 if (!setup.sound_simple)
2146 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
2149 void PlaySoundStereo(int nr, int stereo_position)
2151 if (!setup.sound_simple)
2154 PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
2157 void PlaySoundLoop(int nr)
2159 if (!setup.sound_loops)
2162 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
2165 void PlaySoundMusic(int nr)
2167 if (!setup.sound_music)
2170 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
2173 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
2175 SoundControl snd_ctrl;
2177 if (!audio.sound_available ||
2178 !audio.sound_enabled ||
2179 audio.sound_deactivated)
2182 volume = SETUP_SOUND_VOLUME(volume, state);
2184 if (volume < SOUND_MIN_VOLUME)
2185 volume = SOUND_MIN_VOLUME;
2186 else if (volume > SOUND_MAX_VOLUME)
2187 volume = SOUND_MAX_VOLUME;
2189 if (stereo_position < SOUND_MAX_LEFT)
2190 stereo_position = SOUND_MAX_LEFT;
2191 else if (stereo_position > SOUND_MAX_RIGHT)
2192 stereo_position = SOUND_MAX_RIGHT;
2194 clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */
2196 snd_ctrl.active = TRUE;
2198 snd_ctrl.volume = volume;
2199 snd_ctrl.stereo_position = stereo_position;
2200 snd_ctrl.state = state;
2202 HandleSoundRequest(snd_ctrl);
2205 void FadeMusic(void)
2207 if (!audio.music_available)
2210 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
2213 void FadeSound(int nr)
2215 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
2220 StopSoundExt(-1, SND_CTRL_FADE_ALL);
2223 void FadeSoundsAndMusic()
2229 void StopMusic(void)
2231 if (!audio.music_available)
2234 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
2237 void StopSound(int nr)
2239 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
2245 StopSoundExt(-1, SND_CTRL_STOP_ALL);
2248 void StopSoundExt(int nr, int state)
2250 SoundControl snd_ctrl;
2252 if (!audio.sound_available)
2255 clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */
2257 snd_ctrl.active = FALSE;
2259 snd_ctrl.state = state;
2261 HandleSoundRequest(snd_ctrl);
2264 static void ReloadCustomSounds()
2267 printf("::: reloading sounds '%s' ...\n", artwork.snd_current_identifier);
2270 LoadArtworkConfig(sound_info);
2271 ReloadCustomArtworkList(sound_info);
2274 static void ReloadCustomMusic()
2277 printf("::: reloading music '%s' ...\n", artwork.mus_current_identifier);
2280 LoadArtworkConfig(music_info);
2281 ReloadCustomArtworkList(music_info);
2283 /* load all music files from directory not defined in "musicinfo.conf" */
2284 LoadCustomMusic_NoConf();
2287 void InitReloadCustomSounds(char *set_identifier)
2289 if (!audio.sound_available)
2292 #if defined(AUDIO_UNIX_NATIVE)
2293 LoadArtworkConfig(sound_info); /* also load config on sound client */
2294 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_SOUNDS);
2296 ReloadCustomSounds();
2300 void InitReloadCustomMusic(char *set_identifier)
2302 if (!audio.music_available)
2305 #if defined(AUDIO_UNIX_NATIVE)
2306 LoadArtworkConfig(music_info); /* also load config on sound client */
2307 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
2309 ReloadCustomMusic();
2313 void FreeSound(void *ptr)
2315 SoundInfo *sound = (SoundInfo *)ptr;
2320 if (sound->data_ptr)
2322 #if defined(TARGET_SDL)
2323 Mix_FreeChunk(sound->data_ptr);
2324 #else /* AUDIO_UNIX_NATIVE */
2325 free(sound->data_ptr);
2329 checked_free(sound->source_filename);
2334 void FreeMusic(void *ptr)
2336 MusicInfo *music = (MusicInfo *)ptr;
2341 if (music->data_ptr)
2343 #if defined(TARGET_SDL)
2344 if (music->type == MUS_TYPE_MOD)
2345 Mix_FreeMusic(music->data_ptr);
2347 Mix_FreeChunk(music->data_ptr);
2348 #else /* AUDIO_UNIX_NATIVE */
2349 free(music->data_ptr);
2356 static void FreeAllMusic_NoConf()
2360 if (Music_NoConf == NULL)
2363 for (i = 0; i < num_music_noconf; i++)
2364 FreeMusic(Music_NoConf[i]);
2368 Music_NoConf = NULL;
2369 num_music_noconf = 0;
2372 void FreeAllSounds()
2374 FreeCustomArtworkLists(sound_info);
2379 FreeCustomArtworkLists(music_info);
2380 FreeAllMusic_NoConf();
2383 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2384 /* ========================================================================= */