summaryrefslogtreecommitdiff
path: root/src/modules/alsa
diff options
context:
space:
mode:
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>2011-08-02 18:37:29 -0500
committerArun Raghavan <arun.raghavan@collabora.co.uk>2011-10-17 20:09:50 +0530
commitb232fbd8f8afa5881d483e2fa72e06206f1da861 (patch)
tree32f0243d2fa7bc3dd9a98cdb6047f539a49663dc /src/modules/alsa
parentf0ec495938cf0adbee820aec126ece99eb31a1af (diff)
alsa: support for alternate sampling rate
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>
Diffstat (limited to 'src/modules/alsa')
-rw-r--r--src/modules/alsa/alsa-sink.c72
-rw-r--r--src/modules/alsa/alsa-source.c22
-rw-r--r--src/modules/alsa/module-alsa-sink.c2
-rw-r--r--src/modules/alsa/module-alsa-source.c2
4 files changed, 48 insertions, 50 deletions
diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index bcc6e51a3..0b7bbe00b 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -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);
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index 0766e11e1..c27942910 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -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);
diff --git a/src/modules/alsa/module-alsa-sink.c b/src/modules/alsa/module-alsa-sink.c
index 2a558a145..019ccf0eb 100644
--- a/src/modules/alsa/module-alsa-sink.c
+++ b/src/modules/alsa/module-alsa-sink.c
@@ -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",
diff --git a/src/modules/alsa/module-alsa-source.c b/src/modules/alsa/module-alsa-source.c
index 628e6313a..2d2c8b649 100644
--- a/src/modules/alsa/module-alsa-source.c
+++ b/src/modules/alsa/module-alsa-source.c
@@ -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",