1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2002 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
14 #include <sys/types.h>
25 #if defined(PLATFORM_LINUX)
26 #include <sys/ioctl.h>
27 #include <linux/soundcard.h>
28 #elif defined(PLATFORM_FREEBSD)
29 #include <machine/soundcard.h>
30 #elif defined(PLATFORM_NETBSD)
31 #include <sys/ioctl.h>
32 #include <sys/audioio.h>
33 #elif defined(PLATFORM_HPUX)
34 #include <sys/audio.h>
44 /* expiration time (in milliseconds) for sound loops */
45 #define SOUND_LOOP_EXPIRATION_TIME 200
47 /* one second fading interval == 1000 ticks (milliseconds) */
48 #define SOUND_FADING_INTERVAL 1000
50 #if defined(AUDIO_STREAMING_DSP)
51 #define SOUND_FADING_VOLUME_STEP (SOUND_MAX_VOLUME / 40)
52 #define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2)
55 #define SND_TYPE_NONE 0
56 #define SND_TYPE_WAV 1
58 #define MUS_TYPE_NONE 0
59 #define MUS_TYPE_WAV 1
60 #define MUS_TYPE_MOD 2
62 #define DEVICENAME_DSP "/dev/dsp"
63 #define DEVICENAME_SOUND_DSP "/dev/sound/dsp"
64 #define DEVICENAME_AUDIO "/dev/audio"
65 #define DEVICENAME_AUDIOCTL "/dev/audioCtl"
67 #define SOUND_VOLUME_LEFT(x) (stereo_volume[x])
68 #define SOUND_VOLUME_RIGHT(x) (stereo_volume[SOUND_MAX_LEFT2RIGHT-x])
70 #define SAME_SOUND_NR(x,y) ((x).nr == (y).nr)
71 #define SAME_SOUND_DATA(x,y) ((x).data_ptr == (y).data_ptr)
74 struct SoundHeader_SUN
77 unsigned long hdr_size;
78 unsigned long data_size;
79 unsigned long encoding;
80 unsigned long sample_rate;
81 unsigned long channels;
84 struct SoundHeader_8SVX
87 unsigned long chunk_size;
92 #if defined(AUDIO_UNIX_NATIVE)
93 struct SoundHeader_WAV
95 unsigned short compression_code;
96 unsigned short num_channels;
97 unsigned long sample_rate;
98 unsigned long bytes_per_second;
99 unsigned short block_align;
100 unsigned short bits_per_sample;
104 struct AudioFormatInfo
106 boolean stereo; /* availability of stereo sound */
107 int format; /* size and endianess of sample data */
108 int sample_rate; /* sample frequency */
109 int fragment_size; /* audio device fragment size in bytes */
114 char *source_filename;
119 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
120 long data_len; /* number of samples, NOT number of bytes */
121 int num_channels; /* mono: 1 channel, stereo: 2 channels */
123 typedef struct SampleInfo SoundInfo;
124 typedef struct SampleInfo MusicInfo;
136 unsigned long playing_starttime;
137 unsigned long playing_pos;
141 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
142 long data_len; /* number of samples, NOT number of bytes */
143 int num_channels; /* mono: 1 channel, stereo: 2 channels */
145 #if defined(TARGET_ALLEGRO)
149 typedef struct SoundControl SoundControl;
151 static struct ArtworkListInfo *sound_info = NULL;
152 static SoundInfo **Sound = NULL;
153 static MusicInfo **Music = NULL;
154 static int num_sounds = 0, num_music = 0;
155 static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
158 /* ========================================================================= */
159 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
161 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
162 static int mixer_active_channels = 0;
164 #if defined(AUDIO_UNIX_NATIVE)
165 static struct AudioFormatInfo afmt;
167 static void Mixer_Main(void);
168 #if !defined(AUDIO_STREAMING_DSP)
169 static unsigned char linear_to_ulaw(int);
170 static int ulaw_to_linear(unsigned char);
174 static void ReloadCustomSounds();
175 static void ReloadCustomMusic();
176 static void FreeSound(void *);
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();
260 printf("PID: %d [%s]\n", getpid(),(IS_CHILD_PROCESS() ? "child" : "parent"));
264 if (IS_CHILD_PROCESS())
265 Mixer_Main(); /* this function never returns */
267 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
272 void UnixOpenAudio(void)
274 if (!TestAudioDevices())
277 audio.sound_available = TRUE;
278 audio.sound_enabled = TRUE;
280 #if defined(AUDIO_STREAMING_DSP)
281 audio.music_available = TRUE;
282 audio.loops_available = TRUE;
285 audio.num_channels = NUM_MIXER_CHANNELS;
286 audio.music_channel = MUSIC_CHANNEL;
287 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
290 void UnixCloseAudio(void)
293 close(audio.device_fd);
295 if (IS_PARENT_PROCESS())
296 kill(audio.mixer_pid, SIGTERM);
300 /* ------------------------------------------------------------------------- */
301 /* functions for platform specific audio device initialization */
302 /* ------------------------------------------------------------------------- */
304 #if defined(AUDIO_LINUX_IOCTL)
305 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
307 /* "ioctl()" expects pointer to 'int' value for stereo flag
308 (boolean is defined as 'char', which will not work here) */
309 unsigned int fragment_spec = 0;
310 int fragment_size_query;
319 /* supported audio format in preferred order */
320 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
321 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
322 { AFMT_U8, AUDIO_FORMAT_U8 },
327 /* determine logarithm (log2) of the fragment size */
328 while ((1 << fragment_spec) < afmt->fragment_size)
331 /* use two fragments (play one fragment, prepare the other);
332 one fragment would result in interrupted audio output, more
333 than two fragments would raise audio output latency to much */
334 fragment_spec |= 0x00020000;
336 /* Example for fragment specification:
337 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
338 - (with stereo the effective buffer size will shrink to 256)
339 => fragment_size = 0x00020009 */
341 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
342 Error(ERR_EXIT_SOUND_SERVER,
343 "cannot set fragment size of audio device -- no sounds");
347 while (formats[i].format_result != -1)
349 unsigned int audio_format = formats[i].format_ioctl;
350 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
352 afmt->format = formats[i].format_result;
357 if (afmt->format == 0) /* no supported audio format found */
358 Error(ERR_EXIT_SOUND_SERVER,
359 "cannot set audio format of audio device -- no sounds");
361 /* try if we can use stereo sound */
363 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
364 afmt->stereo = FALSE;
366 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
367 Error(ERR_EXIT_SOUND_SERVER,
368 "cannot set sample rate of audio device -- no sounds");
370 /* get the real fragmentation size; this should return 512 */
371 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
372 Error(ERR_EXIT_SOUND_SERVER,
373 "cannot get fragment size of audio device -- no sounds");
374 if (fragment_size_query != afmt->fragment_size)
375 Error(ERR_EXIT_SOUND_SERVER,
376 "cannot set fragment size of audio device -- no sounds");
378 #endif /* AUDIO_LINUX_IOCTL */
380 #if defined(PLATFORM_NETBSD)
381 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
384 boolean stereo = TRUE;
386 AUDIO_INITINFO(&a_info);
387 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
388 a_info.play.precision = 8;
389 a_info.play.channels = 2;
390 a_info.play.sample_rate = afmt->sample_rate;
391 a_info.blocksize = afmt->fragment_size;
393 afmt->format = AUDIO_FORMAT_U8;
396 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
398 /* try to disable stereo */
399 a_info.play.channels = 1;
401 afmt->stereo = FALSE;
403 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
404 Error(ERR_EXIT_SOUND_SERVER,
405 "cannot set sample rate of audio device -- no sounds");
408 #endif /* PLATFORM_NETBSD */
410 #if defined(PLATFORM_HPUX)
411 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
413 struct audio_describe ainfo;
416 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
418 Error(ERR_EXIT_SOUND_SERVER, "cannot open audio device -- no sounds");
420 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
421 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
423 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
424 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
426 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
427 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
429 afmt->format = AUDIO_FORMAT_U8;
430 afmt->stereo = FALSE;
431 afmt->sample_rate = 8000;
435 #endif /* PLATFORM_HPUX */
437 static void InitAudioDevice(struct AudioFormatInfo *afmt)
440 afmt->format = AUDIO_FORMAT_UNKNOWN;
441 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
442 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
444 #if defined(AUDIO_LINUX_IOCTL)
445 InitAudioDevice_Linux(afmt);
446 #elif defined(PLATFORM_NETBSD)
447 InitAudioDevice_NetBSD(afmt);
448 #elif defined(PLATFORM_HPUX)
449 InitAudioDevice_HPUX(afmt);
451 /* generic /dev/audio stuff might be placed here */
456 /* ------------------------------------------------------------------------- */
457 /* functions for communication between main process and sound mixer process */
458 /* ------------------------------------------------------------------------- */
460 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
462 if (IS_CHILD_PROCESS())
465 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
467 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
468 audio.sound_available = audio.sound_enabled = FALSE;
473 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
475 if (IS_PARENT_PROCESS())
478 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
479 != sizeof(SoundControl))
480 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
483 static void WriteReloadInfoToPipe(char *set_identifier, int type)
485 SoundControl snd_ctrl;
486 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
487 artwork.mus_current);
488 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
489 unsigned long str_size2 = strlen(leveldir_current->sounds_path) + 1;
490 unsigned long str_size3 = strlen(leveldir_current->music_path) + 1;
491 unsigned long str_size4 = strlen(ti->basepath) + 1;
492 unsigned long str_size5 = strlen(ti->fullpath) + 1;
493 boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
494 setup.override_level_sounds :
495 setup.override_level_music);
497 if (IS_CHILD_PROCESS())
500 if (leveldir_current == NULL) /* should never happen */
501 Error(ERR_EXIT, "leveldir_current == NULL");
503 snd_ctrl.active = FALSE;
504 snd_ctrl.state = type;
505 snd_ctrl.data_len = strlen(set_identifier) + 1;
507 if (write(audio.mixer_pipe[1], &snd_ctrl,
508 sizeof(snd_ctrl)) < 0 ||
509 write(audio.mixer_pipe[1], set_identifier,
510 snd_ctrl.data_len) < 0 ||
511 write(audio.mixer_pipe[1], &override_level_artwork,
512 sizeof(boolean)) < 0 ||
513 write(audio.mixer_pipe[1], leveldir_current,
514 sizeof(TreeInfo)) < 0 ||
515 write(audio.mixer_pipe[1], ti,
516 sizeof(TreeInfo)) < 0 ||
517 write(audio.mixer_pipe[1], &str_size1,
518 sizeof(unsigned long)) < 0 ||
519 write(audio.mixer_pipe[1], &str_size2,
520 sizeof(unsigned long)) < 0 ||
521 write(audio.mixer_pipe[1], &str_size3,
522 sizeof(unsigned long)) < 0 ||
523 write(audio.mixer_pipe[1], &str_size4,
524 sizeof(unsigned long)) < 0 ||
525 write(audio.mixer_pipe[1], &str_size5,
526 sizeof(unsigned long)) < 0 ||
527 write(audio.mixer_pipe[1], leveldir_current->fullpath,
529 write(audio.mixer_pipe[1], leveldir_current->sounds_path,
531 write(audio.mixer_pipe[1], leveldir_current->music_path,
533 write(audio.mixer_pipe[1], ti->basepath,
535 write(audio.mixer_pipe[1], ti->fullpath,
538 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
539 audio.sound_available = audio.sound_enabled = FALSE;
544 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
546 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
547 &artwork.snd_current : &artwork.mus_current);
548 TreeInfo *ti = *ti_ptr;
549 unsigned long str_size1, str_size2, str_size3, str_size4, str_size5;
550 static char *set_identifier = NULL;
551 boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
552 &setup.override_level_sounds :
553 &setup.override_level_music);
556 free(set_identifier);
558 set_identifier = checked_malloc(snd_ctrl->data_len);
560 if (leveldir_current == NULL)
561 leveldir_current = checked_calloc(sizeof(TreeInfo));
564 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
565 if (leveldir_current->fullpath != NULL)
566 free(leveldir_current->fullpath);
567 if (leveldir_current->sounds_path != NULL)
568 free(leveldir_current->sounds_path);
569 if (leveldir_current->music_path != NULL)
570 free(leveldir_current->music_path);
571 if (ti->basepath != NULL)
573 if (ti->fullpath != NULL)
576 if (read(audio.mixer_pipe[0], set_identifier,
577 snd_ctrl->data_len) != snd_ctrl->data_len ||
578 read(audio.mixer_pipe[0], override_level_artwork,
579 sizeof(boolean)) != sizeof(boolean) ||
580 read(audio.mixer_pipe[0], leveldir_current,
581 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
582 read(audio.mixer_pipe[0], ti,
583 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
584 read(audio.mixer_pipe[0], &str_size1,
585 sizeof(unsigned long)) != sizeof(unsigned long) ||
586 read(audio.mixer_pipe[0], &str_size2,
587 sizeof(unsigned long)) != sizeof(unsigned long) ||
588 read(audio.mixer_pipe[0], &str_size3,
589 sizeof(unsigned long)) != sizeof(unsigned long) ||
590 read(audio.mixer_pipe[0], &str_size4,
591 sizeof(unsigned long)) != sizeof(unsigned long) ||
592 read(audio.mixer_pipe[0], &str_size5,
593 sizeof(unsigned long)) != sizeof(unsigned long))
594 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
596 leveldir_current->fullpath = checked_calloc(str_size1);
597 leveldir_current->sounds_path = checked_calloc(str_size2);
598 leveldir_current->music_path = checked_calloc(str_size3);
599 ti->basepath = checked_calloc(str_size4);
600 ti->fullpath = checked_calloc(str_size5);
602 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
603 str_size1) != str_size1 ||
604 read(audio.mixer_pipe[0], leveldir_current->sounds_path,
605 str_size2) != str_size2 ||
606 read(audio.mixer_pipe[0], leveldir_current->music_path,
607 str_size3) != str_size3 ||
608 read(audio.mixer_pipe[0], ti->basepath,
609 str_size4) != str_size4 ||
610 read(audio.mixer_pipe[0], ti->fullpath,
611 str_size5) != str_size5)
612 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
614 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
615 artwork.snd_current_identifier = set_identifier;
617 artwork.mus_current_identifier = set_identifier;
620 #endif /* AUDIO_UNIX_NATIVE */
623 /* ------------------------------------------------------------------------- */
624 /* mixer functions */
625 /* ------------------------------------------------------------------------- */
627 void Mixer_InitChannels()
631 for(i=0; i<audio.num_channels; i++)
632 mixer[i].active = FALSE;
633 mixer_active_channels = 0;
636 static void Mixer_ResetChannelExpiration(int channel)
638 mixer[channel].playing_starttime = Counter();
640 #if defined(TARGET_SDL)
641 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
642 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
646 static boolean Mixer_ChannelExpired(int channel)
648 if (!mixer[channel].active)
651 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
652 DelayReached(&mixer[channel].playing_starttime,
653 SOUND_LOOP_EXPIRATION_TIME))
656 #if defined(TARGET_SDL)
658 if (!Mix_Playing(channel))
661 #elif defined(TARGET_ALLEGRO)
663 mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
664 mixer[channel].volume = voice_get_volume(mixer[channel].voice);
666 /* sound sample has completed playing or was completely faded out */
667 if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
670 #endif /* TARGET_ALLEGRO */
675 static boolean Mixer_AllocateChannel(int channel)
677 #if defined(TARGET_ALLEGRO)
678 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
679 if (mixer[channel].voice < 0)
686 static void Mixer_SetChannelProperties(int channel)
688 #if defined(TARGET_SDL)
689 Mix_Volume(channel, mixer[channel].volume);
690 Mix_SetPanning(channel,
691 SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
692 SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
693 #elif defined(TARGET_ALLEGRO)
694 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
695 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
699 static void Mixer_StartChannel(int channel)
701 #if defined(TARGET_SDL)
702 Mix_PlayChannel(channel, mixer[channel].data_ptr,
703 IS_LOOP(mixer[channel]) ? -1 : 0);
704 #elif defined(TARGET_ALLEGRO)
705 if (IS_LOOP(mixer[channel]))
706 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
708 voice_start(mixer[channel].voice);
712 static void Mixer_PlayChannel(int channel)
714 /* start with inactive channel in case something goes wrong */
715 mixer[channel].active = FALSE;
717 if (mixer[channel].type != MUS_TYPE_WAV)
720 if (!Mixer_AllocateChannel(channel))
723 Mixer_SetChannelProperties(channel);
724 Mixer_StartChannel(channel);
726 Mixer_ResetChannelExpiration(channel);
728 mixer[channel].playing_pos = 0;
729 mixer[channel].active = TRUE;
730 mixer_active_channels++;
733 static void Mixer_PlayMusicChannel()
735 Mixer_PlayChannel(audio.music_channel);
737 #if defined(TARGET_SDL)
738 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
740 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
741 this looks like a bug in the SDL_mixer library */
742 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
743 Mix_VolumeMusic(SOUND_MAX_VOLUME);
748 static void Mixer_StopChannel(int channel)
750 if (!mixer[channel].active)
753 #if defined(TARGET_SDL)
754 Mix_HaltChannel(channel);
755 #elif defined(TARGET_ALLEGRO)
756 voice_set_volume(mixer[channel].voice, 0);
757 deallocate_voice(mixer[channel].voice);
760 mixer[channel].active = FALSE;
761 mixer_active_channels--;
764 static void Mixer_StopMusicChannel()
766 Mixer_StopChannel(audio.music_channel);
768 #if defined(TARGET_SDL)
773 static void Mixer_FadeChannel(int channel)
775 if (!mixer[channel].active)
778 mixer[channel].state |= SND_CTRL_FADE;
780 #if defined(TARGET_SDL)
781 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
782 #elif defined(TARGET_ALLEGRO)
783 if (voice_check(mixer[channel].voice))
784 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
788 static void Mixer_FadeMusicChannel()
790 Mixer_FadeChannel(audio.music_channel);
792 #if defined(TARGET_SDL)
793 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
797 static void Mixer_UnFadeChannel(int channel)
799 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
802 mixer[channel].state &= ~SND_CTRL_FADE;
803 mixer[channel].volume = SOUND_MAX_VOLUME;
805 #if defined(TARGET_SDL)
806 Mix_ExpireChannel(channel, -1);
807 Mix_Volume(channel, mixer[channel].volume);
808 #elif defined(TARGET_ALLEGRO)
809 voice_stop_volumeramp(mixer[channel].voice);
810 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
811 mixer[channel].volume);
815 static void Mixer_InsertSound(SoundControl snd_ctrl)
821 printf("NEW SOUND %d ARRIVED [%d] [%d ACTIVE CHANNELS]\n",
822 snd_ctrl.nr, num_sounds, mixer_active_channels);
825 if (IS_MUSIC(snd_ctrl))
830 snd_ctrl.nr = snd_ctrl.nr % num_music;
832 else if (snd_ctrl.nr >= num_sounds)
835 snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
836 if (snd_info == NULL)
839 /* copy sound sample and format information */
840 snd_ctrl.type = snd_info->type;
841 snd_ctrl.format = snd_info->format;
842 snd_ctrl.data_ptr = snd_info->data_ptr;
843 snd_ctrl.data_len = snd_info->data_len;
844 snd_ctrl.num_channels = snd_info->num_channels;
846 /* play music samples on a dedicated music channel */
847 if (IS_MUSIC(snd_ctrl))
849 Mixer_StopMusicChannel();
851 mixer[audio.music_channel] = snd_ctrl;
852 Mixer_PlayMusicChannel();
857 /* check if (and how often) this sound sample is already playing */
858 for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
859 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
863 printf("SOUND %d [CURRENTLY PLAYING %d TIMES]\n", snd_ctrl.nr, k);
866 /* reset expiration delay for already playing loop sounds */
867 if (k > 0 && IS_LOOP(snd_ctrl))
869 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
871 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
874 printf("RESETTING EXPIRATION FOR SOUND %d\n", snd_ctrl.nr);
877 if (IS_FADING(mixer[i]))
878 Mixer_UnFadeChannel(i);
880 /* restore settings like volume and stereo position */
881 mixer[i].volume = snd_ctrl.volume;
882 mixer[i].stereo_position = snd_ctrl.stereo_position;
884 Mixer_SetChannelProperties(i);
885 Mixer_ResetChannelExpiration(i);
888 printf("RESETTING VOLUME/STEREO FOR SOUND %d TO %d/%d\n",
889 snd_ctrl.nr, snd_ctrl.volume, snd_ctrl.stereo_position);
898 printf("PLAYING NEW SOUND %d\n", snd_ctrl.nr);
901 /* don't play sound more than n times simultaneously (with n == 2 for now) */
904 unsigned long playing_current = Counter();
905 int longest = 0, longest_nr = audio.first_sound_channel;
907 /* look for oldest equal sound */
908 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
910 int playing_time = playing_current - mixer[i].playing_starttime;
913 if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
916 actual = 1000 * playing_time / mixer[i].data_len;
918 if (actual >= longest)
925 Mixer_StopChannel(longest_nr);
928 /* If all (non-music) channels are active, stop the channel that has
929 played its sound sample most completely (in percent of the sample
930 length). As we cannot currently get the actual playing position
931 of the channel's sound sample when compiling with the SDL mixer
932 library, we use the current playing time (in milliseconds) instead. */
935 /* channel allocation sanity check -- should not be needed */
936 if (mixer_active_channels ==
937 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
939 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
941 if (!mixer[i].active)
943 Error(ERR_RETURN, "Mixer_InsertSound: Channel %d inactive", i);
944 Error(ERR_RETURN, "Mixer_InsertSound: This should never happen!");
946 mixer_active_channels--;
952 if (mixer_active_channels ==
953 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
955 unsigned long playing_current = Counter();
956 int longest = 0, longest_nr = audio.first_sound_channel;
960 /* print some debugging information about audio channel usage */
961 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
963 Error(ERR_RETURN, "Mixer_InsertSound: %d [%d]: %ld (%ld)",
964 i, mixer[i].active, mixer[i].data_len, (long)mixer[i].data_ptr);
969 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
971 int playing_time = playing_current - mixer[i].playing_starttime;
972 int actual = 1000 * playing_time / mixer[i].data_len;
974 if (!IS_LOOP(mixer[i]) && actual > longest)
981 Mixer_StopChannel(longest_nr);
984 /* add the new sound to the mixer */
985 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
988 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
991 if (!mixer[i].active)
994 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
997 #if defined(AUDIO_UNIX_NATIVE)
998 if (snd_info->data_len == 0)
1000 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
1004 mixer[i] = snd_ctrl;
1005 Mixer_PlayChannel(i);
1012 static void HandleSoundRequest(SoundControl snd_ctrl)
1016 #if defined(AUDIO_UNIX_NATIVE)
1017 if (IS_PARENT_PROCESS())
1019 SendSoundControlToMixerProcess(&snd_ctrl);
1024 /* deactivate channels that have expired since the last request */
1025 for (i=0; i<audio.num_channels; i++)
1026 if (mixer[i].active && Mixer_ChannelExpired(i))
1027 Mixer_StopChannel(i);
1029 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
1031 Mixer_StopMusicChannel();
1032 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1033 Mixer_StopChannel(i);
1035 #if defined(AUDIO_UNIX_NATIVE)
1036 CloseAudioDevice(&audio.device_fd);
1037 ReadReloadInfoFromPipe(&snd_ctrl);
1040 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
1041 ReloadCustomSounds();
1043 ReloadCustomMusic();
1045 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
1047 if (IS_MUSIC(snd_ctrl))
1049 Mixer_FadeMusicChannel();
1053 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1054 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1055 Mixer_FadeChannel(i);
1057 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
1059 if (IS_MUSIC(snd_ctrl))
1061 Mixer_StopMusicChannel();
1065 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1066 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1067 Mixer_StopChannel(i);
1069 #if defined(AUDIO_UNIX_NATIVE)
1070 if (!mixer_active_channels)
1071 CloseAudioDevice(&audio.device_fd);
1074 else if (snd_ctrl.active) /* add new sound to mixer */
1076 Mixer_InsertSound(snd_ctrl);
1080 void StartMixer(void)
1085 SDL_version compile_version;
1086 const SDL_version *link_version;
1087 MIX_VERSION(&compile_version);
1088 printf("compiled with SDL_mixer version: %d.%d.%d\n",
1089 compile_version.major,
1090 compile_version.minor,
1091 compile_version.patch);
1092 link_version = Mix_Linked_Version();
1093 printf("running with SDL_mixer version: %d.%d.%d\n",
1094 link_version->major,
1095 link_version->minor,
1096 link_version->patch);
1099 if (!audio.sound_available)
1102 /* initialize stereo position conversion information */
1103 for(i=0; i<=SOUND_MAX_LEFT2RIGHT; i++)
1105 (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1107 #if defined(AUDIO_UNIX_NATIVE)
1108 if (!ForkAudioProcess())
1109 audio.sound_available = FALSE;
1113 #if defined(AUDIO_UNIX_NATIVE)
1115 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1116 int sample_pos, int sample_size,
1117 short *buffer_base_ptr, int buffer_pos,
1118 int num_output_channels)
1120 short *buffer_ptr = buffer_base_ptr + num_output_channels * buffer_pos;
1121 int num_channels = snd_ctrl->num_channels;
1122 int stepsize = num_channels;
1123 int output_stepsize = num_output_channels;
1126 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1128 byte *sample_ptr = (byte *)snd_ctrl->data_ptr + num_channels * sample_pos;
1130 for (i=0; i<num_output_channels; i++)
1132 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1134 for (j=0; j<sample_size; j++)
1135 buffer_ptr[output_stepsize * j + i] =
1136 ((short)(sample_ptr[stepsize * j + offset] ^ 0x80)) << 8;
1139 else /* AUDIO_FORMAT_S16 */
1141 short *sample_ptr= (short *)snd_ctrl->data_ptr + num_channels * sample_pos;
1143 for (i=0; i<num_output_channels; i++)
1145 int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
1147 for (j=0; j<sample_size; j++)
1148 buffer_ptr[output_stepsize * j + i] =
1149 sample_ptr[stepsize * j + offset];
1154 #if defined(AUDIO_STREAMING_DSP)
1155 static void Mixer_Main_DSP()
1157 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1158 static long premix_last_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1159 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1163 int max_sample_size;
1164 int num_output_channels;
1167 if (!mixer_active_channels)
1170 if (audio.device_fd < 0)
1172 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1175 InitAudioDevice(&afmt);
1178 stereo = afmt.stereo;
1179 fragment_size = afmt.fragment_size;
1180 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1181 num_output_channels = (stereo ? 2 : 1);
1182 max_sample_size = fragment_size / (num_output_channels * sample_bytes);
1184 /* first clear the last premixing buffer */
1185 memset(premix_last_buffer, 0,
1186 max_sample_size * num_output_channels * sizeof(long));
1188 for(i=0; i<audio.num_channels; i++)
1195 if (!mixer[i].active)
1198 if (Mixer_ChannelExpired(i))
1200 Mixer_StopChannel(i);
1204 /* pointer, lenght and actual playing position of sound sample */
1205 sample_ptr = mixer[i].data_ptr;
1206 sample_len = mixer[i].data_len;
1207 sample_pos = mixer[i].playing_pos;
1208 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1209 mixer[i].playing_pos += sample_size;
1211 /* copy original sample to first mixing buffer */
1212 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1213 premix_first_buffer, 0, num_output_channels);
1215 /* are we about to restart a looping sound? */
1216 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1218 while (sample_size < max_sample_size)
1220 int restarted_sample_size =
1221 MIN(max_sample_size - sample_size, sample_len);
1223 CopySampleToMixingBuffer(&mixer[i], 0, restarted_sample_size,
1224 premix_first_buffer, sample_size,
1225 num_output_channels);
1227 mixer[i].playing_pos = restarted_sample_size;
1228 sample_size += restarted_sample_size;
1232 /* decrease volume if sound is fading out */
1233 if (IS_FADING(mixer[i]) &&
1234 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1235 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1237 /* adjust volume of actual sound sample */
1238 if (mixer[i].volume != SOUND_MAX_VOLUME)
1239 for(j=0; j<sample_size * num_output_channels; j++)
1240 premix_first_buffer[j] =
1241 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1243 /* adjust left and right channel volume due to stereo sound position */
1246 int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1247 int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1249 for(j=0; j<sample_size; j++)
1251 premix_first_buffer[2 * j + 0] =
1252 left_volume * premix_first_buffer[2 * j + 0] / SOUND_MAX_LEFT2RIGHT;
1253 premix_first_buffer[2 * j + 1] =
1254 right_volume * premix_first_buffer[2 * j + 1] / SOUND_MAX_LEFT2RIGHT;
1258 /* fill the last mixing buffer with stereo or mono sound */
1259 for(j=0; j<sample_size * num_output_channels; j++)
1260 premix_last_buffer[j] += premix_first_buffer[j];
1262 /* delete completed sound entries from the mixer */
1263 if (mixer[i].playing_pos >= mixer[i].data_len)
1265 if (IS_LOOP(mixer[i]))
1266 mixer[i].playing_pos = 0;
1268 Mixer_StopChannel(i);
1270 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1271 Mixer_StopChannel(i);
1274 /* prepare final playing buffer according to system audio format */
1275 for(i=0; i<max_sample_size * num_output_channels; i++)
1277 /* cut off at 17 bit value */
1278 if (premix_last_buffer[i] < -65535)
1279 premix_last_buffer[i] = -65535;
1280 else if (premix_last_buffer[i] > 65535)
1281 premix_last_buffer[i] = 65535;
1283 /* shift to 16 bit value */
1284 premix_last_buffer[i] >>= 1;
1286 if (afmt.format & AUDIO_FORMAT_U8)
1288 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1290 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1292 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1293 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1295 else /* big endian */
1297 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1298 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1302 /* finally play the sound fragment */
1303 write(audio.device_fd, playing_buffer, fragment_size);
1305 if (!mixer_active_channels)
1306 CloseAudioDevice(&audio.device_fd);
1309 #else /* !AUDIO_STREAMING_DSP */
1311 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1313 static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1314 static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
1315 int max_sample_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
1316 int num_output_channels = 1;
1325 /* pointer, lenght and actual playing position of sound sample */
1326 sample_ptr = mixer[i].data_ptr;
1327 sample_len = mixer[i].data_len;
1328 sample_pos = mixer[i].playing_pos;
1329 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1330 mixer[i].playing_pos += sample_size;
1332 /* copy original sample to first mixing buffer */
1333 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1334 premix_first_buffer, 0, num_output_channels);
1336 /* adjust volume of actual sound sample */
1337 if (mixer[i].volume != SOUND_MAX_VOLUME)
1338 for(j=0; j<sample_size; j++)
1339 premix_first_buffer[j] =
1340 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1342 /* might be needed for u-law /dev/audio */
1344 for(j=0; j<sample_size; j++)
1346 linear_to_ulaw(premix_first_buffer[j]);
1349 /* delete completed sound entries from the mixer */
1350 if (mixer[i].playing_pos >= mixer[i].data_len)
1351 Mixer_StopChannel(i);
1353 for(i=0; i<sample_size; i++)
1354 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1356 /* finally play the sound fragment */
1357 write(audio.device_fd, playing_buffer, sample_size);
1361 #endif /* !AUDIO_STREAMING_DSP */
1365 SoundControl snd_ctrl;
1368 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1370 Mixer_InitChannels();
1372 #if defined(PLATFORM_HPUX)
1373 InitAudioDevice(&afmt);
1376 FD_ZERO(&mixer_fdset);
1377 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1379 while(1) /* wait for sound playing commands from client */
1381 struct timeval delay = { 0, 0 };
1383 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1384 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1385 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1388 ReadSoundControlFromMainProcess(&snd_ctrl);
1390 HandleSoundRequest(snd_ctrl);
1392 #if defined(AUDIO_STREAMING_DSP)
1394 while (mixer_active_channels &&
1395 select(audio.mixer_pipe[0] + 1,
1396 &mixer_fdset, NULL, NULL, &delay) < 1)
1398 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1403 #else /* !AUDIO_STREAMING_DSP */
1405 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1406 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1409 InitAudioDevice(&afmt);
1414 while (mixer_active_channels &&
1415 select(audio.mixer_pipe[0] + 1,
1416 &mixer_fdset, NULL, NULL, &delay) < 1)
1418 int wait_percent = 90; /* wait 90% of the real playing time */
1421 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1423 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1427 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1430 CloseAudioDevice(&audio.device_fd);
1432 Mixer_InitChannels(); /* remove all sounds from mixer */
1434 #endif /* !AUDIO_STREAMING_DSP */
1437 #endif /* AUDIO_UNIX_NATIVE */
1440 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1442 /* these two are stolen from "sox"... :) */
1445 ** This routine converts from linear to ulaw.
1447 ** Craig Reese: IDA/Supercomputing Research Center
1448 ** Joe Campbell: Department of Defense
1449 ** 29 September 1989
1452 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1453 ** 2) "A New Digital Technique for Implementation of Any
1454 ** Continuous PCM Companding Law," Villeret, Michel,
1455 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1456 ** 1973, pg. 11.12-11.17
1457 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1458 ** for Analog-to_Digital Conversion Techniques,"
1461 ** Input: Signed 16 bit linear sample
1462 ** Output: 8 bit ulaw sample
1465 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1466 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1469 static unsigned char linear_to_ulaw(int sample)
1471 static int exp_lut[256] =
1473 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1474 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1475 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1476 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1477 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1478 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1479 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1480 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1481 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1482 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1483 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1484 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1485 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1486 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1487 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1488 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1491 int sign, exponent, mantissa;
1492 unsigned char ulawbyte;
1494 /* Get the sample into sign-magnitude. */
1495 sign = (sample >> 8) & 0x80; /* set aside the sign */
1497 sample = -sample; /* get magnitude */
1499 sample = CLIP; /* clip the magnitude */
1501 /* Convert from 16 bit linear to ulaw. */
1502 sample = sample + BIAS;
1503 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1504 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1505 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1508 ulawbyte = 0x02; /* optional CCITT trap */
1515 ** This routine converts from ulaw to 16 bit linear.
1517 ** Craig Reese: IDA/Supercomputing Research Center
1518 ** 29 September 1989
1521 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1522 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1523 ** for Analog-to_Digital Conversion Techniques,"
1526 ** Input: 8 bit ulaw sample
1527 ** Output: signed 16 bit linear sample
1530 static int ulaw_to_linear(unsigned char ulawbyte)
1532 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1533 int sign, exponent, mantissa, sample;
1535 ulawbyte = ~ ulawbyte;
1536 sign = ( ulawbyte & 0x80 );
1537 exponent = ( ulawbyte >> 4 ) & 0x07;
1538 mantissa = ulawbyte & 0x0F;
1539 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1545 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1548 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1549 /* ========================================================================= */
1550 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1552 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1553 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1555 static void *Load_WAV(char *filename)
1557 SoundInfo *snd_info;
1558 #if defined(AUDIO_UNIX_NATIVE)
1559 struct SoundHeader_WAV header;
1561 byte sound_header_buffer[WAV_HEADER_SIZE];
1564 char chunk_name[CHUNK_ID_LEN + 1];
1570 if (!audio.sound_available)
1574 printf("loading WAV file '%s'\n", filename);
1577 snd_info = checked_calloc(sizeof(SoundInfo));
1579 #if defined(TARGET_SDL)
1581 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1583 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1588 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1590 #elif defined(TARGET_ALLEGRO)
1592 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1594 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1599 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1601 #else /* AUDIO_UNIX_NATIVE */
1603 if ((file = fopen(filename, MODE_READ)) == NULL)
1605 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1610 /* read chunk id "RIFF" */
1611 getFileChunkLE(file, chunk_name, &chunk_size);
1612 if (strcmp(chunk_name, "RIFF") != 0)
1614 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1620 /* read "RIFF" type id "WAVE" */
1621 getFileChunkLE(file, chunk_name, NULL);
1622 if (strcmp(chunk_name, "WAVE") != 0)
1624 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1630 while (getFileChunkLE(file, chunk_name, &chunk_size))
1632 if (strcmp(chunk_name, "fmt ") == 0)
1634 if (chunk_size < WAV_HEADER_SIZE)
1636 Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1642 header.compression_code = getFile16BitLE(file);
1643 header.num_channels = getFile16BitLE(file);
1644 header.sample_rate = getFile32BitLE(file);
1645 header.bytes_per_second = getFile32BitLE(file);
1646 header.block_align = getFile16BitLE(file);
1647 header.bits_per_sample = getFile16BitLE(file);
1649 if (chunk_size > WAV_HEADER_SIZE)
1650 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1652 if (header.compression_code != 1)
1654 Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1655 filename, header.compression_code);
1661 if (header.num_channels != 1 &&
1662 header.num_channels != 2)
1664 Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
1665 filename, header.num_channels);
1671 if (header.bits_per_sample != 8 &&
1672 header.bits_per_sample != 16)
1674 Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1675 filename, header.bits_per_sample);
1681 /* warn, but accept wrong sample rate (may be only slightly different) */
1682 if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1683 Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1684 filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1687 printf("WAV file: '%s'\n", filename);
1688 printf(" Compression code: %d'\n", header.compression_code);
1689 printf(" Number of channels: %d'\n", header.num_channels);
1690 printf(" Sample rate: %ld'\n", header.sample_rate);
1691 printf(" Average bytes per second: %ld'\n", header.bytes_per_second);
1692 printf(" Block align: %d'\n", header.block_align);
1693 printf(" Significant bits per sample: %d'\n", header.bits_per_sample);
1696 else if (strcmp(chunk_name, "data") == 0)
1698 data_byte_len = chunk_size;
1700 snd_info->data_len = data_byte_len;
1701 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1703 /* read sound data */
1704 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1707 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1709 free(snd_info->data_ptr);
1714 /* check for odd number of data bytes (data chunk is word aligned) */
1715 if ((data_byte_len % 2) == 1)
1716 ReadUnusedBytesFromFile(file, 1);
1718 else /* unknown chunk -- ignore */
1719 ReadUnusedBytesFromFile(file, chunk_size);
1724 if (snd_info->data_ptr == NULL)
1726 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1731 if (header.bits_per_sample == 8)
1732 snd_info->format = AUDIO_FORMAT_U8;
1733 else /* header.bits_per_sample == 16 */
1735 snd_info->format = AUDIO_FORMAT_S16;
1736 snd_info->data_len /= 2; /* correct number of samples */
1739 snd_info->num_channels = header.num_channels;
1740 if (header.num_channels == 2)
1741 snd_info->data_len /= 2; /* correct number of samples */
1744 if (header.num_channels == 1) /* convert mono sound to stereo */
1746 void *buffer_ptr = checked_malloc(data_byte_len * 2);
1747 void *sample_ptr = snd_info->data_ptr;
1748 int sample_size = snd_info->data_len;
1751 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1752 for (i=0; i<sample_size; i++)
1754 ((short)(((byte *)sample_ptr)[i] ^ 0x80)) << 8;
1755 else /* AUDIO_FORMAT_S16 */
1756 for (i=0; i<sample_size; i++)
1758 ((short *)sample_ptr)[i];
1762 #endif /* AUDIO_UNIX_NATIVE */
1764 snd_info->type = SND_TYPE_WAV;
1765 snd_info->source_filename = getStringCopy(filename);
1770 int getSoundListSize()
1772 return (sound_info->num_file_list_entries +
1773 sound_info->num_dynamic_file_list_entries);
1776 struct FileInfo *getSoundListEntry(int pos)
1778 int num_list_entries = sound_info->num_file_list_entries;
1779 int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
1781 return (pos < num_list_entries ? &sound_info->file_list[list_pos] :
1782 &sound_info->dynamic_file_list[list_pos]);
1785 int getSoundListPropertyMappingSize()
1787 return sound_info->num_property_mapping_entries;
1790 struct PropertyMapping *getSoundListPropertyMapping()
1792 return sound_info->property_mapping;
1795 void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
1796 struct ConfigInfo *config_suffix_list,
1797 char **base_prefixes,
1798 char **ext1_suffixes,
1799 char **ext2_suffixes,
1800 char **ext3_suffixes)
1804 sound_info = checked_calloc(sizeof(struct ArtworkListInfo));
1805 sound_info->type = ARTWORK_TYPE_SOUNDS;
1807 /* ---------- initialize file list and suffix lists ---------- */
1809 sound_info->num_file_list_entries = num_file_list_entries;
1810 sound_info->num_dynamic_file_list_entries = 0;
1812 sound_info->file_list =
1813 getFileListFromConfigList(config_list, config_suffix_list,
1814 num_file_list_entries);
1815 sound_info->dynamic_file_list = NULL;
1817 sound_info->num_suffix_list_entries = 0;
1818 for (i=0; config_suffix_list[i].token != NULL; i++)
1819 sound_info->num_suffix_list_entries++;
1821 sound_info->suffix_list = config_suffix_list;
1823 /* ---------- initialize base prefix and suffixes lists ---------- */
1825 sound_info->num_base_prefixes = 0;
1826 for (i=0; base_prefixes[i] != NULL; i++)
1827 sound_info->num_base_prefixes++;
1829 sound_info->num_ext1_suffixes = 0;
1830 for (i=0; ext1_suffixes[i] != NULL; i++)
1831 sound_info->num_ext1_suffixes++;
1833 sound_info->num_ext2_suffixes = 0;
1834 for (i=0; ext2_suffixes[i] != NULL; i++)
1835 sound_info->num_ext2_suffixes++;
1837 sound_info->num_ext3_suffixes = 0;
1838 for (i=0; ext3_suffixes[i] != NULL; i++)
1839 sound_info->num_ext3_suffixes++;
1841 sound_info->base_prefixes = base_prefixes;
1842 sound_info->ext1_suffixes = ext1_suffixes;
1843 sound_info->ext2_suffixes = ext2_suffixes;
1844 sound_info->ext3_suffixes = ext3_suffixes;
1846 sound_info->num_property_mapping_entries = 0;
1848 sound_info->property_mapping = NULL;
1850 /* ---------- initialize artwork reference and content lists ---------- */
1852 sound_info->sizeof_artwork_list_entry = sizeof(SoundInfo *);
1854 sound_info->artwork_list =
1855 checked_calloc(num_file_list_entries * sizeof(SoundInfo *));
1856 sound_info->dynamic_artwork_list = NULL;
1858 sound_info->content_list = NULL;
1860 /* ---------- initialize artwork loading/freeing functions ---------- */
1862 sound_info->load_artwork = Load_WAV;
1863 sound_info->free_artwork = FreeSound;
1865 num_sounds = sound_info->num_file_list_entries;
1866 Sound = (SoundInfo **)sound_info->artwork_list;
1869 static MusicInfo *Load_MOD(char *filename)
1871 #if defined(TARGET_SDL)
1872 MusicInfo *mod_info;
1874 if (!audio.sound_available)
1877 mod_info = checked_calloc(sizeof(MusicInfo));
1879 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1881 Error(ERR_WARN, "cannot read music file '%s'", filename);
1886 mod_info->type = MUS_TYPE_MOD;
1887 mod_info->source_filename = getStringCopy(filename);
1895 void LoadCustomMusic(void)
1897 static boolean draw_init_text = TRUE; /* only draw at startup */
1898 static char *last_music_directory = NULL;
1899 char *music_directory = getCustomMusicDirectory();
1901 struct dirent *dir_entry;
1903 if (!audio.sound_available)
1906 if (last_music_directory != NULL &&
1907 strcmp(last_music_directory, music_directory) == 0)
1908 return; /* old and new music directory are the same */
1910 if (last_music_directory != NULL)
1911 free(last_music_directory);
1912 last_music_directory = getStringCopy(music_directory);
1916 if ((dir = opendir(music_directory)) == NULL)
1918 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1919 audio.music_available = FALSE;
1924 DrawInitText("Loading music:", 120, FC_GREEN);
1926 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1928 char *basename = dir_entry->d_name;
1929 char *filename = getPath2(music_directory, basename);
1930 MusicInfo *mus_info = NULL;
1933 printf("DEBUG: loading music '%s' ...\n", basename);
1937 DrawInitText(basename, 150, FC_YELLOW);
1939 if (FileIsSound(basename))
1940 mus_info = Load_WAV(filename);
1941 else if (FileIsMusic(basename))
1942 mus_info = Load_MOD(filename);
1949 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1950 Music[num_music - 1] = mus_info;
1956 draw_init_text = FALSE;
1959 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1963 void PlayMusic(int nr)
1965 if (!audio.music_available)
1971 void PlaySound(int nr)
1973 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
1976 void PlaySoundStereo(int nr, int stereo_position)
1978 PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
1981 void PlaySoundLoop(int nr)
1983 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
1986 void PlaySoundMusic(int nr)
1988 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
1991 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
1993 SoundControl snd_ctrl;
1995 if (!audio.sound_available ||
1996 !audio.sound_enabled ||
1997 audio.sound_deactivated)
2000 if (volume < SOUND_MIN_VOLUME)
2001 volume = SOUND_MIN_VOLUME;
2002 else if (volume > SOUND_MAX_VOLUME)
2003 volume = SOUND_MAX_VOLUME;
2005 if (stereo_position < SOUND_MAX_LEFT)
2006 stereo_position = SOUND_MAX_LEFT;
2007 else if (stereo_position > SOUND_MAX_RIGHT)
2008 stereo_position = SOUND_MAX_RIGHT;
2010 snd_ctrl.active = TRUE;
2012 snd_ctrl.volume = volume;
2013 snd_ctrl.stereo_position = stereo_position;
2014 snd_ctrl.state = state;
2016 HandleSoundRequest(snd_ctrl);
2019 void FadeMusic(void)
2021 if (!audio.music_available)
2024 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
2027 void FadeSound(int nr)
2029 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
2035 StopSoundExt(-1, SND_CTRL_FADE_ALL);
2038 void StopMusic(void)
2040 if (!audio.music_available)
2043 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
2046 void StopSound(int nr)
2048 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
2054 StopSoundExt(-1, SND_CTRL_STOP_ALL);
2057 void StopSoundExt(int nr, int state)
2059 SoundControl snd_ctrl;
2061 if (!audio.sound_available)
2064 snd_ctrl.active = FALSE;
2066 snd_ctrl.state = state;
2068 HandleSoundRequest(snd_ctrl);
2071 static void ReloadCustomSounds()
2074 printf("DEBUG: reloading sounds '%s' ...\n", artwork.snd_current_identifier);
2077 LoadArtworkConfig(sound_info);
2078 ReloadCustomArtworkList(sound_info);
2081 static void ReloadCustomMusic()
2084 printf("DEBUG: reloading music '%s' ...\n", artwork.mus_current_identifier);
2090 void InitReloadCustomSounds(char *set_identifier)
2092 if (!audio.sound_available)
2095 #if defined(AUDIO_UNIX_NATIVE)
2096 LoadArtworkConfig(sound_info); /* also load config on sound client */
2097 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_SOUNDS);
2099 ReloadCustomSounds();
2103 void InitReloadCustomMusic(char *set_identifier)
2105 if (!audio.music_available)
2108 #if defined(AUDIO_UNIX_NATIVE)
2109 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
2111 ReloadCustomMusic();
2115 void FreeSound(void *ptr)
2117 SoundInfo *sound = (SoundInfo *)ptr;
2122 if (sound->data_ptr)
2124 #if defined(TARGET_SDL)
2125 Mix_FreeChunk(sound->data_ptr);
2126 #elif defined(TARGET_ALLEGRO)
2127 destroy_sample(sound->data_ptr);
2128 #else /* AUDIO_UNIX_NATIVE */
2129 free(sound->data_ptr);
2133 if (sound->source_filename)
2134 free(sound->source_filename);
2139 void FreeMusic(MusicInfo *music)
2144 if (music->data_ptr)
2146 #if defined(TARGET_SDL)
2147 if (music->type == MUS_TYPE_MOD)
2148 Mix_FreeMusic(music->data_ptr);
2150 Mix_FreeChunk(music->data_ptr);
2151 #elif defined(TARGET_ALLEGRO)
2152 destroy_sample(music->data_ptr);
2153 #else /* AUDIO_UNIX_NATIVE */
2154 free(music->data_ptr);
2161 void FreeAllSounds()
2163 FreeCustomArtworkLists(sound_info);
2173 for(i=0; i<num_music; i++)
2174 FreeMusic(Music[i]);
2182 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2183 /* ========================================================================= */