+#endif /* PLATFORM_UNIX */
+
+void Mixer_InitChannels()
+{
+ int i;
+
+ for(i=0; i<audio.num_channels; i++)
+ mixer[i].active = FALSE;
+ mixer_active_channels = 0;
+}
+
+static void Mixer_FadeSound(int channel)
+{
+ mixer[channel].state |= SND_CTRL_FADE;
+}
+
+static void Mixer_RemoveSound(int channel)
+{
+ if (!mixer_active_channels || !mixer[channel].active)
+ return;
+
+#if 0
+ printf("REMOVING MIXER SOUND %d\n", channel);
+#endif
+
+ mixer[channel].active = FALSE;
+ mixer_active_channels--;
+}
+
+static void Mixer_InsertSound(struct 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 (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)
+ {
+#if 0
+ printf("sound/music %d undefined\n", snd_ctrl.nr);
+#endif
+ return;
+ }
+
+#if 0
+ printf("-> %d\n", mixer_active_channels);
+#endif
+
+ if (mixer_active_channels == audio.num_channels)
+ {
+ for (i=0; i<audio.num_channels; i++)
+ {
+ if (mixer[i].data_ptr == NULL)
+ {
+#if 1
+ printf("THIS SHOULD NEVER HAPPEN! [%d]\n", i);
+#endif
+
+ Mixer_RemoveSound(i);
+ }
+ }
+ }
+
+ /* if mixer is full, remove oldest sound */
+ if (mixer_active_channels == audio.num_channels)
+ {
+ int longest = 0, longest_nr = audio.first_sound_channel;
+
+ for (i=audio.first_sound_channel; i<audio.num_channels; i++)
+ {
+#if !defined(PLATFORM_MSDOS)
+ int actual = 100 * mixer[i].playingpos / mixer[i].data_len;
+#else
+ int actual = mixer[i].playingpos;
+#endif
+
+ if (!IS_LOOP(mixer[i]) && actual > longest)
+ {
+ longest = actual;
+ longest_nr = i;
+ }
+ }
+#if defined(PLATFORM_MSDOS)
+ voice_set_volume(mixer[longest_nr].voice, 0);
+ deallocate_voice(mixer[longest_nr].voice);
+#endif
+ Mixer_RemoveSound(longest_nr);
+ }
+
+ /* check if sound is already being played (and how often) */
+ for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
+ if (mixer[i].nr == snd_ctrl.nr)
+ k++;
+
+ /* restart loop sounds only if they are just fading out */
+ if (k >= 1 && IS_LOOP(snd_ctrl))
+ {
+ for(i=audio.first_sound_channel; i<audio.num_channels; i++)
+ {
+ if (mixer[i].nr == snd_ctrl.nr && IS_FADING(mixer[i]))
+ {
+ mixer[i].state &= ~SND_CTRL_FADE;
+ mixer[i].volume = PSND_MAX_VOLUME;
+#if defined(PLATFORM_MSDOS)
+ mixer[i].state |= SND_CTRL_LOOP;
+ voice_stop_volumeramp(mixer[i].voice);
+ voice_ramp_volume(mixer[i].voice, mixer[i].volume, 1000);
+#endif
+ }
+ }
+
+ return;
+ }
+
+ /* don't play sound more than n times simultaneously (with n == 2 for now) */
+ if (k >= 2)
+ {
+ int longest = 0, longest_nr = audio.first_sound_channel;
+
+ /* look for oldest equal sound */
+ for(i=audio.first_sound_channel; i<audio.num_channels; i++)
+ {
+ int actual;
+
+ if (!mixer[i].active || mixer[i].nr != snd_ctrl.nr)
+ continue;
+
+#if !defined(PLATFORM_MSDOS)
+ actual = 100 * mixer[i].playingpos / mixer[i].data_len;
+#else
+ actual = mixer[i].playingpos;
+#endif
+ if (actual >= longest)
+ {
+ longest = actual;
+ longest_nr = i;
+ }
+ }
+
+#if defined(PLATFORM_MSDOS)
+ voice_set_volume(mixer[longest_nr].voice, 0);
+ deallocate_voice(mixer[longest_nr].voice);
+#endif
+ Mixer_RemoveSound(longest_nr);
+ }
+
+ /* add new sound to mixer */
+ for(i=0; i<audio.num_channels; i++)
+ {
+#if 0
+ printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
+#endif
+
+ /*
+ if (!mixer[i].active ||
+ (IS_MUSIC(snd_ctrl) && i == audio.music_channel))
+ */
+ if ((i == audio.music_channel && IS_MUSIC(snd_ctrl)) ||
+ (i != audio.music_channel && !mixer[i].active))
+ {
+ snd_ctrl.data_ptr = snd_info->data_ptr;
+ snd_ctrl.data_len = snd_info->data_len;
+ snd_ctrl.format = snd_info->format;
+
+ snd_ctrl.playingpos = 0;
+ snd_ctrl.playingtime = 0;
+
+#if 1
+ if (snd_info->data_len == 0)
+ {
+ printf("THIS SHOULD NEVER HAPPEN! [snd_info->data_len == 0]\n");
+ }
+#endif
+
+#if 1
+ if (IS_MUSIC(snd_ctrl) && i == audio.music_channel && mixer[i].active)
+ {
+ printf("THIS SHOULD NEVER HAPPEN! [adding music twice]\n");
+
+#if 1
+ Mixer_RemoveSound(i);
+#endif
+ }
+#endif
+
+ mixer[i] = snd_ctrl;
+ mixer_active_channels++;
+
+#if 0
+ printf("NEW SOUND %d ADDED TO MIXER\n", snd_ctrl.nr);
+#endif
+
+#if defined(PLATFORM_MSDOS)
+ mixer[i].voice = allocate_voice((SAMPLE *)mixer[i].data_ptr);
+
+ if (snd_ctrl.loop)
+ voice_set_playmode(mixer[i].voice, PLAYMODE_LOOP);
+
+ voice_set_volume(mixer[i].voice, snd_ctrl.volume);
+ voice_set_pan(mixer[i].voice, snd_ctrl.stereo);
+ voice_start(mixer[i].voice);
+#endif
+ break;
+ }
+ }
+}