alsa: Reconfigure sink sample rate for passthrough inputs
authorArun Raghavan <arun.raghavan@collabora.co.uk>
Tue, 8 Mar 2011 08:52:24 +0000 (14:22 +0530)
committerArun Raghavan <arun.raghavan@collabora.co.uk>
Mon, 2 May 2011 06:25:38 +0000 (11:55 +0530)
When a passthrough sink-input is added, we need to reconfigure the
sink's sample rate since no resampling occurs. We revert to the original
rate when the passthrough sink-input is removed.

src/modules/alsa/alsa-sink.c

index ec840af..3f8f6d2 100644 (file)
@@ -108,6 +108,8 @@ struct userdata {
 
     pa_cvolume hardware_volume;
 
+    uint32_t old_rate;
+
     size_t
         frame_size,
         fragment_size,
@@ -1051,6 +1053,56 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
 
     switch (code) {
 
+        case PA_SINK_MESSAGE_FINISH_MOVE:
+        case PA_SINK_MESSAGE_ADD_INPUT: {
+            pa_sink_input *i = PA_SINK_INPUT(data);
+            int r = 0;
+
+            if (PA_LIKELY(pa_format_info_is_pcm(i->format)))
+                break;
+
+            u->old_rate = u->sink->sample_spec.rate;
+
+            /* Passthrough format, see if we need to reset sink sample rate */
+            if (u->sink->sample_spec.rate == i->thread_info.sample_spec.rate)
+                break;
+
+            /* .. we do */
+            if ((r = suspend(u)) < 0)
+                return r;
+
+            u->sink->sample_spec.rate = i->thread_info.sample_spec.rate;
+
+            if ((r = unsuspend(u)) < 0)
+                return r;
+
+            break;
+        }
+
+        case PA_SINK_MESSAGE_START_MOVE:
+        case PA_SINK_MESSAGE_REMOVE_INPUT: {
+            pa_sink_input *i = PA_SINK_INPUT(data);
+            int r = 0;
+
+            if (PA_LIKELY(pa_format_info_is_pcm(i->format)))
+                break;
+
+            /* Passthrough format, see if we need to reset sink sample rate */
+            if (u->sink->sample_spec.rate == u->old_rate)
+                break;
+
+            /* .. we do */
+            if ((r = suspend(u)) < 0)
+                return r;
+
+            u->sink->sample_spec.rate = u->old_rate;
+
+            if ((r = unsuspend(u)) < 0)
+                return r;
+
+            break;
+        }
+
         case PA_SINK_MESSAGE_GET_LATENCY: {
             pa_usec_t r = 0;