[pulseaudio-discuss] [PATCH 1/5] core: add support for alternate sample rate

Pierre-Louis Bossart bossart.nospam at gmail.com
Sun Mar 6 14:30:08 PST 2011


New alternate_sample_rate field, typically configured to 48000 when
default sampling rate is 44100 Hz.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart at intel.com>
---
 man/pulse-daemon.conf.5.xml.in |    8 +++++++
 src/daemon/daemon-conf.c       |   21 ++++++++++++++++++++
 src/daemon/daemon-conf.h       |    1 +
 src/daemon/daemon.conf.in      |    1 +
 src/daemon/main.c              |    1 +
 src/modules/dbus/iface-core.c  |   41 ++++++++++++++++++++++++++++++++++++++++
 src/pulsecore/core.h           |    1 +
 7 files changed, 74 insertions(+), 0 deletions(-)

diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
index f2deff1..7c6a6aa 100644
--- a/man/pulse-daemon.conf.5.xml.in
+++ b/man/pulse-daemon.conf.5.xml.in
@@ -413,6 +413,14 @@ USA.
       <p><opt>default-channel-map</opt> The default channel map.</p>
     </option>
 
+    <option>
+      <p><opt>alternate-sample-rate=</opt> The alternate sample
+      frequency. Sinks and sources will use either the
+      default-rate-rate value or this alternate value, typically 44.1
+      or 48kHz. Switching between default and alternate values is
+      enabled only when the sinks/sources are suspended</p>
+    </option>
+
   </section>
 
   <section name="Default Fragment Settings">
diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index 74e8135..4f91c9d 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -95,6 +95,7 @@ static const pa_daemon_conf default_conf = {
     .sync_volume_safety_margin_usec = 8000,
     .sync_volume_extra_delay_usec = 0,
     .default_sample_spec = { .format = PA_SAMPLE_S16NE, .rate = 44100, .channels = 2 },
+    .alternate_sample_rate = 48000,
     .default_channel_map = { .channels = 2, .map = { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } },
     .shm_size = 0
 #ifdef HAVE_SYS_RESOURCE_H
@@ -355,6 +356,24 @@ static int parse_sample_rate(const char *filename, unsigned line, const char *se
     return 0;
 }
 
+static int parse_alternate_sample_rate(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+    pa_daemon_conf *c = data;
+    uint32_t r;
+
+    pa_assert(filename);
+    pa_assert(lvalue);
+    pa_assert(rvalue);
+    pa_assert(data);
+
+    if (pa_atou(rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0) {
+        pa_log(_("[%s:%u] Invalid sample rate '%s'."), filename, line, rvalue);
+        return -1;
+    }
+
+    c->alternate_sample_rate = r;
+    return 0;
+}
+
 struct channel_conf_info {
     pa_daemon_conf *conf;
     pa_bool_t default_sample_spec_set;
@@ -523,6 +542,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
         { "resample-method",            parse_resample_method,    c, NULL },
         { "default-sample-format",      parse_sample_format,      c, NULL },
         { "default-sample-rate",        parse_sample_rate,        c, NULL },
+        { "alternate-sample-rate",      parse_alternate_sample_rate, c, NULL },
         { "default-sample-channels",    parse_sample_channels,    &ci,  NULL },
         { "default-channel-map",        parse_channel_map,        &ci,  NULL },
         { "default-fragments",          parse_fragments,          c, NULL },
@@ -725,6 +745,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
     pa_strbuf_printf(s, "enable-lfe-remixing = %s\n", pa_yes_no(!c->disable_lfe_remixing));
     pa_strbuf_printf(s, "default-sample-format = %s\n", pa_sample_format_to_string(c->default_sample_spec.format));
     pa_strbuf_printf(s, "default-sample-rate = %u\n", c->default_sample_spec.rate);
+    pa_strbuf_printf(s, "alternate-sample-rate = %u\n", c->alternate_sample_rate);
     pa_strbuf_printf(s, "default-sample-channels = %u\n", c->default_sample_spec.channels);
     pa_strbuf_printf(s, "default-channel-map = %s\n", pa_channel_map_snprint(cm, sizeof(cm), &c->default_channel_map));
     pa_strbuf_printf(s, "default-fragments = %u\n", c->default_n_fragments);
diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h
index 9fd6aba..2f97613 100644
--- a/src/daemon/daemon-conf.h
+++ b/src/daemon/daemon-conf.h
@@ -131,6 +131,7 @@ typedef struct pa_daemon_conf {
     unsigned sync_volume_safety_margin_usec;
     int sync_volume_extra_delay_usec;
     pa_sample_spec default_sample_spec;
+    uint32_t alternate_sample_rate;
     pa_channel_map default_channel_map;
     size_t shm_size;
 } pa_daemon_conf;
diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
index 9beba85..294d5d6 100644
--- a/src/daemon/daemon.conf.in
+++ b/src/daemon/daemon.conf.in
@@ -75,6 +75,7 @@
 
 ; default-sample-format = s16le
 ; default-sample-rate = 44100
+; alternate-sample-rate = 48000
 ; default-sample-channels = 2
 ; default-channel-map = front-left,front-right
 
diff --git a/src/daemon/main.c b/src/daemon/main.c
index f9fcc92..e8cdf96 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -942,6 +942,7 @@ int main(int argc, char *argv[]) {
     }
 
     c->default_sample_spec = conf->default_sample_spec;
+    c->alternate_sample_rate = conf->alternate_sample_rate;
     c->default_channel_map = conf->default_channel_map;
     c->default_n_fragments = conf->default_n_fragments;
     c->default_fragment_size_msec = conf->default_fragment_size_msec;
diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
index 268a87e..0ee75d7 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -62,6 +62,8 @@ static void handle_get_default_sample_format(DBusConnection *conn, DBusMessage *
 static void handle_set_default_sample_format(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
 static void handle_get_default_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
+static void handle_get_alternate_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_alternate_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata);
 static void handle_get_cards(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_fallback_sink(DBusConnection *conn, DBusMessage *msg, void *userdata);
@@ -129,6 +131,7 @@ enum property_handler_index {
     PROPERTY_HANDLER_DEFAULT_CHANNELS,
     PROPERTY_HANDLER_DEFAULT_SAMPLE_FORMAT,
     PROPERTY_HANDLER_DEFAULT_SAMPLE_RATE,
+    PROPERTY_HANDLER_ALTERNATE_SAMPLE_RATE,
     PROPERTY_HANDLER_CARDS,
     PROPERTY_HANDLER_SINKS,
     PROPERTY_HANDLER_FALLBACK_SINK,
@@ -154,6 +157,7 @@ static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = {
     [PROPERTY_HANDLER_DEFAULT_CHANNELS]      = { .property_name = "DefaultChannels",     .type = "au", .get_cb = handle_get_default_channels,      .set_cb = handle_set_default_channels },
     [PROPERTY_HANDLER_DEFAULT_SAMPLE_FORMAT] = { .property_name = "DefaultSampleFormat", .type = "u",  .get_cb = handle_get_default_sample_format, .set_cb = handle_set_default_sample_format },
     [PROPERTY_HANDLER_DEFAULT_SAMPLE_RATE]   = { .property_name = "DefaultSampleRate",   .type = "u",  .get_cb = handle_get_default_sample_rate,   .set_cb = handle_set_default_sample_rate },
+    [PROPERTY_HANDLER_ALTERNATE_SAMPLE_RATE]   = { .property_name = "AlternateSampleRate",   .type = "u",  .get_cb = handle_get_alternate_sample_rate,   .set_cb = handle_set_alternate_sample_rate },
     [PROPERTY_HANDLER_CARDS]                 = { .property_name = "Cards",               .type = "ao", .get_cb = handle_get_cards,                 .set_cb = NULL },
     [PROPERTY_HANDLER_SINKS]                 = { .property_name = "Sinks",               .type = "ao", .get_cb = handle_get_sinks,                 .set_cb = NULL },
     [PROPERTY_HANDLER_FALLBACK_SINK]         = { .property_name = "FallbackSink",        .type = "o",  .get_cb = handle_get_fallback_sink,         .set_cb = handle_set_fallback_sink },
@@ -550,6 +554,40 @@ static void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *ms
     pa_dbus_send_empty_reply(conn, msg);
 }
 
+static void handle_get_alternate_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    dbus_uint32_t alternate_sample_rate;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(c);
+
+    alternate_sample_rate = c->core->alternate_sample_rate;
+
+    pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &alternate_sample_rate);
+}
+
+static void handle_set_alternate_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) {
+    pa_dbusiface_core *c = userdata;
+    dbus_uint32_t alternate_sample_rate;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(iter);
+    pa_assert(c);
+
+    dbus_message_iter_get_basic(iter, &alternate_sample_rate);
+
+    if (alternate_sample_rate <= 0 || alternate_sample_rate > PA_RATE_MAX) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample rate.");
+        return;
+    }
+
+    c->core->alternate_sample_rate = alternate_sample_rate;
+
+    pa_dbus_send_empty_reply(conn, msg);
+}
+
 /* The caller frees the array, but not the strings. */
 static const char **get_cards(pa_dbusiface_core *c, unsigned *n) {
     const char **cards;
@@ -1015,6 +1053,7 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat
     unsigned n_default_channels;
     dbus_uint32_t default_sample_format;
     dbus_uint32_t default_sample_rate;
+    dbus_uint32_t alternate_sample_rate;
     const char **cards;
     unsigned n_cards;
     const char **sinks;
@@ -1050,6 +1089,7 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat
     default_channels = get_default_channels(c, &n_default_channels);
     default_sample_format = c->core->default_sample_spec.format;
     default_sample_rate = c->core->default_sample_spec.rate;
+    alternate_sample_rate = c->core->alternate_sample_rate;
     cards = get_cards(c, &n_cards);
     sinks = get_sinks(c, &n_sinks);
     fallback_sink = c->fallback_sink
@@ -1082,6 +1122,7 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat
     pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_CHANNELS].property_name, DBUS_TYPE_UINT32, default_channels, n_default_channels);
     pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_SAMPLE_FORMAT].property_name, DBUS_TYPE_UINT32, &default_sample_format);
     pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_SAMPLE_RATE].property_name, DBUS_TYPE_UINT32, &default_sample_rate);
+    pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_ALTERNATE_SAMPLE_RATE].property_name, DBUS_TYPE_UINT32, &alternate_sample_rate);
     pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CARDS].property_name, DBUS_TYPE_OBJECT_PATH, cards, n_cards);
     pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SINKS].property_name, DBUS_TYPE_OBJECT_PATH, sinks, n_sinks);
 
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index a1215bb..e324804 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -141,6 +141,7 @@ struct pa_core {
 
     pa_channel_map default_channel_map;
     pa_sample_spec default_sample_spec;
+    uint32_t alternate_sample_rate;
     unsigned default_n_fragments, default_fragment_size_msec;
     unsigned sync_volume_safety_margin_usec;
     int sync_volume_extra_delay_usec;
-- 
1.7.4




More information about the pulseaudio-discuss mailing list