]> code.delx.au - pulseaudio/commitdiff
bluetooth: Abstract microphone gain in transport
authorMikel Astiz <mikel.astiz@bmw-carit.de>
Fri, 14 Dec 2012 14:14:28 +0000 (15:14 +0100)
committerTanu Kaskinen <tanuk@iki.fi>
Wed, 19 Dec 2012 10:31:49 +0000 (12:31 +0200)
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
src/modules/bluetooth/bluetooth-util.h
src/modules/bluetooth/module-bluetooth-device.c

index f3e9b532d49dd418dcaffaaa1c7c6bb8f65843de..92cb4083ff83af989ff809c60b910fbc10e8acfc 100644 (file)
@@ -528,6 +528,31 @@ 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")) {
+                uint16_t gain;
+
+                pa_log_debug("dbus: property '%s' changed to value '%u'", key, value);
+
+                if (!transport) {
+                    pa_log("Volume change does not have an associated transport");
+                    return -1;
+                }
+
+                if ((gain = PA_MIN(value, HSP_MAX_GAIN)) == transport->microphone_gain)
+                    break;
+
+                transport->microphone_gain = gain;
+                pa_hook_fire(&d->discovery->hooks[PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED], transport);
+            }
+
+            break;
+        }
     }
 
     return 0;
@@ -1086,6 +1111,36 @@ void pa_bluetooth_transport_release(pa_bluetooth_transport *t, const char *acces
         pa_log_info("Transport %s released", t->path);
 }
 
+static void set_property(pa_bluetooth_discovery *y, const char *bus, const char *path, const char *interface,
+                         const char *prop_name, int prop_type, void *prop_value) {
+    DBusMessage *m;
+    DBusMessageIter i;
+
+    pa_assert(y);
+    pa_assert(path);
+    pa_assert(interface);
+    pa_assert(prop_name);
+
+    pa_assert_se(m = dbus_message_new_method_call(bus, path, interface, "SetProperty"));
+    dbus_message_iter_init_append(m, &i);
+    dbus_message_iter_append_basic(&i, DBUS_TYPE_STRING, &prop_name);
+    pa_dbus_append_basic_variant(&i, prop_type, prop_value);
+
+    dbus_message_set_no_reply(m, true);
+    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) {
+    dbus_uint16_t gain = PA_MIN(value, HSP_MAX_GAIN);
+
+    pa_assert(t);
+    pa_assert(t->profile == PROFILE_HSP);
+
+    set_property(t->device->discovery, "org.bluez", t->device->path, "org.bluez.Headset",
+                 "MicrophoneGain", DBUS_TYPE_UINT16, &gain);
+}
+
 static int setup_dbus(pa_bluetooth_discovery *y) {
     DBusError err;
 
index 254eded71c58891f728bfefd50716549c31bd7a7..4c909abd1d88c96a3e8171cfca692e5c922c3c59 100644 (file)
@@ -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);
index e5f7f6dda9c52c1f6130d67fad78a893878a454e..70d333460b0a4cbb9aaf8e189ee9554ab807deb3 100644 (file)
@@ -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");