+/* Called from the IO thread or the main thread depending on whether deferred
+ * volume is enabled or not (with deferred volume all mixer handling is done
+ * from the IO thread).
+ *
+ * Sets the mixer settings to match the current source and port state (the port
+ * is given as an argument, because active_port may still point to the old
+ * port, if we're switching ports). */
+static void sync_mixer(struct userdata *u, pa_device_port *port) {
+ pa_alsa_setting *setting = NULL;
+
+ pa_assert(u);
+
+ if (!u->mixer_path)
+ return;
+
+ /* port may be NULL, because if we use a synthesized mixer path, then the
+ * source has no ports. */
+ if (port) {
+ pa_alsa_port_data *data;
+
+ data = PA_DEVICE_PORT_DATA(port);
+ setting = data->setting;
+ }
+
+ pa_alsa_path_select(u->mixer_path, setting, u->mixer_handle, u->source->muted);
+
+ if (u->source->set_mute)
+ u->source->set_mute(u->source);
+ if (u->source->flags & PA_SOURCE_DEFERRED_VOLUME) {
+ if (u->source->write_volume)
+ u->source->write_volume(u->source);
+ } else {
+ if (u->source->set_volume)
+ u->source->set_volume(u->source);
+ }
+}
+