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 #if defined(AUDIO_UNIX_NATIVE)
75 struct SoundHeader_WAV
77 unsigned short compression_code;
78 unsigned short num_channels;
79 unsigned int sample_rate;
80 unsigned int bytes_per_second;
81 unsigned short block_align;
82 unsigned short bits_per_sample;
86 struct AudioFormatInfo
88 boolean stereo; /* availability of stereo sound */
89 int format; /* size and endianess of sample data */
90 int sample_rate; /* sample frequency */
91 int fragment_size; /* audio device fragment size in bytes */
96 char *source_filename;
101 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
102 int data_len; /* number of samples, NOT number of bytes */
103 int num_channels; /* mono: 1 channel, stereo: 2 channels */
105 typedef struct SampleInfo SoundInfo;
106 typedef struct SampleInfo MusicInfo;
118 unsigned int playing_starttime;
119 unsigned int playing_pos;
123 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
124 int data_len; /* number of samples, NOT number of bytes */
125 int num_channels; /* mono: 1 channel, stereo: 2 channels */
127 #if defined(TARGET_ALLEGRO)
131 typedef struct SoundControl SoundControl;
133 static struct ArtworkListInfo *sound_info = NULL;
134 static struct ArtworkListInfo *music_info = NULL;
136 static MusicInfo **Music_NoConf = NULL;
138 static int num_music_noconf = 0;
139 static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
142 /* ========================================================================= */
143 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
145 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
146 static int mixer_active_channels = 0;
148 #if defined(AUDIO_UNIX_NATIVE)
149 static struct AudioFormatInfo afmt;
151 static void Mixer_Main(void);
152 #if !defined(AUDIO_STREAMING_DSP)
153 static unsigned char linear_to_ulaw(int);
154 static int ulaw_to_linear(unsigned char);
158 static void ReloadCustomSounds();
159 static void ReloadCustomMusic();
160 static void FreeSound(void *);
161 static void FreeMusic(void *);
162 static void FreeAllMusic_NoConf();
164 static SoundInfo *getSoundInfoEntryFromSoundID(int);
165 static MusicInfo *getMusicInfoEntryFromMusicID(int);
168 /* ------------------------------------------------------------------------- */
169 /* functions for native (non-SDL) Unix audio/mixer support */
170 /* ------------------------------------------------------------------------- */
172 #if defined(AUDIO_UNIX_NATIVE)
174 static int OpenAudioDevice(char *audio_device_name)
178 /* check if desired audio device is accessible */
179 if (access(audio_device_name, W_OK) != 0)
182 /* try to open audio device in non-blocking mode */
183 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
184 return audio_device_fd;
186 /* re-open audio device in blocking mode */
187 close(audio_device_fd);
188 audio_device_fd = open(audio_device_name, O_WRONLY);
190 return audio_device_fd;
193 static void CloseAudioDevice(int *audio_device_fd)
195 if (*audio_device_fd == 0)
198 close(*audio_device_fd);
199 *audio_device_fd = -1;
202 static boolean TestAudioDevices(void)
204 static char *audio_device_name[] =
207 DEVICENAME_SOUND_DSP,
210 int audio_device_fd = -1;
213 /* look for available audio devices, starting with preferred ones */
214 for (i = 0; i < sizeof(audio_device_name)/sizeof(char *); i++)
215 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
218 if (audio_device_fd < 0)
220 Error(ERR_WARN, "cannot open audio device -- no sound");
224 close(audio_device_fd);
226 audio.device_name = audio_device_name[i];
231 static boolean ForkAudioProcess(void)
233 if (pipe(audio.mixer_pipe) < 0)
235 Error(ERR_WARN, "cannot create pipe -- no sounds");
239 if ((audio.mixer_pid = fork()) < 0)
241 Error(ERR_WARN, "cannot create sound server process -- no sounds");
245 if (audio.mixer_pid == 0) /* we are the child process */
246 audio.mixer_pid = getpid();
248 if (IS_CHILD_PROCESS())
249 Mixer_Main(); /* this function never returns */
251 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
256 void UnixOpenAudio(void)
258 if (!TestAudioDevices())
261 audio.sound_available = TRUE;
262 audio.sound_enabled = TRUE;
264 #if defined(AUDIO_STREAMING_DSP)
265 audio.music_available = TRUE;
266 audio.loops_available = TRUE;
269 audio.num_channels = NUM_MIXER_CHANNELS;
270 audio.music_channel = MUSIC_CHANNEL;
271 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
274 void UnixCloseAudio(void)
277 close(audio.device_fd);
279 if (IS_PARENT_PROCESS() && HAS_CHILD_PROCESS())
280 kill(audio.mixer_pid, SIGTERM);
284 /* ------------------------------------------------------------------------- */
285 /* functions for platform specific audio device initialization */
286 /* ------------------------------------------------------------------------- */
288 #if defined(AUDIO_LINUX_IOCTL)
289 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
291 /* "ioctl()" expects pointer to 'int' value for stereo flag
292 (boolean is defined as 'char', which will not work here) */
293 unsigned int fragment_spec = 0;
294 int fragment_size_query = -1;
303 /* supported audio format in preferred order */
304 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
305 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
306 { AFMT_U8, AUDIO_FORMAT_U8 },
311 /* determine logarithm (log2) of the fragment size */
312 while ((1 << fragment_spec) < afmt->fragment_size)
315 /* use two fragments (play one fragment, prepare the other);
316 one fragment would result in interrupted audio output, more
317 than two fragments would raise audio output latency to much */
318 fragment_spec |= 0x00020000;
320 /* Example for fragment specification:
321 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
322 - (with stereo the effective buffer size will shrink to 256)
323 => fragment_size = 0x00020009 */
325 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
326 Error(ERR_EXIT_SOUND_SERVER,
327 "cannot set fragment size of audio device -- no sounds");
331 while (formats[i].format_result != -1)
333 unsigned int audio_format = formats[i].format_ioctl;
334 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
336 afmt->format = formats[i].format_result;
341 if (afmt->format == 0) /* no supported audio format found */
342 Error(ERR_EXIT_SOUND_SERVER,
343 "cannot set audio format of audio device -- no sounds");
345 /* try if we can use stereo sound */
347 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
348 afmt->stereo = FALSE;
350 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
351 Error(ERR_EXIT_SOUND_SERVER,
352 "cannot set sample rate of audio device -- no sounds");
354 /* get the real fragmentation size; this should return 512 */
355 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
356 Error(ERR_EXIT_SOUND_SERVER,
357 "cannot get fragment size of audio device -- no sounds");
358 if (fragment_size_query != afmt->fragment_size)
359 Error(ERR_EXIT_SOUND_SERVER,
360 "cannot set fragment size of audio device -- no sounds");
362 #endif /* AUDIO_LINUX_IOCTL */
364 #if defined(PLATFORM_NETBSD)
365 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
368 boolean stereo = TRUE;
370 AUDIO_INITINFO(&a_info);
371 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
372 a_info.play.precision = 8;
373 a_info.play.channels = 2;
374 a_info.play.sample_rate = afmt->sample_rate;
375 a_info.blocksize = afmt->fragment_size;
377 afmt->format = AUDIO_FORMAT_U8;
380 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
382 /* try to disable stereo */
383 a_info.play.channels = 1;
385 afmt->stereo = FALSE;
387 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
388 Error(ERR_EXIT_SOUND_SERVER,
389 "cannot set sample rate of audio device -- no sounds");
392 #endif /* PLATFORM_NETBSD */
394 #if defined(PLATFORM_HPUX)
395 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
397 struct audio_describe ainfo;
400 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
402 Error(ERR_EXIT_SOUND_SERVER, "cannot open audio device -- no sounds");
404 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
405 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
407 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
408 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
410 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
411 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
413 afmt->format = AUDIO_FORMAT_U8;
414 afmt->stereo = FALSE;
415 afmt->sample_rate = 8000;
419 #endif /* PLATFORM_HPUX */
421 static void InitAudioDevice(struct AudioFormatInfo *afmt)
424 afmt->format = AUDIO_FORMAT_UNKNOWN;
425 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
426 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
428 #if defined(AUDIO_LINUX_IOCTL)
429 InitAudioDevice_Linux(afmt);
430 #elif defined(PLATFORM_NETBSD)
431 InitAudioDevice_NetBSD(afmt);
432 #elif defined(PLATFORM_HPUX)
433 InitAudioDevice_HPUX(afmt);
435 /* generic /dev/audio stuff might be placed here */
440 /* ------------------------------------------------------------------------- */
441 /* functions for communication between main process and sound mixer process */
442 /* ------------------------------------------------------------------------- */
444 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
446 if (IS_CHILD_PROCESS())
449 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
451 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
452 audio.sound_available = audio.sound_enabled = FALSE;
457 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
459 if (IS_PARENT_PROCESS())
462 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
463 != sizeof(SoundControl))
464 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
467 static void WriteReloadInfoToPipe(char *set_identifier, int type)
469 SoundControl snd_ctrl;
470 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
471 artwork.mus_current);
472 unsigned int str_size1 = strlen(leveldir_current->fullpath) + 1;
473 unsigned int str_size2 = strlen(leveldir_current->sounds_path) + 1;
474 unsigned int str_size3 = strlen(leveldir_current->music_path) + 1;
475 unsigned int str_size4 = strlen(ti->basepath) + 1;
476 unsigned int str_size5 = strlen(ti->fullpath) + 1;
477 boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
478 gfx.override_level_sounds :
479 gfx.override_level_music);
481 if (IS_CHILD_PROCESS())
484 if (leveldir_current == NULL) /* should never happen */
485 Error(ERR_EXIT, "leveldir_current == NULL");
487 clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */
489 snd_ctrl.active = FALSE;
490 snd_ctrl.state = type;
491 snd_ctrl.data_len = strlen(set_identifier) + 1;
493 if (write(audio.mixer_pipe[1], &snd_ctrl,
494 sizeof(snd_ctrl)) < 0 ||
495 write(audio.mixer_pipe[1], set_identifier,
496 snd_ctrl.data_len) < 0 ||
497 write(audio.mixer_pipe[1], &override_level_artwork,
498 sizeof(boolean)) < 0 ||
499 write(audio.mixer_pipe[1], leveldir_current,
500 sizeof(TreeInfo)) < 0 ||
501 write(audio.mixer_pipe[1], ti,
502 sizeof(TreeInfo)) < 0 ||
503 write(audio.mixer_pipe[1], &str_size1,
504 sizeof(unsigned int)) < 0 ||
505 write(audio.mixer_pipe[1], &str_size2,
506 sizeof(unsigned int)) < 0 ||
507 write(audio.mixer_pipe[1], &str_size3,
508 sizeof(unsigned int)) < 0 ||
509 write(audio.mixer_pipe[1], &str_size4,
510 sizeof(unsigned int)) < 0 ||
511 write(audio.mixer_pipe[1], &str_size5,
512 sizeof(unsigned int)) < 0 ||
513 write(audio.mixer_pipe[1], leveldir_current->fullpath,
515 write(audio.mixer_pipe[1], leveldir_current->sounds_path,
517 write(audio.mixer_pipe[1], leveldir_current->music_path,
519 write(audio.mixer_pipe[1], ti->basepath,
521 write(audio.mixer_pipe[1], ti->fullpath,
524 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
525 audio.sound_available = audio.sound_enabled = FALSE;
530 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
532 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
533 &artwork.snd_current : &artwork.mus_current);
534 TreeInfo *ti = *ti_ptr;
535 unsigned int str_size1, str_size2, str_size3, str_size4, str_size5;
536 static char *set_identifier = NULL;
537 boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
538 &gfx.override_level_sounds :
539 &gfx.override_level_music);
541 checked_free(set_identifier);
543 set_identifier = checked_malloc(snd_ctrl->data_len);
545 if (leveldir_current == NULL)
546 leveldir_current = checked_calloc(sizeof(TreeInfo));
549 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
551 checked_free(leveldir_current->fullpath);
552 checked_free(leveldir_current->sounds_path);
553 checked_free(leveldir_current->music_path);
554 checked_free(ti->basepath);
555 checked_free(ti->fullpath);
557 if (read(audio.mixer_pipe[0], set_identifier,
558 snd_ctrl->data_len) != snd_ctrl->data_len ||
559 read(audio.mixer_pipe[0], override_level_artwork,
560 sizeof(boolean)) != sizeof(boolean) ||
561 read(audio.mixer_pipe[0], leveldir_current,
562 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
563 read(audio.mixer_pipe[0], ti,
564 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
565 read(audio.mixer_pipe[0], &str_size1,
566 sizeof(unsigned int)) != sizeof(unsigned int) ||
567 read(audio.mixer_pipe[0], &str_size2,
568 sizeof(unsigned int)) != sizeof(unsigned int) ||
569 read(audio.mixer_pipe[0], &str_size3,
570 sizeof(unsigned int)) != sizeof(unsigned int) ||
571 read(audio.mixer_pipe[0], &str_size4,
572 sizeof(unsigned int)) != sizeof(unsigned int) ||
573 read(audio.mixer_pipe[0], &str_size5,
574 sizeof(unsigned int)) != sizeof(unsigned int))
575 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
577 leveldir_current->fullpath = checked_calloc(str_size1);
578 leveldir_current->sounds_path = checked_calloc(str_size2);
579 leveldir_current->music_path = checked_calloc(str_size3);
580 ti->basepath = checked_calloc(str_size4);
581 ti->fullpath = checked_calloc(str_size5);
583 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
584 str_size1) != str_size1 ||
585 read(audio.mixer_pipe[0], leveldir_current->sounds_path,
586 str_size2) != str_size2 ||
587 read(audio.mixer_pipe[0], leveldir_current->music_path,
588 str_size3) != str_size3 ||
589 read(audio.mixer_pipe[0], ti->basepath,
590 str_size4) != str_size4 ||
591 read(audio.mixer_pipe[0], ti->fullpath,
592 str_size5) != str_size5)
593 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
595 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
596 artwork.snd_current_identifier = set_identifier;
598 artwork.mus_current_identifier = set_identifier;
601 #endif /* AUDIO_UNIX_NATIVE */
604 /* ------------------------------------------------------------------------- */
605 /* mixer functions */
606 /* ------------------------------------------------------------------------- */
608 void Mixer_InitChannels()
612 for (i = 0; i < audio.num_channels; i++)
613 mixer[i].active = FALSE;
614 mixer_active_channels = 0;
617 static void Mixer_ResetChannelExpiration(int channel)
619 mixer[channel].playing_starttime = Counter();
621 #if defined(TARGET_SDL)
622 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
623 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
627 static boolean Mixer_ChannelExpired(int channel)
629 if (!mixer[channel].active)
632 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
633 DelayReached(&mixer[channel].playing_starttime,
634 SOUND_LOOP_EXPIRATION_TIME))
637 #if defined(TARGET_SDL)
639 if (!Mix_Playing(channel))
642 #elif defined(TARGET_ALLEGRO)
644 mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
645 mixer[channel].volume = voice_get_volume(mixer[channel].voice);
647 /* sound sample has completed playing or was completely faded out */
648 if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
651 #endif /* TARGET_ALLEGRO */
656 static boolean Mixer_AllocateChannel(int channel)
658 #if defined(TARGET_ALLEGRO)
659 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
660 if (mixer[channel].voice < 0)
667 static void Mixer_SetChannelProperties(int channel)
669 #if defined(TARGET_SDL)
670 Mix_Volume(channel, mixer[channel].volume);
671 Mix_SetPanning(channel,
672 SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
673 SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
674 #elif defined(TARGET_ALLEGRO)
675 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
676 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
680 static void Mixer_StartChannel(int channel)
682 #if defined(TARGET_SDL)
683 Mix_PlayChannel(channel, mixer[channel].data_ptr,
684 IS_LOOP(mixer[channel]) ? -1 : 0);
685 #elif defined(TARGET_ALLEGRO)
686 if (IS_LOOP(mixer[channel]))
687 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
689 voice_start(mixer[channel].voice);
693 static void Mixer_PlayChannel(int channel)
695 /* start with inactive channel in case something goes wrong */
696 mixer[channel].active = FALSE;
698 if (mixer[channel].type != MUS_TYPE_WAV)
701 if (!Mixer_AllocateChannel(channel))
704 Mixer_SetChannelProperties(channel);
705 Mixer_StartChannel(channel);
707 Mixer_ResetChannelExpiration(channel);
709 mixer[channel].playing_pos = 0;
710 mixer[channel].active = TRUE;
711 mixer_active_channels++;
714 static void Mixer_PlayMusicChannel()
716 Mixer_PlayChannel(audio.music_channel);
718 #if defined(TARGET_SDL)
719 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
721 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
722 this looks like a bug in the SDL_mixer library */
723 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
724 Mix_VolumeMusic(SOUND_MAX_VOLUME);
729 static void Mixer_StopChannel(int channel)
731 if (!mixer[channel].active)
734 #if defined(TARGET_SDL)
735 Mix_HaltChannel(channel);
736 #elif defined(TARGET_ALLEGRO)
737 voice_set_volume(mixer[channel].voice, 0);
738 deallocate_voice(mixer[channel].voice);
741 mixer[channel].active = FALSE;
742 mixer_active_channels--;
745 static void Mixer_StopMusicChannel()
747 Mixer_StopChannel(audio.music_channel);
749 #if defined(TARGET_SDL)
754 static void Mixer_FadeChannel(int channel)
756 if (!mixer[channel].active)
759 mixer[channel].state |= SND_CTRL_FADE;
761 #if defined(TARGET_SDL)
762 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
763 #elif defined(TARGET_ALLEGRO)
764 if (voice_check(mixer[channel].voice))
765 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
769 static void Mixer_FadeMusicChannel()
771 Mixer_FadeChannel(audio.music_channel);
773 #if defined(TARGET_SDL)
774 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
778 static void Mixer_UnFadeChannel(int channel)
780 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
783 mixer[channel].state &= ~SND_CTRL_FADE;
784 mixer[channel].volume = SOUND_MAX_VOLUME;
786 #if defined(TARGET_SDL)
787 Mix_ExpireChannel(channel, -1);
788 Mix_Volume(channel, mixer[channel].volume);
789 #elif defined(TARGET_ALLEGRO)
790 voice_stop_volumeramp(mixer[channel].voice);
791 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
792 mixer[channel].volume);
796 static void Mixer_InsertSound(SoundControl snd_ctrl)
800 int num_sounds = getSoundListSize();
801 int num_music = getMusicListSize();
803 if (IS_MUSIC(snd_ctrl))
805 if (snd_ctrl.nr >= num_music) /* invalid music */
808 if (snd_ctrl.nr < 0) /* undefined music */
810 if (num_music_noconf == 0) /* no fallback music available */
813 snd_ctrl.nr = UNMAP_NOCONF_MUSIC(snd_ctrl.nr) % num_music_noconf;
814 snd_info = Music_NoConf[snd_ctrl.nr];
817 snd_info = getMusicInfoEntryFromMusicID(snd_ctrl.nr);
821 if (snd_ctrl.nr < 0 || snd_ctrl.nr >= num_sounds)
824 snd_info = getSoundInfoEntryFromSoundID(snd_ctrl.nr);
827 if (snd_info == NULL)
830 /* copy sound sample and format information */
831 snd_ctrl.type = snd_info->type;
832 snd_ctrl.format = snd_info->format;
833 snd_ctrl.data_ptr = snd_info->data_ptr;
834 snd_ctrl.data_len = snd_info->data_len;
835 snd_ctrl.num_channels = snd_info->num_channels;
837 /* play music samples on a dedicated music channel */
838 if (IS_MUSIC(snd_ctrl))
840 Mixer_StopMusicChannel();
842 mixer[audio.music_channel] = snd_ctrl;
843 Mixer_PlayMusicChannel();
848 /* check if (and how often) this sound sample is already playing */
849 for (k = 0, i = audio.first_sound_channel; i < audio.num_channels; i++)
850 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
853 /* reset expiration delay for already playing loop sounds */
854 if (k > 0 && IS_LOOP(snd_ctrl))
856 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
858 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
860 if (IS_FADING(mixer[i]))
861 Mixer_UnFadeChannel(i);
863 /* restore settings like volume and stereo position */
864 mixer[i].volume = snd_ctrl.volume;
865 mixer[i].stereo_position = snd_ctrl.stereo_position;
867 Mixer_SetChannelProperties(i);
868 Mixer_ResetChannelExpiration(i);
875 /* don't play sound more than n times simultaneously (with n == 2 for now) */
878 unsigned int playing_current = Counter();
879 int longest = 0, longest_nr = audio.first_sound_channel;
881 /* look for oldest equal sound */
882 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
884 int playing_time = playing_current - mixer[i].playing_starttime;
887 if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
890 actual = 1000 * playing_time / mixer[i].data_len;
892 if (actual >= longest)
899 Mixer_StopChannel(longest_nr);
902 /* If all (non-music) channels are active, stop the channel that has
903 played its sound sample most completely (in percent of the sample
904 length). As we cannot currently get the actual playing position
905 of the channel's sound sample when compiling with the SDL mixer
906 library, we use the current playing time (in milliseconds) instead. */
909 /* channel allocation sanity check -- should not be needed */
910 if (mixer_active_channels ==
911 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
913 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
915 if (!mixer[i].active)
917 Error(ERR_INFO, "Mixer_InsertSound: Channel %d inactive", i);
918 Error(ERR_INFO, "Mixer_InsertSound: This should never happen!");
920 mixer_active_channels--;
926 if (mixer_active_channels ==
927 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
929 unsigned int playing_current = Counter();
930 int longest = 0, longest_nr = audio.first_sound_channel;
934 /* print some debugging information about audio channel usage */
935 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
937 Error(ERR_INFO, "Mixer_InsertSound: %d [%d]: %d (%d)",
938 i, mixer[i].active, mixer[i].data_len, (int)mixer[i].data_ptr);
943 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
945 int playing_time = playing_current - mixer[i].playing_starttime;
946 int actual = 1000 * playing_time / mixer[i].data_len;
948 if (!IS_LOOP(mixer[i]) && actual > longest)
955 Mixer_StopChannel(longest_nr);
958 /* add the new sound to the mixer */
959 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
961 if (!mixer[i].active)
963 #if defined(AUDIO_UNIX_NATIVE)
964 if (snd_info->data_len == 0)
966 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
971 Mixer_PlayChannel(i);
978 static void HandleSoundRequest(SoundControl snd_ctrl)
982 #if defined(AUDIO_UNIX_NATIVE)
983 if (IS_PARENT_PROCESS())
985 SendSoundControlToMixerProcess(&snd_ctrl);
990 /* deactivate channels that have expired since the last request */
991 for (i = 0; i < audio.num_channels; i++)
992 if (mixer[i].active && Mixer_ChannelExpired(i))
993 Mixer_StopChannel(i);
995 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
997 Mixer_StopMusicChannel();
998 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
999 Mixer_StopChannel(i);
1001 #if defined(AUDIO_UNIX_NATIVE)
1002 CloseAudioDevice(&audio.device_fd);
1003 ReadReloadInfoFromPipe(&snd_ctrl);
1006 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
1007 ReloadCustomSounds();
1009 ReloadCustomMusic();
1011 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
1013 if (IS_MUSIC(snd_ctrl))
1015 Mixer_FadeMusicChannel();
1019 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1020 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1021 Mixer_FadeChannel(i);
1023 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
1025 if (IS_MUSIC(snd_ctrl))
1027 Mixer_StopMusicChannel();
1031 for (i = audio.first_sound_channel; i < audio.num_channels; i++)
1032 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1033 Mixer_StopChannel(i);
1035 #if defined(AUDIO_UNIX_NATIVE)
1036 if (!mixer_active_channels)
1037 CloseAudioDevice(&audio.device_fd);
1040 else if (snd_ctrl.active) /* add new sound to mixer */
1042 Mixer_InsertSound(snd_ctrl);
1046 void StartMixer(void)
1051 SDL_version compile_version;
1052 const SDL_version *link_version;
1053 MIX_VERSION(&compile_version);
1054 printf("compiled with SDL_mixer version: %d.%d.%d\n",
1055 compile_version.major,
1056 compile_version.minor,
1057 compile_version.patch);
1058 link_version = Mix_Linked_Version();
1059 printf("running with SDL_mixer version: %d.%d.%d\n",
1060 link_version->major,
1061 link_version->minor,
1062 link_version->patch);
1065 if (!audio.sound_available)
1068 /* initialize stereo position conversion information */
1069 for (i = 0; i <= SOUND_MAX_LEFT2RIGHT; i++)
1071 (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1073 #if defined(AUDIO_UNIX_NATIVE)
1074 if (!ForkAudioProcess())
1075 audio.sound_available = FALSE;
1079 #if defined(AUDIO_UNIX_NATIVE)
1081 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1082 int sample_pos, int sample_size,
1083 short *buffer_base_ptr, int buffer_pos,
1084 int num_output_channels)
1086 short *buffer_ptr = buffer_base_ptr + num_output_channels * buffer_pos;
1087 int num_channels = snd_ctrl->num_channels;
1088 int stepsize = num_channels;
1089 int output_stepsize = num_output_channels;
1092 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1094 byte *sample_ptr = (byte *)snd_ctrl->data_ptr + num_channels * sample_pos;
1096 for (i = 0; i < num_output_channels; i++)
1098 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1100 for (j = 0; j < sample_size; j++)
1101 buffer_ptr[output_stepsize * j + i] =
1102 ((short)(sample_ptr[stepsize * j + offset] ^ 0x80)) << 8;
1105 else /* AUDIO_FORMAT_S16 */
1107 short *sample_ptr= (short *)snd_ctrl->data_ptr + num_channels * sample_pos;
1109 for (i = 0; i < num_output_channels; i++)
1111 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1113 for (j = 0; j < sample_size; j++)
1114 buffer_ptr[output_stepsize * j + i] =
1115 sample_ptr[stepsize * j + offset];
1120 #if defined(AUDIO_STREAMING_DSP)
1121 static void Mixer_Main_DSP()
1123 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1124 static int premix_last_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1125 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1129 int max_sample_size;
1130 int num_output_channels;
1133 if (!mixer_active_channels)
1136 if (audio.device_fd < 0)
1138 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1141 InitAudioDevice(&afmt);
1144 stereo = afmt.stereo;
1145 fragment_size = afmt.fragment_size;
1146 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1147 num_output_channels = (stereo ? 2 : 1);
1148 max_sample_size = fragment_size / (num_output_channels * sample_bytes);
1150 /* first clear the last premixing buffer */
1151 clear_mem(premix_last_buffer,
1152 max_sample_size * num_output_channels * sizeof(int));
1154 for (i = 0; i < audio.num_channels; i++)
1156 // void *sample_ptr;
1161 if (!mixer[i].active)
1164 if (Mixer_ChannelExpired(i))
1166 Mixer_StopChannel(i);
1170 /* pointer, lenght and actual playing position of sound sample */
1171 // sample_ptr = mixer[i].data_ptr;
1172 sample_len = mixer[i].data_len;
1173 sample_pos = mixer[i].playing_pos;
1174 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1175 mixer[i].playing_pos += sample_size;
1177 /* copy original sample to first mixing buffer */
1178 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1179 premix_first_buffer, 0, num_output_channels);
1181 /* are we about to restart a looping sound? */
1182 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1184 while (sample_size < max_sample_size)
1186 int restarted_sample_size =
1187 MIN(max_sample_size - sample_size, sample_len);
1189 CopySampleToMixingBuffer(&mixer[i], 0, restarted_sample_size,
1190 premix_first_buffer, sample_size,
1191 num_output_channels);
1193 mixer[i].playing_pos = restarted_sample_size;
1194 sample_size += restarted_sample_size;
1198 /* decrease volume if sound is fading out */
1199 if (IS_FADING(mixer[i]) &&
1200 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1201 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1203 /* adjust volume of actual sound sample */
1204 if (mixer[i].volume != SOUND_MAX_VOLUME)
1205 for (j = 0; j < sample_size * num_output_channels; j++)
1206 premix_first_buffer[j] =
1207 mixer[i].volume * (int)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1209 /* adjust left and right channel volume due to stereo sound position */
1212 int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1213 int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1215 for (j = 0; j < sample_size; j++)
1217 premix_first_buffer[2 * j + 0] =
1218 left_volume * premix_first_buffer[2 * j + 0] / SOUND_MAX_LEFT2RIGHT;
1219 premix_first_buffer[2 * j + 1] =
1220 right_volume * premix_first_buffer[2 * j + 1] / SOUND_MAX_LEFT2RIGHT;
1224 /* fill the last mixing buffer with stereo or mono sound */
1225 for (j = 0; j < sample_size * num_output_channels; j++)
1226 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 * num_output_channels; 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 if (write(audio.device_fd, playing_buffer, fragment_size) == -1)
1270 Error(ERR_WARN, "write() failed; %s", strerror(errno));
1272 if (!mixer_active_channels)
1273 CloseAudioDevice(&audio.device_fd);
1276 #else /* !AUDIO_STREAMING_DSP */
1278 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1280 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1281 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1282 int max_sample_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
1283 int num_output_channels = 1;
1292 /* pointer, lenght and actual playing position of sound sample */
1293 sample_ptr = mixer[i].data_ptr;
1294 sample_len = mixer[i].data_len;
1295 sample_pos = mixer[i].playing_pos;
1296 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1297 mixer[i].playing_pos += sample_size;
1299 /* copy original sample to first mixing buffer */
1300 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1301 premix_first_buffer, 0, num_output_channels);
1303 /* adjust volume of actual sound sample */
1304 if (mixer[i].volume != SOUND_MAX_VOLUME)
1305 for (j = 0; j < sample_size; j++)
1306 premix_first_buffer[j] =
1307 mixer[i].volume * (int)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1309 /* might be needed for u-law /dev/audio */
1310 for (j = 0; j < sample_size; j++)
1312 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 void *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];
1535 if (!audio.sound_available)
1538 snd_info = checked_calloc(sizeof(SoundInfo));
1540 #if defined(TARGET_SDL)
1542 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1544 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1549 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1551 #elif defined(TARGET_ALLEGRO)
1553 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1555 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1560 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1562 #else /* AUDIO_UNIX_NATIVE */
1564 clear_mem(&header, sizeof(struct SoundHeader_WAV)); /* to make gcc happy */
1566 if ((file = fopen(filename, MODE_READ)) == NULL)
1568 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1573 /* read chunk id "RIFF" */
1574 getFileChunkLE(file, chunk_name, &chunk_size);
1575 if (!strEqual(chunk_name, "RIFF"))
1577 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1583 /* read "RIFF" type id "WAVE" */
1584 getFileChunkLE(file, chunk_name, NULL);
1585 if (!strEqual(chunk_name, "WAVE"))
1587 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1593 while (getFileChunkLE(file, chunk_name, &chunk_size))
1595 if (strEqual(chunk_name, "fmt "))
1597 if (chunk_size < WAV_HEADER_SIZE)
1599 Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1605 header.compression_code = getFile16BitLE(file);
1606 header.num_channels = getFile16BitLE(file);
1607 header.sample_rate = getFile32BitLE(file);
1608 header.bytes_per_second = getFile32BitLE(file);
1609 header.block_align = getFile16BitLE(file);
1610 header.bits_per_sample = getFile16BitLE(file);
1612 if (chunk_size > WAV_HEADER_SIZE)
1613 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1615 if (header.compression_code != 1)
1617 Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1618 filename, header.compression_code);
1624 if (header.num_channels != 1 &&
1625 header.num_channels != 2)
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 &&
1635 header.bits_per_sample != 16)
1637 Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1638 filename, header.bits_per_sample);
1644 /* warn, but accept wrong sample rate (may be only slightly different) */
1645 if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1646 Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1647 filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1650 printf("WAV file: '%s'\n", filename);
1651 printf(" Compression code: %d'\n", header.compression_code);
1652 printf(" Number of channels: %d'\n", header.num_channels);
1653 printf(" Sample rate: %d'\n", header.sample_rate);
1654 printf(" Average bytes per second: %d'\n", header.bytes_per_second);
1655 printf(" Block align: %d'\n", header.block_align);
1656 printf(" Significant bits per sample: %d'\n", header.bits_per_sample);
1659 else if (strEqual(chunk_name, "data"))
1661 data_byte_len = chunk_size;
1663 snd_info->data_len = data_byte_len;
1664 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1666 /* read sound data */
1667 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1670 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1672 free(snd_info->data_ptr);
1677 /* check for odd number of data bytes (data chunk is word aligned) */
1678 if ((data_byte_len % 2) == 1)
1679 ReadUnusedBytesFromFile(file, 1);
1681 else /* unknown chunk -- ignore */
1682 ReadUnusedBytesFromFile(file, chunk_size);
1687 if (snd_info->data_ptr == NULL)
1689 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1694 if (header.bits_per_sample == 8)
1695 snd_info->format = AUDIO_FORMAT_U8;
1696 else /* header.bits_per_sample == 16 */
1698 snd_info->format = AUDIO_FORMAT_S16;
1699 snd_info->data_len /= 2; /* correct number of samples */
1702 snd_info->num_channels = header.num_channels;
1703 if (header.num_channels == 2)
1704 snd_info->data_len /= 2; /* correct number of samples */
1707 if (header.num_channels == 1) /* convert mono sound to stereo */
1709 void *buffer_ptr = checked_malloc(data_byte_len * 2);
1710 void *sample_ptr = snd_info->data_ptr;
1711 int sample_size = snd_info->data_len;
1714 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1715 for (i = 0; i < sample_size; i++)
1717 ((short)(((byte *)sample_ptr)[i] ^ 0x80)) << 8;
1718 else /* AUDIO_FORMAT_S16 */
1719 for (i = 0; i < sample_size; i++)
1721 ((short *)sample_ptr)[i];
1725 #endif /* AUDIO_UNIX_NATIVE */
1727 snd_info->type = SND_TYPE_WAV;
1728 snd_info->source_filename = getStringCopy(filename);
1733 static void *Load_MOD(char *filename)
1735 #if defined(TARGET_SDL)
1736 MusicInfo *mod_info;
1738 if (!audio.sound_available)
1741 mod_info = checked_calloc(sizeof(MusicInfo));
1743 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1745 Error(ERR_WARN, "cannot read music file '%s'", filename);
1750 mod_info->type = MUS_TYPE_MOD;
1751 mod_info->source_filename = getStringCopy(filename);
1759 static void *Load_WAV_or_MOD(char *filename)
1761 if (FileIsSound(filename))
1762 return Load_WAV(filename);
1763 else if (FileIsMusic(filename))
1764 return Load_MOD(filename);
1769 void LoadCustomMusic_NoConf(void)
1771 static boolean draw_init_text = TRUE; /* only draw at startup */
1772 static char *last_music_directory = NULL;
1773 char *music_directory = getCustomMusicDirectory();
1775 struct dirent *dir_entry;
1776 int num_music = getMusicListSize();
1778 if (!audio.sound_available)
1781 if (last_music_directory != NULL &&
1782 strEqual(last_music_directory, music_directory))
1783 return; /* old and new music directory are the same */
1785 if (last_music_directory != NULL)
1786 free(last_music_directory);
1787 last_music_directory = getStringCopy(music_directory);
1789 FreeAllMusic_NoConf();
1791 if ((dir = opendir(music_directory)) == NULL)
1793 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1794 audio.music_available = FALSE;
1799 DrawInitText("Loading music", 120, FC_GREEN);
1801 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1803 char *basename = dir_entry->d_name;
1804 char *filename = NULL;
1805 MusicInfo *mus_info = NULL;
1806 boolean music_already_used = FALSE;
1809 /* skip all music files that are configured in music config file */
1810 for (i = 0; i < num_music; i++)
1812 struct FileInfo *music = getMusicListEntry(i);
1814 if (strEqual(basename, music->filename))
1816 music_already_used = TRUE;
1821 if (music_already_used)
1825 DrawInitText(basename, 150, FC_YELLOW);
1827 filename = getPath2(music_directory, basename);
1829 if (FileIsMusic(basename))
1830 mus_info = Load_WAV_or_MOD(filename);
1837 Music_NoConf = checked_realloc(Music_NoConf,
1838 num_music_noconf * sizeof(MusicInfo *));
1839 Music_NoConf[num_music_noconf - 1] = mus_info;
1845 draw_init_text = FALSE;
1848 int getSoundListSize()
1850 return (sound_info->num_file_list_entries +
1851 sound_info->num_dynamic_file_list_entries);
1854 int getMusicListSize()
1856 return (music_info->num_file_list_entries +
1857 music_info->num_dynamic_file_list_entries);
1860 struct FileInfo *getSoundListEntry(int pos)
1862 int num_list_entries = sound_info->num_file_list_entries;
1863 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1865 return (pos < num_list_entries ? &sound_info->file_list[list_pos] :
1866 &sound_info->dynamic_file_list[list_pos]);
1869 struct FileInfo *getMusicListEntry(int pos)
1871 int num_list_entries = music_info->num_file_list_entries;
1872 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1874 return (pos < num_list_entries ? &music_info->file_list[list_pos] :
1875 &music_info->dynamic_file_list[list_pos]);
1878 static SoundInfo *getSoundInfoEntryFromSoundID(int pos)
1880 int num_list_entries = sound_info->num_file_list_entries;
1881 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1882 SoundInfo **snd_info =
1883 (SoundInfo **)(pos < num_list_entries ? sound_info->artwork_list :
1884 sound_info->dynamic_artwork_list);
1886 return snd_info[list_pos];
1889 static MusicInfo *getMusicInfoEntryFromMusicID(int pos)
1891 int num_list_entries = music_info->num_file_list_entries;
1892 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1893 MusicInfo **mus_info =
1894 (MusicInfo **)(pos < num_list_entries ? music_info->artwork_list :
1895 music_info->dynamic_artwork_list);
1897 return mus_info[list_pos];
1900 int getSoundListPropertyMappingSize()
1902 return sound_info->num_property_mapping_entries;
1905 int getMusicListPropertyMappingSize()
1907 return music_info->num_property_mapping_entries;
1910 struct PropertyMapping *getSoundListPropertyMapping()
1912 return sound_info->property_mapping;
1915 struct PropertyMapping *getMusicListPropertyMapping()
1917 return music_info->property_mapping;
1920 void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
1921 struct ConfigTypeInfo *config_suffix_list,
1922 char **base_prefixes, char **ext1_suffixes,
1923 char **ext2_suffixes, char **ext3_suffixes,
1924 char **ignore_tokens)
1928 sound_info = checked_calloc(sizeof(struct ArtworkListInfo));
1929 sound_info->type = ARTWORK_TYPE_SOUNDS;
1931 /* ---------- initialize file list and suffix lists ---------- */
1933 sound_info->num_file_list_entries = num_file_list_entries;
1934 sound_info->num_dynamic_file_list_entries = 0;
1936 sound_info->file_list =
1937 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
1938 num_file_list_entries);
1939 sound_info->dynamic_file_list = NULL;
1941 sound_info->num_suffix_list_entries = 0;
1942 for (i = 0; config_suffix_list[i].token != NULL; i++)
1943 sound_info->num_suffix_list_entries++;
1945 sound_info->suffix_list = config_suffix_list;
1947 /* ---------- initialize base prefix and suffixes lists ---------- */
1949 sound_info->num_base_prefixes = 0;
1950 for (i = 0; base_prefixes[i] != NULL; i++)
1951 sound_info->num_base_prefixes++;
1953 sound_info->num_ext1_suffixes = 0;
1954 for (i = 0; ext1_suffixes[i] != NULL; i++)
1955 sound_info->num_ext1_suffixes++;
1957 sound_info->num_ext2_suffixes = 0;
1958 for (i = 0; ext2_suffixes[i] != NULL; i++)
1959 sound_info->num_ext2_suffixes++;
1961 sound_info->num_ext3_suffixes = 0;
1962 for (i = 0; ext3_suffixes[i] != NULL; i++)
1963 sound_info->num_ext3_suffixes++;
1965 sound_info->num_ignore_tokens = 0;
1966 for (i = 0; ignore_tokens[i] != NULL; i++)
1967 sound_info->num_ignore_tokens++;
1969 sound_info->base_prefixes = base_prefixes;
1970 sound_info->ext1_suffixes = ext1_suffixes;
1971 sound_info->ext2_suffixes = ext2_suffixes;
1972 sound_info->ext3_suffixes = ext3_suffixes;
1973 sound_info->ignore_tokens = ignore_tokens;
1975 sound_info->num_property_mapping_entries = 0;
1977 sound_info->property_mapping = NULL;
1979 /* ---------- initialize artwork reference and content lists ---------- */
1981 sound_info->sizeof_artwork_list_entry = sizeof(SoundInfo *);
1983 sound_info->artwork_list =
1984 checked_calloc(num_file_list_entries * sizeof(SoundInfo *));
1985 sound_info->dynamic_artwork_list = NULL;
1987 sound_info->content_list = NULL;
1989 /* ---------- initialize artwork loading/freeing functions ---------- */
1991 sound_info->load_artwork = Load_WAV;
1992 sound_info->free_artwork = FreeSound;
1995 void InitMusicList(struct ConfigInfo *config_list, int num_file_list_entries,
1996 struct ConfigTypeInfo *config_suffix_list,
1997 char **base_prefixes, char **ext1_suffixes,
1998 char **ext2_suffixes, char **ext3_suffixes,
1999 char **ignore_tokens)
2003 music_info = checked_calloc(sizeof(struct ArtworkListInfo));
2004 music_info->type = ARTWORK_TYPE_MUSIC;
2006 /* ---------- initialize file list and suffix lists ---------- */
2008 music_info->num_file_list_entries = num_file_list_entries;
2009 music_info->num_dynamic_file_list_entries = 0;
2011 music_info->file_list =
2012 getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
2013 num_file_list_entries);
2014 music_info->dynamic_file_list = NULL;
2016 music_info->num_suffix_list_entries = 0;
2017 for (i = 0; config_suffix_list[i].token != NULL; i++)
2018 music_info->num_suffix_list_entries++;
2020 music_info->suffix_list = config_suffix_list;
2022 /* ---------- initialize base prefix and suffixes lists ---------- */
2024 music_info->num_base_prefixes = 0;
2025 for (i = 0; base_prefixes[i] != NULL; i++)
2026 music_info->num_base_prefixes++;
2028 music_info->num_ext1_suffixes = 0;
2029 for (i = 0; ext1_suffixes[i] != NULL; i++)
2030 music_info->num_ext1_suffixes++;
2032 music_info->num_ext2_suffixes = 0;
2033 for (i = 0; ext2_suffixes[i] != NULL; i++)
2034 music_info->num_ext2_suffixes++;
2036 music_info->num_ext3_suffixes = 0;
2037 for (i = 0; ext3_suffixes[i] != NULL; i++)
2038 music_info->num_ext3_suffixes++;
2040 music_info->num_ignore_tokens = 0;
2041 for (i = 0; ignore_tokens[i] != NULL; i++)
2042 music_info->num_ignore_tokens++;
2044 music_info->base_prefixes = base_prefixes;
2045 music_info->ext1_suffixes = ext1_suffixes;
2046 music_info->ext2_suffixes = ext2_suffixes;
2047 music_info->ext3_suffixes = ext3_suffixes;
2048 music_info->ignore_tokens = ignore_tokens;
2050 music_info->num_property_mapping_entries = 0;
2052 music_info->property_mapping = NULL;
2054 /* ---------- initialize artwork reference and content lists ---------- */
2056 music_info->sizeof_artwork_list_entry = sizeof(MusicInfo *);
2058 music_info->artwork_list =
2059 checked_calloc(num_file_list_entries * sizeof(MusicInfo *));
2060 music_info->dynamic_artwork_list = NULL;
2062 music_info->content_list = NULL;
2064 /* ---------- initialize artwork loading/freeing functions ---------- */
2066 music_info->load_artwork = Load_WAV_or_MOD;
2067 music_info->free_artwork = FreeMusic;
2070 void PlayMusic(int nr)
2072 if (!audio.music_available)
2078 void PlaySound(int nr)
2080 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
2083 void PlaySoundStereo(int nr, int stereo_position)
2085 PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
2088 void PlaySoundLoop(int nr)
2090 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
2093 void PlaySoundMusic(int nr)
2095 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
2098 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
2100 SoundControl snd_ctrl;
2102 if (!audio.sound_available ||
2103 !audio.sound_enabled ||
2104 audio.sound_deactivated)
2107 if (volume < SOUND_MIN_VOLUME)
2108 volume = SOUND_MIN_VOLUME;
2109 else if (volume > SOUND_MAX_VOLUME)
2110 volume = SOUND_MAX_VOLUME;
2112 if (stereo_position < SOUND_MAX_LEFT)
2113 stereo_position = SOUND_MAX_LEFT;
2114 else if (stereo_position > SOUND_MAX_RIGHT)
2115 stereo_position = SOUND_MAX_RIGHT;
2117 clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */
2119 snd_ctrl.active = TRUE;
2121 snd_ctrl.volume = volume;
2122 snd_ctrl.stereo_position = stereo_position;
2123 snd_ctrl.state = state;
2125 HandleSoundRequest(snd_ctrl);
2128 void FadeMusic(void)
2130 if (!audio.music_available)
2133 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
2136 void FadeSound(int nr)
2138 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
2143 StopSoundExt(-1, SND_CTRL_FADE_ALL);
2146 void FadeSoundsAndMusic()
2152 void StopMusic(void)
2154 if (!audio.music_available)
2157 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
2160 void StopSound(int nr)
2162 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
2168 StopSoundExt(-1, SND_CTRL_STOP_ALL);
2171 void StopSoundExt(int nr, int state)
2173 SoundControl snd_ctrl;
2175 if (!audio.sound_available)
2178 clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */
2180 snd_ctrl.active = FALSE;
2182 snd_ctrl.state = state;
2184 HandleSoundRequest(snd_ctrl);
2187 static void ReloadCustomSounds()
2190 printf("::: reloading sounds '%s' ...\n", artwork.snd_current_identifier);
2193 LoadArtworkConfig(sound_info);
2194 ReloadCustomArtworkList(sound_info);
2197 static void ReloadCustomMusic()
2200 printf("::: reloading music '%s' ...\n", artwork.mus_current_identifier);
2203 LoadArtworkConfig(music_info);
2204 ReloadCustomArtworkList(music_info);
2206 /* load all music files from directory not defined in "musicinfo.conf" */
2207 LoadCustomMusic_NoConf();
2210 void InitReloadCustomSounds(char *set_identifier)
2212 if (!audio.sound_available)
2215 #if defined(AUDIO_UNIX_NATIVE)
2216 LoadArtworkConfig(sound_info); /* also load config on sound client */
2217 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_SOUNDS);
2219 ReloadCustomSounds();
2223 void InitReloadCustomMusic(char *set_identifier)
2225 if (!audio.music_available)
2228 #if defined(AUDIO_UNIX_NATIVE)
2229 LoadArtworkConfig(music_info); /* also load config on sound client */
2230 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
2232 ReloadCustomMusic();
2236 void FreeSound(void *ptr)
2238 SoundInfo *sound = (SoundInfo *)ptr;
2243 if (sound->data_ptr)
2245 #if defined(TARGET_SDL)
2246 Mix_FreeChunk(sound->data_ptr);
2247 #elif defined(TARGET_ALLEGRO)
2248 destroy_sample(sound->data_ptr);
2249 #else /* AUDIO_UNIX_NATIVE */
2250 free(sound->data_ptr);
2254 checked_free(sound->source_filename);
2259 void FreeMusic(void *ptr)
2261 MusicInfo *music = (MusicInfo *)ptr;
2266 if (music->data_ptr)
2268 #if defined(TARGET_SDL)
2269 if (music->type == MUS_TYPE_MOD)
2270 Mix_FreeMusic(music->data_ptr);
2272 Mix_FreeChunk(music->data_ptr);
2273 #elif defined(TARGET_ALLEGRO)
2274 destroy_sample(music->data_ptr);
2275 #else /* AUDIO_UNIX_NATIVE */
2276 free(music->data_ptr);
2283 static void FreeAllMusic_NoConf()
2287 if (Music_NoConf == NULL)
2290 for (i = 0; i < num_music_noconf; i++)
2291 FreeMusic(Music_NoConf[i]);
2295 Music_NoConf = NULL;
2296 num_music_noconf = 0;
2299 void FreeAllSounds()
2301 FreeCustomArtworkLists(sound_info);
2306 FreeCustomArtworkLists(music_info);
2307 FreeAllMusic_NoConf();
2310 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2311 /* ========================================================================= */