1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2002 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
14 #include <sys/types.h>
25 #if defined(PLATFORM_LINUX)
26 #include <sys/ioctl.h>
27 #include <linux/soundcard.h>
28 #elif defined(PLATFORM_FREEBSD)
29 #include <machine/soundcard.h>
30 #elif defined(PLATFORM_NETBSD)
31 #include <sys/ioctl.h>
32 #include <sys/audioio.h>
33 #elif defined(PLATFORM_HPUX)
34 #include <sys/audio.h>
44 /* expiration time (in milliseconds) for sound loops */
45 #define SOUND_LOOP_EXPIRATION_TIME 200
47 /* one second fading interval == 1000 ticks (milliseconds) */
48 #define SOUND_FADING_INTERVAL 1000
50 #if defined(AUDIO_STREAMING_DSP)
51 #define SOUND_FADING_VOLUME_STEP (SOUND_MAX_VOLUME / 40)
52 #define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2)
55 #if !defined(PLATFORM_HPUX)
56 #define SND_BLOCKSIZE 4096
58 #define SND_BLOCKSIZE 32768
61 #define SND_TYPE_NONE 0
62 #define SND_TYPE_WAV 1
64 #define MUS_TYPE_NONE 0
65 #define MUS_TYPE_WAV 1
66 #define MUS_TYPE_MOD 2
68 #define DEVICENAME_DSP "/dev/dsp"
69 #define DEVICENAME_SOUND_DSP "/dev/sound/dsp"
70 #define DEVICENAME_AUDIO "/dev/audio"
71 #define DEVICENAME_AUDIOCTL "/dev/audioCtl"
73 #define SOUND_VOLUME_LEFT(x) (stereo_volume[x])
74 #define SOUND_VOLUME_RIGHT(x) (stereo_volume[SOUND_MAX_LEFT2RIGHT-x])
76 #define SAME_SOUND_NR(x,y) ((x).nr == (y).nr)
77 #define SAME_SOUND_DATA(x,y) ((x).data_ptr == (y).data_ptr)
80 struct SoundHeader_SUN
83 unsigned long hdr_size;
84 unsigned long data_size;
85 unsigned long encoding;
86 unsigned long sample_rate;
87 unsigned long channels;
90 struct SoundHeader_8SVX
93 unsigned long chunk_size;
98 #if defined(AUDIO_UNIX_NATIVE)
99 struct SoundHeader_WAV
101 unsigned short compression_code;
102 unsigned short num_channels;
103 unsigned long sample_rate;
104 unsigned long bytes_per_second;
105 unsigned short block_align;
106 unsigned short bits_per_sample;
110 struct AudioFormatInfo
112 boolean stereo; /* availability of stereo sound */
113 int format; /* size and endianess of sample data */
114 int sample_rate; /* sample frequency */
115 int fragment_size; /* audio device fragment size in bytes */
120 char *source_filename;
125 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
126 long data_len; /* number of samples, NOT number of bytes */
128 typedef struct SampleInfo SoundInfo;
129 typedef struct SampleInfo MusicInfo;
141 unsigned long playing_starttime;
142 unsigned long playing_pos;
146 void *data_ptr; /* pointer to first sample (8 or 16 bit) */
147 long data_len; /* number of samples, NOT number of bytes */
149 #if defined(TARGET_ALLEGRO)
153 typedef struct SoundControl SoundControl;
155 static struct ArtworkListInfo *sound_info = NULL;
156 static SoundInfo **Sound = NULL;
157 static MusicInfo **Music = NULL;
158 static int num_sounds = 0, num_music = 0;
159 static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
162 /* ========================================================================= */
163 /* THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
165 static struct SoundControl mixer[NUM_MIXER_CHANNELS];
166 static int mixer_active_channels = 0;
168 #if defined(AUDIO_UNIX_NATIVE)
169 static struct AudioFormatInfo afmt;
171 static void Mixer_Main(void);
172 #if !defined(AUDIO_STREAMING_DSP)
173 static unsigned char linear_to_ulaw(int);
174 static int ulaw_to_linear(unsigned char);
178 static void ReloadCustomSounds();
179 static void ReloadCustomMusic();
180 static void FreeSound(void *);
183 /* ------------------------------------------------------------------------- */
184 /* functions for native (non-SDL) Unix audio/mixer support */
185 /* ------------------------------------------------------------------------- */
187 #if defined(AUDIO_UNIX_NATIVE)
189 static int OpenAudioDevice(char *audio_device_name)
193 /* check if desired audio device is accessible */
194 if (access(audio_device_name, W_OK) != 0)
197 /* try to open audio device in non-blocking mode */
198 if ((audio_device_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
199 return audio_device_fd;
201 /* re-open audio device in blocking mode */
202 close(audio_device_fd);
203 audio_device_fd = open(audio_device_name, O_WRONLY);
205 return audio_device_fd;
208 static void CloseAudioDevice(int *audio_device_fd)
210 if (*audio_device_fd == 0)
213 close(*audio_device_fd);
214 *audio_device_fd = -1;
217 static boolean TestAudioDevices(void)
219 static char *audio_device_name[] =
222 DEVICENAME_SOUND_DSP,
225 int audio_device_fd = -1;
228 /* look for available audio devices, starting with preferred ones */
229 for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
230 if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
233 if (audio_device_fd < 0)
235 Error(ERR_WARN, "cannot open audio device -- no sound");
239 close(audio_device_fd);
241 audio.device_name = audio_device_name[i];
246 static boolean ForkAudioProcess(void)
248 if (pipe(audio.mixer_pipe) < 0)
250 Error(ERR_WARN, "cannot create pipe -- no sounds");
254 if ((audio.mixer_pid = fork()) < 0)
256 Error(ERR_WARN, "cannot create sound server process -- no sounds");
261 printf("PID: %d [%s]\n", getpid(),
262 (IS_CHILD_PROCESS(audio.mixer_pid) ? "child" : "parent"));
266 if (IS_CHILD_PROCESS(audio.mixer_pid))
267 Mixer_Main(); /* this function never returns */
269 close(audio.mixer_pipe[0]); /* no reading from pipe needed */
274 void UnixOpenAudio(void)
276 if (!TestAudioDevices())
279 audio.sound_available = TRUE;
280 audio.sound_enabled = TRUE;
282 #if defined(AUDIO_STREAMING_DSP)
283 audio.music_available = TRUE;
284 audio.loops_available = TRUE;
287 audio.num_channels = NUM_MIXER_CHANNELS;
288 audio.music_channel = MUSIC_CHANNEL;
289 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
292 void UnixCloseAudio(void)
295 close(audio.device_fd);
297 if (IS_PARENT_PROCESS(audio.mixer_pid))
298 kill(audio.mixer_pid, SIGTERM);
302 /* ------------------------------------------------------------------------- */
303 /* functions for platform specific audio device initialization */
304 /* ------------------------------------------------------------------------- */
306 #if defined(AUDIO_LINUX_IOCTL)
307 static void InitAudioDevice_Linux(struct AudioFormatInfo *afmt)
309 /* "ioctl()" expects pointer to 'int' value for stereo flag
310 (boolean is defined as 'char', which will not work here) */
311 unsigned int fragment_spec = 0;
312 int fragment_size_query;
321 /* supported audio format in preferred order */
322 { AFMT_S16_LE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_LE },
323 { AFMT_S16_BE, AUDIO_FORMAT_S16 | AUDIO_FORMAT_BE },
324 { AFMT_U8, AUDIO_FORMAT_U8 },
329 /* determine logarithm (log2) of the fragment size */
330 while ((1 << fragment_spec) < afmt->fragment_size)
333 /* use two fragments (play one fragment, prepare the other);
334 one fragment would result in interrupted audio output, more
335 than two fragments would raise audio output latency to much */
336 fragment_spec |= 0x00020000;
338 /* Example for fragment specification:
339 - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
340 - (with stereo the effective buffer size will shrink to 256)
341 => fragment_size = 0x00020009 */
343 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_spec) < 0)
344 Error(ERR_EXIT_SOUND_SERVER,
345 "cannot set fragment size of audio device -- no sounds");
349 while (formats[i].format_result != -1)
351 unsigned int audio_format = formats[i].format_ioctl;
352 if (ioctl(audio.device_fd, SNDCTL_DSP_SETFMT, &audio_format) == 0)
354 afmt->format = formats[i].format_result;
359 if (afmt->format == 0) /* no supported audio format found */
360 Error(ERR_EXIT_SOUND_SERVER,
361 "cannot set audio format of audio device -- no sounds");
363 /* try if we can use stereo sound */
365 if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
366 afmt->stereo = FALSE;
368 if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &afmt->sample_rate) < 0)
369 Error(ERR_EXIT_SOUND_SERVER,
370 "cannot set sample rate of audio device -- no sounds");
372 /* get the real fragmentation size; this should return 512 */
373 if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size_query) < 0)
374 Error(ERR_EXIT_SOUND_SERVER,
375 "cannot get fragment size of audio device -- no sounds");
376 if (fragment_size_query != afmt->fragment_size)
377 Error(ERR_EXIT_SOUND_SERVER,
378 "cannot set fragment size of audio device -- no sounds");
380 #endif /* AUDIO_LINUX_IOCTL */
382 #if defined(PLATFORM_NETBSD)
383 static void InitAudioDevice_NetBSD(struct AudioFormatInfo *afmt)
386 boolean stereo = TRUE;
388 AUDIO_INITINFO(&a_info);
389 a_info.play.encoding = AUDIO_ENCODING_LINEAR8;
390 a_info.play.precision = 8;
391 a_info.play.channels = 2;
392 a_info.play.sample_rate = afmt->sample_rate;
393 a_info.blocksize = afmt->fragment_size;
395 afmt->format = AUDIO_FORMAT_U8;
398 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
400 /* try to disable stereo */
401 a_info.play.channels = 1;
403 afmt->stereo = FALSE;
405 if (ioctl(audio.device_fd, AUDIO_SETINFO, &a_info) < 0)
406 Error(ERR_EXIT_SOUND_SERVER,
407 "cannot set sample rate of audio device -- no sounds");
410 #endif /* PLATFORM_NETBSD */
412 #if defined(PLATFORM_HPUX)
413 static void InitAudioDevice_HPUX(struct AudioFormatInfo *afmt)
415 struct audio_describe ainfo;
418 audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
420 Error(ERR_EXIT_SOUND_SERVER, "cannot open audio device -- no sounds");
422 if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
423 Error(ERR_EXIT_SOUND_SERVER, "no audio info -- no sounds");
425 if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
426 Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available -- no sounds");
428 ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
429 ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
431 afmt->format = AUDIO_FORMAT_U8;
432 afmt->stereo = FALSE;
433 afmt->sample_rate = 8000;
437 #endif /* PLATFORM_HPUX */
439 static void InitAudioDevice(struct AudioFormatInfo *afmt)
442 afmt->format = AUDIO_FORMAT_UNKNOWN;
443 afmt->sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
444 afmt->fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
446 #if defined(AUDIO_LINUX_IOCTL)
447 InitAudioDevice_Linux(afmt);
448 #elif defined(PLATFORM_NETBSD)
449 InitAudioDevice_NetBSD(afmt);
450 #elif defined(PLATFORM_HPUX)
451 InitAudioDevice_HPUX(afmt);
453 /* generic /dev/audio stuff might be placed here */
458 /* ------------------------------------------------------------------------- */
459 /* functions for communication between main process and sound mixer process */
460 /* ------------------------------------------------------------------------- */
462 static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
464 if (IS_CHILD_PROCESS(audio.mixer_pid))
467 if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
469 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
470 audio.sound_available = audio.sound_enabled = FALSE;
475 static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
477 if (IS_PARENT_PROCESS(audio.mixer_pid))
480 if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
481 != sizeof(SoundControl))
482 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
485 static void WriteReloadInfoToPipe(char *set_identifier, int type)
487 SoundControl snd_ctrl;
488 TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
489 artwork.mus_current);
490 unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
491 unsigned long str_size2 = strlen(leveldir_current->sounds_path) + 1;
492 unsigned long str_size3 = strlen(leveldir_current->music_path) + 1;
493 unsigned long str_size4 = strlen(ti->basepath) + 1;
494 unsigned long str_size5 = strlen(ti->fullpath) + 1;
495 boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
496 setup.override_level_sounds :
497 setup.override_level_music);
499 if (IS_CHILD_PROCESS(audio.mixer_pid))
502 if (leveldir_current == NULL) /* should never happen */
503 Error(ERR_EXIT, "leveldir_current == NULL");
505 snd_ctrl.active = FALSE;
506 snd_ctrl.state = type;
507 snd_ctrl.data_len = strlen(set_identifier) + 1;
509 if (write(audio.mixer_pipe[1], &snd_ctrl,
510 sizeof(snd_ctrl)) < 0 ||
511 write(audio.mixer_pipe[1], set_identifier,
512 snd_ctrl.data_len) < 0 ||
513 write(audio.mixer_pipe[1], &override_level_artwork,
514 sizeof(boolean)) < 0 ||
515 write(audio.mixer_pipe[1], leveldir_current,
516 sizeof(TreeInfo)) < 0 ||
517 write(audio.mixer_pipe[1], ti,
518 sizeof(TreeInfo)) < 0 ||
519 write(audio.mixer_pipe[1], &str_size1,
520 sizeof(unsigned long)) < 0 ||
521 write(audio.mixer_pipe[1], &str_size2,
522 sizeof(unsigned long)) < 0 ||
523 write(audio.mixer_pipe[1], &str_size3,
524 sizeof(unsigned long)) < 0 ||
525 write(audio.mixer_pipe[1], &str_size4,
526 sizeof(unsigned long)) < 0 ||
527 write(audio.mixer_pipe[1], &str_size5,
528 sizeof(unsigned long)) < 0 ||
529 write(audio.mixer_pipe[1], leveldir_current->fullpath,
531 write(audio.mixer_pipe[1], leveldir_current->sounds_path,
533 write(audio.mixer_pipe[1], leveldir_current->music_path,
535 write(audio.mixer_pipe[1], ti->basepath,
537 write(audio.mixer_pipe[1], ti->fullpath,
540 Error(ERR_WARN, "cannot pipe to child process -- no sounds");
541 audio.sound_available = audio.sound_enabled = FALSE;
546 static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
548 TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
549 &artwork.snd_current : &artwork.mus_current);
550 TreeInfo *ti = *ti_ptr;
551 unsigned long str_size1, str_size2, str_size3, str_size4, str_size5;
552 static char *set_identifier = NULL;
553 boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
554 &setup.override_level_sounds :
555 &setup.override_level_music);
558 free(set_identifier);
560 set_identifier = checked_malloc(snd_ctrl->data_len);
562 if (leveldir_current == NULL)
563 leveldir_current = checked_calloc(sizeof(TreeInfo));
566 ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
567 if (leveldir_current->fullpath != NULL)
568 free(leveldir_current->fullpath);
569 if (leveldir_current->sounds_path != NULL)
570 free(leveldir_current->sounds_path);
571 if (leveldir_current->music_path != NULL)
572 free(leveldir_current->music_path);
573 if (ti->basepath != NULL)
575 if (ti->fullpath != NULL)
578 if (read(audio.mixer_pipe[0], set_identifier,
579 snd_ctrl->data_len) != snd_ctrl->data_len ||
580 read(audio.mixer_pipe[0], override_level_artwork,
581 sizeof(boolean)) != sizeof(boolean) ||
582 read(audio.mixer_pipe[0], leveldir_current,
583 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
584 read(audio.mixer_pipe[0], ti,
585 sizeof(TreeInfo)) != sizeof(TreeInfo) ||
586 read(audio.mixer_pipe[0], &str_size1,
587 sizeof(unsigned long)) != sizeof(unsigned long) ||
588 read(audio.mixer_pipe[0], &str_size2,
589 sizeof(unsigned long)) != sizeof(unsigned long) ||
590 read(audio.mixer_pipe[0], &str_size3,
591 sizeof(unsigned long)) != sizeof(unsigned long) ||
592 read(audio.mixer_pipe[0], &str_size4,
593 sizeof(unsigned long)) != sizeof(unsigned long) ||
594 read(audio.mixer_pipe[0], &str_size5,
595 sizeof(unsigned long)) != sizeof(unsigned long))
596 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
598 leveldir_current->fullpath = checked_calloc(str_size1);
599 leveldir_current->sounds_path = checked_calloc(str_size2);
600 leveldir_current->music_path = checked_calloc(str_size3);
601 ti->basepath = checked_calloc(str_size4);
602 ti->fullpath = checked_calloc(str_size5);
604 if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
605 str_size1) != str_size1 ||
606 read(audio.mixer_pipe[0], leveldir_current->sounds_path,
607 str_size2) != str_size2 ||
608 read(audio.mixer_pipe[0], leveldir_current->music_path,
609 str_size3) != str_size3 ||
610 read(audio.mixer_pipe[0], ti->basepath,
611 str_size4) != str_size4 ||
612 read(audio.mixer_pipe[0], ti->fullpath,
613 str_size5) != str_size5)
614 Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
616 if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
617 artwork.snd_current_identifier = set_identifier;
619 artwork.mus_current_identifier = set_identifier;
622 #endif /* AUDIO_UNIX_NATIVE */
625 /* ------------------------------------------------------------------------- */
626 /* mixer functions */
627 /* ------------------------------------------------------------------------- */
629 void Mixer_InitChannels()
633 for(i=0; i<audio.num_channels; i++)
634 mixer[i].active = FALSE;
635 mixer_active_channels = 0;
638 static void Mixer_ResetChannelExpiration(int channel)
640 mixer[channel].playing_starttime = Counter();
642 #if defined(TARGET_SDL)
643 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]))
644 Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME);
648 static boolean Mixer_ChannelExpired(int channel)
650 if (!mixer[channel].active)
653 if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) &&
654 DelayReached(&mixer[channel].playing_starttime,
655 SOUND_LOOP_EXPIRATION_TIME))
658 #if defined(TARGET_SDL)
660 if (!Mix_Playing(channel))
663 #elif defined(TARGET_ALLEGRO)
665 mixer[channel].playing_pos = voice_get_position(mixer[channel].voice);
666 mixer[channel].volume = voice_get_volume(mixer[channel].voice);
668 /* sound sample has completed playing or was completely faded out */
669 if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0)
672 #endif /* TARGET_ALLEGRO */
677 static boolean Mixer_AllocateChannel(int channel)
679 #if defined(TARGET_ALLEGRO)
680 mixer[channel].voice = allocate_voice((SAMPLE *)mixer[channel].data_ptr);
681 if (mixer[channel].voice < 0)
688 static void Mixer_SetChannelProperties(int channel)
690 #if defined(TARGET_SDL)
691 Mix_Volume(channel, mixer[channel].volume);
692 Mix_SetPanning(channel,
693 SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
694 SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
695 #elif defined(TARGET_ALLEGRO)
696 voice_set_volume(mixer[channel].voice, mixer[channel].volume);
697 voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
701 static void Mixer_StartChannel(int channel)
703 #if defined(TARGET_SDL)
704 Mix_PlayChannel(channel, mixer[channel].data_ptr,
705 IS_LOOP(mixer[channel]) ? -1 : 0);
706 #elif defined(TARGET_ALLEGRO)
707 if (IS_LOOP(mixer[channel]))
708 voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
710 voice_start(mixer[channel].voice);
714 static void Mixer_PlayChannel(int channel)
716 /* start with inactive channel in case something goes wrong */
717 mixer[channel].active = FALSE;
719 if (mixer[channel].type != MUS_TYPE_WAV)
722 if (!Mixer_AllocateChannel(channel))
725 Mixer_SetChannelProperties(channel);
726 Mixer_StartChannel(channel);
728 Mixer_ResetChannelExpiration(channel);
730 mixer[channel].playing_pos = 0;
731 mixer[channel].active = TRUE;
732 mixer_active_channels++;
735 static void Mixer_PlayMusicChannel()
737 Mixer_PlayChannel(audio.music_channel);
739 #if defined(TARGET_SDL)
740 if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
742 /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
743 this looks like a bug in the SDL_mixer library */
744 Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
745 Mix_VolumeMusic(SOUND_MAX_VOLUME);
750 static void Mixer_StopChannel(int channel)
752 if (!mixer[channel].active)
755 #if defined(TARGET_SDL)
756 Mix_HaltChannel(channel);
757 #elif defined(TARGET_ALLEGRO)
758 voice_set_volume(mixer[channel].voice, 0);
759 deallocate_voice(mixer[channel].voice);
762 mixer[channel].active = FALSE;
763 mixer_active_channels--;
766 static void Mixer_StopMusicChannel()
768 Mixer_StopChannel(audio.music_channel);
770 #if defined(TARGET_SDL)
775 static void Mixer_FadeChannel(int channel)
777 if (!mixer[channel].active)
780 mixer[channel].state |= SND_CTRL_FADE;
782 #if defined(TARGET_SDL)
783 Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
784 #elif defined(TARGET_ALLEGRO)
785 if (voice_check(mixer[channel].voice))
786 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
790 static void Mixer_FadeMusicChannel()
792 Mixer_FadeChannel(audio.music_channel);
794 #if defined(TARGET_SDL)
795 Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
799 static void Mixer_UnFadeChannel(int channel)
801 if (!mixer[channel].active || !IS_FADING(mixer[channel]))
804 mixer[channel].state &= ~SND_CTRL_FADE;
805 mixer[channel].volume = SOUND_MAX_VOLUME;
807 #if defined(TARGET_SDL)
808 Mix_ExpireChannel(channel, -1);
809 Mix_Volume(channel, mixer[channel].volume);
810 #elif defined(TARGET_ALLEGRO)
811 voice_stop_volumeramp(mixer[channel].voice);
812 voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
813 mixer[channel].volume);
817 static void Mixer_InsertSound(SoundControl snd_ctrl)
823 printf("NEW SOUND %d ARRIVED [%d] [%d ACTIVE CHANNELS]\n",
824 snd_ctrl.nr, num_sounds, mixer_active_channels);
827 if (IS_MUSIC(snd_ctrl))
832 snd_ctrl.nr = snd_ctrl.nr % num_music;
834 else if (snd_ctrl.nr >= num_sounds)
837 snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
838 if (snd_info == NULL)
841 /* copy sound sample and format information */
842 snd_ctrl.type = snd_info->type;
843 snd_ctrl.format = snd_info->format;
844 snd_ctrl.data_ptr = snd_info->data_ptr;
845 snd_ctrl.data_len = snd_info->data_len;
847 /* play music samples on a dedicated music channel */
848 if (IS_MUSIC(snd_ctrl))
850 Mixer_StopMusicChannel();
852 mixer[audio.music_channel] = snd_ctrl;
853 Mixer_PlayMusicChannel();
858 /* check if (and how often) this sound sample is already playing */
859 for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
860 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
864 printf("SOUND %d [CURRENTLY PLAYING %d TIMES]\n", snd_ctrl.nr, k);
867 /* reset expiration delay for already playing loop sounds */
868 if (k > 0 && IS_LOOP(snd_ctrl))
870 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
872 if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
875 printf("RESETTING EXPIRATION FOR SOUND %d\n", snd_ctrl.nr);
878 if (IS_FADING(mixer[i]))
879 Mixer_UnFadeChannel(i);
881 /* restore settings like volume and stereo position */
882 mixer[i].volume = snd_ctrl.volume;
883 mixer[i].stereo_position = snd_ctrl.stereo_position;
885 Mixer_SetChannelProperties(i);
886 Mixer_ResetChannelExpiration(i);
889 printf("RESETTING VOLUME/STEREO FOR SOUND %d TO %d/%d\n",
890 snd_ctrl.nr, snd_ctrl.volume, snd_ctrl.stereo_position);
899 printf("PLAYING NEW SOUND %d\n", snd_ctrl.nr);
902 /* don't play sound more than n times simultaneously (with n == 2 for now) */
905 unsigned long playing_current = Counter();
906 int longest = 0, longest_nr = audio.first_sound_channel;
908 /* look for oldest equal sound */
909 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
911 int playing_time = playing_current - mixer[i].playing_starttime;
914 if (!mixer[i].active || !SAME_SOUND_NR(mixer[i], snd_ctrl))
917 actual = 1000 * playing_time / mixer[i].data_len;
919 if (actual >= longest)
926 Mixer_StopChannel(longest_nr);
929 /* If all (non-music) channels are active, stop the channel that has
930 played its sound sample most completely (in percent of the sample
931 length). As we cannot currently get the actual playing position
932 of the channel's sound sample when compiling with the SDL mixer
933 library, we use the current playing time (in milliseconds) instead. */
936 /* channel allocation sanity check -- should not be needed */
937 if (mixer_active_channels ==
938 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
940 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
942 if (!mixer[i].active)
944 Error(ERR_RETURN, "Mixer_InsertSound: Channel %d inactive", i);
945 Error(ERR_RETURN, "Mixer_InsertSound: This should never happen!");
947 mixer_active_channels--;
953 if (mixer_active_channels ==
954 audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
956 unsigned long playing_current = Counter();
957 int longest = 0, longest_nr = audio.first_sound_channel;
959 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
961 Error(ERR_RETURN, "Mixer_InsertSound: %d [%d]: %ld (%ld)",
962 i, mixer[i].active, mixer[i].data_len, (long)mixer[i].data_ptr);
965 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
967 int playing_time = playing_current - mixer[i].playing_starttime;
968 int actual = 1000 * playing_time / mixer[i].data_len;
970 if (!IS_LOOP(mixer[i]) && actual > longest)
977 Mixer_StopChannel(longest_nr);
980 /* add the new sound to the mixer */
981 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
984 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
987 if (!mixer[i].active)
990 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
993 #if defined(AUDIO_UNIX_NATIVE)
994 if (snd_info->data_len == 0)
996 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
1000 mixer[i] = snd_ctrl;
1001 Mixer_PlayChannel(i);
1008 static void HandleSoundRequest(SoundControl snd_ctrl)
1012 #if defined(AUDIO_UNIX_NATIVE)
1013 if (IS_PARENT_PROCESS(audio.mixer_pid))
1015 SendSoundControlToMixerProcess(&snd_ctrl);
1020 /* deactivate channels that have expired since the last request */
1021 for (i=0; i<audio.num_channels; i++)
1022 if (mixer[i].active && Mixer_ChannelExpired(i))
1023 Mixer_StopChannel(i);
1025 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
1027 Mixer_StopMusicChannel();
1028 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1029 Mixer_StopChannel(i);
1031 #if defined(AUDIO_UNIX_NATIVE)
1032 CloseAudioDevice(&audio.device_fd);
1033 ReadReloadInfoFromPipe(&snd_ctrl);
1036 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
1037 ReloadCustomSounds();
1039 ReloadCustomMusic();
1041 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
1043 if (IS_MUSIC(snd_ctrl))
1045 Mixer_FadeMusicChannel();
1049 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1050 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1051 Mixer_FadeChannel(i);
1053 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
1055 if (IS_MUSIC(snd_ctrl))
1057 Mixer_StopMusicChannel();
1061 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1062 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1063 Mixer_StopChannel(i);
1065 #if defined(AUDIO_UNIX_NATIVE)
1066 if (!mixer_active_channels)
1067 CloseAudioDevice(&audio.device_fd);
1070 else if (snd_ctrl.active) /* add new sound to mixer */
1072 Mixer_InsertSound(snd_ctrl);
1076 void StartMixer(void)
1081 SDL_version compile_version;
1082 const SDL_version *link_version;
1083 MIX_VERSION(&compile_version);
1084 printf("compiled with SDL_mixer version: %d.%d.%d\n",
1085 compile_version.major,
1086 compile_version.minor,
1087 compile_version.patch);
1088 link_version = Mix_Linked_Version();
1089 printf("running with SDL_mixer version: %d.%d.%d\n",
1090 link_version->major,
1091 link_version->minor,
1092 link_version->patch);
1095 if (!audio.sound_available)
1098 /* initialize stereo position conversion information */
1099 for(i=0; i<=SOUND_MAX_LEFT2RIGHT; i++)
1101 (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1103 #if defined(AUDIO_UNIX_NATIVE)
1104 if (!ForkAudioProcess())
1105 audio.sound_available = FALSE;
1109 #if defined(AUDIO_UNIX_NATIVE)
1111 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1112 int sample_pos, int sample_size,
1115 void *sample_ptr = snd_ctrl->data_ptr;
1118 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1119 for (i=0; i<sample_size; i++)
1121 ((short)(((byte *)sample_ptr)[sample_pos + i] ^ 0x80)) << 8;
1122 else /* AUDIO_FORMAT_S16 */
1123 for (i=0; i<sample_size; i++)
1125 ((short *)sample_ptr)[sample_pos + i];
1128 #if defined(AUDIO_STREAMING_DSP)
1129 static void Mixer_Main_DSP()
1131 static short premix_first_buffer[SND_BLOCKSIZE];
1132 static short premix_left_buffer[SND_BLOCKSIZE];
1133 static short premix_right_buffer[SND_BLOCKSIZE];
1134 static long premix_last_buffer[SND_BLOCKSIZE];
1135 static byte playing_buffer[SND_BLOCKSIZE];
1139 int max_sample_size;
1142 if (!mixer_active_channels)
1145 if (audio.device_fd < 0)
1147 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1150 InitAudioDevice(&afmt);
1153 stereo = afmt.stereo;
1154 fragment_size = afmt.fragment_size;
1155 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1156 max_sample_size = fragment_size / ((stereo ? 2 : 1) * sample_bytes);
1158 /* first clear the last premixing buffer */
1159 memset(premix_last_buffer, 0,
1160 max_sample_size * (stereo ? 2 : 1) * sizeof(long));
1162 for(i=0; i<audio.num_channels; i++)
1169 if (!mixer[i].active)
1172 if (Mixer_ChannelExpired(i))
1174 Mixer_StopChannel(i);
1178 /* pointer, lenght and actual playing position of sound sample */
1179 sample_ptr = mixer[i].data_ptr;
1180 sample_len = mixer[i].data_len;
1181 sample_pos = mixer[i].playing_pos;
1182 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1183 mixer[i].playing_pos += sample_size;
1185 /* copy original sample to first mixing buffer */
1186 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1187 premix_first_buffer);
1189 /* are we about to restart a looping sound? */
1190 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1192 while (sample_size < max_sample_size)
1194 int restarted_sample_size =
1195 MIN(max_sample_size - sample_size, sample_len);
1197 if (mixer[i].format == AUDIO_FORMAT_U8)
1198 for (j=0; j<restarted_sample_size; j++)
1199 premix_first_buffer[sample_size + j] =
1200 ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
1202 for (j=0; j<restarted_sample_size; j++)
1203 premix_first_buffer[sample_size + j] =
1204 ((short *)sample_ptr)[j];
1206 mixer[i].playing_pos = restarted_sample_size;
1207 sample_size += restarted_sample_size;
1211 /* decrease volume if sound is fading out */
1212 if (IS_FADING(mixer[i]) &&
1213 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1214 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1216 /* adjust volume of actual sound sample */
1217 if (mixer[i].volume != SOUND_MAX_VOLUME)
1218 for(j=0; j<sample_size; j++)
1219 premix_first_buffer[j] =
1220 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1222 /* fill the last mixing buffer with stereo or mono sound */
1225 int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1226 int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1228 for(j=0; j<sample_size; j++)
1230 premix_left_buffer[j] =
1231 left_volume * premix_first_buffer[j] / SOUND_MAX_LEFT2RIGHT;
1232 premix_right_buffer[j] =
1233 right_volume * premix_first_buffer[j] / SOUND_MAX_LEFT2RIGHT;
1235 premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
1236 premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
1241 for(j=0; j<sample_size; j++)
1242 premix_last_buffer[j] += premix_first_buffer[j];
1245 /* delete completed sound entries from the mixer */
1246 if (mixer[i].playing_pos >= mixer[i].data_len)
1248 if (IS_LOOP(mixer[i]))
1249 mixer[i].playing_pos = 0;
1251 Mixer_StopChannel(i);
1253 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1254 Mixer_StopChannel(i);
1257 /* prepare final playing buffer according to system audio format */
1258 for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
1260 /* cut off at 17 bit value */
1261 if (premix_last_buffer[i] < -65535)
1262 premix_last_buffer[i] = -65535;
1263 else if (premix_last_buffer[i] > 65535)
1264 premix_last_buffer[i] = 65535;
1266 /* shift to 16 bit value */
1267 premix_last_buffer[i] >>= 1;
1269 if (afmt.format & AUDIO_FORMAT_U8)
1271 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1273 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1275 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1276 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1278 else /* big endian */
1280 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1281 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1285 /* finally play the sound fragment */
1286 write(audio.device_fd, playing_buffer, fragment_size);
1288 if (!mixer_active_channels)
1289 CloseAudioDevice(&audio.device_fd);
1292 #else /* !AUDIO_STREAMING_DSP */
1294 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1296 static short premix_first_buffer[SND_BLOCKSIZE];
1297 static byte playing_buffer[SND_BLOCKSIZE];
1298 int max_sample_size = SND_BLOCKSIZE;
1307 /* pointer, lenght and actual playing position of sound sample */
1308 sample_ptr = mixer[i].data_ptr;
1309 sample_len = mixer[i].data_len;
1310 sample_pos = mixer[i].playing_pos;
1311 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1312 mixer[i].playing_pos += sample_size;
1314 /* copy original sample to first mixing buffer */
1315 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1316 premix_first_buffer);
1318 /* adjust volume of actual sound sample */
1319 if (mixer[i].volume != SOUND_MAX_VOLUME)
1320 for(j=0; j<sample_size; j++)
1321 premix_first_buffer[j] =
1322 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1324 /* might be needed for u-law /dev/audio */
1326 for(j=0; j<sample_size; j++)
1328 linear_to_ulaw(premix_first_buffer[j]);
1331 /* delete completed sound entries from the mixer */
1332 if (mixer[i].playing_pos >= mixer[i].data_len)
1333 Mixer_StopChannel(i);
1335 for(i=0; i<sample_size; i++)
1336 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1338 /* finally play the sound fragment */
1339 write(audio.device_fd, playing_buffer, sample_size);
1343 #endif /* !AUDIO_STREAMING_DSP */
1347 SoundControl snd_ctrl;
1350 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1352 Mixer_InitChannels();
1354 #if defined(PLATFORM_HPUX)
1355 InitAudioDevice(&afmt);
1358 FD_ZERO(&mixer_fdset);
1359 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1361 while(1) /* wait for sound playing commands from client */
1363 struct timeval delay = { 0, 0 };
1365 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1366 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1367 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1370 ReadSoundControlFromMainProcess(&snd_ctrl);
1372 HandleSoundRequest(snd_ctrl);
1374 #if defined(AUDIO_STREAMING_DSP)
1376 while (mixer_active_channels &&
1377 select(audio.mixer_pipe[0] + 1,
1378 &mixer_fdset, NULL, NULL, &delay) < 1)
1380 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1385 #else /* !AUDIO_STREAMING_DSP */
1387 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1388 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1391 InitAudioDevice(&afmt);
1396 while (mixer_active_channels &&
1397 select(audio.mixer_pipe[0] + 1,
1398 &mixer_fdset, NULL, NULL, &delay) < 1)
1400 int wait_percent = 90; /* wait 90% of the real playing time */
1403 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1405 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1409 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1412 CloseAudioDevice(&audio.device_fd);
1414 Mixer_InitChannels(); /* remove all sounds from mixer */
1416 #endif /* !AUDIO_STREAMING_DSP */
1419 #endif /* AUDIO_UNIX_NATIVE */
1422 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1424 /* these two are stolen from "sox"... :) */
1427 ** This routine converts from linear to ulaw.
1429 ** Craig Reese: IDA/Supercomputing Research Center
1430 ** Joe Campbell: Department of Defense
1431 ** 29 September 1989
1434 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1435 ** 2) "A New Digital Technique for Implementation of Any
1436 ** Continuous PCM Companding Law," Villeret, Michel,
1437 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1438 ** 1973, pg. 11.12-11.17
1439 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1440 ** for Analog-to_Digital Conversion Techniques,"
1443 ** Input: Signed 16 bit linear sample
1444 ** Output: 8 bit ulaw sample
1447 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1448 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1451 static unsigned char linear_to_ulaw(int sample)
1453 static int exp_lut[256] =
1455 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1456 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1457 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1458 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1459 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1460 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1461 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1462 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1463 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1464 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1465 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1466 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1467 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1468 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1469 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1470 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1473 int sign, exponent, mantissa;
1474 unsigned char ulawbyte;
1476 /* Get the sample into sign-magnitude. */
1477 sign = (sample >> 8) & 0x80; /* set aside the sign */
1479 sample = -sample; /* get magnitude */
1481 sample = CLIP; /* clip the magnitude */
1483 /* Convert from 16 bit linear to ulaw. */
1484 sample = sample + BIAS;
1485 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1486 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1487 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1490 ulawbyte = 0x02; /* optional CCITT trap */
1497 ** This routine converts from ulaw to 16 bit linear.
1499 ** Craig Reese: IDA/Supercomputing Research Center
1500 ** 29 September 1989
1503 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1504 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1505 ** for Analog-to_Digital Conversion Techniques,"
1508 ** Input: 8 bit ulaw sample
1509 ** Output: signed 16 bit linear sample
1512 static int ulaw_to_linear(unsigned char ulawbyte)
1514 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1515 int sign, exponent, mantissa, sample;
1517 ulawbyte = ~ ulawbyte;
1518 sign = ( ulawbyte & 0x80 );
1519 exponent = ( ulawbyte >> 4 ) & 0x07;
1520 mantissa = ulawbyte & 0x0F;
1521 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1527 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1530 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1531 /* ========================================================================= */
1532 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1534 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1535 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1537 static void *Load_WAV(char *filename)
1539 SoundInfo *snd_info;
1540 #if defined(AUDIO_UNIX_NATIVE)
1541 struct SoundHeader_WAV header;
1543 byte sound_header_buffer[WAV_HEADER_SIZE];
1546 char chunk_name[CHUNK_ID_LEN + 1];
1551 if (!audio.sound_available)
1555 printf("loading WAV file '%s'\n", filename);
1558 snd_info = checked_calloc(sizeof(SoundInfo));
1560 #if defined(TARGET_SDL)
1562 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1564 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1569 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1571 #elif defined(TARGET_ALLEGRO)
1573 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1575 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1580 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1582 #else /* AUDIO_UNIX_NATIVE */
1584 if ((file = fopen(filename, MODE_READ)) == NULL)
1586 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1591 /* read chunk id "RIFF" */
1592 getFileChunkLE(file, chunk_name, &chunk_size);
1593 if (strcmp(chunk_name, "RIFF") != 0)
1595 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1601 /* read "RIFF" type id "WAVE" */
1602 getFileChunkLE(file, chunk_name, NULL);
1603 if (strcmp(chunk_name, "WAVE") != 0)
1605 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1611 while (getFileChunkLE(file, chunk_name, &chunk_size))
1613 if (strcmp(chunk_name, "fmt ") == 0)
1615 if (chunk_size < WAV_HEADER_SIZE)
1617 Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1623 header.compression_code = getFile16BitLE(file);
1624 header.num_channels = getFile16BitLE(file);
1625 header.sample_rate = getFile32BitLE(file);
1626 header.bytes_per_second = getFile32BitLE(file);
1627 header.block_align = getFile16BitLE(file);
1628 header.bits_per_sample = getFile16BitLE(file);
1630 if (chunk_size > WAV_HEADER_SIZE)
1631 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1633 if (header.compression_code != 1)
1635 Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1636 filename, header.compression_code);
1642 if (header.num_channels != 1)
1644 Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
1645 filename, header.num_channels);
1651 if (header.bits_per_sample != 8 && header.bits_per_sample != 16)
1653 Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1654 filename, header.bits_per_sample);
1660 /* warn, but accept wrong sample rate (may be only slightly different) */
1661 if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1662 Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1663 filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1666 printf("WAV file: '%s'\n", filename);
1667 printf(" Compression code: %d'\n", header.compression_code);
1668 printf(" Number of channels: %d'\n", header.num_channels);
1669 printf(" Sample rate: %ld'\n", header.sample_rate);
1670 printf(" Average bytes per second: %ld'\n", header.bytes_per_second);
1671 printf(" Block align: %d'\n", header.block_align);
1672 printf(" Significant bits per sample: %d'\n", header.bits_per_sample);
1675 else if (strcmp(chunk_name, "data") == 0)
1677 snd_info->data_len = chunk_size;
1678 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1680 /* read sound data */
1681 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1684 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1686 free(snd_info->data_ptr);
1691 /* check for odd number of sample bytes (data chunk is word aligned) */
1692 if ((chunk_size % 2) == 1)
1693 ReadUnusedBytesFromFile(file, 1);
1695 else /* unknown chunk -- ignore */
1696 ReadUnusedBytesFromFile(file, chunk_size);
1701 if (snd_info->data_ptr == NULL)
1703 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1708 if (header.bits_per_sample == 8)
1709 snd_info->format = AUDIO_FORMAT_U8;
1710 else /* header.bits_per_sample == 16 */
1712 snd_info->format = AUDIO_FORMAT_S16;
1713 snd_info->data_len /= 2; /* correct number of samples */
1716 #endif /* AUDIO_UNIX_NATIVE */
1718 snd_info->type = SND_TYPE_WAV;
1719 snd_info->source_filename = getStringCopy(filename);
1724 struct FileInfo *getCurrentSoundList()
1726 return sound_info->file_list;
1729 void InitSoundList(struct ConfigInfo *config_list,
1730 struct ConfigInfo *config_suffix_list,
1731 int num_file_list_entries)
1735 sound_info = checked_calloc(sizeof(struct ArtworkListInfo));
1737 sound_info->type = ARTWORK_TYPE_SOUNDS;
1739 sound_info->num_file_list_entries = num_file_list_entries;
1740 sound_info->num_suffix_list_entries = 0;
1741 for (i=0; config_suffix_list[i].token != NULL; i++)
1742 sound_info->num_suffix_list_entries++;
1744 sound_info->file_list =
1745 getFileListFromConfigList(config_list, config_suffix_list,
1746 num_file_list_entries);
1747 sound_info->suffix_list = config_suffix_list;
1749 sound_info->artwork_list =
1750 checked_calloc(num_file_list_entries * sizeof(SoundInfo *));
1752 sound_info->content_list = NULL;
1754 sound_info->load_artwork = Load_WAV;
1755 sound_info->free_artwork = FreeSound;
1757 num_sounds = sound_info->num_file_list_entries;
1758 Sound = (SoundInfo **)sound_info->artwork_list;
1761 static MusicInfo *Load_MOD(char *filename)
1763 #if defined(TARGET_SDL)
1764 MusicInfo *mod_info;
1766 if (!audio.sound_available)
1769 mod_info = checked_calloc(sizeof(MusicInfo));
1771 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1773 Error(ERR_WARN, "cannot read music file '%s'", filename);
1778 mod_info->type = MUS_TYPE_MOD;
1779 mod_info->source_filename = getStringCopy(filename);
1787 void LoadCustomMusic(void)
1789 static boolean draw_init_text = TRUE; /* only draw at startup */
1790 static char *last_music_directory = NULL;
1791 char *music_directory = getCustomMusicDirectory();
1793 struct dirent *dir_entry;
1795 if (!audio.sound_available)
1798 if (last_music_directory != NULL &&
1799 strcmp(last_music_directory, music_directory) == 0)
1800 return; /* old and new music directory are the same */
1802 if (last_music_directory != NULL)
1803 free(last_music_directory);
1804 last_music_directory = getStringCopy(music_directory);
1808 if ((dir = opendir(music_directory)) == NULL)
1810 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1811 audio.music_available = FALSE;
1816 DrawInitText("Loading music:", 120, FC_GREEN);
1818 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1820 char *basename = dir_entry->d_name;
1821 char *filename = getPath2(music_directory, basename);
1822 MusicInfo *mus_info = NULL;
1825 printf("DEBUG: loading music '%s' ...\n", basename);
1829 DrawInitText(basename, 150, FC_YELLOW);
1831 if (FileIsSound(basename))
1832 mus_info = Load_WAV(filename);
1833 else if (FileIsMusic(basename))
1834 mus_info = Load_MOD(filename);
1841 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1842 Music[num_music -1] = mus_info;
1848 draw_init_text = FALSE;
1851 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1855 void PlayMusic(int nr)
1857 if (!audio.music_available)
1863 void PlaySound(int nr)
1865 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
1868 void PlaySoundStereo(int nr, int stereo_position)
1870 PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
1873 void PlaySoundLoop(int nr)
1875 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
1878 void PlaySoundMusic(int nr)
1880 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
1883 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
1885 SoundControl snd_ctrl;
1887 if (!audio.sound_available ||
1888 !audio.sound_enabled ||
1889 audio.sound_deactivated)
1892 if (volume < SOUND_MIN_VOLUME)
1893 volume = SOUND_MIN_VOLUME;
1894 else if (volume > SOUND_MAX_VOLUME)
1895 volume = SOUND_MAX_VOLUME;
1897 if (stereo_position < SOUND_MAX_LEFT)
1898 stereo_position = SOUND_MAX_LEFT;
1899 else if (stereo_position > SOUND_MAX_RIGHT)
1900 stereo_position = SOUND_MAX_RIGHT;
1902 snd_ctrl.active = TRUE;
1904 snd_ctrl.volume = volume;
1905 snd_ctrl.stereo_position = stereo_position;
1906 snd_ctrl.state = state;
1908 HandleSoundRequest(snd_ctrl);
1911 void FadeMusic(void)
1913 if (!audio.music_available)
1916 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
1919 void FadeSound(int nr)
1921 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
1927 StopSoundExt(-1, SND_CTRL_FADE_ALL);
1930 void StopMusic(void)
1932 if (!audio.music_available)
1935 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
1938 void StopSound(int nr)
1940 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
1946 StopSoundExt(-1, SND_CTRL_STOP_ALL);
1949 void StopSoundExt(int nr, int state)
1951 SoundControl snd_ctrl;
1953 if (!audio.sound_available)
1956 snd_ctrl.active = FALSE;
1958 snd_ctrl.state = state;
1960 HandleSoundRequest(snd_ctrl);
1963 static void ReloadCustomSounds()
1966 printf("DEBUG: reloading sounds '%s' ...\n", artwork.snd_current_identifier);
1969 ReloadCustomArtworkList(sound_info);
1972 static void ReloadCustomMusic()
1975 printf("DEBUG: reloading music '%s' ...\n", artwork.mus_current_identifier);
1981 void InitReloadSounds(char *set_identifier)
1983 if (!audio.sound_available)
1986 #if defined(AUDIO_UNIX_NATIVE)
1987 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_SOUNDS);
1989 ReloadCustomSounds();
1993 void InitReloadMusic(char *set_identifier)
1995 if (!audio.music_available)
1998 #if defined(AUDIO_UNIX_NATIVE)
1999 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
2001 ReloadCustomMusic();
2005 void FreeSound(void *ptr)
2007 SoundInfo *sound = (SoundInfo *)ptr;
2012 if (sound->data_ptr)
2014 #if defined(TARGET_SDL)
2015 Mix_FreeChunk(sound->data_ptr);
2016 #elif defined(TARGET_ALLEGRO)
2017 destroy_sample(sound->data_ptr);
2018 #else /* AUDIO_UNIX_NATIVE */
2019 free(sound->data_ptr);
2023 if (sound->source_filename)
2024 free(sound->source_filename);
2029 void FreeMusic(MusicInfo *music)
2034 if (music->data_ptr)
2036 #if defined(TARGET_SDL)
2037 if (music->type == MUS_TYPE_MOD)
2038 Mix_FreeMusic(music->data_ptr);
2040 Mix_FreeChunk(music->data_ptr);
2041 #elif defined(TARGET_ALLEGRO)
2042 destroy_sample(music->data_ptr);
2043 #else /* AUDIO_UNIX_NATIVE */
2044 free(music->data_ptr);
2051 void FreeAllSounds()
2053 FreeCustomArtworkList(sound_info);
2063 for(i=0; i<num_music; i++)
2064 FreeMusic(Music[i]);
2072 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2073 /* ========================================================================= */