[pulseaudio-discuss] [PATCH next v0 01/10] bluetooth: Abstract microphone gain in transport

Mikel Astiz mikel.astiz.oss at gmail.com
Wed Dec 12 04:17:01 PST 2012


From: Mikel Astiz <mikel.astiz at bmw-carit.de>

The microphone gain represents the volume of the incoming audio stream
from the headset. This can be nicely abstracted inside the transport
object in bluetooth-util, so the modules don't have to take care about
the D-Bus details.
---
 src/modules/bluetooth/bluetooth-util.c          | 60 +++++++++++++++++++++++++
 src/modules/bluetooth/bluetooth-util.h          |  6 +++
 src/modules/bluetooth/module-bluetooth-device.c |  1 -
 3 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c
index f3e9b53..a319db3 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -528,6 +528,27 @@ static int parse_audio_property(pa_bluetooth_device *d, const char *interface, D
 
             break;
         }
+
+        case DBUS_TYPE_UINT16: {
+            uint16_t value;
+
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "MicrophoneGain")) {
+                pa_log_debug("dbus: property 'State' changed to value '%u'", value);
+
+                if (!transport) {
+                    pa_log("Volume change does not have an associated transport");
+                    return -1;
+                }
+
+                transport->microphone_gain = PA_MIN(value, HSP_MAX_GAIN);
+
+                pa_hook_fire(&d->discovery->hooks[PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED], transport);
+            }
+
+            break;
+        }
     }
 
     return 0;
@@ -1086,6 +1107,45 @@ void pa_bluetooth_transport_release(pa_bluetooth_transport *t, const char *acces
         pa_log_info("Transport %s released", t->path);
 }
 
+static void pa_bt_set_property(pa_bluetooth_discovery *y, const char *path, const char *interface, const char *prop_name,
+                               int prop_type, void *prop_value) {
+    DBusMessage *m;
+    DBusMessageIter i;
+    DBusMessageIter variant;
+    const char *variant_signature;
+
+    pa_assert(y);
+    pa_assert(path);
+    pa_assert(interface);
+    pa_assert(prop_name);
+
+    pa_assert_se(m = dbus_message_new_method_call("org.bluez", path, interface, "SetProperty"));
+    dbus_message_iter_init_append(m, &i);
+    dbus_message_iter_append_basic(&i, DBUS_TYPE_STRING, &prop_name);
+
+    switch (prop_type) {
+        case DBUS_TYPE_UINT16:
+            variant_signature = DBUS_TYPE_UINT16_AS_STRING;
+            break;
+        default:
+            pa_assert_not_reached(); /* Not implemented */
+    }
+
+    dbus_message_iter_open_container(&i, DBUS_TYPE_VARIANT, variant_signature, &variant);
+    dbus_message_iter_append_basic(&variant, prop_type, prop_value);
+    dbus_message_iter_close_container(&i, &variant);
+
+    pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y->connection), m, NULL));
+    dbus_message_unref(m);
+}
+
+void pa_bluetooth_transport_set_microphone_gain(pa_bluetooth_transport *t, uint16_t value) {
+    pa_assert(t);
+    pa_assert(t->profile == PROFILE_HSP);
+
+    pa_bt_set_property(t->device->discovery, t->device->path, "org.bluez.Headset", "MicrophoneGain", DBUS_TYPE_UINT16, &value);
+}
+
 static int setup_dbus(pa_bluetooth_discovery *y) {
     DBusError err;
 
diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h
index 254eded..4c909ab 100644
--- a/src/modules/bluetooth/bluetooth-util.h
+++ b/src/modules/bluetooth/bluetooth-util.h
@@ -43,6 +43,8 @@
 #define A2DP_SOURCE_UUID        "0000110a-0000-1000-8000-00805f9b34fb"
 #define A2DP_SINK_UUID          "0000110b-0000-1000-8000-00805f9b34fb"
 
+#define HSP_MAX_GAIN 15
+
 typedef struct pa_bluetooth_uuid pa_bluetooth_uuid;
 typedef struct pa_bluetooth_device pa_bluetooth_device;
 typedef struct pa_bluetooth_discovery pa_bluetooth_discovery;
@@ -76,6 +78,7 @@ typedef enum pa_bluetooth_hook {
     PA_BLUETOOTH_HOOK_DEVICE_UUID_ADDED, /* Call data: pa_bluetooth_hook_uuid_data */
     PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED, /* Call data: pa_bluetooth_transport */
     PA_BLUETOOTH_HOOK_TRANSPORT_NREC_CHANGED, /* Call data: pa_bluetooth_transport */
+    PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED, /* Call data: pa_bluetooth_transport */
     PA_BLUETOOTH_HOOK_MAX
 } pa_bluetooth_hook_t;
 
@@ -96,6 +99,7 @@ struct pa_bluetooth_transport {
 
     pa_bluetooth_transport_state_t state;
     pa_bool_t nrec;
+    uint16_t microphone_gain; /* Used for HSP/HFP */
 };
 
 /* This enum is shared among Audio, Headset, AudioSink, and AudioSource, although not all values are acceptable in all profiles */
@@ -145,6 +149,8 @@ bool pa_bluetooth_device_any_audio_connected(const pa_bluetooth_device *d);
 int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, const char *accesstype, size_t *imtu, size_t *omtu);
 void pa_bluetooth_transport_release(pa_bluetooth_transport *t, const char *accesstype);
 
+void pa_bluetooth_transport_set_microphone_gain(pa_bluetooth_transport *t, uint16_t value);
+
 pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hook_t hook);
 
 const char* pa_bluetooth_get_form_factor(uint32_t class);
diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index e5f7f6d..70d3334 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -60,7 +60,6 @@
 
 #define BITPOOL_DEC_LIMIT 32
 #define BITPOOL_DEC_STEP 5
-#define HSP_MAX_GAIN 15
 
 PA_MODULE_AUTHOR("Joao Paulo Rechi Vita");
 PA_MODULE_DESCRIPTION("Bluetooth audio sink and source");
-- 
1.7.11.7



More information about the pulseaudio-discuss mailing list