Support call-voice with BT SCO 03/142303/1 accepted/tizen/4.0/unified/20170828.224205 accepted/tizen/unified/20170808.171205 submit/tizen/20170807.083505 submit/tizen_4.0/20170828.110001
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 3 Aug 2017 08:19:03 +0000 (17:19 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 3 Aug 2017 08:23:46 +0000 (17:23 +0900)
UCM BT-SCO devices are supported as below
 - "bt-8k-sco-nb-headset"
 - "bt-8k-sco-nb-mic"
 - "bt-8k-sco-wb-headset"
 - "bt-8k-sco-wb-mic"
 - "bt-16k-sco-nb-headset"
 - "bt-16k-sco-nb-mic"
 - "bt-16k-sco-wb-headset"
 - "bt-16k-sco-wb-mic"

[Version] 0.1.5
[Profile] Wearable
[Issue Type] New feature

Change-Id: I231f57ce040bdb3042099096c8aa64a3836125e8
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
packaging/audio-hal-wm1831-tw2.spec
tizen-audio-internal.h
tizen-audio-routing.c

index 5ead07a..d760fa3 100644 (file)
@@ -1,6 +1,6 @@
 Name:       audio-hal-wm1831-tw2
 Summary:    TIZEN Audio HAL for WM1831(TW2)
-Version:    0.1.4
+Version:    0.1.5
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0
index 81ec92a..d1a3867 100644 (file)
@@ -20,6 +20,7 @@
  *
  */
 
+#include <stdbool.h>
 #include <dlog.h>
 #include <time.h>
 #include <sys/types.h>
         return NULL; \
     } \
 } while (0)
+/*
+static device_type_t outDeviceTypes[] = {
+    { AUDIO_DEVICE_OUT_SPEAKER, "speaker" },
+    { AUDIO_DEVICE_OUT_BT_SCO, "bt-sco-headset" },
+    { AUDIO_DEVICE_OUT_BT_SCO_8K_NB, "bt-8k-sco-nb-headset" },
+    { AUDIO_DEVICE_OUT_BT_SCO_16K_NB, "bt-16k-sco-nb-headset" },
+    { AUDIO_DEVICE_OUT_BT_SCO_8K_WB, "bt-8k-sco-wb-headset" },
+    { AUDIO_DEVICE_OUT_BT_SCO_16K_WB, "bt-16k-sco-wb-headset" },
+    { 0, 0 },
+};
+
+static device_type_t inDeviceTypes[] = {
+    { AUDIO_DEVICE_IN_MAIN_MIC, "main-mic" },
+    { AUDIO_DEVICE_IN_BT_SCO, "bt-sco-mic" },
+    { AUDIO_DEVICE_IN_BT_SCO_8K_NB, "bt-8k-sco-nb-mic" },
+    { AUDIO_DEVICE_IN_BT_SCO_16K_NB, "bt-16k-sco-nb-mic" },
+    { AUDIO_DEVICE_IN_BT_SCO_8K_WB, "bt-8k-sco-wb-mic" },
+    { AUDIO_DEVICE_IN_BT_SCO_16K_WB, "bt-16k-sco-wb-mic" },
+    { 0, 0 },
+};
+
+
+*/
 
 /* Devices : Normal  */
 #define AUDIO_DEVICE_OUT               0x00000000
@@ -86,19 +110,35 @@ enum audio_device_type {
     AUDIO_DEVICE_OUT_RECEIVER         = AUDIO_DEVICE_OUT | 0x00000002,
     AUDIO_DEVICE_OUT_JACK             = AUDIO_DEVICE_OUT | 0x00000004,
     AUDIO_DEVICE_OUT_BT_SCO           = AUDIO_DEVICE_OUT | 0x00000008,
+    AUDIO_DEVICE_OUT_BT_SCO_8K_NB     = AUDIO_DEVICE_OUT | 0x00000010,
+    AUDIO_DEVICE_OUT_BT_SCO_16K_NB    = AUDIO_DEVICE_OUT | 0x00000020,
+    AUDIO_DEVICE_OUT_BT_SCO_8K_WB     = AUDIO_DEVICE_OUT | 0x00000040,
+    AUDIO_DEVICE_OUT_BT_SCO_16K_WB    = AUDIO_DEVICE_OUT | 0x00000080,
     AUDIO_DEVICE_OUT_ALL              = (AUDIO_DEVICE_OUT_SPEAKER |
                                          AUDIO_DEVICE_OUT_RECEIVER |
                                          AUDIO_DEVICE_OUT_JACK |
-                                         AUDIO_DEVICE_OUT_BT_SCO),
+                                         AUDIO_DEVICE_OUT_BT_SCO |
+                                         AUDIO_DEVICE_OUT_BT_SCO_8K_NB |
+                                         AUDIO_DEVICE_OUT_BT_SCO_16K_NB |
+                                         AUDIO_DEVICE_OUT_BT_SCO_8K_WB |
+                                         AUDIO_DEVICE_OUT_BT_SCO_16K_WB),
     /* input devices */
     AUDIO_DEVICE_IN_MAIN_MIC          = AUDIO_DEVICE_IN | 0x00000001,
     AUDIO_DEVICE_IN_SUB_MIC           = AUDIO_DEVICE_IN | 0x00000002,
     AUDIO_DEVICE_IN_JACK              = AUDIO_DEVICE_IN | 0x00000004,
     AUDIO_DEVICE_IN_BT_SCO            = AUDIO_DEVICE_IN | 0x00000008,
+    AUDIO_DEVICE_IN_BT_SCO_8K_NB      = AUDIO_DEVICE_IN | 0x00000010,
+    AUDIO_DEVICE_IN_BT_SCO_16K_NB     = AUDIO_DEVICE_IN | 0x00000020,
+    AUDIO_DEVICE_IN_BT_SCO_8K_WB      = AUDIO_DEVICE_IN | 0x00000040,
+    AUDIO_DEVICE_IN_BT_SCO_16K_WB     = AUDIO_DEVICE_IN | 0x00000080,
     AUDIO_DEVICE_IN_ALL               = (AUDIO_DEVICE_IN_MAIN_MIC |
                                          AUDIO_DEVICE_IN_SUB_MIC |
                                          AUDIO_DEVICE_IN_JACK |
-                                         AUDIO_DEVICE_IN_BT_SCO),
+                                         AUDIO_DEVICE_IN_BT_SCO |
+                                         AUDIO_DEVICE_IN_BT_SCO_8K_NB |
+                                         AUDIO_DEVICE_IN_BT_SCO_16K_NB |
+                                         AUDIO_DEVICE_IN_BT_SCO_8K_WB |
+                                         AUDIO_DEVICE_IN_BT_SCO_16K_WB),
 };
 
 typedef struct device_type {
@@ -162,7 +202,7 @@ typedef struct audio_hal_device {
     audio_pcm_devices_t voice_pcm;
     audio_pcm_devices_t bt_pcm;
     audio_route_mode_t mode;
-    uint32_t bt_wideband;
+    bool bt_wideband;
 } audio_hal_device_t;
 
 /* Volume */
@@ -257,6 +297,7 @@ typedef struct audio_hal {
     audio_hal_volume_t volume;
     audio_hal_ucm_t ucm;
     audio_hal_mixer_t mixer;
+    bool call_wideband;
 } audio_hal_t;
 
 audio_return_t _audio_volume_init(audio_hal_t *ah);
index e126712..fcf297a 100644 (file)
@@ -24,7 +24,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stdbool.h>
 
 #include "tizen-audio-internal.h"
 #include "tizen-audio-impl.h"
 static device_type_t outDeviceTypes[] = {
     { AUDIO_DEVICE_OUT_SPEAKER, "speaker" },
     { AUDIO_DEVICE_OUT_BT_SCO, "bt-sco-headset" },
+    { AUDIO_DEVICE_OUT_BT_SCO_8K_NB, "bt-8k-sco-nb-headset" },
+    { AUDIO_DEVICE_OUT_BT_SCO_16K_NB, "bt-16k-sco-nb-headset" },
+    { AUDIO_DEVICE_OUT_BT_SCO_8K_WB, "bt-8k-sco-wb-headset" },
+    { AUDIO_DEVICE_OUT_BT_SCO_16K_WB, "bt-16k-sco-wb-headset" },
     { 0, 0 },
 };
 
 static device_type_t inDeviceTypes[] = {
     { AUDIO_DEVICE_IN_MAIN_MIC, "main-mic" },
     { AUDIO_DEVICE_IN_BT_SCO, "bt-sco-mic" },
+    { AUDIO_DEVICE_IN_BT_SCO_8K_NB, "bt-8k-sco-nb-mic" },
+    { AUDIO_DEVICE_IN_BT_SCO_16K_NB, "bt-16k-sco-nb-mic" },
+    { AUDIO_DEVICE_IN_BT_SCO_8K_WB, "bt-8k-sco-wb-mic" },
+    { AUDIO_DEVICE_IN_BT_SCO_16K_WB, "bt-16k-sco-wb-mic" },
     { 0, 0 },
 };
 
@@ -49,21 +56,87 @@ static const char* mode_to_verb_str[] = {
     AUDIO_USE_CASE_VERB_VOIP,
 };
 
-static uint32_t __convert_device_string_to_enum(const char* device_str, uint32_t direction)
+static bool __is_acive_device_bt_sco_for_call(audio_hal_t *ah)
+{
+    if (!ah) {
+        AUDIO_LOG_WARN("ah is null");
+        return false;
+    }
+
+    if (ah->device.active_in & AUDIO_DEVICE_IN_BT_SCO_8K_NB &&
+        ah->device.active_out & AUDIO_DEVICE_OUT_BT_SCO_8K_NB)
+        return true;
+    if (ah->device.active_in & AUDIO_DEVICE_IN_BT_SCO_16K_NB &&
+        ah->device.active_out & AUDIO_DEVICE_OUT_BT_SCO_16K_NB)
+        return true;
+    if (ah->device.active_in & AUDIO_DEVICE_IN_BT_SCO_8K_WB &&
+        ah->device.active_out & AUDIO_DEVICE_OUT_BT_SCO_8K_WB)
+        return true;
+    if (ah->device.active_in & AUDIO_DEVICE_IN_BT_SCO_16K_WB &&
+        ah->device.active_out & AUDIO_DEVICE_OUT_BT_SCO_16K_WB)
+        return true;
+
+    return false;
+}
+
+static uint32_t __convert_device_string_to_enum(audio_hal_t *ah, const char *verb, const char* device_str, uint32_t direction)
 {
     uint32_t device = 0;
 
+    AUDIO_LOG_INFO("verb(%s), device string(%s), direction(%d)", verb, device_str, direction);
+
     if (!strncmp(device_str, "builtin-speaker", MAX_NAME_LEN)) {
         device = AUDIO_DEVICE_OUT_SPEAKER;
+
     } else if ((!strncmp(device_str, "bt-sco", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_OUT)) {
-        device = AUDIO_DEVICE_OUT_BT_SCO;
+        if (!strncmp(verb, AUDIO_USE_CASE_VERB_HIFI, MAX_NAME_LEN)) {
+            device = AUDIO_DEVICE_OUT_BT_SCO;
+        } else if (!strncmp(verb, AUDIO_USE_CASE_VERB_VOICECALL, MAX_NAME_LEN)) {
+            AUDIO_LOG_INFO("device.bt_widband(%d), call_wideband(%d)", ah->device.bt_wideband, ah->call_wideband);
+            if (ah->device.bt_wideband) {
+                if (ah->call_wideband)
+                    device = AUDIO_DEVICE_OUT_BT_SCO_16K_WB;
+                else
+                    device = AUDIO_DEVICE_OUT_BT_SCO_16K_NB;
+            } else {
+                if (ah->call_wideband)
+                    device = AUDIO_DEVICE_OUT_BT_SCO_8K_WB;
+                else
+                    device = AUDIO_DEVICE_OUT_BT_SCO_8K_NB;
+            }
+        } else {
+            device = AUDIO_DEVICE_OUT_BT_SCO;
+            AUDIO_LOG_WARN("invalid verb, set device(%d) forcedly", device);
+        }
+
     } else if ((!strncmp(device_str, "builtin-mic", MAX_NAME_LEN))) {
         device = AUDIO_DEVICE_IN_MAIN_MIC;
+
     } else if ((!strncmp(device_str, "bt-sco", MAX_NAME_LEN)) && (direction == AUDIO_DIRECTION_IN)) {
-        device = AUDIO_DEVICE_IN_BT_SCO;
+        if (!strncmp(verb, AUDIO_USE_CASE_VERB_HIFI, MAX_NAME_LEN)) {
+            device = AUDIO_DEVICE_IN_BT_SCO;
+        } else if (!strncmp(verb, AUDIO_USE_CASE_VERB_VOICECALL, MAX_NAME_LEN)) {
+            AUDIO_LOG_INFO("device.bt_widband(%d), call_wideband(%d)", ah->device.bt_wideband, ah->call_wideband);
+            if (ah->device.bt_wideband) {
+                if (ah->call_wideband)
+                    device = AUDIO_DEVICE_IN_BT_SCO_16K_WB;
+                else
+                    device = AUDIO_DEVICE_IN_BT_SCO_16K_NB;
+            } else {
+                if (ah->call_wideband)
+                    device = AUDIO_DEVICE_IN_BT_SCO_8K_WB;
+                else
+                    device = AUDIO_DEVICE_IN_BT_SCO_8K_NB;
+            }
+        } else {
+            device = AUDIO_DEVICE_IN_BT_SCO;
+            AUDIO_LOG_WARN("invalid verb, set device(%d) forcedly", device);
+        }
+
     } else {
         device = AUDIO_DEVICE_NONE;
     }
+
     AUDIO_LOG_INFO("device type(%s), enum(0x%x)", device_str, device);
     return device;
 }
@@ -106,7 +179,7 @@ static audio_return_t __set_devices(audio_hal_t *ah, const char *verb, device_in
     }
 
     for (i = 0; i < num_of_devices; i++) {
-        new_device = __convert_device_string_to_enum(devices[i].type, devices[i].direction);
+        new_device = __convert_device_string_to_enum(ah, verb, devices[i].type, devices[i].direction);
         if (new_device & AUDIO_DEVICE_IN) {
             for (j = 0; j < inDeviceTypes[j].type; j++) {
                 if (new_device == inDeviceTypes[j].type) {
@@ -180,9 +253,20 @@ static audio_return_t __update_route_voicecall(audio_hal_t *ah, device_info_t *d
 
     if (ah->device.mode != VERB_VOICECALL) {
         ah->device.mode = VERB_VOICECALL;
-        /* FIXME. Get network info and configure rate in pcm device */
         _reset_pcm_devices(ah);
     } else {
+        /* if this request is for BT SCO device */
+        if (__is_acive_device_bt_sco_for_call(ah)) {
+            if (_is_bt_pcm_opened_all(ah)) {
+                AUDIO_LOG_INFO("bt pcm device is already opened, skip it");
+                return audio_ret;
+            }
+            if ((audio_ret = _bt_pcm_open_all(ah))) {
+                AUDIO_LOG_ERROR("Failed to open bt pcm device: error = 0x%x", audio_ret);
+                return audio_ret;
+            }
+        }
+
         if (_is_voice_pcm_opened_all(ah)) {
             AUDIO_LOG_INFO("voice pcm device is already opened, skip it");
             return audio_ret;
@@ -346,6 +430,10 @@ static audio_return_t __update_route_reset(audio_hal_t *ah, uint32_t direction)
     if ((audio_ret = _ucm_set_devices(ah, mode_to_verb_str[ah->device.mode], active_devices)))
         AUDIO_LOG_ERROR("failed to _ucm_set_devices(), ret(0x%x)", audio_ret);
 
+    /* reset bandwidth information */
+    ah->device.bt_wideband = false;
+    ah->call_wideband = false;
+
     return audio_ret;
 }
 
@@ -434,13 +522,16 @@ audio_return_t audio_update_route_option(void *audio_handle, audio_route_option_
     AUDIO_RETURN_VAL_IF_FAIL(option, AUDIO_ERR_PARAMETER);
 
     AUDIO_LOG_INFO("role:%s, name:%s, value:%d", option->role, option->name, option->value);
-    if (!strncmp("voice-recognition", option->role, MAX_NAME_LEN)) {
-        if (!strncmp("bt-wideband", option->name, MAX_NAME_LEN)) {
-            if (option->value > 0)
-                ah->device.bt_wideband = 1;
-            else
-                ah->device.bt_wideband = 0;
-        }
+    if (!strncmp("voice-recognition", option->role, MAX_NAME_LEN) ||
+        !strncmp("voice-information", option->role, MAX_NAME_LEN)) {
+        if (!strncmp("bt-wideband", option->name, MAX_NAME_LEN))
+            ah->device.bt_wideband = (option->value > 0) ? true : false;
+
+    } else if (!strncmp("call-voice", option->role, MAX_NAME_LEN)) {
+        if (!strncmp("bt-wideband", option->name, MAX_NAME_LEN))
+            ah->device.bt_wideband = (option->value > 0) ? true : false;
+        if (!strncmp("call-wideband", option->name, MAX_NAME_LEN))
+            ah->call_wideband = (option->value > 0) ? true : false;
     }
 
     return audio_ret;