+ if (use_alternate)
+ desired_rate = alternate_rate;
+ else
+ desired_rate = default_rate;
+ } else {
+ desired_rate = rate; /* use stream sampling rate, discard default/alternate settings */
+ }
+
+ if (desired_rate == s->sample_spec.rate)
+ return -1;
+
+ if (!passthrough && pa_source_used_by(s) > 0)
+ return -1;
+
+ pa_log_debug("Suspending source %s due to changing the sample rate.", s->name);
+ pa_source_suspend(s, true, PA_SUSPEND_INTERNAL);
+
+ if (s->update_rate)
+ ret = s->update_rate(s, desired_rate);
+ else {
+ /* This is a monitor source. */
+
+ /* XXX: This code is written with non-passthrough streams in mind. I
+ * have no idea whether the behaviour with passthrough streams is
+ * sensible. */
+ if (!passthrough) {
+ uint32_t old_rate = s->sample_spec.rate;
+
+ s->sample_spec.rate = desired_rate;
+ ret = pa_sink_update_rate(s->monitor_of, desired_rate, false);
+
+ if (ret < 0) {
+ /* Changing the sink rate failed, roll back the old rate for
+ * the monitor source. Why did we set the source rate before
+ * calling pa_sink_update_rate(), you may ask. The reason is
+ * that pa_sink_update_rate() tries to update the monitor
+ * source rate, but we are already in the process of updating
+ * the monitor source rate, so there's a risk of entering an
+ * infinite loop. Setting the source rate before calling
+ * pa_sink_update_rate() makes the rate == s->sample_spec.rate
+ * check in the beginning of this function return early, so we
+ * avoid looping. */
+ s->sample_spec.rate = old_rate;
+ }
+ } else
+ ret = -1;
+ }