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;
961 /* print some debugging information about audio channel usage */
962 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
964 Error(ERR_RETURN, "Mixer_InsertSound: %d [%d]: %ld (%ld)",
965 i, mixer[i].active, mixer[i].data_len, (long)mixer[i].data_ptr);
970 for (i=audio.first_sound_channel; i<audio.num_channels; i++)
972 int playing_time = playing_current - mixer[i].playing_starttime;
973 int actual = 1000 * playing_time / mixer[i].data_len;
975 if (!IS_LOOP(mixer[i]) && actual > longest)
982 Mixer_StopChannel(longest_nr);
985 /* add the new sound to the mixer */
986 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
989 printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
992 if (!mixer[i].active)
995 printf("ADDING NEW SOUND %d TO MIXER\n", snd_ctrl.nr);
998 #if defined(AUDIO_UNIX_NATIVE)
999 if (snd_info->data_len == 0)
1001 printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
1005 mixer[i] = snd_ctrl;
1006 Mixer_PlayChannel(i);
1013 static void HandleSoundRequest(SoundControl snd_ctrl)
1017 #if defined(AUDIO_UNIX_NATIVE)
1018 if (IS_PARENT_PROCESS(audio.mixer_pid))
1020 SendSoundControlToMixerProcess(&snd_ctrl);
1025 /* deactivate channels that have expired since the last request */
1026 for (i=0; i<audio.num_channels; i++)
1027 if (mixer[i].active && Mixer_ChannelExpired(i))
1028 Mixer_StopChannel(i);
1030 if (IS_RELOADING(snd_ctrl)) /* load new sound or music files */
1032 Mixer_StopMusicChannel();
1033 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1034 Mixer_StopChannel(i);
1036 #if defined(AUDIO_UNIX_NATIVE)
1037 CloseAudioDevice(&audio.device_fd);
1038 ReadReloadInfoFromPipe(&snd_ctrl);
1041 if (snd_ctrl.state & SND_CTRL_RELOAD_SOUNDS)
1042 ReloadCustomSounds();
1044 ReloadCustomMusic();
1046 else if (IS_FADING(snd_ctrl)) /* fade out existing sound or music */
1048 if (IS_MUSIC(snd_ctrl))
1050 Mixer_FadeMusicChannel();
1054 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1055 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1056 Mixer_FadeChannel(i);
1058 else if (IS_STOPPING(snd_ctrl)) /* stop existing sound or music */
1060 if (IS_MUSIC(snd_ctrl))
1062 Mixer_StopMusicChannel();
1066 for(i=audio.first_sound_channel; i<audio.num_channels; i++)
1067 if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
1068 Mixer_StopChannel(i);
1070 #if defined(AUDIO_UNIX_NATIVE)
1071 if (!mixer_active_channels)
1072 CloseAudioDevice(&audio.device_fd);
1075 else if (snd_ctrl.active) /* add new sound to mixer */
1077 Mixer_InsertSound(snd_ctrl);
1081 void StartMixer(void)
1086 SDL_version compile_version;
1087 const SDL_version *link_version;
1088 MIX_VERSION(&compile_version);
1089 printf("compiled with SDL_mixer version: %d.%d.%d\n",
1090 compile_version.major,
1091 compile_version.minor,
1092 compile_version.patch);
1093 link_version = Mix_Linked_Version();
1094 printf("running with SDL_mixer version: %d.%d.%d\n",
1095 link_version->major,
1096 link_version->minor,
1097 link_version->patch);
1100 if (!audio.sound_available)
1103 /* initialize stereo position conversion information */
1104 for(i=0; i<=SOUND_MAX_LEFT2RIGHT; i++)
1106 (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
1108 #if defined(AUDIO_UNIX_NATIVE)
1109 if (!ForkAudioProcess())
1110 audio.sound_available = FALSE;
1114 #if defined(AUDIO_UNIX_NATIVE)
1116 static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
1117 int sample_pos, int sample_size,
1120 void *sample_ptr = snd_ctrl->data_ptr;
1123 if (snd_ctrl->format == AUDIO_FORMAT_U8)
1124 for (i=0; i<sample_size; i++)
1126 ((short)(((byte *)sample_ptr)[sample_pos + i] ^ 0x80)) << 8;
1127 else /* AUDIO_FORMAT_S16 */
1128 for (i=0; i<sample_size; i++)
1130 ((short *)sample_ptr)[sample_pos + i];
1133 #if defined(AUDIO_STREAMING_DSP)
1134 static void Mixer_Main_DSP()
1136 static short premix_first_buffer[SND_BLOCKSIZE];
1137 static short premix_left_buffer[SND_BLOCKSIZE];
1138 static short premix_right_buffer[SND_BLOCKSIZE];
1139 static long premix_last_buffer[SND_BLOCKSIZE];
1140 static byte playing_buffer[SND_BLOCKSIZE];
1144 int max_sample_size;
1147 if (!mixer_active_channels)
1150 if (audio.device_fd < 0)
1152 if ((audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1155 InitAudioDevice(&afmt);
1158 stereo = afmt.stereo;
1159 fragment_size = afmt.fragment_size;
1160 sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
1161 max_sample_size = fragment_size / ((stereo ? 2 : 1) * sample_bytes);
1163 /* first clear the last premixing buffer */
1164 memset(premix_last_buffer, 0,
1165 max_sample_size * (stereo ? 2 : 1) * sizeof(long));
1167 for(i=0; i<audio.num_channels; i++)
1174 if (!mixer[i].active)
1177 if (Mixer_ChannelExpired(i))
1179 Mixer_StopChannel(i);
1183 /* pointer, lenght and actual playing position of sound sample */
1184 sample_ptr = mixer[i].data_ptr;
1185 sample_len = mixer[i].data_len;
1186 sample_pos = mixer[i].playing_pos;
1187 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1188 mixer[i].playing_pos += sample_size;
1190 /* copy original sample to first mixing buffer */
1191 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1192 premix_first_buffer);
1194 /* are we about to restart a looping sound? */
1195 if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
1197 while (sample_size < max_sample_size)
1199 int restarted_sample_size =
1200 MIN(max_sample_size - sample_size, sample_len);
1202 if (mixer[i].format == AUDIO_FORMAT_U8)
1203 for (j=0; j<restarted_sample_size; j++)
1204 premix_first_buffer[sample_size + j] =
1205 ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
1207 for (j=0; j<restarted_sample_size; j++)
1208 premix_first_buffer[sample_size + j] =
1209 ((short *)sample_ptr)[j];
1211 mixer[i].playing_pos = restarted_sample_size;
1212 sample_size += restarted_sample_size;
1216 /* decrease volume if sound is fading out */
1217 if (IS_FADING(mixer[i]) &&
1218 mixer[i].volume >= SOUND_FADING_VOLUME_THRESHOLD)
1219 mixer[i].volume -= SOUND_FADING_VOLUME_STEP;
1221 /* adjust volume of actual sound sample */
1222 if (mixer[i].volume != SOUND_MAX_VOLUME)
1223 for(j=0; j<sample_size; j++)
1224 premix_first_buffer[j] =
1225 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1227 /* fill the last mixing buffer with stereo or mono sound */
1230 int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
1231 int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
1233 for(j=0; j<sample_size; j++)
1235 premix_left_buffer[j] =
1236 left_volume * premix_first_buffer[j] / SOUND_MAX_LEFT2RIGHT;
1237 premix_right_buffer[j] =
1238 right_volume * premix_first_buffer[j] / SOUND_MAX_LEFT2RIGHT;
1240 premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
1241 premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
1246 for(j=0; j<sample_size; j++)
1247 premix_last_buffer[j] += premix_first_buffer[j];
1250 /* delete completed sound entries from the mixer */
1251 if (mixer[i].playing_pos >= mixer[i].data_len)
1253 if (IS_LOOP(mixer[i]))
1254 mixer[i].playing_pos = 0;
1256 Mixer_StopChannel(i);
1258 else if (mixer[i].volume <= SOUND_FADING_VOLUME_THRESHOLD)
1259 Mixer_StopChannel(i);
1262 /* prepare final playing buffer according to system audio format */
1263 for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
1265 /* cut off at 17 bit value */
1266 if (premix_last_buffer[i] < -65535)
1267 premix_last_buffer[i] = -65535;
1268 else if (premix_last_buffer[i] > 65535)
1269 premix_last_buffer[i] = 65535;
1271 /* shift to 16 bit value */
1272 premix_last_buffer[i] >>= 1;
1274 if (afmt.format & AUDIO_FORMAT_U8)
1276 playing_buffer[i] = (premix_last_buffer[i] >> 8) ^ 0x80;
1278 else if (afmt.format & AUDIO_FORMAT_LE) /* 16 bit */
1280 playing_buffer[2 * i + 0] = premix_last_buffer[i] & 0xff;
1281 playing_buffer[2 * i + 1] = premix_last_buffer[i] >> 8;
1283 else /* big endian */
1285 playing_buffer[2 * i + 0] = premix_last_buffer[i] >> 8;
1286 playing_buffer[2 * i + 1] = premix_last_buffer[i] & 0xff;
1290 /* finally play the sound fragment */
1291 write(audio.device_fd, playing_buffer, fragment_size);
1293 if (!mixer_active_channels)
1294 CloseAudioDevice(&audio.device_fd);
1297 #else /* !AUDIO_STREAMING_DSP */
1299 static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
1301 static short premix_first_buffer[SND_BLOCKSIZE];
1302 static byte playing_buffer[SND_BLOCKSIZE];
1303 int max_sample_size = SND_BLOCKSIZE;
1312 /* pointer, lenght and actual playing position of sound sample */
1313 sample_ptr = mixer[i].data_ptr;
1314 sample_len = mixer[i].data_len;
1315 sample_pos = mixer[i].playing_pos;
1316 sample_size = MIN(max_sample_size, sample_len - sample_pos);
1317 mixer[i].playing_pos += sample_size;
1319 /* copy original sample to first mixing buffer */
1320 CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
1321 premix_first_buffer);
1323 /* adjust volume of actual sound sample */
1324 if (mixer[i].volume != SOUND_MAX_VOLUME)
1325 for(j=0; j<sample_size; j++)
1326 premix_first_buffer[j] =
1327 mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
1329 /* might be needed for u-law /dev/audio */
1331 for(j=0; j<sample_size; j++)
1333 linear_to_ulaw(premix_first_buffer[j]);
1336 /* delete completed sound entries from the mixer */
1337 if (mixer[i].playing_pos >= mixer[i].data_len)
1338 Mixer_StopChannel(i);
1340 for(i=0; i<sample_size; i++)
1341 playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
1343 /* finally play the sound fragment */
1344 write(audio.device_fd, playing_buffer, sample_size);
1348 #endif /* !AUDIO_STREAMING_DSP */
1352 SoundControl snd_ctrl;
1355 close(audio.mixer_pipe[1]); /* no writing into pipe needed */
1357 Mixer_InitChannels();
1359 #if defined(PLATFORM_HPUX)
1360 InitAudioDevice(&afmt);
1363 FD_ZERO(&mixer_fdset);
1364 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1366 while(1) /* wait for sound playing commands from client */
1368 struct timeval delay = { 0, 0 };
1370 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1371 select(audio.mixer_pipe[0] + 1, &mixer_fdset, NULL, NULL, NULL);
1372 if (!FD_ISSET(audio.mixer_pipe[0], &mixer_fdset))
1375 ReadSoundControlFromMainProcess(&snd_ctrl);
1377 HandleSoundRequest(snd_ctrl);
1379 #if defined(AUDIO_STREAMING_DSP)
1381 while (mixer_active_channels &&
1382 select(audio.mixer_pipe[0] + 1,
1383 &mixer_fdset, NULL, NULL, &delay) < 1)
1385 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1390 #else /* !AUDIO_STREAMING_DSP */
1392 if (!snd_ctrl.active || IS_LOOP(snd_ctrl) ||
1393 (audio.device_fd = OpenAudioDevice(audio.device_name)) < 0)
1396 InitAudioDevice(&afmt);
1401 while (mixer_active_channels &&
1402 select(audio.mixer_pipe[0] + 1,
1403 &mixer_fdset, NULL, NULL, &delay) < 1)
1405 int wait_percent = 90; /* wait 90% of the real playing time */
1408 FD_SET(audio.mixer_pipe[0], &mixer_fdset);
1410 sample_size = Mixer_Main_SimpleAudio(snd_ctrl);
1414 ((sample_size * 10 * wait_percent) / afmt.sample_rate) * 1000;
1417 CloseAudioDevice(&audio.device_fd);
1419 Mixer_InitChannels(); /* remove all sounds from mixer */
1421 #endif /* !AUDIO_STREAMING_DSP */
1424 #endif /* AUDIO_UNIX_NATIVE */
1427 #if defined(AUDIO_UNIX_NATIVE) && !defined(AUDIO_STREAMING_DSP)
1429 /* these two are stolen from "sox"... :) */
1432 ** This routine converts from linear to ulaw.
1434 ** Craig Reese: IDA/Supercomputing Research Center
1435 ** Joe Campbell: Department of Defense
1436 ** 29 September 1989
1439 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1440 ** 2) "A New Digital Technique for Implementation of Any
1441 ** Continuous PCM Companding Law," Villeret, Michel,
1442 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
1443 ** 1973, pg. 11.12-11.17
1444 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
1445 ** for Analog-to_Digital Conversion Techniques,"
1448 ** Input: Signed 16 bit linear sample
1449 ** Output: 8 bit ulaw sample
1452 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
1453 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
1456 static unsigned char linear_to_ulaw(int sample)
1458 static int exp_lut[256] =
1460 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
1461 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
1462 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1463 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1464 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1465 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1466 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1467 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
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,
1471 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1472 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1473 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1474 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1475 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
1478 int sign, exponent, mantissa;
1479 unsigned char ulawbyte;
1481 /* Get the sample into sign-magnitude. */
1482 sign = (sample >> 8) & 0x80; /* set aside the sign */
1484 sample = -sample; /* get magnitude */
1486 sample = CLIP; /* clip the magnitude */
1488 /* Convert from 16 bit linear to ulaw. */
1489 sample = sample + BIAS;
1490 exponent = exp_lut[( sample >> 7 ) & 0xFF];
1491 mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
1492 ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
1495 ulawbyte = 0x02; /* optional CCITT trap */
1502 ** This routine converts from ulaw to 16 bit linear.
1504 ** Craig Reese: IDA/Supercomputing Research Center
1505 ** 29 September 1989
1508 ** 1) CCITT Recommendation G.711 (very difficult to follow)
1509 ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
1510 ** for Analog-to_Digital Conversion Techniques,"
1513 ** Input: 8 bit ulaw sample
1514 ** Output: signed 16 bit linear sample
1517 static int ulaw_to_linear(unsigned char ulawbyte)
1519 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
1520 int sign, exponent, mantissa, sample;
1522 ulawbyte = ~ ulawbyte;
1523 sign = ( ulawbyte & 0x80 );
1524 exponent = ( ulawbyte >> 4 ) & 0x07;
1525 mantissa = ulawbyte & 0x0F;
1526 sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
1532 #endif /* AUDIO_UNIX_NATIVE && !AUDIO_STREAMING_DSP */
1535 /* THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS */
1536 /* ========================================================================= */
1537 /* THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS */
1539 #define CHUNK_ID_LEN 4 /* IFF style chunk id length */
1540 #define WAV_HEADER_SIZE 16 /* size of WAV file header */
1542 static void *Load_WAV(char *filename)
1544 SoundInfo *snd_info;
1545 #if defined(AUDIO_UNIX_NATIVE)
1546 struct SoundHeader_WAV header;
1548 byte sound_header_buffer[WAV_HEADER_SIZE];
1551 char chunk_name[CHUNK_ID_LEN + 1];
1556 if (!audio.sound_available)
1560 printf("loading WAV file '%s'\n", filename);
1563 snd_info = checked_calloc(sizeof(SoundInfo));
1565 #if defined(TARGET_SDL)
1567 if ((snd_info->data_ptr = Mix_LoadWAV(filename)) == NULL)
1569 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1574 snd_info->data_len = ((Mix_Chunk *)snd_info->data_ptr)->alen;
1576 #elif defined(TARGET_ALLEGRO)
1578 if ((snd_info->data_ptr = load_sample(filename)) == NULL)
1580 Error(ERR_WARN, "cannot read sound file '%s'", filename);
1585 snd_info->data_len = ((SAMPLE *)snd_info->data_ptr)->len;
1587 #else /* AUDIO_UNIX_NATIVE */
1589 if ((file = fopen(filename, MODE_READ)) == NULL)
1591 Error(ERR_WARN, "cannot open sound file '%s'", filename);
1596 /* read chunk id "RIFF" */
1597 getFileChunkLE(file, chunk_name, &chunk_size);
1598 if (strcmp(chunk_name, "RIFF") != 0)
1600 Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
1606 /* read "RIFF" type id "WAVE" */
1607 getFileChunkLE(file, chunk_name, NULL);
1608 if (strcmp(chunk_name, "WAVE") != 0)
1610 Error(ERR_WARN, "missing 'WAVE' type ID of sound file '%s'", filename);
1616 while (getFileChunkLE(file, chunk_name, &chunk_size))
1618 if (strcmp(chunk_name, "fmt ") == 0)
1620 if (chunk_size < WAV_HEADER_SIZE)
1622 Error(ERR_WARN, "sound file '%s': chunk 'fmt ' too short", filename);
1628 header.compression_code = getFile16BitLE(file);
1629 header.num_channels = getFile16BitLE(file);
1630 header.sample_rate = getFile32BitLE(file);
1631 header.bytes_per_second = getFile32BitLE(file);
1632 header.block_align = getFile16BitLE(file);
1633 header.bits_per_sample = getFile16BitLE(file);
1635 if (chunk_size > WAV_HEADER_SIZE)
1636 ReadUnusedBytesFromFile(file, chunk_size - WAV_HEADER_SIZE);
1638 if (header.compression_code != 1)
1640 Error(ERR_WARN, "sound file '%s': compression code %d not supported",
1641 filename, header.compression_code);
1647 if (header.num_channels != 1 &&
1648 header.num_channels != 2)
1650 Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
1651 filename, header.num_channels);
1657 if (header.bits_per_sample != 8 && header.bits_per_sample != 16)
1659 Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
1660 filename, header.bits_per_sample);
1666 /* warn, but accept wrong sample rate (may be only slightly different) */
1667 if (header.sample_rate != DEFAULT_AUDIO_SAMPLE_RATE)
1668 Error(ERR_WARN, "sound file '%s': wrong sample rate %d instead of %d",
1669 filename, header.sample_rate, DEFAULT_AUDIO_SAMPLE_RATE);
1672 printf("WAV file: '%s'\n", filename);
1673 printf(" Compression code: %d'\n", header.compression_code);
1674 printf(" Number of channels: %d'\n", header.num_channels);
1675 printf(" Sample rate: %ld'\n", header.sample_rate);
1676 printf(" Average bytes per second: %ld'\n", header.bytes_per_second);
1677 printf(" Block align: %d'\n", header.block_align);
1678 printf(" Significant bits per sample: %d'\n", header.bits_per_sample);
1681 else if (strcmp(chunk_name, "data") == 0)
1683 snd_info->data_len = chunk_size;
1684 snd_info->data_ptr = checked_malloc(snd_info->data_len);
1686 /* read sound data */
1687 if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
1690 Error(ERR_WARN,"cannot read 'data' chunk of sound file '%s'",filename);
1692 free(snd_info->data_ptr);
1697 /* check for odd number of sample bytes (data chunk is word aligned) */
1698 if ((chunk_size % 2) == 1)
1699 ReadUnusedBytesFromFile(file, 1);
1701 else /* unknown chunk -- ignore */
1702 ReadUnusedBytesFromFile(file, chunk_size);
1707 if (snd_info->data_ptr == NULL)
1709 Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
1714 if (header.bits_per_sample == 8)
1715 snd_info->format = AUDIO_FORMAT_U8;
1716 else /* header.bits_per_sample == 16 */
1718 snd_info->format = AUDIO_FORMAT_S16;
1719 snd_info->data_len /= 2; /* correct number of samples */
1722 #endif /* AUDIO_UNIX_NATIVE */
1724 snd_info->type = SND_TYPE_WAV;
1725 snd_info->source_filename = getStringCopy(filename);
1730 struct FileInfo *getCurrentSoundList()
1732 return sound_info->file_list;
1735 void InitSoundList(struct ConfigInfo *config_list,
1736 struct ConfigInfo *config_suffix_list,
1737 int num_file_list_entries)
1741 sound_info = checked_calloc(sizeof(struct ArtworkListInfo));
1743 sound_info->type = ARTWORK_TYPE_SOUNDS;
1745 sound_info->num_file_list_entries = num_file_list_entries;
1746 sound_info->num_suffix_list_entries = 0;
1747 for (i=0; config_suffix_list[i].token != NULL; i++)
1748 sound_info->num_suffix_list_entries++;
1750 sound_info->file_list =
1751 getFileListFromConfigList(config_list, config_suffix_list,
1752 num_file_list_entries);
1753 sound_info->suffix_list = config_suffix_list;
1755 sound_info->artwork_list =
1756 checked_calloc(num_file_list_entries * sizeof(SoundInfo *));
1758 sound_info->content_list = NULL;
1760 sound_info->load_artwork = Load_WAV;
1761 sound_info->free_artwork = FreeSound;
1763 num_sounds = sound_info->num_file_list_entries;
1764 Sound = (SoundInfo **)sound_info->artwork_list;
1767 static MusicInfo *Load_MOD(char *filename)
1769 #if defined(TARGET_SDL)
1770 MusicInfo *mod_info;
1772 if (!audio.sound_available)
1775 mod_info = checked_calloc(sizeof(MusicInfo));
1777 if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
1779 Error(ERR_WARN, "cannot read music file '%s'", filename);
1784 mod_info->type = MUS_TYPE_MOD;
1785 mod_info->source_filename = getStringCopy(filename);
1793 void LoadCustomMusic(void)
1795 static boolean draw_init_text = TRUE; /* only draw at startup */
1796 static char *last_music_directory = NULL;
1797 char *music_directory = getCustomMusicDirectory();
1799 struct dirent *dir_entry;
1801 if (!audio.sound_available)
1804 if (last_music_directory != NULL &&
1805 strcmp(last_music_directory, music_directory) == 0)
1806 return; /* old and new music directory are the same */
1808 if (last_music_directory != NULL)
1809 free(last_music_directory);
1810 last_music_directory = getStringCopy(music_directory);
1814 if ((dir = opendir(music_directory)) == NULL)
1816 Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
1817 audio.music_available = FALSE;
1822 DrawInitText("Loading music:", 120, FC_GREEN);
1824 while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */
1826 char *basename = dir_entry->d_name;
1827 char *filename = getPath2(music_directory, basename);
1828 MusicInfo *mus_info = NULL;
1831 printf("DEBUG: loading music '%s' ...\n", basename);
1835 DrawInitText(basename, 150, FC_YELLOW);
1837 if (FileIsSound(basename))
1838 mus_info = Load_WAV(filename);
1839 else if (FileIsMusic(basename))
1840 mus_info = Load_MOD(filename);
1847 Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
1848 Music[num_music -1] = mus_info;
1854 draw_init_text = FALSE;
1857 Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
1861 void PlayMusic(int nr)
1863 if (!audio.music_available)
1869 void PlaySound(int nr)
1871 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND);
1874 void PlaySoundStereo(int nr, int stereo_position)
1876 PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND);
1879 void PlaySoundLoop(int nr)
1881 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP);
1884 void PlaySoundMusic(int nr)
1886 PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC);
1889 void PlaySoundExt(int nr, int volume, int stereo_position, int state)
1891 SoundControl snd_ctrl;
1893 if (!audio.sound_available ||
1894 !audio.sound_enabled ||
1895 audio.sound_deactivated)
1898 if (volume < SOUND_MIN_VOLUME)
1899 volume = SOUND_MIN_VOLUME;
1900 else if (volume > SOUND_MAX_VOLUME)
1901 volume = SOUND_MAX_VOLUME;
1903 if (stereo_position < SOUND_MAX_LEFT)
1904 stereo_position = SOUND_MAX_LEFT;
1905 else if (stereo_position > SOUND_MAX_RIGHT)
1906 stereo_position = SOUND_MAX_RIGHT;
1908 snd_ctrl.active = TRUE;
1910 snd_ctrl.volume = volume;
1911 snd_ctrl.stereo_position = stereo_position;
1912 snd_ctrl.state = state;
1914 HandleSoundRequest(snd_ctrl);
1917 void FadeMusic(void)
1919 if (!audio.music_available)
1922 StopSoundExt(-1, SND_CTRL_FADE_MUSIC);
1925 void FadeSound(int nr)
1927 StopSoundExt(nr, SND_CTRL_FADE_SOUND);
1933 StopSoundExt(-1, SND_CTRL_FADE_ALL);
1936 void StopMusic(void)
1938 if (!audio.music_available)
1941 StopSoundExt(-1, SND_CTRL_STOP_MUSIC);
1944 void StopSound(int nr)
1946 StopSoundExt(nr, SND_CTRL_STOP_SOUND);
1952 StopSoundExt(-1, SND_CTRL_STOP_ALL);
1955 void StopSoundExt(int nr, int state)
1957 SoundControl snd_ctrl;
1959 if (!audio.sound_available)
1962 snd_ctrl.active = FALSE;
1964 snd_ctrl.state = state;
1966 HandleSoundRequest(snd_ctrl);
1969 static void ReloadCustomSounds()
1972 printf("DEBUG: reloading sounds '%s' ...\n", artwork.snd_current_identifier);
1975 ReloadCustomArtworkList(sound_info);
1978 static void ReloadCustomMusic()
1981 printf("DEBUG: reloading music '%s' ...\n", artwork.mus_current_identifier);
1987 void InitReloadSounds(char *set_identifier)
1989 if (!audio.sound_available)
1992 #if defined(AUDIO_UNIX_NATIVE)
1993 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_SOUNDS);
1995 ReloadCustomSounds();
1999 void InitReloadMusic(char *set_identifier)
2001 if (!audio.music_available)
2004 #if defined(AUDIO_UNIX_NATIVE)
2005 WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
2007 ReloadCustomMusic();
2011 void FreeSound(void *ptr)
2013 SoundInfo *sound = (SoundInfo *)ptr;
2018 if (sound->data_ptr)
2020 #if defined(TARGET_SDL)
2021 Mix_FreeChunk(sound->data_ptr);
2022 #elif defined(TARGET_ALLEGRO)
2023 destroy_sample(sound->data_ptr);
2024 #else /* AUDIO_UNIX_NATIVE */
2025 free(sound->data_ptr);
2029 if (sound->source_filename)
2030 free(sound->source_filename);
2035 void FreeMusic(MusicInfo *music)
2040 if (music->data_ptr)
2042 #if defined(TARGET_SDL)
2043 if (music->type == MUS_TYPE_MOD)
2044 Mix_FreeMusic(music->data_ptr);
2046 Mix_FreeChunk(music->data_ptr);
2047 #elif defined(TARGET_ALLEGRO)
2048 destroy_sample(music->data_ptr);
2049 #else /* AUDIO_UNIX_NATIVE */
2050 free(music->data_ptr);
2057 void FreeAllSounds()
2059 FreeCustomArtworkList(sound_info);
2069 for(i=0; i<num_music; i++)
2070 FreeMusic(Music[i]);
2078 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS */
2079 /* ========================================================================= */