]> code.delx.au - pulseaudio/commitdiff
alsa: support for alternate sampling rate
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Tue, 2 Aug 2011 23:37:29 +0000 (18:37 -0500)
committerArun Raghavan <arun.raghavan@collabora.co.uk>
Mon, 17 Oct 2011 14:39:50 +0000 (20:09 +0530)
This is where the actual changes happen.
Some additional checks would be required to make sure the
rate is actually supported
Tested with both PCM and passthrough streams

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
src/modules/alsa/alsa-sink.c
src/modules/alsa/alsa-source.c
src/modules/alsa/module-alsa-sink.c
src/modules/alsa/module-alsa-source.c

index bcc6e51a319dc8f4297fa647ce90e7a0921d7d1e..0b7bbe00bea8b3aa819e42136ef6f852925cc854 100644 (file)
@@ -1121,56 +1121,6 @@ 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_sink_input_is_passthrough(i)))
-                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_sink_input_is_passthrough(i)))
-                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 (PA_SINK_IS_OPENED(u->sink->thread_info.state) && ((r = suspend(u)) < 0))
-                return r;
-
-            u->sink->sample_spec.rate = u->old_rate;
-
-            if (PA_SINK_IS_OPENED(u->sink->thread_info.state) && ((r = unsuspend(u)) < 0))
-                return r;
-
-            break;
-        }
-
         case PA_SINK_MESSAGE_GET_LATENCY: {
             pa_usec_t r = 0;
 
@@ -1595,6 +1545,19 @@ static pa_bool_t sink_set_formats(pa_sink *s, pa_idxset *formats) {
     return TRUE;
 }
 
+static pa_bool_t sink_update_rate_cb(pa_sink *s, uint32_t rate)
+{
+    struct userdata *u = s->userdata;
+    pa_assert(u);
+
+    if (!PA_SINK_IS_OPENED(s->state)) {
+        pa_log_info("Updating rate for device %s, new rate is %d",u->device_name, rate);
+        u->sink->sample_spec.rate = rate;
+        return TRUE;
+    }
+    return FALSE;
+}
+
 static int process_rewind(struct userdata *u) {
     snd_pcm_sframes_t unused;
     size_t rewind_nbytes, unused_nbytes, limit_nbytes;
@@ -1975,6 +1938,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
     struct userdata *u = NULL;
     const char *dev_id = NULL;
     pa_sample_spec ss;
+    uint32_t alternate_sample_rate;
     pa_channel_map map;
     uint32_t nfrags, frag_size, buffer_size, tsched_size, tsched_watermark, rewind_safeguard;
     snd_pcm_uframes_t period_frames, buffer_frames, tsched_frames;
@@ -1993,6 +1957,12 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
         goto fail;
     }
 
+    alternate_sample_rate = m->core->alternate_sample_rate;
+    if (pa_modargs_get_alternate_sample_rate(ma, &alternate_sample_rate) < 0) {
+        pa_log("Failed to parse alternate sample rate");
+        goto fail;
+    }
+
     frame_size = pa_frame_size(&ss);
 
     nfrags = m->core->default_n_fragments;
@@ -2178,6 +2148,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
 
     pa_sink_new_data_set_sample_spec(&data, &ss);
     pa_sink_new_data_set_channel_map(&data, &map);
+    pa_sink_new_data_set_alternate_sample_rate(&data, alternate_sample_rate);
 
     pa_alsa_init_proplist_pcm(m->core, data.proplist, u->pcm_handle);
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
@@ -2230,6 +2201,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
         u->sink->update_requested_latency = sink_update_requested_latency_cb;
     u->sink->set_state = sink_set_state_cb;
     u->sink->set_port = sink_set_port_cb;
+    u->sink->update_rate = sink_update_rate_cb;
     u->sink->userdata = u;
 
     pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
index 0766e11e17fde468cad89132a1b69ce014847ebe..c27942910c5eeaed760a9a4dbba70f7bd06563e5 100644 (file)
@@ -1382,6 +1382,19 @@ static void source_update_requested_latency_cb(pa_source *s) {
     update_sw_params(u);
 }
 
+static pa_bool_t source_update_rate_cb(pa_source *s, uint32_t rate)
+{
+    struct userdata *u = s->userdata;
+    pa_assert(u);
+
+    if (!PA_SOURCE_IS_OPENED(s->state)) {
+        pa_log_info("Updating rate for device %s, new rate is %d", u->device_name, rate);
+        u->source->sample_spec.rate = rate;
+        return TRUE;
+    }
+    return FALSE;
+}
+
 static void thread_func(void *userdata) {
     struct userdata *u = userdata;
     unsigned short revents = 0;
@@ -1674,6 +1687,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
     struct userdata *u = NULL;
     const char *dev_id = NULL;
     pa_sample_spec ss;
+    uint32_t alternate_sample_rate;
     pa_channel_map map;
     uint32_t nfrags, frag_size, buffer_size, tsched_size, tsched_watermark;
     snd_pcm_uframes_t period_frames, buffer_frames, tsched_frames;
@@ -1692,6 +1706,12 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
         goto fail;
     }
 
+    alternate_sample_rate = m->core->alternate_sample_rate;
+    if (pa_modargs_get_alternate_sample_rate(ma, &alternate_sample_rate) < 0) {
+        pa_log("Failed to parse alternate sample rate");
+        goto fail;
+    }
+
     frame_size = pa_frame_size(&ss);
 
     nfrags = m->core->default_n_fragments;
@@ -1867,6 +1887,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
 
     pa_source_new_data_set_sample_spec(&data, &ss);
     pa_source_new_data_set_channel_map(&data, &map);
+    pa_source_new_data_set_alternate_sample_rate(&data, alternate_sample_rate);
 
     pa_alsa_init_proplist_pcm(m->core, data.proplist, u->pcm_handle);
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
@@ -1918,6 +1939,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
         u->source->update_requested_latency = source_update_requested_latency_cb;
     u->source->set_state = source_set_state_cb;
     u->source->set_port = source_set_port_cb;
+    u->source->update_rate = source_update_rate_cb;
     u->source->userdata = u;
 
     pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
index 2a558a145b1bc292bd7e89fdbeb9d6c20e34ed60..019ccf0eb0c16819f7c003ce79ef30ad0ff0e3ea 100644 (file)
@@ -45,6 +45,7 @@ PA_MODULE_USAGE(
         "device_id=<ALSA card index> "
         "format=<sample format> "
         "rate=<sample rate> "
+        "alternate_rate=<alternate sample rate> "
         "channels=<number of channels> "
         "channel_map=<channel map> "
         "fragments=<number of fragments> "
@@ -69,6 +70,7 @@ static const char* const valid_modargs[] = {
     "device_id",
     "format",
     "rate",
+    "alternate_rate",
     "channels",
     "channel_map",
     "fragments",
index 628e6313a95c12e0cf2f48f89cc79a1cf83ff327..2d2c8b6492a3654a6a6ee8b9eeb8b1216d13fe1c 100644 (file)
@@ -54,6 +54,7 @@ PA_MODULE_USAGE(
         "device_id=<ALSA card index> "
         "format=<sample format> "
         "rate=<sample rate> "
+        "alternate_rate=<alternate sample rate> "
         "channels=<number of channels> "
         "channel_map=<channel map> "
         "fragments=<number of fragments> "
@@ -77,6 +78,7 @@ static const char* const valid_modargs[] = {
     "device_id",
     "format",
     "rate",
+    "alternate_rate",
     "channels",
     "channel_map",
     "fragments",