+
+ return TRUE;
+}
+
+static void Mixer_SetChannelProperties(int channel)
+{
+#if defined(TARGET_SDL)
+ Mix_Volume(channel, mixer[channel].volume);
+ Mix_SetPanning(channel,
+ SOUND_VOLUME_LEFT(mixer[channel].stereo_position),
+ SOUND_VOLUME_RIGHT(mixer[channel].stereo_position));
+#elif defined(TARGET_ALLEGRO)
+ voice_set_volume(mixer[channel].voice, mixer[channel].volume);
+ voice_set_pan(mixer[channel].voice, mixer[channel].stereo_position);
+#endif
+}
+
+static void Mixer_StartChannel(int channel)
+{
+#if defined(TARGET_SDL)
+ Mix_PlayChannel(channel, mixer[channel].data_ptr,
+ IS_LOOP(mixer[channel]) ? -1 : 0);
+#elif defined(TARGET_ALLEGRO)
+ if (IS_LOOP(mixer[channel]))
+ voice_set_playmode(mixer[channel].voice, PLAYMODE_LOOP);
+
+ voice_start(mixer[channel].voice);
+#endif
+}
+
+static void Mixer_PlayChannel(int channel)
+{
+ /* start with inactive channel in case something goes wrong */
+ mixer[channel].active = FALSE;
+
+ if (mixer[channel].type != MUS_TYPE_WAV)
+ return;
+
+ if (!Mixer_AllocateChannel(channel))
+ return;
+
+ Mixer_SetChannelProperties(channel);
+ Mixer_StartChannel(channel);
+
+ Mixer_ResetChannelExpiration(channel);
+
+ mixer[channel].playing_pos = 0;
+ mixer[channel].active = TRUE;
+ mixer_active_channels++;
+}
+
+static void Mixer_PlayMusicChannel()
+{
+ Mixer_PlayChannel(audio.music_channel);
+
+#if defined(TARGET_SDL)
+ if (mixer[audio.music_channel].type != MUS_TYPE_WAV)
+ {
+ /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() --
+ this looks like a bug in the SDL_mixer library */
+ Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1);
+ Mix_VolumeMusic(SOUND_MAX_VOLUME);
+ }
+#endif
+}
+
+static void Mixer_StopChannel(int channel)
+{
+ if (!mixer[channel].active)
+ return;
+
+#if defined(TARGET_SDL)
+ Mix_HaltChannel(channel);
+#elif defined(TARGET_ALLEGRO)
+ voice_set_volume(mixer[channel].voice, 0);
+ deallocate_voice(mixer[channel].voice);
+#endif
+
+ mixer[channel].active = FALSE;
+ mixer_active_channels--;
+}
+
+static void Mixer_StopMusicChannel()
+{
+ Mixer_StopChannel(audio.music_channel);
+
+#if defined(TARGET_SDL)
+ Mix_HaltMusic();
+#endif
+}
+
+static void Mixer_FadeChannel(int channel)
+{
+ if (!mixer[channel].active)
+ return;
+
+ mixer[channel].state |= SND_CTRL_FADE;
+
+#if defined(TARGET_SDL)
+ Mix_FadeOutChannel(channel, SOUND_FADING_INTERVAL);
+#elif defined(TARGET_ALLEGRO)
+ if (voice_check(mixer[channel].voice))
+ voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL, 0);
+#endif
+}
+
+static void Mixer_FadeMusicChannel()
+{
+ Mixer_FadeChannel(audio.music_channel);
+
+#if defined(TARGET_SDL)
+ Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
+#endif
+}
+
+static void Mixer_UnFadeChannel(int channel)
+{
+ if (!mixer[channel].active || !IS_FADING(mixer[channel]))
+ return;
+
+ mixer[channel].state &= ~SND_CTRL_FADE;
+ mixer[channel].volume = SOUND_MAX_VOLUME;
+
+#if defined(TARGET_SDL)
+ Mix_ExpireChannel(channel, -1);
+ Mix_Volume(channel, mixer[channel].volume);
+#elif defined(TARGET_ALLEGRO)
+ voice_stop_volumeramp(mixer[channel].voice);
+ voice_ramp_volume(mixer[channel].voice, SOUND_FADING_INTERVAL,
+ mixer[channel].volume);
+#endif
+}
+
+static void Mixer_InsertSound(SoundControl snd_ctrl)
+{
+ SoundInfo *snd_info;
+ int i, k;
+
+#if 0
+ printf("NEW SOUND %d HAS ARRIVED [%d]\n", snd_ctrl.nr, num_sounds);
+#endif
+
+#if 0
+ printf("%d ACTIVE CHANNELS\n", mixer_active_channels);
+#endif
+
+ if (IS_MUSIC(snd_ctrl))
+ snd_ctrl.nr = snd_ctrl.nr % num_music;
+ else if (snd_ctrl.nr >= num_sounds)
+ return;
+
+ snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
+ if (snd_info == NULL)
+ return;
+
+ /* copy sound sample and format information */
+ snd_ctrl.type = snd_info->type;
+ snd_ctrl.format = snd_info->format;
+ snd_ctrl.data_ptr = snd_info->data_ptr;
+ snd_ctrl.data_len = snd_info->data_len;
+
+ /* play music samples on a dedicated music channel */
+ if (IS_MUSIC(snd_ctrl))
+ {
+#if 0
+ printf("PLAY MUSIC WITH VOLUME/STEREO %d/%d\n",
+ snd_ctrl.volume, snd_ctrl.stereo_position);
+#endif
+
+ mixer[audio.music_channel] = snd_ctrl;
+ Mixer_PlayMusicChannel();
+
+ return;