+
+/* ------------------------------------------------------------------------- */
+/* functions for communication between main process and sound mixer process */
+/* ------------------------------------------------------------------------- */
+
+static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
+{
+ if (IS_CHILD_PROCESS())
+ return;
+
+ if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
+ {
+ Error(ERR_WARN, "cannot pipe to child process -- no sounds");
+ audio.sound_available = audio.sound_enabled = FALSE;
+ return;
+ }
+}
+
+static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
+{
+ if (IS_PARENT_PROCESS())
+ return;
+
+ if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
+ != sizeof(SoundControl))
+ Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
+}
+
+static void WriteReloadInfoToPipe(char *set_identifier, int type)
+{
+ SoundControl snd_ctrl;
+ TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
+ artwork.mus_current);
+ unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
+ unsigned long str_size2 = strlen(leveldir_current->sounds_path) + 1;
+ unsigned long str_size3 = strlen(leveldir_current->music_path) + 1;
+ unsigned long str_size4 = strlen(ti->basepath) + 1;
+ unsigned long str_size5 = strlen(ti->fullpath) + 1;
+ boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
+ setup.override_level_sounds :
+ setup.override_level_music);
+
+ if (IS_CHILD_PROCESS())
+ return;
+
+ if (leveldir_current == NULL) /* should never happen */
+ Error(ERR_EXIT, "leveldir_current == NULL");
+
+ snd_ctrl.active = FALSE;
+ snd_ctrl.state = type;
+ snd_ctrl.data_len = strlen(set_identifier) + 1;
+
+ if (write(audio.mixer_pipe[1], &snd_ctrl,
+ sizeof(snd_ctrl)) < 0 ||
+ write(audio.mixer_pipe[1], set_identifier,
+ snd_ctrl.data_len) < 0 ||
+ write(audio.mixer_pipe[1], &override_level_artwork,
+ sizeof(boolean)) < 0 ||
+ write(audio.mixer_pipe[1], leveldir_current,
+ sizeof(TreeInfo)) < 0 ||
+ write(audio.mixer_pipe[1], ti,
+ sizeof(TreeInfo)) < 0 ||
+ write(audio.mixer_pipe[1], &str_size1,
+ sizeof(unsigned long)) < 0 ||
+ write(audio.mixer_pipe[1], &str_size2,
+ sizeof(unsigned long)) < 0 ||
+ write(audio.mixer_pipe[1], &str_size3,
+ sizeof(unsigned long)) < 0 ||
+ write(audio.mixer_pipe[1], &str_size4,
+ sizeof(unsigned long)) < 0 ||
+ write(audio.mixer_pipe[1], &str_size5,
+ sizeof(unsigned long)) < 0 ||
+ write(audio.mixer_pipe[1], leveldir_current->fullpath,
+ str_size1) < 0 ||
+ write(audio.mixer_pipe[1], leveldir_current->sounds_path,
+ str_size2) < 0 ||
+ write(audio.mixer_pipe[1], leveldir_current->music_path,
+ str_size3) < 0 ||
+ write(audio.mixer_pipe[1], ti->basepath,
+ str_size4) < 0 ||
+ write(audio.mixer_pipe[1], ti->fullpath,
+ str_size5) < 0)
+ {
+ Error(ERR_WARN, "cannot pipe to child process -- no sounds");
+ audio.sound_available = audio.sound_enabled = FALSE;
+ return;
+ }
+}
+
+static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
+{
+ TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
+ &artwork.snd_current : &artwork.mus_current);
+ TreeInfo *ti = *ti_ptr;
+ unsigned long str_size1, str_size2, str_size3, str_size4, str_size5;
+ static char *set_identifier = NULL;
+ boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
+ &setup.override_level_sounds :
+ &setup.override_level_music);
+
+ if (set_identifier)
+ free(set_identifier);
+
+ set_identifier = checked_malloc(snd_ctrl->data_len);
+
+ if (leveldir_current == NULL)
+ leveldir_current = checked_calloc(sizeof(TreeInfo));
+
+ if (ti == NULL)
+ ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
+ if (leveldir_current->fullpath != NULL)
+ free(leveldir_current->fullpath);
+ if (leveldir_current->sounds_path != NULL)
+ free(leveldir_current->sounds_path);
+ if (leveldir_current->music_path != NULL)
+ free(leveldir_current->music_path);
+ if (ti->basepath != NULL)
+ free(ti->basepath);
+ if (ti->fullpath != NULL)
+ free(ti->fullpath);
+
+ if (read(audio.mixer_pipe[0], set_identifier,
+ snd_ctrl->data_len) != snd_ctrl->data_len ||
+ read(audio.mixer_pipe[0], override_level_artwork,
+ sizeof(boolean)) != sizeof(boolean) ||
+ read(audio.mixer_pipe[0], leveldir_current,
+ sizeof(TreeInfo)) != sizeof(TreeInfo) ||
+ read(audio.mixer_pipe[0], ti,
+ sizeof(TreeInfo)) != sizeof(TreeInfo) ||
+ read(audio.mixer_pipe[0], &str_size1,
+ sizeof(unsigned long)) != sizeof(unsigned long) ||
+ read(audio.mixer_pipe[0], &str_size2,
+ sizeof(unsigned long)) != sizeof(unsigned long) ||
+ read(audio.mixer_pipe[0], &str_size3,
+ sizeof(unsigned long)) != sizeof(unsigned long) ||
+ read(audio.mixer_pipe[0], &str_size4,
+ sizeof(unsigned long)) != sizeof(unsigned long) ||
+ read(audio.mixer_pipe[0], &str_size5,
+ sizeof(unsigned long)) != sizeof(unsigned long))
+ Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
+
+ leveldir_current->fullpath = checked_calloc(str_size1);
+ leveldir_current->sounds_path = checked_calloc(str_size2);
+ leveldir_current->music_path = checked_calloc(str_size3);
+ ti->basepath = checked_calloc(str_size4);
+ ti->fullpath = checked_calloc(str_size5);
+
+ if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
+ str_size1) != str_size1 ||
+ read(audio.mixer_pipe[0], leveldir_current->sounds_path,
+ str_size2) != str_size2 ||
+ read(audio.mixer_pipe[0], leveldir_current->music_path,
+ str_size3) != str_size3 ||
+ read(audio.mixer_pipe[0], ti->basepath,
+ str_size4) != str_size4 ||
+ read(audio.mixer_pipe[0], ti->fullpath,
+ str_size5) != str_size5)
+ Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
+
+ if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
+ artwork.snd_current_identifier = set_identifier;
+ else
+ artwork.mus_current_identifier = set_identifier;
+}
+
+#endif /* AUDIO_UNIX_NATIVE */
+
+
+/* ------------------------------------------------------------------------- */
+/* mixer functions */
+/* ------------------------------------------------------------------------- */
+
+void Mixer_InitChannels()