瀏覽代碼

component/bt: add new example for A2DP

1. add new example for A2DP and the related btif layer source code is ported
2. modification on osi_alarm_new API to support periodic timer
3. enable macro BTA_AR_INCLUDED, BTA_AV_INCLUDED, BTA_AV_SINK_INCLUDED
4. The A2DP example cannot work and can only be built successfuly
wangmengyang 9 年之前
父節點
當前提交
30198ee8c1
共有 90 個文件被更改,包括 20676 次插入17 次删除
  1. 1 1
      components/bt/bluedroid/bta/sys/bta_sys_main.c
  2. 1 1
      components/bt/bluedroid/hci/hci_layer.c
  3. 3 3
      components/bt/bluedroid/include/bt_target.h
  4. 3 2
      components/bt/bluedroid/osi/alarm.c
  5. 2 1
      components/bt/bluedroid/osi/include/alarm.h
  6. 1 1
      components/bt/bluedroid/osi/include/thread.h
  7. 3 3
      components/bt/bluedroid/stack/btu/btu_task.c
  8. 32 0
      components/bt/bluedroid/utils/bt_utils.c
  9. 2 2
      components/bt/bluedroid/utils/include/bt_utils.h
  10. 1 1
      examples/06_bluedroid_demos/components/bluedroid_demos/app_core/bt_app_core.c
  11. 1 1
      examples/08_bt_sdp/components/bluedroid_demos/btif/btif_core.c
  12. 1 1
      examples/08_bt_sdp/components/bluedroid_demos/include/btif_util.h
  13. 11 0
      examples/09_a2dp/Makefile
  14. 5 0
      examples/09_a2dp/README.rst
  15. 174 0
      examples/09_a2dp/components/bluedroid_demos/app_core/bt_app_core.c
  16. 169 0
      examples/09_a2dp/components/bluedroid_demos/app_project/SampleBtSdp.c
  17. 1423 0
      examples/09_a2dp/components/bluedroid_demos/audio_a2dp_hw/audio_a2dp_hw.c
  18. 88 0
      examples/09_a2dp/components/bluedroid_demos/audio_a2dp_hw/include/audio_a2dp_hw.h
  19. 1435 0
      examples/09_a2dp/components/bluedroid_demos/btif/btif_av.c
  20. 483 0
      examples/09_a2dp/components/bluedroid_demos/btif/btif_core.c
  21. 233 0
      examples/09_a2dp/components/bluedroid_demos/btif/btif_dm.c
  22. 2836 0
      examples/09_a2dp/components/bluedroid_demos/btif/btif_media_task.c
  23. 179 0
      examples/09_a2dp/components/bluedroid_demos/btif/btif_profile_queue.c
  24. 175 0
      examples/09_a2dp/components/bluedroid_demos/btif/btif_sdp.c
  25. 777 0
      examples/09_a2dp/components/bluedroid_demos/btif/btif_sdp_server.c
  26. 208 0
      examples/09_a2dp/components/bluedroid_demos/btif/btif_sm.c
  27. 159 0
      examples/09_a2dp/components/bluedroid_demos/btif/btif_util.c
  28. 88 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/btif_api.h
  29. 154 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/btif_av.h
  30. 210 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/btif_av_api.h
  31. 174 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/btif_av_co.h
  32. 125 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/btif_common.h
  33. 32 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/btif_dm.h
  34. 282 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/btif_media.h
  35. 37 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/btif_profile_queue.h
  36. 38 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/btif_sdp.h
  37. 118 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/btif_sm.h
  38. 31 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/btif_stack_manager.h
  39. 53 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/btif_util.h
  40. 29 0
      examples/09_a2dp/components/bluedroid_demos/btif/include/stack_manager.h
  41. 160 0
      examples/09_a2dp/components/bluedroid_demos/btif/stack_manager.c
  42. 29 0
      examples/09_a2dp/components/bluedroid_demos/component.mk
  43. 86 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_assert.h
  44. 123 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_bitstream.h
  45. 229 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_bt_spec.h
  46. 484 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_codec_sbc.h
  47. 229 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_codec_sbc_private.h
  48. 43 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_common.h
  49. 505 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_cpu_dep.h
  50. 171 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_modules.h
  51. 197 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_osinterface.h
  52. 579 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_status.h
  53. 232 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_stddefs.h
  54. 208 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_string.h
  55. 200 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_time.h
  56. 377 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_utils.h
  57. 78 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/alloc.c
  58. 165 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/bitalloc-sbc.c
  59. 392 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/bitalloc.c
  60. 92 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/bitstream-decode.c
  61. 140 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/decoder-oina.c
  62. 227 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/decoder-private.c
  63. 465 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/decoder-sbc.c
  64. 210 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/dequant.c
  65. 54 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/framing-sbc.c
  66. 249 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/framing.c
  67. 57 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/oi_codec_version.c
  68. 111 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/readsamplesjoint.inc
  69. 135 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/synthesis-8-generated.c
  70. 305 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/synthesis-dct8.c
  71. 510 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/synthesis-sbc.c
  72. 91 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/include/sbc_dct.h
  73. 57 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/include/sbc_enc_func_declare.h
  74. 202 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/include/sbc_encoder.h
  75. 47 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/include/sbc_if.h
  76. 59 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/include/sbc_types.h
  77. 1107 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_analysis.c
  78. 245 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_dct.c
  79. 200 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_dct_coeffs.c
  80. 199 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_enc_bit_alloc_mono.c
  81. 212 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c
  82. 319 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_enc_coeffs.c
  83. 402 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_encoder.c
  84. 274 0
      examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_packing.c
  85. 30 0
      examples/09_a2dp/components/bluedroid_demos/include/bt_app_common.h
  86. 103 0
      examples/09_a2dp/components/bluedroid_demos/include/bt_av.h
  87. 133 0
      examples/09_a2dp/components/bluedroid_demos/udrv/include/uipc.h
  88. 139 0
      examples/09_a2dp/components/bluedroid_demos/udrv/ulinux/uipc.c
  89. 10 0
      examples/09_a2dp/main/component.mk
  90. 28 0
      examples/09_a2dp/main/demo_main.c

+ 1 - 1
components/bt/bluedroid/bta/sys/bta_sys_main.c

@@ -631,7 +631,7 @@ void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms) {
   // Get the alarm for this p_tle.
   pthread_mutex_lock(&bta_alarm_lock);
   if (!hash_map_has_key(bta_alarm_hash_map, p_tle)) {
-    hash_map_set(bta_alarm_hash_map, p_tle, osi_alarm_new("bta_sys", bta_alarm_cb, p_tle, 0));
+    hash_map_set(bta_alarm_hash_map, p_tle, osi_alarm_new("bta_sys", bta_alarm_cb, p_tle, 0, false));
   }
   pthread_mutex_unlock(&bta_alarm_lock);
 

+ 1 - 1
components/bt/bluedroid/hci/hci_layer.c

@@ -187,7 +187,7 @@ static int hci_layer_init_env(void)
     return -1;
   }
   pthread_mutex_init(&cmd_wait_q->commands_pending_response_lock, NULL);
-  cmd_wait_q->command_response_timer = osi_alarm_new("cmd_rsp_to", command_timed_out, cmd_wait_q, COMMAND_PENDING_TIMEOUT);
+  cmd_wait_q->command_response_timer = osi_alarm_new("cmd_rsp_to", command_timed_out, cmd_wait_q, COMMAND_PENDING_TIMEOUT, false);
   if (!cmd_wait_q->command_response_timer) {
     LOG_ERROR("%s unable to create command response timer.", __func__);
     return -1;

+ 3 - 3
components/bt/bluedroid/include/bt_target.h

@@ -86,15 +86,15 @@
 #endif
 
 #ifndef BTA_AR_INCLUDED
-#define BTA_AR_INCLUDED FALSE//TRUE
+#define BTA_AR_INCLUDED TRUE//TRUE
 #endif
 
 #ifndef BTA_AV_INCLUDED
-#define BTA_AV_INCLUDED FALSE//TRUE
+#define BTA_AV_INCLUDED TRUE//TRUE
 #endif
 
 #ifndef BTA_AV_SINK_INCLUDED
-#define BTA_AV_SINK_INCLUDED FALSE//FALSE
+#define BTA_AV_SINK_INCLUDED TRUE//FALSE
 #endif
 
 #ifndef BTA_DISABLE_DELAY

+ 3 - 2
components/bt/bluedroid/osi/alarm.c

@@ -73,7 +73,7 @@ static void alarm_cb_handler(TimerHandle_t xTimer)
 	}
 }
 
-osi_alarm_t *osi_alarm_new(char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire)
+osi_alarm_t *osi_alarm_new(char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire, bool is_periodic)
 {
 	struct alarm_t *timer_id;
 	TimerHandle_t t;
@@ -88,7 +88,8 @@ osi_alarm_t *osi_alarm_new(char *alarm_name, osi_alarm_callback_t callback, void
 		return NULL;
 	}
 
-	t = xTimerCreate(alarm_name, timer_expire / portTICK_PERIOD_MS, pdFALSE, timer_id, alarm_cb_handler);
+	portBASE_TYPE auto_reload = is_periodic ? pdTRUE : pdFALSE;
+	t = xTimerCreate(alarm_name, timer_expire / portTICK_PERIOD_MS, auto_reload, timer_id, alarm_cb_handler);
 	if (!t) {
 		LOG_ERROR("%s error\n", __func__);
 		return NULL;

+ 2 - 1
components/bt/bluedroid/osi/include/alarm.h

@@ -20,6 +20,7 @@
 #define _ALARM_H_
 
 #include <stdint.h>
+#include <stdbool.h>
 #include <freertos/FreeRTOS.h>
 #include <freertos/timers.h>
 
@@ -39,7 +40,7 @@ void osi_alarm_init(void);
 
 // Creates a new alarm object. The returned object must be freed by calling
 // |alarm_free|. Returns NULL on failure.
-osi_alarm_t *osi_alarm_new(char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire);
+osi_alarm_t *osi_alarm_new(char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire, bool is_periodc);
 
 // Frees an alarm object created by |alarm_new|. |alarm| may be NULL. If the
 // alarm is pending, it will be cancelled. It is not safe to call |alarm_free|

+ 1 - 1
components/bt/bluedroid/osi/include/thread.h

@@ -26,7 +26,7 @@ enum {
     SIG_PRF_WORK = 0xfd,
     SIG_BTU_START_UP = 0xfe,
     SIG_BTU_WORK = 0xff,
-    SIG_BTIF_WORK = 0xff
+    // SIG_BTIF_WORK = 0xff
 };
 
 void btu_task_post(uint32_t sig);

+ 3 - 3
components/bt/bluedroid/stack/btu/btu_task.c

@@ -522,7 +522,7 @@ void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec) {
   // Get the alarm for the timer list entry.
   pthread_mutex_lock(&btu_general_alarm_lock);
   if (!hash_map_has_key(btu_general_alarm_hash_map, p_tle)) {
-    alarm = osi_alarm_new("btu_gen", btu_general_alarm_cb, (void *)p_tle, 0);
+    alarm = osi_alarm_new("btu_gen", btu_general_alarm_cb, (void *)p_tle, 0, false);
     hash_map_set(btu_general_alarm_hash_map, p_tle, alarm);
   }
   pthread_mutex_unlock(&btu_general_alarm_lock);
@@ -607,7 +607,7 @@ void btu_start_quick_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ti
   // Get the alarm for the timer list entry.
   pthread_mutex_lock(&btu_l2cap_alarm_lock);
   if (!hash_map_has_key(btu_l2cap_alarm_hash_map, p_tle)) {
-    alarm = osi_alarm_new("btu_l2cap", btu_l2cap_alarm_cb, (void *)p_tle, 0);
+    alarm = osi_alarm_new("btu_l2cap", btu_l2cap_alarm_cb, (void *)p_tle, 0, false);
     hash_map_set(btu_l2cap_alarm_hash_map, p_tle, (void *)alarm);
   }
   pthread_mutex_unlock(&btu_l2cap_alarm_lock);
@@ -674,7 +674,7 @@ void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_
   // Get the alarm for the timer list entry.
   pthread_mutex_lock(&btu_oneshot_alarm_lock);
   if (!hash_map_has_key(btu_oneshot_alarm_hash_map, p_tle)) {
-    alarm = osi_alarm_new("btu_oneshot", btu_oneshot_alarm_cb, (void *)p_tle, 0);
+    alarm = osi_alarm_new("btu_oneshot", btu_oneshot_alarm_cb, (void *)p_tle, 0, false);
     hash_map_set(btu_oneshot_alarm_hash_map, p_tle, alarm);
   }
   pthread_mutex_unlock(&btu_oneshot_alarm_lock);

+ 32 - 0
components/bt/bluedroid/utils/bt_utils.c

@@ -0,0 +1,32 @@
+#include "bt_utils.h"
+
+
+/*****************************************************************************
+**
+** Function        raise_priority_a2dp
+**
+** Description     Raise task priority for A2DP streaming
+**
+** Returns         void
+**
+*******************************************************************************/
+void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task)
+{
+    return;
+}
+
+/*****************************************************************************
+**
+** Function        adjust_priority_a2dp
+**
+** Description     increase the a2dp consumer task priority temporarily when start
+**                 audio playing, to avoid overflow the audio packet queue, restore
+**                 the a2dp consumer task priority when stop audio playing.
+**
+** Returns         void
+**
+*******************************************************************************/
+void adjust_priority_a2dp(int start)
+{
+    return;
+}

+ 2 - 2
components/bt/bluedroid/utils/include/bt_utils.h

@@ -40,7 +40,7 @@ typedef enum {
 **  Functions
 ********************************************************************************/
 
-// void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task);
-// void adjust_priority_a2dp(int start);
+void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task);
+void adjust_priority_a2dp(int start);
 #define UNUSED(x) (void)(x)
 #endif /* BT_UTILS_H */

+ 1 - 1
examples/06_bluedroid_demos/components/bluedroid_demos/app_core/bt_app_core.c

@@ -329,7 +329,7 @@ void bt_app_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
     // Get the alarm for the timer list entry.
     pthread_mutex_lock(&bt_app_general_alarm_lock);
     if (!hash_map_has_key(bt_app_general_alarm_hash_map, p_tle)) {
-        alarm = osi_alarm_new("bt_app", bt_app_general_alarm_cb, (void *)p_tle, 0);
+        alarm = osi_alarm_new("bt_app", bt_app_general_alarm_cb, (void *)p_tle, 0. false);
         hash_map_set(bt_app_general_alarm_hash_map, p_tle, alarm);
     }
     pthread_mutex_unlock(&bt_app_general_alarm_lock);

+ 1 - 1
examples/08_bt_sdp/components/bluedroid_demos/btif/btif_core.c

@@ -90,7 +90,7 @@ static void btif_thread_post(uint32_t sig);
 /************************************************************************************
 **  Externs
 ************************************************************************************/
-static fixed_queue_t *xBtifQueue = NULL;
+static QueueHandle_t xBtifQueue = NULL;
 
 /** TODO: Move these to _common.h */
 void bte_main_boot_entry(void *);

+ 1 - 1
examples/08_bt_sdp/components/bluedroid_demos/include/btif_util.h

@@ -26,7 +26,7 @@
 // #include <sys/time.h>
 
 #include "bt_types.h"
-// #include "bt_utils.h"
+#include "bt_utils.h"
 #include "bt_defs.h"
 
 /*******************************************************************************

+ 11 - 0
examples/09_a2dp/Makefile

@@ -0,0 +1,11 @@
+#
+# This is a project Makefile. It is assumed the directory this Makefile resides in is a
+# project subdirectory.
+#
+
+PROJECT_NAME := bluedroid_demos
+
+COMPONENT_ADD_INCLUDEDIRS := components/include
+
+include $(IDF_PATH)/make/project.mk
+

+ 5 - 0
examples/09_a2dp/README.rst

@@ -0,0 +1,5 @@
+ESP-IDF 09 A2DP
+=======================
+
+Demo of A2DP audio sink role
+

+ 174 - 0
examples/09_a2dp/components/bluedroid_demos/app_core/bt_app_core.c

@@ -0,0 +1,174 @@
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "fixed_queue.h"
+#include "gki.h"
+#include "bt_defs.h"
+#include "bt_trace.h"
+#include "bt_types.h"
+#include "allocator.h"
+
+#include "bta_api.h"
+#include "bta_gatt_api.h"
+#include "bt_app_common.h"
+
+#include "controller.h"
+#include "thread.h"
+#include "bt_app_common.h"
+
+static fixed_queue_t *bt_app_msg_queue;
+
+xQueueHandle xBtAppQueue;
+xTaskHandle xBtAppTaskHandle;
+
+static void bt_app_context_switched(void *p_msg);
+static void bt_app_send_msg(void *p_msg);
+static void bt_app_task_handler(void *arg);
+static void bta_app_msg_ready(fixed_queue_t *queue);
+static void bt_app_task_shut_down(void);
+
+
+extern void app_main_entry(void);
+
+static void bt_app_task_handler(void *arg)
+{
+    app_main_entry();
+    BtTaskEvt_t *e;
+    for (;;) {
+        if (pdTRUE == xQueueReceive(xBtAppQueue, &e, (portTickType)portMAX_DELAY)) {
+            if (e->sig == 0xff) {
+                fixed_queue_process(bt_app_msg_queue);
+            }
+            osi_free(e);
+        }
+    }
+}
+
+static void bt_app_task_post(void)
+{
+     BtTaskEvt_t *evt = (BtTaskEvt_t *)osi_malloc(sizeof(BtTaskEvt_t));
+     if (evt == NULL)
+        return;
+
+     evt->sig = 0xff;
+     evt->par = 0;
+
+     if (xQueueSend(xBtAppQueue, &evt, 10/portTICK_RATE_MS) != pdTRUE) {
+         ets_printf("btdm_post failed\n");
+     }
+}
+
+static void bta_app_msg_ready(fixed_queue_t *queue) {
+    BT_HDR *p_msg;
+    while (!fixed_queue_is_empty(queue)) {
+        p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
+        LOG_ERROR("bta_app_msg_ready, evt: %d\n", p_msg->event);
+        switch (p_msg->event) {
+        case BT_EVT_APP_CONTEXT_SWITCH:
+            bt_app_context_switched(p_msg);
+            break;
+        default:
+            LOG_ERROR("unhandled BT_APP event (%d)\n", p_msg->event & BT_EVT_MASK);
+            break;
+        }
+        GKI_freebuf(p_msg);
+    }
+}
+
+static void bt_app_context_switched(void *p_msg)
+{
+    tBTAPP_CONTEXT_SWITCH_CBACK *p = (tBTAPP_CONTEXT_SWITCH_CBACK *) p_msg;
+    
+    if (p->p_cb)
+        p->p_cb(p->event, p->p_param);
+}
+
+static void bt_app_send_msg(void *p_msg)
+{
+    if (bt_app_msg_queue) {
+        fixed_queue_enqueue(bt_app_msg_queue, p_msg);
+        bt_app_task_post();
+    }
+}
+
+bt_status_t bt_app_transfer_context (tBTAPP_CBACK *p_cback, UINT16 event, char* p_params, int param_len, tBTAPP_COPY_CBACK *p_copy_cback)
+{
+    tBTAPP_CONTEXT_SWITCH_CBACK *p_msg;
+
+    LOG_ERROR("btapp_transfer_context evt %d, len %d\n", event, param_len);
+
+    /* allocate and send message that will be executed in btif context */
+    if ((p_msg = (tBTAPP_CONTEXT_SWITCH_CBACK *) GKI_getbuf(sizeof(tBTAPP_CONTEXT_SWITCH_CBACK) + param_len)) != NULL)
+    {
+        p_msg->hdr.event = BT_EVT_APP_CONTEXT_SWITCH; /* internal event */
+        p_msg->p_cb = p_cback;
+
+        p_msg->event = event;                         /* callback event */
+
+        /* check if caller has provided a copy callback to do the deep copy */
+        if (p_copy_cback)
+        {
+            p_copy_cback(event, p_msg->p_param, p_params);
+        }
+        else if (p_params)
+        {
+            memcpy(p_msg->p_param, p_params, param_len);  /* callback parameter data */
+        }
+
+        bt_app_send_msg(p_msg);
+        return BT_STATUS_SUCCESS;
+    }
+    else
+    {
+        /* let caller deal with a failed allocation */
+        return BT_STATUS_NOMEM;
+    }
+}
+
+void bt_app_task_start_up(void)
+{
+    bt_app_msg_queue = fixed_queue_new(SIZE_MAX);
+    if (bt_app_msg_queue == NULL)
+        goto error_exit;
+    //ke_event_callback_set(KE_EVENT_BT_APP_TASK, &bt_app_task_handler);
+
+    xBtAppQueue = xQueueCreate(3, sizeof(void *));
+    xTaskCreate(bt_app_task_handler, "BtaApp1T", 8192, NULL, configMAX_PRIORITIES - 3, xBtAppTaskHandle);
+
+    fixed_queue_register_dequeue(bt_app_msg_queue, bta_app_msg_ready);
+
+    return;
+
+error_exit:
+    LOG_ERROR("%s Unable to allocate resources for bt_app\n", __func__);
+    bt_app_task_shut_down();
+}
+
+static void bt_app_task_shut_down(void)
+{
+    fixed_queue_unregister_dequeue(bt_app_msg_queue);
+    fixed_queue_free(bt_app_msg_queue, NULL);
+    bt_app_msg_queue = NULL;
+
+    vTaskDelete(xBtAppTaskHandle);
+    vQueueDelete(xBtAppQueue);
+}
+
+/*
+static void bt_app_upstreams_evt(UINT16 event, char *p_param)
+{
+    tBTA_DM_SEC *p_data = (tBTA_DM_SEC*)p_param;
+    switch (event) {
+    default:
+        break;
+    }
+}
+
+static void bt_stack_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data)
+{
+    LOG_ERROR("bt_stack_evt: %d\n", (uint16_t)event);
+    bt_app_transfer_context(bt_app_upstreams_evt, (uint16_t)event, 
+           (void *)p_data, sizeof(tBTA_DM_SEC), NULL);
+}
+*/

+ 169 - 0
examples/09_a2dp/components/bluedroid_demos/app_project/SampleBtSdp.c

@@ -0,0 +1,169 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+
+#include "bt_app_common.h"
+#include "btif_stack_manager.h"
+#include "btif_sdp.h"
+#include "bt_gap_api.h"
+
+#include "bta_api.h"
+
+#include "alarm.h"
+typedef enum {
+    BT_APP_EVT_STACK_ON,
+    BT_APP_EVT_STACK_OFF,
+    BT_APP_EVT_ADD_SDP_RECORD_TO,
+    BT_APP_EVT_SDP_SEARCH_START_TO,
+    BT_APP_EVT
+} tBT_APP_EVT;
+
+typedef union {
+    uint32_t dummy;
+} tBT_APP_EVT_DATA;
+
+static void bt_stack_evt(tBT_APP_EVT event, tBT_APP_EVT_DATA *p_data);
+static void bt_stack_state_changed(bt_state_t state);
+static int bt_sdp_add_record(void);
+static void bt_sdp_search_complete(bt_status_t status, bt_bdaddr_t *bd_addr, uint8_t* uuid, int num_records, bluetooth_sdp_record *records);
+
+// static bt_bdaddr_t peer_bd_addr = {{0x00, 0x1b, 0xdc, 0x08, 0x0f, 0xe7}};
+static bt_bdaddr_t peer_bd_addr = {{0xfc, 0x3f, 0x7c, 0xf1, 0x2c, 0x78}};
+
+/* root browse
+static const uint8_t target_uuid[16] = { 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x00,
+                                         0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
+*/
+
+/* UUID_MAP_MAS */
+static const uint8_t  target_uuid[] = {0x00, 0x00, 0x11, 0x32, 0x00, 0x00, 0x10, 0x00,
+                                        0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
+
+/* UUID AUDIO Source */
+/*
+static const uint8_t  target_uuid[] = {0x00, 0x00, 0x11, 0x0A, 0x00, 0x00, 0x10, 0x00,
+                                        0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
+*/
+
+static bt_callbacks_t bt_callbacks = {
+    bt_stack_state_changed
+};
+
+static btsdp_callbacks_t btsdp_callbacks = {
+    bt_sdp_search_complete
+};
+
+osi_alarm_t *app_alarm = NULL;
+
+static void bt_sdp_add_record_to(void *context)
+{
+    (void)(context);
+    bt_stack_evt(BT_APP_EVT_ADD_SDP_RECORD_TO, NULL);
+}
+
+static void bt_sdp_search_start_to(void *context)
+{
+    (void)(context);
+    bt_stack_evt(BT_APP_EVT_SDP_SEARCH_START_TO, NULL);
+}
+
+static void bt_app_stack_evt(UINT16 event, char *p_param)
+{
+    switch (event) {
+    case BT_APP_EVT_STACK_ON: {
+	char *dev_name = "SDP_SERVER_CLIENT";
+	BTM_SetTraceLevel(BT_TRACE_LEVEL_DEBUG);
+	BTA_DmSetDeviceName(dev_name);
+    
+        esp_bt_gap_set_scan_mode(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+        BTIF_SdpInit(&btsdp_callbacks);
+
+        app_alarm = osi_alarm_new("app_alarm", bt_sdp_add_record_to, NULL, 1000, false);
+        osi_alarm_set(app_alarm, 1000);
+    }
+        break;
+    case BT_APP_EVT_ADD_SDP_RECORD_TO: {
+        bt_sdp_add_record();
+        osi_alarm_free(app_alarm);
+        app_alarm = NULL;
+        app_alarm = osi_alarm_new("app_alarm", bt_sdp_search_start_to, NULL, 20000, false);
+        osi_alarm_set(app_alarm, 20000);
+    }
+        break;
+    case BT_APP_EVT_SDP_SEARCH_START_TO: {
+        osi_alarm_free(app_alarm);
+        app_alarm = NULL;
+        BTIF_SdpSearch(&peer_bd_addr, target_uuid);
+    }
+        break;
+    default:
+        break;
+    }
+}
+
+static void bt_stack_evt(tBT_APP_EVT event, tBT_APP_EVT_DATA *p_data)
+{
+    LOG_ERROR("bt_stack_evt: %d\n", (uint16_t)event);
+    bt_app_transfer_context(bt_app_stack_evt, (uint16_t)event, 
+           (void *)p_data, sizeof(tBT_APP_EVT_DATA), NULL);
+}
+
+static void bt_stack_state_changed(bt_state_t state)
+{
+    if (state == BT_STATE_ON) {
+        bt_stack_evt(BT_APP_EVT_STACK_ON, NULL);
+    }
+}
+
+static int bt_sdp_add_record(void)
+{
+    int handle;
+    bluetooth_sdp_sap_record sap_svr;
+    memset (&sap_svr, 0, sizeof(bluetooth_sdp_sap_record));
+    
+    sap_svr.hdr.type = SDP_TYPE_SAP_SERVER;
+    sap_svr.hdr.rfcomm_channel_number = 2;
+    sap_svr.hdr.service_name = "SIM ACCESS";
+    sap_svr.hdr.service_name_length = 10;
+    sap_svr.hdr.profile_version = 0x0100;
+
+    BTIF_SdpCreateRecord((bluetooth_sdp_record *)(&sap_svr), &handle);
+    return handle;
+}
+
+static void bt_sdp_search_complete(bt_status_t status, bt_bdaddr_t *bd_addr, uint8_t* uuid, int num_records, bluetooth_sdp_record *records)
+{
+    uint8_t *addr = bd_addr->address;
+    bluetooth_sdp_hdr_overlay *p = &records->mas.hdr;
+    LOG_ERROR("sdp search cmpl: st %d, bd_addr: %02x:%02x:%02x:%02x:%02x:%02x, records %d\n",
+              status, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], num_records);
+    if (p->service_name_length > 0) {
+        LOG_ERROR("service name: %s\n", p->service_name);
+    }
+    LOG_ERROR("rfc_chl_num %d, l2cap_psm %d, version %02x\n",
+	      p->rfcomm_channel_number, p->l2cap_psm, p->profile_version);
+#if 0
+    uint8_t *addr = bd_addr->address;
+    bluetooth_sdp_hdr_overlay *p = &records->hdr;
+    LOG_ERROR("sdp search cmpl: st %d, bd_addr: %02x:%02x:%02x:%02x:%02x:%02x, records %d, len:%d\n",
+              status, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], num_records, p->user1_ptr_len);
+    if (p->service_name_length > 0) {
+        LOG_ERROR("service name: %s\n", p->service_name);
+    }
+#endif
+}
+
+void app_main_entry(void)
+{
+    bt_status_t stat;
+    stat = BTIF_InitStack(&bt_callbacks);
+    if (stat == BT_STATUS_SUCCESS) {
+        BTIF_EnableStack();
+    }
+}
+

+ 1423 - 0
examples/09_a2dp/components/bluedroid_demos/audio_a2dp_hw/audio_a2dp_hw.c

@@ -0,0 +1,1423 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/*****************************************************************************
+ *
+ *  Filename:      audio_a2dp_hw.c
+ *
+ *  Description:   Implements hal for bluedroid a2dp audio device
+ *
+ *****************************************************************************/
+
+#include <errno.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <stdint.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/poll.h>
+#include <sys/errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <cutils/str_parms.h>
+#include <cutils/sockets.h>
+
+#include <system/audio.h>
+#include <hardware/audio.h>
+
+#include <hardware/hardware.h>
+#include "audio_a2dp_hw.h"
+#include "bt_utils.h"
+
+#define LOG_TAG "bt_a2dp_hw"
+#include "osi/include/log.h"
+
+/*****************************************************************************
+**  Constants & Macros
+******************************************************************************/
+
+#define CTRL_CHAN_RETRY_COUNT 3
+#define USEC_PER_SEC 1000000L
+
+#define CASE_RETURN_STR(const) case const: return #const;
+
+#define FNLOG()             LOG_VERBOSE("%s", __FUNCTION__);
+#define DEBUG(fmt, ...)     LOG_VERBOSE("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
+#define INFO(fmt, ...)      LOG_INFO("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
+#define ERROR(fmt, ...)     LOG_ERROR("%s: " fmt,__FUNCTION__, ## __VA_ARGS__)
+
+#define ASSERTC(cond, msg, val) if (!(cond)) {ERROR("### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);}
+
+/*****************************************************************************
+**  Local type definitions
+******************************************************************************/
+
+typedef enum {
+    AUDIO_A2DP_STATE_STARTING,
+    AUDIO_A2DP_STATE_STARTED,
+    AUDIO_A2DP_STATE_STOPPING,
+    AUDIO_A2DP_STATE_STOPPED,
+    AUDIO_A2DP_STATE_SUSPENDED, /* need explicit set param call to resume (suspend=false) */
+    AUDIO_A2DP_STATE_STANDBY    /* allows write to autoresume */
+} a2dp_state_t;
+
+struct a2dp_stream_in;
+struct a2dp_stream_out;
+
+struct a2dp_audio_device {
+    struct audio_hw_device device;
+    struct a2dp_stream_in  *input;
+    struct a2dp_stream_out *output;
+};
+
+struct a2dp_config {
+    uint32_t                rate;
+    uint32_t                channel_flags;
+    int                     format;
+};
+
+/* move ctrl_fd outside output stream and keep open until HAL unloaded ? */
+
+struct a2dp_stream_common {
+    pthread_mutex_t         lock;
+    int                     ctrl_fd;
+    int                     audio_fd;
+    size_t                  buffer_sz;
+    struct a2dp_config      cfg;
+    a2dp_state_t            state;
+};
+
+struct a2dp_stream_out {
+    struct audio_stream_out stream;
+    struct a2dp_stream_common common;
+    uint64_t frames_presented; // frames written, never reset
+    uint64_t frames_rendered;  // frames written, reset on standby
+};
+
+struct a2dp_stream_in {
+    struct audio_stream_in  stream;
+    struct a2dp_stream_common common;
+};
+
+/*****************************************************************************
+**  Static variables
+******************************************************************************/
+
+/*****************************************************************************
+**  Static functions
+******************************************************************************/
+
+static size_t out_get_buffer_size(const struct audio_stream *stream);
+
+/*****************************************************************************
+**  Externs
+******************************************************************************/
+
+/*****************************************************************************
+**  Functions
+******************************************************************************/
+
+/*****************************************************************************
+**   Miscellaneous helper functions
+******************************************************************************/
+
+static const char* dump_a2dp_ctrl_event(char event)
+{
+    switch(event)
+    {
+        CASE_RETURN_STR(A2DP_CTRL_CMD_NONE)
+        CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY)
+        CASE_RETURN_STR(A2DP_CTRL_CMD_START)
+        CASE_RETURN_STR(A2DP_CTRL_CMD_STOP)
+        CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND)
+        default:
+            return "UNKNOWN MSG ID";
+    }
+}
+
+/* logs timestamp with microsec precision
+   pprev is optional in case a dedicated diff is required */
+static void ts_log(char *tag, int val, struct timespec *pprev_opt)
+{
+    struct timespec now;
+    static struct timespec prev = {0,0};
+    unsigned long long now_us;
+    unsigned long long diff_us;
+    UNUSED(tag);
+    UNUSED(val);
+
+    clock_gettime(CLOCK_MONOTONIC, &now);
+
+    now_us = now.tv_sec*USEC_PER_SEC + now.tv_nsec/1000;
+
+    if (pprev_opt)
+    {
+        diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000;
+        *pprev_opt = now;
+        DEBUG("[%s] ts %08lld, *diff %08lld, val %d", tag, now_us, diff_us, val);
+    }
+    else
+    {
+        diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC + (now.tv_nsec - prev.tv_nsec)/1000;
+        prev = now;
+        DEBUG("[%s] ts %08lld, diff %08lld, val %d", tag, now_us, diff_us, val);
+    }
+}
+
+static int calc_audiotime(struct a2dp_config cfg, int bytes)
+{
+    int chan_count = popcount(cfg.channel_flags);
+
+    ASSERTC(cfg.format == AUDIO_FORMAT_PCM_16_BIT,
+            "unsupported sample sz", cfg.format);
+
+    return bytes*(1000000/(chan_count*2))/cfg.rate;
+}
+
+/*****************************************************************************
+**
+**   bluedroid stack adaptation
+**
+*****************************************************************************/
+
+static int skt_connect(char *path, size_t buffer_sz)
+{
+    int ret;
+    int skt_fd;
+    struct sockaddr_un remote;
+    int len;
+
+    INFO("connect to %s (sz %zu)", path, buffer_sz);
+
+    skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+
+    if(socket_local_client_connect(skt_fd, path,
+            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0)
+    {
+        ERROR("failed to connect (%s)", strerror(errno));
+        close(skt_fd);
+        return -1;
+    }
+
+    len = buffer_sz;
+    ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, (int)sizeof(len));
+
+    /* only issue warning if failed */
+    if (ret < 0)
+        ERROR("setsockopt failed (%s)", strerror(errno));
+
+    ret = setsockopt(skt_fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, (int)sizeof(len));
+
+    /* only issue warning if failed */
+    if (ret < 0)
+        ERROR("setsockopt failed (%s)", strerror(errno));
+
+    INFO("connected to stack fd = %d", skt_fd);
+
+    return skt_fd;
+}
+
+static int skt_read(int fd, void *p, size_t len)
+{
+    int read;
+    struct pollfd pfd;
+    struct timespec ts;
+
+    FNLOG();
+
+    ts_log("skt_read recv", len, NULL);
+
+    if ((read = recv(fd, p, len, MSG_NOSIGNAL)) == -1)
+    {
+        ERROR("write failed with errno=%d\n", errno);
+        return -1;
+    }
+
+    return read;
+}
+
+static int skt_write(int fd, const void *p, size_t len)
+{
+    int sent;
+    struct pollfd pfd;
+
+    FNLOG();
+
+    pfd.fd = fd;
+    pfd.events = POLLOUT;
+
+    /* poll for 500 ms */
+
+    /* send time out */
+    if (poll(&pfd, 1, 500) == 0)
+        return 0;
+
+    ts_log("skt_write", len, NULL);
+
+    if ((sent = send(fd, p, len, MSG_NOSIGNAL)) == -1)
+    {
+        ERROR("write failed with errno=%d\n", errno);
+        return -1;
+    }
+
+    return sent;
+}
+
+static int skt_disconnect(int fd)
+{
+    INFO("fd %d", fd);
+
+    if (fd != AUDIO_SKT_DISCONNECTED)
+    {
+        shutdown(fd, SHUT_RDWR);
+        close(fd);
+    }
+    return 0;
+}
+
+
+
+/*****************************************************************************
+**
+**  AUDIO CONTROL PATH
+**
+*****************************************************************************/
+
+static int a2dp_ctrl_receive(struct a2dp_stream_common *common, void* buffer, int length)
+{
+    int ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL);
+    if (ret < 0)
+    {
+        ERROR("ack failed (%s)", strerror(errno));
+        if (errno == EINTR)
+        {
+            /* retry again */
+            ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL);
+            if (ret < 0)
+            {
+               ERROR("ack failed (%s)", strerror(errno));
+               skt_disconnect(common->ctrl_fd);
+               common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
+               return -1;
+            }
+        }
+        else
+        {
+               skt_disconnect(common->ctrl_fd);
+               common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
+               return -1;
+
+        }
+    }
+    return ret;
+}
+
+static int a2dp_command(struct a2dp_stream_common *common, char cmd)
+{
+    char ack;
+
+    DEBUG("A2DP COMMAND %s", dump_a2dp_ctrl_event(cmd));
+
+    /* send command */
+    if (send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL) == -1)
+    {
+        ERROR("cmd failed (%s)", strerror(errno));
+        skt_disconnect(common->ctrl_fd);
+        common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
+        return -1;
+    }
+
+    /* wait for ack byte */
+    if (a2dp_ctrl_receive(common, &ack, 1) < 0)
+        return -1;
+
+    DEBUG("A2DP COMMAND %s DONE STATUS %d", dump_a2dp_ctrl_event(cmd), ack);
+
+    if (ack == A2DP_CTRL_ACK_INCALL_FAILURE)
+        return ack;
+    if (ack != A2DP_CTRL_ACK_SUCCESS)
+        return -1;
+
+    return 0;
+}
+
+static int check_a2dp_ready(struct a2dp_stream_common *common)
+{
+    if (a2dp_command(common, A2DP_CTRL_CMD_CHECK_READY) < 0)
+    {
+        ERROR("check a2dp ready failed");
+        return -1;
+    }
+    return 0;
+}
+
+static int a2dp_read_audio_config(struct a2dp_stream_common *common)
+{
+    char cmd = A2DP_CTRL_GET_AUDIO_CONFIG;
+    uint32_t sample_rate;
+    uint8_t channel_count;
+
+    if (a2dp_command(common, A2DP_CTRL_GET_AUDIO_CONFIG) < 0)
+    {
+        ERROR("check a2dp ready failed");
+        return -1;
+    }
+
+    if (a2dp_ctrl_receive(common, &sample_rate, 4) < 0)
+        return -1;
+    if (a2dp_ctrl_receive(common, &channel_count, 1) < 0)
+        return -1;
+
+    common->cfg.channel_flags = (channel_count == 1 ? AUDIO_CHANNEL_IN_MONO : AUDIO_CHANNEL_IN_STEREO);
+    common->cfg.format = AUDIO_STREAM_DEFAULT_FORMAT;
+    common->cfg.rate = sample_rate;
+
+    INFO("got config %d %d", common->cfg.format, common->cfg.rate);
+
+    return 0;
+}
+
+static void a2dp_open_ctrl_path(struct a2dp_stream_common *common)
+{
+    int i;
+
+    /* retry logic to catch any timing variations on control channel */
+    for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++)
+    {
+        /* connect control channel if not already connected */
+        if ((common->ctrl_fd = skt_connect(A2DP_CTRL_PATH, common->buffer_sz)) > 0)
+        {
+            /* success, now check if stack is ready */
+            if (check_a2dp_ready(common) == 0)
+                break;
+
+            ERROR("error : a2dp not ready, wait 250 ms and retry");
+            usleep(250000);
+            skt_disconnect(common->ctrl_fd);
+            common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
+        }
+
+        /* ctrl channel not ready, wait a bit */
+        usleep(250000);
+    }
+}
+
+/*****************************************************************************
+**
+** AUDIO DATA PATH
+**
+*****************************************************************************/
+
+static void a2dp_stream_common_init(struct a2dp_stream_common *common)
+{
+    pthread_mutexattr_t lock_attr;
+
+    FNLOG();
+
+    pthread_mutexattr_init(&lock_attr);
+    pthread_mutexattr_settype(&lock_attr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init(&common->lock, &lock_attr);
+
+    common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
+    common->audio_fd = AUDIO_SKT_DISCONNECTED;
+    common->state = AUDIO_A2DP_STATE_STOPPED;
+
+    /* manages max capacity of socket pipe */
+    common->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
+}
+
+static int start_audio_datapath(struct a2dp_stream_common *common)
+{
+    INFO("state %d", common->state);
+
+    if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
+        INFO("%s AUDIO_SKT_DISCONNECTED", __func__);
+        return -1;
+    }
+
+    int oldstate = common->state;
+    common->state = AUDIO_A2DP_STATE_STARTING;
+
+    int a2dp_status = a2dp_command(common, A2DP_CTRL_CMD_START);
+    if (a2dp_status < 0)
+    {
+        ERROR("%s Audiopath start failed (status %d)", __func__, a2dp_status);
+
+        common->state = oldstate;
+        return -1;
+    }
+    else if (a2dp_status == A2DP_CTRL_ACK_INCALL_FAILURE)
+    {
+        ERROR("%s Audiopath start failed - in call, move to suspended", __func__);
+        common->state = oldstate;
+        return -1;
+    }
+
+    /* connect socket if not yet connected */
+    if (common->audio_fd == AUDIO_SKT_DISCONNECTED)
+    {
+        common->audio_fd = skt_connect(A2DP_DATA_PATH, common->buffer_sz);
+        if (common->audio_fd < 0)
+        {
+            common->state = oldstate;
+            return -1;
+        }
+
+        common->state = AUDIO_A2DP_STATE_STARTED;
+    }
+
+    return 0;
+}
+
+static int stop_audio_datapath(struct a2dp_stream_common *common)
+{
+    int oldstate = common->state;
+
+    INFO("state %d", common->state);
+
+    if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED)
+         return -1;
+
+    /* prevent any stray output writes from autostarting the stream
+       while stopping audiopath */
+    common->state = AUDIO_A2DP_STATE_STOPPING;
+
+    if (a2dp_command(common, A2DP_CTRL_CMD_STOP) < 0)
+    {
+        ERROR("audiopath stop failed");
+        common->state = oldstate;
+        return -1;
+    }
+
+    common->state = AUDIO_A2DP_STATE_STOPPED;
+
+    /* disconnect audio path */
+    skt_disconnect(common->audio_fd);
+    common->audio_fd = AUDIO_SKT_DISCONNECTED;
+
+    return 0;
+}
+
+static int suspend_audio_datapath(struct a2dp_stream_common *common, bool standby)
+{
+    INFO("state %d", common->state);
+
+    if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED)
+         return -1;
+
+    if (common->state == AUDIO_A2DP_STATE_STOPPING)
+        return -1;
+
+    if (a2dp_command(common, A2DP_CTRL_CMD_SUSPEND) < 0)
+        return -1;
+
+    if (standby)
+        common->state = AUDIO_A2DP_STATE_STANDBY;
+    else
+        common->state = AUDIO_A2DP_STATE_SUSPENDED;
+
+    /* disconnect audio path */
+    skt_disconnect(common->audio_fd);
+
+    common->audio_fd = AUDIO_SKT_DISCONNECTED;
+
+    return 0;
+}
+
+
+/*****************************************************************************
+**
+**  audio output callbacks
+**
+*****************************************************************************/
+
+static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
+                         size_t bytes)
+{
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+    int sent;
+
+    DEBUG("write %zu bytes (fd %d)", bytes, out->common.audio_fd);
+
+    pthread_mutex_lock(&out->common.lock);
+
+    if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
+    {
+        DEBUG("stream suspended");
+        pthread_mutex_unlock(&out->common.lock);
+        return -1;
+    }
+
+    /* only allow autostarting if we are in stopped or standby */
+    if ((out->common.state == AUDIO_A2DP_STATE_STOPPED) ||
+        (out->common.state == AUDIO_A2DP_STATE_STANDBY))
+    {
+        if (start_audio_datapath(&out->common) < 0)
+        {
+            /* emulate time this write represents to avoid very fast write
+               failures during transition periods or remote suspend */
+
+            int us_delay = calc_audiotime(out->common.cfg, bytes);
+
+            DEBUG("emulate a2dp write delay (%d us)", us_delay);
+
+            usleep(us_delay);
+            pthread_mutex_unlock(&out->common.lock);
+            return -1;
+        }
+    }
+    else if (out->common.state != AUDIO_A2DP_STATE_STARTED)
+    {
+        ERROR("stream not in stopped or standby");
+        pthread_mutex_unlock(&out->common.lock);
+        return -1;
+    }
+
+    pthread_mutex_unlock(&out->common.lock);
+    sent = skt_write(out->common.audio_fd, buffer,  bytes);
+
+    if (sent == -1) {
+        skt_disconnect(out->common.audio_fd);
+        out->common.audio_fd = AUDIO_SKT_DISCONNECTED;
+        if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED)
+            out->common.state = AUDIO_A2DP_STATE_STOPPED;
+        else
+            ERROR("write failed : stream suspended, avoid resetting state");
+    } else {
+        const size_t frames = bytes / audio_stream_out_frame_size(stream);
+        out->frames_rendered += frames;
+        out->frames_presented += frames;
+    }
+
+    DEBUG("wrote %d bytes out of %zu bytes", sent, bytes);
+    return sent;
+}
+
+
+static uint32_t out_get_sample_rate(const struct audio_stream *stream)
+{
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+
+    DEBUG("rate %" PRIu32,out->common.cfg.rate);
+
+    return out->common.cfg.rate;
+}
+
+static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
+{
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+
+    DEBUG("out_set_sample_rate : %" PRIu32, rate);
+
+    if (rate != AUDIO_STREAM_DEFAULT_RATE)
+    {
+        ERROR("only rate %d supported", AUDIO_STREAM_DEFAULT_RATE);
+        return -1;
+    }
+
+    out->common.cfg.rate = rate;
+
+    return 0;
+}
+
+static size_t out_get_buffer_size(const struct audio_stream *stream)
+{
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+
+    DEBUG("buffer_size : %zu", out->common.buffer_sz);
+
+    return out->common.buffer_sz;
+}
+
+static uint32_t out_get_channels(const struct audio_stream *stream)
+{
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+
+    DEBUG("channels 0x%" PRIx32, out->common.cfg.channel_flags);
+
+    return out->common.cfg.channel_flags;
+}
+
+static audio_format_t out_get_format(const struct audio_stream *stream)
+{
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+    DEBUG("format 0x%x", out->common.cfg.format);
+    return out->common.cfg.format;
+}
+
+static int out_set_format(struct audio_stream *stream, audio_format_t format)
+{
+    UNUSED(format);
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+    DEBUG("setting format not yet supported (0x%x)", format);
+    return -ENOSYS;
+}
+
+static int out_standby(struct audio_stream *stream)
+{
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+    int retVal = 0;
+
+    FNLOG();
+
+    pthread_mutex_lock(&out->common.lock);
+    // Do nothing in SUSPENDED state.
+    if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED)
+        retVal = suspend_audio_datapath(&out->common, true);
+    out->frames_rendered = 0; // rendered is reset, presented is not
+    pthread_mutex_unlock (&out->common.lock);
+
+    return retVal;
+}
+
+static int out_dump(const struct audio_stream *stream, int fd)
+{
+    UNUSED(fd);
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+    FNLOG();
+    return 0;
+}
+
+static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
+{
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+    struct str_parms *parms;
+    char keyval[16];
+    int retval;
+    int status = 0;
+
+    INFO("state %d", out->common.state);
+
+    parms = str_parms_create_str(kvpairs);
+
+    /* dump params */
+    str_parms_dump(parms);
+
+    retval = str_parms_get_str(parms, "closing", keyval, sizeof(keyval));
+
+    if (retval >= 0)
+    {
+        if (strcmp(keyval, "true") == 0)
+        {
+            DEBUG("stream closing, disallow any writes");
+            pthread_mutex_lock(&out->common.lock);
+            out->common.state = AUDIO_A2DP_STATE_STOPPING;
+            pthread_mutex_unlock(&out->common.lock);
+        }
+    }
+
+    retval = str_parms_get_str(parms, "A2dpSuspended", keyval, sizeof(keyval));
+
+    if (retval >= 0)
+    {
+        pthread_mutex_lock(&out->common.lock);
+        if (strcmp(keyval, "true") == 0)
+        {
+            if (out->common.state == AUDIO_A2DP_STATE_STARTED)
+                status = suspend_audio_datapath(&out->common, false);
+        }
+        else
+        {
+            /* Do not start the streaming automatically. If the phone was streaming
+             * prior to being suspended, the next out_write shall trigger the
+             * AVDTP start procedure */
+            if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
+                out->common.state = AUDIO_A2DP_STATE_STANDBY;
+            /* Irrespective of the state, return 0 */
+        }
+        pthread_mutex_unlock(&out->common.lock);
+    }
+
+    str_parms_destroy(parms);
+
+    return status;
+}
+
+static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
+{
+    UNUSED(keys);
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+
+    FNLOG();
+
+    /* add populating param here */
+
+    return strdup("");
+}
+
+static uint32_t out_get_latency(const struct audio_stream_out *stream)
+{
+    int latency_us;
+
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+
+    FNLOG();
+
+    latency_us = ((out->common.buffer_sz * 1000 ) /
+                    audio_stream_out_frame_size(&out->stream) /
+                    out->common.cfg.rate) * 1000;
+
+
+    return (latency_us / 1000) + 200;
+}
+
+static int out_set_volume(struct audio_stream_out *stream, float left,
+                          float right)
+{
+    UNUSED(stream);
+    UNUSED(left);
+    UNUSED(right);
+
+    FNLOG();
+
+    /* volume controlled in audioflinger mixer (digital) */
+
+    return -ENOSYS;
+}
+
+static int out_get_presentation_position(const struct audio_stream_out *stream,
+                                         uint64_t *frames, struct timespec *timestamp)
+{
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+
+    FNLOG();
+    if (stream == NULL || frames == NULL || timestamp == NULL)
+        return -EINVAL;
+
+    int ret = -EWOULDBLOCK;
+    pthread_mutex_lock(&out->common.lock);
+    uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
+    if (out->frames_presented >= latency_frames) {
+        *frames = out->frames_presented - latency_frames;
+        clock_gettime(CLOCK_MONOTONIC, timestamp); // could also be associated with out_write().
+        ret = 0;
+    }
+    pthread_mutex_unlock(&out->common.lock);
+    return ret;
+}
+
+static int out_get_render_position(const struct audio_stream_out *stream,
+                                   uint32_t *dsp_frames)
+{
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+
+    FNLOG();
+    if (stream == NULL || dsp_frames == NULL)
+        return -EINVAL;
+
+    pthread_mutex_lock(&out->common.lock);
+    uint64_t latency_frames = (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
+    if (out->frames_rendered >= latency_frames) {
+        *dsp_frames = (uint32_t)(out->frames_rendered - latency_frames);
+    } else {
+        *dsp_frames = 0;
+    }
+    pthread_mutex_unlock(&out->common.lock);
+    return 0;
+}
+
+static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
+{
+    UNUSED(stream);
+    UNUSED(effect);
+
+    FNLOG();
+    return 0;
+}
+
+static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
+{
+    UNUSED(stream);
+    UNUSED(effect);
+
+    FNLOG();
+    return 0;
+}
+
+/*
+ * AUDIO INPUT STREAM
+ */
+
+static uint32_t in_get_sample_rate(const struct audio_stream *stream)
+{
+    struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
+
+    FNLOG();
+    return in->common.cfg.rate;
+}
+
+static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
+{
+    struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
+
+    FNLOG();
+
+    if (in->common.cfg.rate > 0 && in->common.cfg.rate == rate)
+        return 0;
+    else
+        return -1;
+}
+
+static size_t in_get_buffer_size(const struct audio_stream *stream)
+{
+    UNUSED(stream);
+
+    FNLOG();
+    return 320;
+}
+
+static uint32_t in_get_channels(const struct audio_stream *stream)
+{
+    struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
+
+    FNLOG();
+    return in->common.cfg.channel_flags;
+}
+
+static audio_format_t in_get_format(const struct audio_stream *stream)
+{
+    UNUSED(stream);
+
+    FNLOG();
+    return AUDIO_FORMAT_PCM_16_BIT;
+}
+
+static int in_set_format(struct audio_stream *stream, audio_format_t format)
+{
+    UNUSED(stream);
+    UNUSED(format);
+
+    FNLOG();
+    if (format == AUDIO_FORMAT_PCM_16_BIT)
+        return 0;
+    else
+        return -1;
+}
+
+static int in_standby(struct audio_stream *stream)
+{
+    UNUSED(stream);
+
+    FNLOG();
+    return 0;
+}
+
+static int in_dump(const struct audio_stream *stream, int fd)
+{
+    UNUSED(stream);
+    UNUSED(fd);
+
+    FNLOG();
+    return 0;
+}
+
+static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
+{
+    UNUSED(stream);
+    UNUSED(kvpairs);
+
+    FNLOG();
+    return 0;
+}
+
+static char * in_get_parameters(const struct audio_stream *stream,
+                                const char *keys)
+{
+    UNUSED(stream);
+    UNUSED(keys);
+
+    FNLOG();
+    return strdup("");
+}
+
+static int in_set_gain(struct audio_stream_in *stream, float gain)
+{
+    UNUSED(stream);
+    UNUSED(gain);
+
+    FNLOG();
+    return 0;
+}
+
+static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
+                       size_t bytes)
+{
+    struct a2dp_stream_in *in = (struct a2dp_stream_in *)stream;
+    int read;
+
+    DEBUG("read %zu bytes, state: %d", bytes, in->common.state);
+
+    if (in->common.state == AUDIO_A2DP_STATE_SUSPENDED)
+    {
+        DEBUG("stream suspended");
+        return -1;
+    }
+
+    /* only allow autostarting if we are in stopped or standby */
+    if ((in->common.state == AUDIO_A2DP_STATE_STOPPED) ||
+        (in->common.state == AUDIO_A2DP_STATE_STANDBY))
+    {
+        pthread_mutex_lock(&in->common.lock);
+
+        if (start_audio_datapath(&in->common) < 0)
+        {
+            /* emulate time this write represents to avoid very fast write
+               failures during transition periods or remote suspend */
+
+            int us_delay = calc_audiotime(in->common.cfg, bytes);
+
+            DEBUG("emulate a2dp read delay (%d us)", us_delay);
+
+            usleep(us_delay);
+            pthread_mutex_unlock(&in->common.lock);
+            return -1;
+        }
+
+        pthread_mutex_unlock(&in->common.lock);
+    }
+    else if (in->common.state != AUDIO_A2DP_STATE_STARTED)
+    {
+        ERROR("stream not in stopped or standby");
+        return -1;
+    }
+
+    read = skt_read(in->common.audio_fd, buffer, bytes);
+
+    if (read == -1)
+    {
+        skt_disconnect(in->common.audio_fd);
+        in->common.audio_fd = AUDIO_SKT_DISCONNECTED;
+        in->common.state = AUDIO_A2DP_STATE_STOPPED;
+    } else if (read == 0) {
+        DEBUG("read time out - return zeros");
+        memset(buffer, 0, bytes);
+        read = bytes;
+    }
+
+    DEBUG("read %d bytes out of %zu bytes", read, bytes);
+    return read;
+}
+
+static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
+{
+    UNUSED(stream);
+
+    FNLOG();
+    return 0;
+}
+
+static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
+{
+    UNUSED(stream);
+    UNUSED(effect);
+
+    FNLOG();
+    return 0;
+}
+
+static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
+{
+    UNUSED(stream);
+    UNUSED(effect);
+
+    FNLOG();
+
+    return 0;
+}
+
+static int adev_open_output_stream(struct audio_hw_device *dev,
+                                   audio_io_handle_t handle,
+                                   audio_devices_t devices,
+                                   audio_output_flags_t flags,
+                                   struct audio_config *config,
+                                   struct audio_stream_out **stream_out,
+                                   const char *address)
+
+{
+    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
+    struct a2dp_stream_out *out;
+    int ret = 0;
+    int i;
+    UNUSED(address);
+    UNUSED(handle);
+    UNUSED(devices);
+    UNUSED(flags);
+
+    INFO("opening output");
+
+    out = (struct a2dp_stream_out *)calloc(1, sizeof(struct a2dp_stream_out));
+
+    if (!out)
+        return -ENOMEM;
+
+    out->stream.common.get_sample_rate = out_get_sample_rate;
+    out->stream.common.set_sample_rate = out_set_sample_rate;
+    out->stream.common.get_buffer_size = out_get_buffer_size;
+    out->stream.common.get_channels = out_get_channels;
+    out->stream.common.get_format = out_get_format;
+    out->stream.common.set_format = out_set_format;
+    out->stream.common.standby = out_standby;
+    out->stream.common.dump = out_dump;
+    out->stream.common.set_parameters = out_set_parameters;
+    out->stream.common.get_parameters = out_get_parameters;
+    out->stream.common.add_audio_effect = out_add_audio_effect;
+    out->stream.common.remove_audio_effect = out_remove_audio_effect;
+    out->stream.get_latency = out_get_latency;
+    out->stream.set_volume = out_set_volume;
+    out->stream.write = out_write;
+    out->stream.get_render_position = out_get_render_position;
+    out->stream.get_presentation_position = out_get_presentation_position;
+
+
+    /* initialize a2dp specifics */
+    a2dp_stream_common_init(&out->common);
+
+    out->common.cfg.channel_flags = AUDIO_STREAM_DEFAULT_CHANNEL_FLAG;
+    out->common.cfg.format = AUDIO_STREAM_DEFAULT_FORMAT;
+    out->common.cfg.rate = AUDIO_STREAM_DEFAULT_RATE;
+
+   /* set output config values */
+   if (config)
+   {
+      config->format = out_get_format((const struct audio_stream *)&out->stream);
+      config->sample_rate = out_get_sample_rate((const struct audio_stream *)&out->stream);
+      config->channel_mask = out_get_channels((const struct audio_stream *)&out->stream);
+   }
+    *stream_out = &out->stream;
+    a2dp_dev->output = out;
+
+    a2dp_open_ctrl_path(&out->common);
+    if (out->common.ctrl_fd == AUDIO_SKT_DISCONNECTED)
+    {
+        ERROR("ctrl socket failed to connect (%s)", strerror(errno));
+        ret = -1;
+        goto err_open;
+    }
+
+    DEBUG("success");
+    /* Delay to ensure Headset is in proper state when START is initiated
+       from DUT immediately after the connection due to ongoing music playback. */
+    usleep(250000);
+    return 0;
+
+err_open:
+    free(out);
+    *stream_out = NULL;
+    a2dp_dev->output = NULL;
+    ERROR("failed");
+    return ret;
+}
+
+static void adev_close_output_stream(struct audio_hw_device *dev,
+                                     struct audio_stream_out *stream)
+{
+    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
+    struct a2dp_stream_out *out = (struct a2dp_stream_out *)stream;
+
+    INFO("closing output (state %d)", out->common.state);
+
+    pthread_mutex_lock(&out->common.lock);
+    if ((out->common.state == AUDIO_A2DP_STATE_STARTED) || (out->common.state == AUDIO_A2DP_STATE_STOPPING))
+        stop_audio_datapath(&out->common);
+
+    skt_disconnect(out->common.ctrl_fd);
+    free(stream);
+    a2dp_dev->output = NULL;
+    pthread_mutex_unlock(&out->common.lock);
+
+    DEBUG("done");
+}
+
+static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
+{
+    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
+    struct a2dp_stream_out *out = a2dp_dev->output;
+    int retval = 0;
+
+    if (out == NULL)
+        return retval;
+
+    INFO("state %d", out->common.state);
+
+    retval = out->stream.common.set_parameters((struct audio_stream *)out, kvpairs);
+
+    return retval;
+}
+
+static char * adev_get_parameters(const struct audio_hw_device *dev,
+                                  const char *keys)
+{
+    struct str_parms *parms;
+    UNUSED(dev);
+
+    FNLOG();
+
+    parms = str_parms_create_str(keys);
+
+    str_parms_dump(parms);
+
+    str_parms_destroy(parms);
+
+    return strdup("");
+}
+
+static int adev_init_check(const struct audio_hw_device *dev)
+{
+    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device*)dev;
+
+    FNLOG();
+
+    return 0;
+}
+
+static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
+{
+    UNUSED(dev);
+    UNUSED(volume);
+
+    FNLOG();
+
+    return -ENOSYS;
+}
+
+static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
+{
+    UNUSED(dev);
+    UNUSED(volume);
+
+    FNLOG();
+
+    return -ENOSYS;
+}
+
+static int adev_set_mode(struct audio_hw_device *dev, int mode)
+{
+    UNUSED(dev);
+    UNUSED(mode);
+
+    FNLOG();
+
+    return 0;
+}
+
+static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
+{
+    UNUSED(dev);
+    UNUSED(state);
+
+    FNLOG();
+
+    return -ENOSYS;
+}
+
+static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
+{
+    UNUSED(dev);
+    UNUSED(state);
+
+    FNLOG();
+
+    return -ENOSYS;
+}
+
+static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
+                                         const struct audio_config *config)
+{
+    UNUSED(dev);
+    UNUSED(config);
+
+    FNLOG();
+
+    return 320;
+}
+
+static int adev_open_input_stream(struct audio_hw_device *dev,
+                                  audio_io_handle_t handle,
+                                  audio_devices_t devices,
+                                  struct audio_config *config,
+                                  struct audio_stream_in **stream_in,
+                                  audio_input_flags_t flags,
+                                  const char *address,
+                                  audio_source_t source)
+{
+    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
+    struct a2dp_stream_in *in;
+    int ret;
+    UNUSED(address);
+    UNUSED(config);
+    UNUSED(devices);
+    UNUSED(flags);
+    UNUSED(handle);
+    UNUSED(source);
+
+    FNLOG();
+
+    in = (struct a2dp_stream_in *)calloc(1, sizeof(struct a2dp_stream_in));
+
+    if (!in)
+        return -ENOMEM;
+
+    in->stream.common.get_sample_rate = in_get_sample_rate;
+    in->stream.common.set_sample_rate = in_set_sample_rate;
+    in->stream.common.get_buffer_size = in_get_buffer_size;
+    in->stream.common.get_channels = in_get_channels;
+    in->stream.common.get_format = in_get_format;
+    in->stream.common.set_format = in_set_format;
+    in->stream.common.standby = in_standby;
+    in->stream.common.dump = in_dump;
+    in->stream.common.set_parameters = in_set_parameters;
+    in->stream.common.get_parameters = in_get_parameters;
+    in->stream.common.add_audio_effect = in_add_audio_effect;
+    in->stream.common.remove_audio_effect = in_remove_audio_effect;
+    in->stream.set_gain = in_set_gain;
+    in->stream.read = in_read;
+    in->stream.get_input_frames_lost = in_get_input_frames_lost;
+
+    /* initialize a2dp specifics */
+    a2dp_stream_common_init(&in->common);
+
+    *stream_in = &in->stream;
+    a2dp_dev->input = in;
+
+    a2dp_open_ctrl_path(&in->common);
+    if (in->common.ctrl_fd == AUDIO_SKT_DISCONNECTED)
+    {
+        ERROR("ctrl socket failed to connect (%s)", strerror(errno));
+        ret = -1;
+        goto err_open;
+    }
+
+    if (a2dp_read_audio_config(&in->common) < 0) {
+        ERROR("a2dp_read_audio_config failed (%s)", strerror(errno));
+        ret = -1;
+        goto err_open;
+    }
+
+    DEBUG("success");
+    return 0;
+
+err_open:
+    free(in);
+    *stream_in = NULL;
+    a2dp_dev->input = NULL;
+    ERROR("failed");
+    return ret;
+}
+
+static void adev_close_input_stream(struct audio_hw_device *dev,
+                                   struct audio_stream_in *stream)
+{
+    struct a2dp_audio_device *a2dp_dev = (struct a2dp_audio_device *)dev;
+    struct a2dp_stream_in* in = (struct a2dp_stream_in *)stream;
+    a2dp_state_t state = in->common.state;
+
+    INFO("closing input (state %d)", state);
+
+    if ((state == AUDIO_A2DP_STATE_STARTED) || (state == AUDIO_A2DP_STATE_STOPPING))
+        stop_audio_datapath(&in->common);
+
+    skt_disconnect(in->common.ctrl_fd);
+    free(stream);
+    a2dp_dev->input = NULL;
+
+    DEBUG("done");
+}
+
+static int adev_dump(const audio_hw_device_t *device, int fd)
+{
+    UNUSED(device);
+    UNUSED(fd);
+
+    FNLOG();
+
+    return 0;
+}
+
+static int adev_close(hw_device_t *device)
+{
+    FNLOG();
+
+    free(device);
+    return 0;
+}
+
+static int adev_open(const hw_module_t* module, const char* name,
+                     hw_device_t** device)
+{
+    struct a2dp_audio_device *adev;
+    int ret;
+
+    INFO(" adev_open in A2dp_hw module");
+    FNLOG();
+
+    if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
+    {
+        ERROR("interface %s not matching [%s]", name, AUDIO_HARDWARE_INTERFACE);
+        return -EINVAL;
+    }
+
+    adev = calloc(1, sizeof(struct a2dp_audio_device));
+
+    if (!adev)
+        return -ENOMEM;
+
+    adev->device.common.tag = HARDWARE_DEVICE_TAG;
+    adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
+    adev->device.common.module = (struct hw_module_t *) module;
+    adev->device.common.close = adev_close;
+
+    adev->device.init_check = adev_init_check;
+    adev->device.set_voice_volume = adev_set_voice_volume;
+    adev->device.set_master_volume = adev_set_master_volume;
+    adev->device.set_mode = adev_set_mode;
+    adev->device.set_mic_mute = adev_set_mic_mute;
+    adev->device.get_mic_mute = adev_get_mic_mute;
+    adev->device.set_parameters = adev_set_parameters;
+    adev->device.get_parameters = adev_get_parameters;
+    adev->device.get_input_buffer_size = adev_get_input_buffer_size;
+    adev->device.open_output_stream = adev_open_output_stream;
+    adev->device.close_output_stream = adev_close_output_stream;
+    adev->device.open_input_stream = adev_open_input_stream;
+    adev->device.close_input_stream = adev_close_input_stream;
+    adev->device.dump = adev_dump;
+
+    adev->output = NULL;
+
+
+    *device = &adev->device.common;
+
+    return 0;
+}
+
+static struct hw_module_methods_t hal_module_methods = {
+    .open = adev_open,
+};
+
+struct audio_module HAL_MODULE_INFO_SYM = {
+    .common = {
+        .tag = HARDWARE_MODULE_TAG,
+        .version_major = 1,
+        .version_minor = 0,
+        .id = AUDIO_HARDWARE_MODULE_ID,
+        .name = "A2DP Audio HW HAL",
+        .author = "The Android Open Source Project",
+        .methods = &hal_module_methods,
+    },
+};

+ 88 - 0
examples/09_a2dp/components/bluedroid_demos/audio_a2dp_hw/include/audio_a2dp_hw.h

@@ -0,0 +1,88 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/*****************************************************************************
+ *
+ *  Filename:      audio_a2dp_hw.h
+ *
+ *  Description:
+ *
+ *****************************************************************************/
+
+#ifndef AUDIO_A2DP_HW_H
+#define AUDIO_A2DP_HW_H
+
+/*****************************************************************************
+**  Constants & Macros
+******************************************************************************/
+
+#define A2DP_AUDIO_HARDWARE_INTERFACE "audio.a2dp"
+#define A2DP_CTRL_PATH "/data/misc/bluedroid/.a2dp_ctrl"
+#define A2DP_DATA_PATH "/data/misc/bluedroid/.a2dp_data"
+
+#define AUDIO_STREAM_DEFAULT_RATE          44100
+#define AUDIO_STREAM_DEFAULT_FORMAT        AUDIO_FORMAT_PCM_16_BIT
+#define AUDIO_STREAM_DEFAULT_CHANNEL_FLAG  AUDIO_CHANNEL_OUT_STEREO
+#define AUDIO_STREAM_OUTPUT_BUFFER_SZ      (20*512)
+#define AUDIO_SKT_DISCONNECTED             (-1)
+
+typedef enum {
+    A2DP_CTRL_CMD_NONE,
+    A2DP_CTRL_CMD_CHECK_READY,
+    A2DP_CTRL_CMD_START,
+    A2DP_CTRL_CMD_STOP,
+    A2DP_CTRL_CMD_SUSPEND,
+    A2DP_CTRL_GET_AUDIO_CONFIG,
+} tA2DP_CTRL_CMD;
+
+typedef enum {
+    A2DP_CTRL_ACK_SUCCESS,
+    A2DP_CTRL_ACK_FAILURE,
+    A2DP_CTRL_ACK_INCALL_FAILURE /* Failure when in Call*/
+} tA2DP_CTRL_ACK;
+
+
+/*****************************************************************************
+**  Type definitions for callback functions
+******************************************************************************/
+
+/*****************************************************************************
+**  Type definitions and return values
+******************************************************************************/
+
+/*****************************************************************************
+**  Extern variables and functions
+******************************************************************************/
+
+/*****************************************************************************
+**  Functions
+******************************************************************************/
+
+
+/*****************************************************************************
+**
+** Function
+**
+** Description
+**
+** Returns
+**
+******************************************************************************/
+
+#endif /* A2DP_AUDIO_HW_H */
+

+ 1435 - 0
examples/09_a2dp/components/bluedroid_demos/btif/btif_av.c

@@ -0,0 +1,1435 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/*****************************************************************************
+ *
+ *  Filename:      btif_av.c
+ *
+ *  Description:   Bluedroid AV implementation
+ *
+ *****************************************************************************/
+
+// #include <assert.h>
+#include "bt_trace.h"
+#include <string.h>
+
+// #include <hardware/bluetooth.h>
+#include "bt_defs.h"
+// #include <system/audio.h>
+#include "bt_av.h"
+#include "allocator.h"
+
+#define LOG_TAG "bt_btif_av"
+
+#include "btif_av.h"
+#include "btif_util.h"
+#include "btif_profile_queue.h"
+#include "bta_api.h"
+#include "btif_media.h"
+#include "bta_av_api.h"
+#include "gki.h"
+#include "btu.h"
+#include "bt_utils.h"
+
+/*****************************************************************************
+**  Constants & Macros
+******************************************************************************/
+#define BTIF_AV_SERVICE_NAME "Advanced Audio"
+
+#define BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS  2
+
+typedef enum {
+    BTIF_AV_STATE_IDLE = 0x0,
+    BTIF_AV_STATE_OPENING,
+    BTIF_AV_STATE_OPENED,
+    BTIF_AV_STATE_STARTED,
+    BTIF_AV_STATE_CLOSING
+} btif_av_state_t;
+
+/* Should not need dedicated suspend state as actual actions are no
+   different than open state. Suspend flags are needed however to prevent
+   media task from trying to restart stream during remote suspend or while
+   we are in the process of a local suspend */
+
+#define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
+#define BTIF_AV_FLAG_REMOTE_SUSPEND        0x2
+#define BTIF_AV_FLAG_PENDING_START         0x4
+#define BTIF_AV_FLAG_PENDING_STOP          0x8
+
+/*****************************************************************************
+**  Local type definitions
+******************************************************************************/
+
+typedef struct
+{
+    tBTA_AV_HNDL bta_handle;
+    bt_bdaddr_t peer_bda;
+    btif_sm_handle_t sm_handle;
+    UINT8 flags;
+    tBTA_AV_EDR edr;
+    UINT8   peer_sep;  /* sep type of peer device */
+} btif_av_cb_t;
+
+typedef struct
+{
+    bt_bdaddr_t *target_bda;
+    uint16_t uuid;
+} btif_av_connect_req_t;
+
+typedef struct
+{
+    int sample_rate;
+    int channel_count;
+} btif_av_sink_config_req_t;
+
+/*****************************************************************************
+**  Static variables
+******************************************************************************/
+static btav_callbacks_t *bt_av_src_callbacks = NULL;
+static btav_callbacks_t *bt_av_sink_callbacks = NULL;
+static btif_av_cb_t btif_av_cb = {0};
+static TIMER_LIST_ENT tle_av_open_on_rc;
+
+/* both interface and media task needs to be ready to alloc incoming request */
+#define CHECK_BTAV_INIT() if (((bt_av_src_callbacks == NULL) &&(bt_av_sink_callbacks == NULL)) \
+        || (btif_av_cb.sm_handle == NULL))\
+{\
+     BTIF_TRACE_WARNING("%s: BTAV not initialized", __FUNCTION__);\
+     return BT_STATUS_NOT_READY;\
+}\
+else\
+{\
+     BTIF_TRACE_EVENT("%s", __FUNCTION__);\
+}
+
+/* Helper macro to avoid code duplication in the state machine handlers */
+#define CHECK_RC_EVENT(e, d) \
+    case BTA_AV_RC_OPEN_EVT: \
+    case BTA_AV_RC_CLOSE_EVT: \
+    case BTA_AV_REMOTE_CMD_EVT: \
+    case BTA_AV_VENDOR_CMD_EVT: \
+    case BTA_AV_META_MSG_EVT: \
+    case BTA_AV_RC_FEAT_EVT: \
+    case BTA_AV_REMOTE_RSP_EVT: \
+    { \
+         btif_rc_handler(e, d);\
+    }break; \
+
+static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *data);
+static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *data);
+static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *data);
+static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *data);
+static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *data);
+
+static const btif_sm_handler_t btif_av_state_handlers[] =
+{
+    btif_av_state_idle_handler,
+    btif_av_state_opening_handler,
+    btif_av_state_opened_handler,
+    btif_av_state_started_handler,
+    btif_av_state_closing_handler
+};
+
+static void btif_av_event_free_data(btif_sm_event_t event, void *p_data);
+
+/*************************************************************************
+** Extern functions
+*************************************************************************/
+extern void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data);
+extern BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr);
+extern void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp);
+
+/*****************************************************************************
+** Local helper functions
+******************************************************************************/
+
+const char *dump_av_sm_state_name(btif_av_state_t state)
+{
+    switch (state)
+    {
+        CASE_RETURN_STR(BTIF_AV_STATE_IDLE)
+        CASE_RETURN_STR(BTIF_AV_STATE_OPENING)
+        CASE_RETURN_STR(BTIF_AV_STATE_OPENED)
+        CASE_RETURN_STR(BTIF_AV_STATE_STARTED)
+        CASE_RETURN_STR(BTIF_AV_STATE_CLOSING)
+        default: return "UNKNOWN_STATE";
+    }
+}
+
+const char *dump_av_sm_event_name(btif_av_sm_event_t event)
+{
+    switch((int)event)
+    {
+        CASE_RETURN_STR(BTA_AV_ENABLE_EVT)
+        CASE_RETURN_STR(BTA_AV_REGISTER_EVT)
+        CASE_RETURN_STR(BTA_AV_OPEN_EVT)
+        CASE_RETURN_STR(BTA_AV_CLOSE_EVT)
+        CASE_RETURN_STR(BTA_AV_START_EVT)
+        CASE_RETURN_STR(BTA_AV_STOP_EVT)
+        CASE_RETURN_STR(BTA_AV_PROTECT_REQ_EVT)
+        CASE_RETURN_STR(BTA_AV_PROTECT_RSP_EVT)
+        CASE_RETURN_STR(BTA_AV_RC_OPEN_EVT)
+        CASE_RETURN_STR(BTA_AV_RC_CLOSE_EVT)
+        CASE_RETURN_STR(BTA_AV_REMOTE_CMD_EVT)
+        CASE_RETURN_STR(BTA_AV_REMOTE_RSP_EVT)
+        CASE_RETURN_STR(BTA_AV_VENDOR_CMD_EVT)
+        CASE_RETURN_STR(BTA_AV_VENDOR_RSP_EVT)
+        CASE_RETURN_STR(BTA_AV_RECONFIG_EVT)
+        CASE_RETURN_STR(BTA_AV_SUSPEND_EVT)
+        CASE_RETURN_STR(BTA_AV_PENDING_EVT)
+        CASE_RETURN_STR(BTA_AV_META_MSG_EVT)
+        CASE_RETURN_STR(BTA_AV_REJECT_EVT)
+        CASE_RETURN_STR(BTA_AV_RC_FEAT_EVT)
+        CASE_RETURN_STR(BTIF_SM_ENTER_EVT)
+        CASE_RETURN_STR(BTIF_SM_EXIT_EVT)
+        CASE_RETURN_STR(BTIF_AV_CONNECT_REQ_EVT)
+        CASE_RETURN_STR(BTIF_AV_DISCONNECT_REQ_EVT)
+        CASE_RETURN_STR(BTIF_AV_START_STREAM_REQ_EVT)
+        CASE_RETURN_STR(BTIF_AV_STOP_STREAM_REQ_EVT)
+        CASE_RETURN_STR(BTIF_AV_SUSPEND_STREAM_REQ_EVT)
+        CASE_RETURN_STR(BTIF_AV_SINK_CONFIG_REQ_EVT)
+        default: return "UNKNOWN_EVENT";
+   }
+}
+
+/****************************************************************************
+**  Local helper functions
+*****************************************************************************/
+/*******************************************************************************
+**
+** Function         btif_initiate_av_open_tmr_hdlr
+**
+** Description      Timer to trigger AV open if the remote headset establishes
+**                  RC connection w/o AV connection. The timer is needed to IOP
+**                  with headsets that do establish AV after RC connection.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void btif_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
+{
+    BD_ADDR peer_addr;
+    UNUSED(tle);
+    btif_av_connect_req_t connect_req;
+    UNUSED(tle);
+    /* is there at least one RC connection - There should be */
+    if (btif_rc_get_connected_peer(peer_addr)) {
+       BTIF_TRACE_DEBUG("%s Issuing connect to the remote RC peer", __FUNCTION__);
+       /* In case of AVRCP connection request, we will initiate SRC connection */
+       connect_req.target_bda = (bt_bdaddr_t*)&peer_addr;
+       connect_req.uuid = UUID_SERVCLASS_AUDIO_SOURCE;
+       btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
+    }
+    else
+    {
+        BTIF_TRACE_ERROR("%s No connected RC peers", __FUNCTION__);
+    }
+}
+
+/*****************************************************************************
+**  Static functions
+******************************************************************************/
+
+static void btif_report_connection_state(btav_connection_state_t state, bt_bdaddr_t *bd_addr)
+{
+    if (bt_av_sink_callbacks != NULL) {
+        HAL_CBACK(bt_av_sink_callbacks, connection_state_cb, state, bd_addr);
+    } else if (bt_av_src_callbacks != NULL) {
+        HAL_CBACK(bt_av_src_callbacks, connection_state_cb, state, bd_addr);
+    }
+}
+
+static void btif_report_audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr)
+{
+    if (bt_av_sink_callbacks != NULL) {
+        HAL_CBACK(bt_av_sink_callbacks, audio_state_cb, state, bd_addr);
+    } else if (bt_av_src_callbacks != NULL) {
+        HAL_CBACK(bt_av_src_callbacks, audio_state_cb, state, bd_addr);
+    }
+}
+
+/*****************************************************************************
+**
+** Function     btif_av_state_idle_handler
+**
+** Description  State managing disconnected AV link
+**
+** Returns      TRUE if event was processed, FALSE otherwise
+**
+*******************************************************************************/
+
+static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data)
+{
+    BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
+                     dump_av_sm_event_name(event), btif_av_cb.flags);
+
+    switch (event)
+    {
+        case BTIF_SM_ENTER_EVT:
+            /* clear the peer_bda */
+            memset(&btif_av_cb.peer_bda, 0, sizeof(bt_bdaddr_t));
+            btif_av_cb.flags = 0;
+            btif_av_cb.edr = 0;
+            btif_a2dp_on_idle();
+            break;
+
+        case BTIF_SM_EXIT_EVT:
+            break;
+
+        case BTA_AV_ENABLE_EVT:
+            break;
+
+        case BTA_AV_REGISTER_EVT:
+            btif_av_cb.bta_handle = ((tBTA_AV*)p_data)->registr.hndl;
+            break;
+
+        case BTA_AV_PENDING_EVT:
+        case BTIF_AV_CONNECT_REQ_EVT:
+        {
+             if (event == BTIF_AV_CONNECT_REQ_EVT)
+             {
+                 memcpy(&btif_av_cb.peer_bda, ((btif_av_connect_req_t*)p_data)->target_bda,
+                                                                   sizeof(bt_bdaddr_t));
+                 BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
+                    TRUE, BTA_SEC_AUTHENTICATE, ((btif_av_connect_req_t*)p_data)->uuid);
+             }
+             else if (event == BTA_AV_PENDING_EVT)
+             {
+                  bdcpy(btif_av_cb.peer_bda.address, ((tBTA_AV*)p_data)->pend.bd_addr);
+                  BTA_AvOpen(btif_av_cb.peer_bda.address, btif_av_cb.bta_handle,
+                    TRUE, BTA_SEC_AUTHENTICATE, UUID_SERVCLASS_AUDIO_SOURCE);
+             }
+             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENING);
+        } break;
+
+        case BTA_AV_RC_OPEN_EVT:
+            /* IOP_FIX: Jabra 620 only does RC open without AV open whenever it connects. So
+             * as per the AV WP, an AVRC connection cannot exist without an AV connection. Therefore,
+             * we initiate an AV connection if an RC_OPEN_EVT is received when we are in AV_CLOSED state.
+             * We initiate the AV connection after a small 3s timeout to avoid any collisions from the
+             * headsets, as some headsets initiate the AVRC connection first and then
+             * immediately initiate the AV connection
+             *
+             * TODO: We may need to do this only on an AVRCP Play. FixMe
+             */
+
+            BTIF_TRACE_DEBUG("BTA_AV_RC_OPEN_EVT received w/o AV");
+            memset(&tle_av_open_on_rc, 0, sizeof(tle_av_open_on_rc));
+            tle_av_open_on_rc.param = (UINT32)btif_initiate_av_open_tmr_hdlr;
+            btu_start_timer(&tle_av_open_on_rc, BTU_TTYPE_USER_FUNC,
+                            BTIF_TIMEOUT_AV_OPEN_ON_RC_SECS);
+            btif_rc_handler(event, p_data);
+            break;
+
+        case BTA_AV_REMOTE_CMD_EVT:
+        case BTA_AV_VENDOR_CMD_EVT:
+        case BTA_AV_META_MSG_EVT:
+        case BTA_AV_RC_FEAT_EVT:
+        case BTA_AV_REMOTE_RSP_EVT:
+            btif_rc_handler(event, (tBTA_AV*)p_data);
+            break;
+
+        case BTA_AV_RC_CLOSE_EVT:
+            if (tle_av_open_on_rc.in_use) {
+                BTIF_TRACE_DEBUG("BTA_AV_RC_CLOSE_EVT: Stopping AV timer.");
+                btu_stop_timer(&tle_av_open_on_rc);
+            }
+            btif_rc_handler(event, p_data);
+            break;
+
+        default:
+            BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
+                                dump_av_sm_event_name(event));
+            return FALSE;
+
+    }
+
+    return TRUE;
+}
+/*****************************************************************************
+**
+** Function        btif_av_state_opening_handler
+**
+** Description     Intermediate state managing events during establishment
+**                 of avdtp channel
+**
+** Returns         TRUE if event was processed, FALSE otherwise
+**
+*******************************************************************************/
+
+static BOOLEAN btif_av_state_opening_handler(btif_sm_event_t event, void *p_data)
+{
+    BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
+                     dump_av_sm_event_name(event), btif_av_cb.flags);
+
+    switch (event)
+    {
+        case BTIF_SM_ENTER_EVT:
+            /* inform the application that we are entering connecting state */
+            btif_report_connection_state(BTAV_CONNECTION_STATE_CONNECTING, &(btif_av_cb.peer_bda));
+            break;
+
+        case BTIF_SM_EXIT_EVT:
+            break;
+
+        case BTA_AV_REJECT_EVT:
+            BTIF_TRACE_DEBUG(" Received  BTA_AV_REJECT_EVT ");
+            btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
+            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
+            break;
+
+        case BTA_AV_OPEN_EVT:
+        {
+            tBTA_AV *p_bta_data = (tBTA_AV*)p_data;
+            btav_connection_state_t state;
+            btif_sm_state_t av_state;
+            BTIF_TRACE_DEBUG("status:%d, edr 0x%x",p_bta_data->open.status,
+                               p_bta_data->open.edr);
+
+            if (p_bta_data->open.status == BTA_AV_SUCCESS)
+            {
+                 state = BTAV_CONNECTION_STATE_CONNECTED;
+                 av_state = BTIF_AV_STATE_OPENED;
+                 btif_av_cb.edr = p_bta_data->open.edr;
+
+                 btif_av_cb.peer_sep = p_bta_data->open.sep;
+                 btif_a2dp_set_peer_sep(p_bta_data->open.sep);
+            }
+            else
+            {
+                BTIF_TRACE_WARNING("BTA_AV_OPEN_EVT::FAILED status: %d",
+                                     p_bta_data->open.status );
+                state = BTAV_CONNECTION_STATE_DISCONNECTED;
+                av_state  = BTIF_AV_STATE_IDLE;
+            }
+
+            /* inform the application of the event */
+            btif_report_connection_state(state, &(btif_av_cb.peer_bda));
+            /* change state to open/idle based on the status */
+            btif_sm_change_state(btif_av_cb.sm_handle, av_state);
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+            {
+                /* if queued PLAY command,  send it now */
+                btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
+                                             (p_bta_data->open.status == BTA_AV_SUCCESS));
+            }
+            else if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
+            {
+                /* if queued PLAY command,  send it now */
+                btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
+                /* Bring up AVRCP connection too */
+                BTA_AvOpenRc(btif_av_cb.bta_handle);
+            }
+            btif_queue_advance();
+        } break;
+
+        case BTIF_AV_SINK_CONFIG_REQ_EVT:
+        {
+            btif_av_sink_config_req_t req;
+            // copy to avoid alignment problems
+            memcpy(&req, p_data, sizeof(req));
+
+            BTIF_TRACE_WARNING("BTIF_AV_SINK_CONFIG_REQ_EVT %d %d", req.sample_rate,
+                    req.channel_count);
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC && bt_av_sink_callbacks != NULL) {
+                HAL_CBACK(bt_av_sink_callbacks, audio_config_cb, &(btif_av_cb.peer_bda),
+                        req.sample_rate, req.channel_count);
+            }
+        } break;
+
+        case BTIF_AV_CONNECT_REQ_EVT:
+            // Check for device, if same device which moved to opening then ignore callback
+            if (memcmp ((bt_bdaddr_t*)p_data, &(btif_av_cb.peer_bda),
+                sizeof(btif_av_cb.peer_bda)) == 0)
+            {
+                BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Connect Req", __func__);
+                btif_queue_advance();
+                break;
+            }
+            else
+            {
+                BTIF_TRACE_DEBUG("%s: Moved from idle by Incoming Connection request", __func__);
+                btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, (bt_bdaddr_t*)p_data);
+                btif_queue_advance();
+                break;
+            }
+
+        case BTA_AV_PENDING_EVT:
+            // Check for device, if same device which moved to opening then ignore callback
+            if (memcmp (((tBTA_AV*)p_data)->pend.bd_addr, &(btif_av_cb.peer_bda),
+                sizeof(btif_av_cb.peer_bda)) == 0)
+            {
+                BTIF_TRACE_DEBUG("%s: Same device moved to Opening state,ignore Pending Req", __func__);
+                break;
+            }
+            else
+            {
+                BTIF_TRACE_DEBUG("%s: Moved from idle by outgoing Connection request", __func__);
+                BTA_AvDisconnect(((tBTA_AV*)p_data)->pend.bd_addr);
+                break;
+            }
+
+        CHECK_RC_EVENT(event, p_data);
+
+        default:
+            BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
+                                dump_av_sm_event_name(event));
+            return FALSE;
+
+   }
+   return TRUE;
+}
+
+
+/*****************************************************************************
+**
+** Function        btif_av_state_closing_handler
+**
+** Description     Intermediate state managing events during closing
+**                 of avdtp channel
+**
+** Returns         TRUE if event was processed, FALSE otherwise
+**
+*******************************************************************************/
+
+static BOOLEAN btif_av_state_closing_handler(btif_sm_event_t event, void *p_data)
+{
+    BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
+                     dump_av_sm_event_name(event), btif_av_cb.flags);
+
+    switch (event)
+    {
+        case BTIF_SM_ENTER_EVT:
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+            {
+                /* immediately stop transmission of frames */
+                btif_a2dp_set_tx_flush(TRUE);
+                /* wait for audioflinger to stop a2dp */
+            }
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
+            {
+                btif_a2dp_set_rx_flush(TRUE);
+            }
+            break;
+
+        case BTA_AV_STOP_EVT:
+        case BTIF_AV_STOP_STREAM_REQ_EVT:
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+            {
+              /* immediately flush any pending tx frames while suspend is pending */
+              btif_a2dp_set_tx_flush(TRUE);
+            }
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
+            {
+                btif_a2dp_set_rx_flush(TRUE);
+            }
+
+            btif_a2dp_on_stopped(NULL);
+            break;
+
+        case BTIF_SM_EXIT_EVT:
+            break;
+
+        case BTA_AV_CLOSE_EVT:
+
+            /* inform the application that we are disconnecting */
+            btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
+
+            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
+            break;
+
+        /* Handle the RC_CLOSE event for the cleanup */
+        case BTA_AV_RC_CLOSE_EVT:
+            btif_rc_handler(event, (tBTA_AV*)p_data);
+            break;
+
+        default:
+            BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
+                                dump_av_sm_event_name(event));
+            return FALSE;
+   }
+   return TRUE;
+}
+
+
+/*****************************************************************************
+**
+** Function     btif_av_state_opened_handler
+**
+** Description  Handles AV events while AVDTP is in OPEN state
+**
+** Returns      TRUE if event was processed, FALSE otherwise
+**
+*******************************************************************************/
+
+static BOOLEAN btif_av_state_opened_handler(btif_sm_event_t event, void *p_data)
+{
+    tBTA_AV *p_av = (tBTA_AV*)p_data;
+
+    BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
+                     dump_av_sm_event_name(event), btif_av_cb.flags);
+
+    if ( (event == BTA_AV_REMOTE_CMD_EVT) && (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND) &&
+         (p_av->remote_cmd.rc_id == BTA_AV_RC_PLAY) )
+    {
+        BTIF_TRACE_EVENT("%s: Resetting remote suspend flag on RC PLAY", __FUNCTION__);
+        btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
+    }
+
+    switch (event)
+    {
+        case BTIF_SM_ENTER_EVT:
+            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
+            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
+            break;
+
+        case BTIF_SM_EXIT_EVT:
+            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
+            break;
+
+        case BTIF_AV_START_STREAM_REQ_EVT:
+            if (btif_av_cb.peer_sep != AVDT_TSEP_SRC)
+                btif_a2dp_setup_codec();
+            BTA_AvStart();
+            btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
+            break;
+
+        case BTA_AV_START_EVT:
+        {
+            BTIF_TRACE_EVENT("BTA_AV_START_EVT status %d, suspending %d, init %d",
+                p_av->start.status, p_av->start.suspending, p_av->start.initiator);
+
+            if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
+                return TRUE;
+
+            /* if remote tries to start a2dp when DUT is a2dp source
+             * then suspend. In case a2dp is sink and call is active
+             * then disconnect the AVDTP channel
+             */
+            if (!(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START))
+            {
+                if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+                {
+                    BTIF_TRACE_EVENT("%s: trigger suspend as remote initiated!!", __FUNCTION__);
+                    btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
+                }
+            }
+
+            /*  In case peer is A2DP SRC we do not want to ack commands on UIPC*/
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+            {
+                if (btif_a2dp_on_started(&p_av->start,
+                    ((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) != 0)))
+                {
+                    /* only clear pending flag after acknowledgement */
+                    btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
+                }
+            }
+
+            /* remain in open state if status failed */
+            if (p_av->start.status != BTA_AV_SUCCESS)
+                return FALSE;
+
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC)
+            {
+                btif_a2dp_set_rx_flush(FALSE); /*  remove flush state, ready for streaming*/
+            }
+
+            /* change state to started, send acknowledgement if start is pending */
+            if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
+                if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+                    btif_a2dp_on_started(NULL, TRUE);
+                /* pending start flag will be cleared when exit current state */
+            }
+            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_STARTED);
+
+        } break;
+
+        case BTIF_AV_DISCONNECT_REQ_EVT:
+            BTA_AvClose(btif_av_cb.bta_handle);
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
+                BTA_AvCloseRc(btif_av_cb.bta_handle);
+            }
+
+            /* inform the application that we are disconnecting */
+            btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
+            break;
+
+        case BTA_AV_CLOSE_EVT:
+             /* avdtp link is closed */
+            btif_a2dp_on_stopped(NULL);
+
+            /* inform the application that we are disconnected */
+            btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
+
+            /* change state to idle, send acknowledgement if start is pending */
+            if (btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) {
+                btif_a2dp_ack_fail();
+                /* pending start flag will be cleared when exit current state */
+            }
+            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
+            break;
+
+        case BTA_AV_RECONFIG_EVT:
+            if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
+                (p_av->reconfig.status == BTA_AV_SUCCESS))
+            {
+               APPL_TRACE_WARNING("reconfig done BTA_AVstart()");
+               BTA_AvStart();
+            }
+            else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
+            {
+               btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
+               btif_a2dp_ack_fail();
+            }
+            break;
+
+        case BTIF_AV_CONNECT_REQ_EVT:
+            if (memcmp ((bt_bdaddr_t*)p_data, &(btif_av_cb.peer_bda),
+                sizeof(btif_av_cb.peer_bda)) == 0)
+            {
+                BTIF_TRACE_DEBUG("%s: Ignore BTIF_AV_CONNECT_REQ_EVT for same device", __func__);
+            }
+            else
+            {
+                BTIF_TRACE_DEBUG("%s: Moved to opened by Other Incoming Conn req", __func__);
+                btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED,
+                        (bt_bdaddr_t*)p_data);
+            }
+            btif_queue_advance();
+            break;
+
+        CHECK_RC_EVENT(event, p_data);
+
+        default:
+            BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
+                               dump_av_sm_event_name(event));
+            return FALSE;
+
+    }
+    return TRUE;
+}
+
+/*****************************************************************************
+**
+** Function     btif_av_state_started_handler
+**
+** Description  Handles AV events while A2DP stream is started
+**
+** Returns      TRUE if event was processed, FALSE otherwise
+**
+*******************************************************************************/
+
+static BOOLEAN btif_av_state_started_handler(btif_sm_event_t event, void *p_data)
+{
+    tBTA_AV *p_av = (tBTA_AV*)p_data;
+
+    BTIF_TRACE_DEBUG("%s event:%s flags %x", __FUNCTION__,
+                     dump_av_sm_event_name(event), btif_av_cb.flags);
+
+    switch (event)
+    {
+        case BTIF_SM_ENTER_EVT:
+
+            /* we are again in started state, clear any remote suspend flags */
+            btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
+
+            btif_report_audio_state(BTAV_AUDIO_STATE_STARTED, &(btif_av_cb.peer_bda));
+
+            /* increase the a2dp consumer task priority temporarily when start
+            ** audio playing, to avoid overflow the audio packet queue. */
+            adjust_priority_a2dp(TRUE);
+
+            break;
+
+        case BTIF_SM_EXIT_EVT:
+            /* restore the a2dp consumer task priority when stop audio playing. */
+            adjust_priority_a2dp(FALSE);
+
+            break;
+
+        case BTIF_AV_START_STREAM_REQ_EVT:
+            /* we were remotely started, just ack back the local request */
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+                btif_a2dp_on_started(NULL, TRUE);
+            break;
+
+        /* fixme -- use suspend = true always to work around issue with BTA AV */
+        case BTIF_AV_STOP_STREAM_REQ_EVT:
+        case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
+
+            /* set pending flag to ensure btif task is not trying to restart
+               stream while suspend is in progress */
+            btif_av_cb.flags |= BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
+
+            /* if we were remotely suspended but suspend locally, local suspend
+               always overrides */
+            btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
+
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+            {
+            /* immediately stop transmission of frames while suspend is pending */
+                btif_a2dp_set_tx_flush(TRUE);
+            }
+
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
+                btif_a2dp_set_rx_flush(TRUE);
+                btif_a2dp_on_stopped(NULL);
+            }
+
+            BTA_AvStop(TRUE);
+            break;
+
+        case BTIF_AV_DISCONNECT_REQ_EVT:
+
+            /* request avdtp to close */
+            BTA_AvClose(btif_av_cb.bta_handle);
+            if (btif_av_cb.peer_sep == AVDT_TSEP_SRC) {
+                BTA_AvCloseRc(btif_av_cb.bta_handle);
+            }
+
+            /* inform the application that we are disconnecting */
+            btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTING, &(btif_av_cb.peer_bda));
+
+            /* wait in closing state until fully closed */
+            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_CLOSING);
+            break;
+
+        case BTA_AV_SUSPEND_EVT:
+
+            BTIF_TRACE_EVENT("BTA_AV_SUSPEND_EVT status %d, init %d",
+                 p_av->suspend.status, p_av->suspend.initiator);
+
+            /* a2dp suspended, stop media task until resumed */
+            btif_a2dp_on_suspended(&p_av->suspend);
+
+            /* if not successful, remain in current state */
+            if (p_av->suspend.status != BTA_AV_SUCCESS)
+            {
+                btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
+
+               if (btif_av_cb.peer_sep == AVDT_TSEP_SNK)
+               {
+                /* suspend failed, reset back tx flush state */
+                    btif_a2dp_set_tx_flush(FALSE);
+               }
+                return FALSE;
+            }
+
+            if (p_av->suspend.initiator != TRUE)
+            {
+                /* remote suspend, notify HAL and await audioflinger to
+                   suspend/stop stream */
+
+                /* set remote suspend flag to block media task from restarting
+                   stream only if we did not already initiate a local suspend */
+                if ((btif_av_cb.flags & BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING) == 0)
+                    btif_av_cb.flags |= BTIF_AV_FLAG_REMOTE_SUSPEND;
+
+                btif_report_audio_state(BTAV_AUDIO_STATE_REMOTE_SUSPEND, &(btif_av_cb.peer_bda));
+            }
+            else
+            {
+                btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
+            }
+
+            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
+
+            /* suspend completed and state changed, clear pending status */
+            btif_av_cb.flags &= ~BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING;
+            break;
+
+        case BTA_AV_STOP_EVT:
+
+            btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
+            btif_a2dp_on_stopped(&p_av->suspend);
+
+            btif_report_audio_state(BTAV_AUDIO_STATE_STOPPED, &(btif_av_cb.peer_bda));
+
+            /* if stop was successful, change state to open */
+            if (p_av->suspend.status == BTA_AV_SUCCESS)
+                btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_OPENED);
+
+            break;
+
+        case BTA_AV_CLOSE_EVT:
+
+             btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
+
+            /* avdtp link is closed */
+            btif_a2dp_on_stopped(NULL);
+
+            /* inform the application that we are disconnected */
+            btif_report_connection_state(BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
+
+            btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
+            break;
+
+        CHECK_RC_EVENT(event, p_data);
+
+        default:
+            BTIF_TRACE_WARNING("%s : unhandled event:%s", __FUNCTION__,
+                                 dump_av_sm_event_name(event));
+            return FALSE;
+
+    }
+    return TRUE;
+}
+
+/*****************************************************************************
+**  Local event handlers
+******************************************************************************/
+
+static void btif_av_handle_event(UINT16 event, char* p_param)
+{
+    btif_sm_dispatch(btif_av_cb.sm_handle, event, (void*)p_param);
+    btif_av_event_free_data(event, p_param);
+}
+
+void btif_av_event_deep_copy(UINT16 event, char *p_dest, char *p_src)
+{
+    tBTA_AV *av_src = (tBTA_AV *)p_src;
+    tBTA_AV *av_dest = (tBTA_AV *)p_dest;
+
+    // First copy the structure
+    memcpy(p_dest, p_src, sizeof(tBTA_AV));
+
+    switch (event)
+    {
+        case BTA_AV_META_MSG_EVT:
+            if (av_src->meta_msg.p_data && av_src->meta_msg.len)
+            {
+                av_dest->meta_msg.p_data = osi_calloc(av_src->meta_msg.len);
+                assert(av_dest->meta_msg.p_data);
+                memcpy(av_dest->meta_msg.p_data, av_src->meta_msg.p_data, av_src->meta_msg.len);
+            }
+
+            if (av_src->meta_msg.p_msg)
+            {
+                av_dest->meta_msg.p_msg = osi_calloc(sizeof(tAVRC_MSG));
+                assert(av_dest->meta_msg.p_msg);
+                memcpy(av_dest->meta_msg.p_msg, av_src->meta_msg.p_msg, sizeof(tAVRC_MSG));
+
+                if (av_src->meta_msg.p_msg->vendor.p_vendor_data &&
+                    av_src->meta_msg.p_msg->vendor.vendor_len)
+                {
+                    av_dest->meta_msg.p_msg->vendor.p_vendor_data = osi_calloc(
+                        av_src->meta_msg.p_msg->vendor.vendor_len);
+                    assert(av_dest->meta_msg.p_msg->vendor.p_vendor_data);
+                    memcpy(av_dest->meta_msg.p_msg->vendor.p_vendor_data,
+                        av_src->meta_msg.p_msg->vendor.p_vendor_data,
+                        av_src->meta_msg.p_msg->vendor.vendor_len);
+                }
+            }
+            break;
+
+        default:
+            break;
+    }
+}
+
+static void btif_av_event_free_data(btif_sm_event_t event, void *p_data)
+{
+    switch (event)
+    {
+        case BTA_AV_META_MSG_EVT:
+            {
+                tBTA_AV *av = (tBTA_AV*)p_data;
+                if (av->meta_msg.p_data)
+                    osi_free(av->meta_msg.p_data);
+
+                if (av->meta_msg.p_msg)
+                {
+                    if (av->meta_msg.p_msg->vendor.p_vendor_data)
+                        osi_free(av->meta_msg.p_msg->vendor.p_vendor_data);
+                    osi_free(av->meta_msg.p_msg);
+                }
+            }
+            break;
+
+        default:
+            break;
+    }
+}
+
+static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
+{
+    btif_transfer_context(btif_av_handle_event, event,
+                          (char*)p_data, sizeof(tBTA_AV), btif_av_event_deep_copy);
+}
+
+static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
+{
+    btif_sm_state_t state;
+    UINT8 que_len;
+    tA2D_STATUS a2d_status;
+    tA2D_SBC_CIE sbc_cie;
+    btif_av_sink_config_req_t config_req;
+
+    if (event == BTA_AV_MEDIA_DATA_EVT)/* Switch to BTIF_MEDIA context */
+    {
+        state= btif_sm_get_state(btif_av_cb.sm_handle);
+        if ( (state == BTIF_AV_STATE_STARTED) || /* send SBC packets only in Started State */
+             (state == BTIF_AV_STATE_OPENED) )
+        {
+            que_len = btif_media_sink_enque_buf((BT_HDR *)p_data);
+            BTIF_TRACE_DEBUG(" Packets in Que %d",que_len);
+        }
+        else
+            return;
+    }
+
+    if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
+        /* send a command to BT Media Task */
+        btif_reset_decoder((UINT8*)p_data);
+
+        a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
+        if (a2d_status == A2D_SUCCESS) {
+            /* Switch to BTIF context */
+            config_req.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
+            config_req.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
+            btif_transfer_context(btif_av_handle_event, BTIF_AV_SINK_CONFIG_REQ_EVT,
+                                     (char*)&config_req, sizeof(config_req), NULL);
+        } else {
+            APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
+        }
+    }
+}
+/*******************************************************************************
+**
+** Function         btif_av_init
+**
+** Description      Initializes btif AV if not already done
+**
+** Returns          bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_av_init()
+{
+    if (btif_av_cb.sm_handle == NULL)
+    {
+        if (!btif_a2dp_start_media_task())
+            return BT_STATUS_FAIL;
+
+        /* Also initialize the AV state machine */
+        btif_av_cb.sm_handle =
+                btif_sm_init((const btif_sm_handler_t*)btif_av_state_handlers, BTIF_AV_STATE_IDLE);
+
+        btif_enable_service(BTA_A2DP_SOURCE_SERVICE_ID);
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+        btif_enable_service(BTA_A2DP_SINK_SERVICE_ID);
+#endif
+
+        btif_a2dp_on_init();
+    }
+
+    return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         init_src
+**
+** Description      Initializes the AV interface for source mode
+**
+** Returns          bt_status_t
+**
+*******************************************************************************/
+
+static bt_status_t init_src(btav_callbacks_t* callbacks)
+{
+    BTIF_TRACE_EVENT("%s()", __func__);
+
+    bt_status_t status = btif_av_init();
+    if (status == BT_STATUS_SUCCESS)
+        bt_av_src_callbacks = callbacks;
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         init_sink
+**
+** Description      Initializes the AV interface for sink mode
+**
+** Returns          bt_status_t
+**
+*******************************************************************************/
+
+static bt_status_t init_sink(btav_callbacks_t* callbacks)
+{
+    BTIF_TRACE_EVENT("%s()", __func__);
+
+    bt_status_t status = btif_av_init();
+    if (status == BT_STATUS_SUCCESS)
+        bt_av_sink_callbacks = callbacks;
+
+    return status;
+}
+
+/*******************************************************************************
+**
+** Function         connect
+**
+** Description      Establishes the AV signalling channel with the remote headset
+**
+** Returns          bt_status_t
+**
+*******************************************************************************/
+
+static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
+{
+    btif_av_connect_req_t connect_req;
+    connect_req.target_bda = bd_addr;
+    connect_req.uuid = uuid;
+    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+
+    btif_sm_dispatch(btif_av_cb.sm_handle, BTIF_AV_CONNECT_REQ_EVT, (char*)&connect_req);
+
+    return BT_STATUS_SUCCESS;
+}
+
+static bt_status_t src_connect_sink(bt_bdaddr_t *bd_addr)
+{
+    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+    CHECK_BTAV_INIT();
+
+    return btif_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, bd_addr, connect_int);
+}
+
+static bt_status_t sink_connect_src(bt_bdaddr_t *bd_addr)
+{
+    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+    CHECK_BTAV_INIT();
+
+    return btif_queue_connect(UUID_SERVCLASS_AUDIO_SINK, bd_addr, connect_int);
+}
+
+/*******************************************************************************
+**
+** Function         disconnect
+**
+** Description      Tears down the AV signalling channel with the remote headset
+**
+** Returns          bt_status_t
+**
+*******************************************************************************/
+static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
+{
+    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+
+    CHECK_BTAV_INIT();
+
+    /* Switch to BTIF context */
+    return btif_transfer_context(btif_av_handle_event, BTIF_AV_DISCONNECT_REQ_EVT,
+                                 (char*)bd_addr, sizeof(bt_bdaddr_t), NULL);
+}
+
+/*******************************************************************************
+**
+** Function         cleanup
+**
+** Description      Shuts down the AV interface and does the cleanup
+**
+** Returns          None
+**
+*******************************************************************************/
+static void cleanup(void)
+{
+    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+
+    btif_a2dp_stop_media_task();
+
+    btif_disable_service(BTA_A2DP_SOURCE_SERVICE_ID);
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+    btif_disable_service(BTA_A2DP_SINK_SERVICE_ID);
+#endif
+
+    /* Also shut down the AV state machine */
+    btif_sm_shutdown(btif_av_cb.sm_handle);
+    btif_av_cb.sm_handle = NULL;
+}
+
+static void cleanup_src(void) {
+    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+
+    if (bt_av_src_callbacks)
+    {
+        bt_av_src_callbacks = NULL;
+        if (bt_av_sink_callbacks == NULL)
+            cleanup();
+    }
+}
+
+static void cleanup_sink(void) {
+    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+
+    if (bt_av_sink_callbacks)
+    {
+        bt_av_sink_callbacks = NULL;
+        if (bt_av_src_callbacks == NULL)
+            cleanup();
+    }
+}
+
+static const btav_interface_t bt_av_src_interface = {
+    sizeof(btav_interface_t),
+    init_src,
+    src_connect_sink,
+    disconnect,
+    cleanup_src,
+};
+
+static const btav_interface_t bt_av_sink_interface = {
+    sizeof(btav_interface_t),
+    init_sink,
+    sink_connect_src,
+    disconnect,
+    cleanup_sink,
+};
+
+/*******************************************************************************
+**
+** Function         btif_av_get_sm_handle
+**
+** Description      Fetches current av SM handle
+**
+** Returns          None
+**
+*******************************************************************************/
+
+btif_sm_handle_t btif_av_get_sm_handle(void)
+{
+    return btif_av_cb.sm_handle;
+}
+
+/*******************************************************************************
+**
+** Function         btif_av_stream_ready
+**
+** Description      Checks whether AV is ready for starting a stream
+**
+** Returns          None
+**
+*******************************************************************************/
+
+BOOLEAN btif_av_stream_ready(void)
+{
+    btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
+
+    BTIF_TRACE_DEBUG("btif_av_stream_ready : sm hdl %d, state %d, flags %x",
+                btif_av_cb.sm_handle, state, btif_av_cb.flags);
+
+    /* also make sure main adapter is enabled */
+    if (btif_is_enabled() == 0)
+    {
+        BTIF_TRACE_EVENT("main adapter not enabled");
+        return FALSE;
+    }
+
+    /* check if we are remotely suspended or stop is pending */
+    if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
+        return FALSE;
+
+    return (state == BTIF_AV_STATE_OPENED);
+}
+
+/*******************************************************************************
+**
+** Function         btif_av_stream_started_ready
+**
+** Description      Checks whether AV ready for media start in streaming state
+**
+** Returns          None
+**
+*******************************************************************************/
+
+BOOLEAN btif_av_stream_started_ready(void)
+{
+    btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
+
+    BTIF_TRACE_DEBUG("btif_av_stream_started : sm hdl %d, state %d, flags %x",
+                btif_av_cb.sm_handle, state, btif_av_cb.flags);
+
+    /* disallow media task to start if we have pending actions */
+    if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
+        | BTIF_AV_FLAG_PENDING_STOP))
+        return FALSE;
+
+    return (state == BTIF_AV_STATE_STARTED);
+}
+
+/*******************************************************************************
+**
+** Function         btif_dispatch_sm_event
+**
+** Description      Send event to AV statemachine
+**
+** Returns          None
+**
+*******************************************************************************/
+
+/* used to pass events to AV statemachine from other tasks */
+void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len)
+{
+    /* Switch to BTIF context */
+    btif_transfer_context(btif_av_handle_event, event,
+                          (char*)p_data, len, NULL);
+}
+
+/*******************************************************************************
+**
+** Function         btif_av_execute_service
+**
+** Description      Initializes/Shuts down the service
+**
+** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_av_execute_service(BOOLEAN b_enable)
+{
+     if (b_enable)
+     {
+         /* TODO: Removed BTA_SEC_AUTHORIZE since the Java/App does not
+          * handle this request in order to allow incoming connections to succeed.
+          * We need to put this back once support for this is added */
+
+         /* Added BTA_AV_FEAT_NO_SCO_SSPD - this ensures that the BTA does not
+          * auto-suspend av streaming on AG events(SCO or Call). The suspend shall
+          * be initiated by the app/audioflinger layers */
+#if (AVRC_METADATA_INCLUDED == TRUE)
+         BTA_AvEnable(BTA_SEC_AUTHENTICATE,
+             BTA_AV_FEAT_RCTG|BTA_AV_FEAT_METADATA|BTA_AV_FEAT_VENDOR|BTA_AV_FEAT_NO_SCO_SSPD
+#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
+             |BTA_AV_FEAT_RCCT
+             |BTA_AV_FEAT_ADV_CTRL
+#endif
+             ,bte_av_callback);
+#else
+         BTA_AvEnable(BTA_SEC_AUTHENTICATE, (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_NO_SCO_SSPD),
+                      bte_av_callback);
+#endif
+         BTA_AvRegister(BTA_AV_CHNL_AUDIO, BTIF_AV_SERVICE_NAME, 0, bte_av_media_callback);
+     }
+     else {
+         BTA_AvDeregister(btif_av_cb.bta_handle);
+         BTA_AvDisable();
+     }
+     return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         btif_av_sink_execute_service
+**
+** Description      Initializes/Shuts down the service
+**
+** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_av_sink_execute_service(BOOLEAN b_enable)
+{
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+    BTA_AvEnable_Sink(b_enable);
+#endif
+    return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         btif_av_get_src_interface
+**
+** Description      Get the AV callback interface for A2DP source profile
+**
+** Returns          btav_interface_t
+**
+*******************************************************************************/
+const btav_interface_t *btif_av_get_src_interface(void)
+{
+    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+    return &bt_av_src_interface;
+}
+
+/*******************************************************************************
+**
+** Function         btif_av_get_sink_interface
+**
+** Description      Get the AV callback interface for A2DP sink profile
+**
+** Returns          btav_interface_t
+**
+*******************************************************************************/
+const btav_interface_t *btif_av_get_sink_interface(void)
+{
+    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+    return &bt_av_sink_interface;
+}
+
+/*******************************************************************************
+**
+** Function         btif_av_is_connected
+**
+** Description      Checks if av has a connected sink
+**
+** Returns          BOOLEAN
+**
+*******************************************************************************/
+BOOLEAN btif_av_is_connected(void)
+{
+    btif_sm_state_t state = btif_sm_get_state(btif_av_cb.sm_handle);
+    return ((state == BTIF_AV_STATE_OPENED) || (state ==  BTIF_AV_STATE_STARTED));
+}
+
+/*******************************************************************************
+**
+** Function         btif_av_is_peer_edr
+**
+** Description      Check if the connected a2dp device supports
+**                  EDR or not. Only when connected this function
+**                  will accurately provide a true capability of
+**                  remote peer. If not connected it will always be false.
+**
+** Returns          TRUE if remote device is capable of EDR
+**
+*******************************************************************************/
+BOOLEAN btif_av_is_peer_edr(void)
+{
+    ASSERTC(btif_av_is_connected(), "No active a2dp connection", 0);
+
+    if (btif_av_cb.edr)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+/******************************************************************************
+**
+** Function        btif_av_clear_remote_suspend_flag
+**
+** Description     Clears btif_av_cd.flags if BTIF_AV_FLAG_REMOTE_SUSPEND is set
+**
+** Returns          void
+******************************************************************************/
+void btif_av_clear_remote_suspend_flag(void)
+{
+    BTIF_TRACE_DEBUG("%s: flag :%x",__func__, btif_av_cb.flags);
+    btif_av_cb.flags &= ~BTIF_AV_FLAG_REMOTE_SUSPEND;
+}

+ 483 - 0
examples/09_a2dp/components/bluedroid_demos/btif/btif_core.c

@@ -0,0 +1,483 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/************************************************************************************
+ *
+ *  Filename:      btif_core.c
+ *
+ *  Description:   Contains core functionality related to interfacing between
+ *                 Bluetooth HAL and BTE core stack.
+ *
+ ***********************************************************************************/
+
+#include <ctype.h>
+// #include <cutils/properties.h>
+// #include <dirent.h>
+// #include <fcntl.h>
+// #include <hardware/bluetooth.h>
+#include <stdlib.h>
+#include <string.h>
+// #include <sys/stat.h>
+// #include <sys/types.h>
+
+#define LOG_TAG "bt_btif_core"
+// #include "btcore/include/bdaddr.h"
+
+#include "bdaddr.h"
+// #include "bt_utils.h"
+#include "bta_api.h"
+#include "bte.h"
+#include "btif_api.h"
+// #include "btif_av.h"
+// #include "btif_config.h"
+// #include "btif_pan.h"
+// #include "btif_profile_queue.h"
+// #include "btif_config.h"
+// #include "btif_sock.h"
+// #include "btif_storage.h"
+#include "btif_util.h"
+#include "btu.h"
+#include "controller.h"
+#include "fixed_queue.h"
+#include "future.h"
+#include "gki.h"
+#include "osi.h"
+// #include "osi/include/log.h"
+#include "stack_manager.h"
+#include "thread.h"
+#include "btif_common.h"
+#include "btif_dm.h"
+/************************************************************************************
+**  Constants & Macros
+************************************************************************************/
+
+/************************************************************************************
+**  Local type definitions
+************************************************************************************/
+
+/************************************************************************************
+**  Static variables
+************************************************************************************/
+
+static tBTA_SERVICE_MASK btif_enabled_services = 0;
+
+static fixed_queue_t *btif_msg_queue = NULL;
+static xTaskHandle  xBtifTaskHandle = NULL;
+
+/************************************************************************************
+**  Static functions
+************************************************************************************/
+
+/* sends message to btif task */
+static void btif_sendmsg(void *p_msg);
+static void btif_thread_post(uint32_t sig);
+/************************************************************************************
+**  Externs
+************************************************************************************/
+static fixed_queue_t *xBtifQueue = NULL;
+
+/** TODO: Move these to _common.h */
+void bte_main_boot_entry(void *);
+void bte_main_disable(void);
+void bte_main_shutdown(void);
+void btif_dm_execute_service_request(UINT16 event, char *p_param);
+
+/*******************************************************************************
+**
+** Function         btif_context_switched
+**
+** Description      Callback used to execute transferred context callback
+**
+**                  p_msg : message to be executed in btif context
+**
+** Returns          void
+**
+*******************************************************************************/
+
+static void btif_context_switched(void *p_msg)
+{
+
+    BTIF_TRACE_VERBOSE("btif_context_switched");
+
+    tBTIF_CONTEXT_SWITCH_CBACK *p = (tBTIF_CONTEXT_SWITCH_CBACK *) p_msg;
+
+    /* each callback knows how to parse the data */
+    if (p->p_cb)
+        p->p_cb(p->event, p->p_param);
+}
+
+
+/*******************************************************************************
+**
+** Function         btif_transfer_context
+**
+** Description      This function switches context to btif task
+**
+**                  p_cback   : callback used to process message in btif context
+**                  event     : event id of message
+**                  p_params  : parameter area passed to callback (copied)
+**                  param_len : length of parameter area
+**                  p_copy_cback : If set this function will be invoked for deep copy
+**
+** Returns          void
+**
+*******************************************************************************/
+
+bt_status_t btif_transfer_context (tBTIF_CBACK *p_cback, UINT16 event, char* p_params, int param_len, tBTIF_COPY_CBACK *p_copy_cback)
+{
+    tBTIF_CONTEXT_SWITCH_CBACK *p_msg;
+
+    BTIF_TRACE_VERBOSE("btif_transfer_context event %d, len %d", event, param_len);
+
+    /* allocate and send message that will be executed in btif context */
+    if ((p_msg = (tBTIF_CONTEXT_SWITCH_CBACK *) GKI_getbuf(sizeof(tBTIF_CONTEXT_SWITCH_CBACK) + param_len)) != NULL)
+    {
+        p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT; /* internal event */
+        p_msg->p_cb = p_cback;
+
+        p_msg->event = event;                         /* callback event */
+
+        /* check if caller has provided a copy callback to do the deep copy */
+        if (p_copy_cback)
+        {
+            p_copy_cback(event, p_msg->p_param, p_params);
+        }
+        else if (p_params)
+        {
+            memcpy(p_msg->p_param, p_params, param_len);  /* callback parameter data */
+        }
+
+        btif_sendmsg(p_msg);
+        return BT_STATUS_SUCCESS;
+    }
+    else
+    {
+        /* let caller deal with a failed allocation */
+        return BT_STATUS_NOMEM;
+    }
+}
+
+int btif_is_enabled(void)
+{
+    return (stack_manager_is_stack_running());
+}
+
+void btif_init_ok(void) {
+    BTIF_TRACE_DEBUG("btif_task: received trigger stack init event");
+    future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function         btif_enable_bluetooth_evt
+**
+** Description      Event indicating bluetooth enable is completed
+**                  Notifies HAL user with updated adapter state
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void btif_enable_bluetooth_evt(tBTA_STATUS status)
+{
+    if (status == BTA_SUCCESS) {
+        future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS);
+    } else {
+        future_ready(stack_manager_get_hack_future(), FUTURE_FAIL);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         btif_disable_bluetooth_evt
+**
+** Description      Event notifying BT disable is now complete.
+**                  Terminates main stack tasks and notifies HAL
+**                  user with updated BT state.
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void btif_disable_bluetooth_evt(void)
+{
+    BTIF_TRACE_DEBUG("%s", __FUNCTION__);
+
+    /* callback to HAL */
+    future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS);
+}
+
+/*******************************************************************************
+**
+** Function         btif_task
+**
+** Description      BTIF task handler managing all messages being passed
+**                  Bluetooth HAL and BTA.
+**
+** Returns          void
+**
+*******************************************************************************/
+static void bt_jni_msg_ready(fixed_queue_t *queue) {
+    BT_HDR *p_msg;
+    while (!fixed_queue_is_empty(queue)) {
+        p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
+	BTIF_TRACE_VERBOSE("btif task fetched event %x", p_msg->event);
+        switch (p_msg->event) {
+        case BT_EVT_CONTEXT_SWITCH_EVT:
+            btif_context_switched(p_msg);
+            break;
+        default:
+            BTIF_TRACE_ERROR("unhandled btif event (%d)", p_msg->event & BT_EVT_MASK);                      break;
+        }
+        GKI_freebuf(p_msg);
+    }
+}
+
+/*******************************************************************************
+**
+** Function         btif_sendmsg
+**
+** Description      Sends msg to BTIF task
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void btif_sendmsg(void *p_msg)
+{
+    fixed_queue_enqueue(btif_msg_queue, p_msg);
+    btif_thread_post(SIG_BTIF_WORK);
+}
+
+static void btif_thread_post(uint32_t sig) {
+    BtTaskEvt_t *evt = (BtTaskEvt_t *)osi_malloc(sizeof(BtTaskEvt_t));
+    if (evt == NULL)
+        return;
+
+    evt->sig = sig;
+    evt->par = 0;
+
+    if (xQueueSend(xBtifQueue, &evt, 10/portTICK_RATE_MS) != pdTRUE) {
+            ets_printf("xBtifQueue failed\n");
+    }
+}
+
+/*****************************************************************************
+**
+** Function         btif_task_thread_handler
+**
+** Description      Process BTif Task Thread.
+******************************************************************************/
+void btif_task_thread_handler(void *arg)
+{
+    BtTaskEvt_t *e;
+
+    for (;;) {
+        if (pdTRUE == xQueueReceive(xBtifQueue, &e, (portTickType)portMAX_DELAY)) {
+
+            if (e->sig == SIG_BTIF_WORK) {
+                fixed_queue_process(btif_msg_queue);
+            }
+            osi_free(e);
+        }
+    }
+}
+
+/*******************************************************************************
+**
+** Function         btif_init_bluetooth
+**
+** Description      Creates BTIF task and prepares BT scheduler for startup
+**
+** Returns          bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_init_bluetooth(void) {
+    bte_main_boot_entry(btif_init_ok);
+
+    btif_msg_queue = fixed_queue_new(SIZE_MAX);
+    if (btif_msg_queue == NULL) {
+        goto error_exit;
+    }
+    xBtifQueue = xQueueCreate(60, sizeof(void *));
+    xTaskCreate(btif_task_thread_handler, "BtifT", 8192, NULL, configMAX_PRIORITIES - 1, &xBtifTaskHandle);
+    fixed_queue_register_dequeue(btif_msg_queue, bt_jni_msg_ready);
+    
+    return BT_STATUS_SUCCESS;
+
+error_exit:;
+    btif_shutdown_bluetooth();
+
+    return BT_STATUS_FAIL;
+}
+
+/*******************************************************************************
+**
+** Function         btif_enable_bluetooth
+**
+** Description      Inititates shutdown of Bluetooth system.
+**                  Any active links will be dropped and device entering
+**                  non connectable/discoverable mode
+**
+** Returns          void
+**
+*******************************************************************************/
+bt_status_t btif_enable_bluetooth(void)
+{
+    BTIF_TRACE_DEBUG("BTIF ENABLE BLUETOOTH");
+
+    BTA_EnableBluetooth(bte_dm_evt);
+
+    return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         btif_disable_bluetooth
+**
+** Description      Inititates shutdown of Bluetooth system.
+**                  Any active links will be dropped and device entering
+**                  non connectable/discoverable mode
+**
+** Returns          void
+**
+*******************************************************************************/
+bt_status_t btif_disable_bluetooth(void)
+{
+    BTIF_TRACE_DEBUG("BTIF DISABLE BLUETOOTH");
+
+    // btif_dm_on_disable();
+    /* cleanup rfcomm & l2cap api */
+    // btif_sock_cleanup();
+    // btif_pan_cleanup();
+    BTA_DisableBluetooth();
+
+    return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         btif_shutdown_bluetooth
+**
+** Description      Finalizes BT scheduler shutdown and terminates BTIF
+**                  task.
+**
+** Returns          void
+**
+*******************************************************************************/
+
+bt_status_t btif_shutdown_bluetooth(void)
+{
+    BTIF_TRACE_DEBUG("%s", __FUNCTION__);
+
+    fixed_queue_unregister_dequeue(btif_msg_queue);
+    fixed_queue_free(btif_msg_queue, NULL);
+    btif_msg_queue = NULL;
+
+    vTaskDelete(xBtifTaskHandle);
+    xBtifTaskHandle = NULL;
+    
+    vQueueDelete(xBtifQueue);
+    xBtifQueue = NULL;
+    
+    bte_main_shutdown();
+
+    return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         btif_get_enabled_services_mask
+**
+** Description      Fetches currently enabled services
+**
+** Returns          tBTA_SERVICE_MASK
+**
+*******************************************************************************/
+
+tBTA_SERVICE_MASK btif_get_enabled_services_mask(void)
+{
+    return btif_enabled_services;
+}
+
+/*******************************************************************************
+**
+** Function         btif_enable_service
+**
+** Description      Enables the service 'service_ID' to the service_mask.
+**                  Upon BT enable, BTIF core shall invoke the BTA APIs to
+**                  enable the profiles
+**
+** Returns          bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_enable_service(tBTA_SERVICE_ID service_id)
+{
+    tBTA_SERVICE_ID *p_id = &service_id;
+
+    /* If BT is enabled, we need to switch to BTIF context and trigger the
+     * enable for that profile
+     *
+     * Otherwise, we just set the flag. On BT_Enable, the DM will trigger
+     * enable for the profiles that have been enabled */
+
+    btif_enabled_services |= (1 << service_id);
+
+    BTIF_TRACE_DEBUG("%s: current services:0x%x", __FUNCTION__, btif_enabled_services);
+
+    if (btif_is_enabled()) {
+        btif_transfer_context(btif_dm_execute_service_request,
+                              BTIF_DM_ENABLE_SERVICE,
+                              (char*)p_id, sizeof(tBTA_SERVICE_ID), NULL);
+    }
+
+    return BT_STATUS_SUCCESS;
+}
+/*******************************************************************************
+**
+** Function         btif_disable_service
+**
+** Description      Disables the service 'service_ID' to the service_mask.
+**                  Upon BT disable, BTIF core shall invoke the BTA APIs to
+**                  disable the profiles
+**
+** Returns          bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_disable_service(tBTA_SERVICE_ID service_id)
+{
+    tBTA_SERVICE_ID *p_id = &service_id;
+
+    /* If BT is enabled, we need to switch to BTIF context and trigger the
+     * disable for that profile so that the appropriate uuid_property_changed will
+     * be triggerred. Otherwise, we just need to clear the service_id in the mask
+     */
+
+    btif_enabled_services &=  (tBTA_SERVICE_MASK)(~(1<<service_id));
+
+    BTIF_TRACE_DEBUG("%s: Current Services:0x%x", __FUNCTION__, btif_enabled_services);
+
+    if (btif_is_enabled()) {
+        btif_transfer_context(btif_dm_execute_service_request,
+                              BTIF_DM_DISABLE_SERVICE,
+                              (char*)p_id, sizeof(tBTA_SERVICE_ID), NULL);
+    }
+
+    return BT_STATUS_SUCCESS;
+}

+ 233 - 0
examples/09_a2dp/components/bluedroid_demos/btif/btif_dm.c

@@ -0,0 +1,233 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/************************************************************************************
+ *
+ *  Filename:      btif_dm.c
+ *
+ *  Description:   Contains Device Management (DM) related functionality
+ *
+ *
+ ***********************************************************************************/
+
+#define LOG_TAG "bt_btif_dm"
+
+// #include <assert.h>
+// #include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+// #include <sys/types.h>
+// #include <unistd.h>
+
+// #include <hardware/bluetooth.h>
+
+// #include <cutils/properties.h>
+#include "gki.h"
+#include "btu.h"
+// #include "btcore/include/bdaddr.h"
+#include "bta_api.h"
+#include "btif_api.h"
+#include "btif_util.h"
+#include "btif_dm.h"
+// #include "btif_storage.h"
+// #include "btif_hh.h"
+// #include "btif_config.h"
+// #include "btif_sdp.h"
+// #include "bta_gatt_api.h"
+// #include "device/include/interop.h"
+// #include "include/stack_config.h"
+// #include "osi/include/log.h"
+#include "allocator.h"
+#include "btm_int.h"
+#include "bt_defs.h"
+#include "future.h"
+#include "stack_manager.h"
+
+/******************************************************************************
+**  Constants & Macros
+******************************************************************************/
+#define BTA_SERVICE_ID_TO_SERVICE_MASK(id)       (1 << (id))
+
+/************************************************************************************
+**  Static variables
+************************************************************************************/
+/******************************************************************************
+**  Static functions
+******************************************************************************/
+/******************************************************************************
+**  Externs
+******************************************************************************/
+extern bt_status_t btif_sdp_execute_service(BOOLEAN b_enable);
+
+/******************************************************************************
+**  Functions
+******************************************************************************/
+
+static void btif_dm_data_copy(uint16_t event, char *dst, char *src)
+{
+    tBTA_DM_SEC *dst_dm_sec = (tBTA_DM_SEC*)dst;
+    tBTA_DM_SEC *src_dm_sec = (tBTA_DM_SEC*)src;
+
+    if (!src_dm_sec)
+        return;
+
+    assert(dst_dm_sec);
+    memcpy(dst_dm_sec, src_dm_sec, sizeof(tBTA_DM_SEC));
+
+    if (event == BTA_DM_BLE_KEY_EVT) {
+        dst_dm_sec->ble_key.p_key_value = osi_malloc(sizeof(tBTM_LE_KEY_VALUE));
+        assert(src_dm_sec->ble_key.p_key_value);
+        assert(dst_dm_sec->ble_key.p_key_value);
+        memcpy(dst_dm_sec->ble_key.p_key_value, src_dm_sec->ble_key.p_key_value, sizeof(tBTM_LE_KEY_VALUE));
+    }
+}
+
+static void btif_dm_data_free(uint16_t event, tBTA_DM_SEC *dm_sec)
+{
+    if (event == BTA_DM_BLE_KEY_EVT) {
+        osi_free(dm_sec->ble_key.p_key_value);
+    }
+}
+
+bt_status_t btif_in_execute_service_request(tBTA_SERVICE_ID service_id,
+                                                BOOLEAN b_enable)
+{
+    BTIF_TRACE_DEBUG("%s service_id: %d\n", __FUNCTION__, service_id);
+    /* Check the service_ID and invoke the profile's BT state changed API */
+    switch (service_id) {
+    case BTA_SDP_SERVICE_ID:
+        btif_sdp_execute_service(b_enable);
+        break;
+    default:
+        BTIF_TRACE_ERROR("%s: Unknown service being enabled\n", __FUNCTION__);
+        return BT_STATUS_FAIL;
+    }
+    return BT_STATUS_SUCCESS;
+}
+
+void btif_dm_execute_service_request(UINT16 event, char *p_param)
+{
+    BOOLEAN b_enable = FALSE;
+    if (event == BTIF_DM_ENABLE_SERVICE) {
+        b_enable = TRUE;
+    }
+
+    btif_in_execute_service_request(*((tBTA_SERVICE_ID*)p_param), b_enable);
+}
+
+/*******************************************************************************
+**
+** Function         btif_dm_upstreams_cback
+**
+** Description      Executes UPSTREAMS events in btif context
+**
+** Returns          void
+**
+*******************************************************************************/
+static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
+{
+    tBTA_DM_SEC *p_data = (tBTA_DM_SEC*)p_param;
+    tBTA_SERVICE_MASK service_mask;
+    uint32_t i;
+    BTIF_TRACE_EVENT("btif_dm_upstreams_cback  ev: %d\n", event);
+
+    switch (event) {
+    case BTA_DM_ENABLE_EVT:
+        /* for each of the enabled services in the mask, trigger the profile
+         * enable */
+        service_mask = btif_get_enabled_services_mask();
+        for (i=0; i <= BTA_MAX_SERVICE_ID; i++) {
+            if (service_mask &
+                (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(i))) {
+                btif_in_execute_service_request(i, TRUE);
+            }
+        }
+        btif_enable_bluetooth_evt(p_data->enable.status);
+        break;
+    case BTA_DM_DISABLE_EVT:
+        /* for each of the enabled services in the mask, trigger the profile
+         * disable */
+        service_mask = btif_get_enabled_services_mask();
+        for (i=0; i <= BTA_MAX_SERVICE_ID; i++) {
+            if (service_mask &
+                (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(i))) {
+                btif_in_execute_service_request(i, FALSE);
+            }
+        }
+        btif_disable_bluetooth_evt();
+        break;
+    case BTA_DM_PIN_REQ_EVT:
+    case BTA_DM_AUTH_CMPL_EVT:
+    case BTA_DM_BOND_CANCEL_CMPL_EVT:
+    case BTA_DM_SP_CFM_REQ_EVT:
+    case BTA_DM_SP_KEY_NOTIF_EVT:
+
+    case BTA_DM_DEV_UNPAIRED_EVT:
+    case BTA_DM_BUSY_LEVEL_EVT:
+    case BTA_DM_LINK_UP_EVT:
+    case BTA_DM_LINK_DOWN_EVT:
+    case BTA_DM_HW_ERROR_EVT:
+
+#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
+    case BTA_DM_BLE_KEY_EVT:
+    case BTA_DM_BLE_SEC_REQ_EVT:
+    case BTA_DM_BLE_PASSKEY_NOTIF_EVT:
+    case BTA_DM_BLE_PASSKEY_REQ_EVT:
+    case BTA_DM_BLE_NC_REQ_EVT:
+    case BTA_DM_BLE_OOB_REQ_EVT:
+    case BTA_DM_BLE_LOCAL_IR_EVT:
+    case BTA_DM_BLE_LOCAL_ER_EVT:
+    case BTA_DM_BLE_AUTH_CMPL_EVT:
+    case BTA_DM_LE_FEATURES_READ:
+    case BTA_DM_ENER_INFO_READ:
+#endif
+
+    case BTA_DM_AUTHORIZE_EVT:
+    case BTA_DM_SIG_STRENGTH_EVT:
+    case BTA_DM_SP_RMT_OOB_EVT:
+    case BTA_DM_SP_KEYPRESS_EVT:
+    case BTA_DM_ROLE_CHG_EVT:
+
+    default:
+        BTIF_TRACE_WARNING( "btif_dm_cback : unhandled event (%d)\n", event );
+        break;
+    }
+
+    btif_dm_data_free(event, p_data);
+}
+
+/*******************************************************************************
+**
+** Function         bte_dm_evt
+**
+** Description      Switches context from BTE to BTIF for all DM events
+**
+** Returns          void
+**
+*******************************************************************************/
+
+void bte_dm_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data)
+{
+    /* switch context to btif task context (copy full union size for convenience) */
+    bt_status_t status = btif_transfer_context(btif_dm_upstreams_evt, (uint16_t)event,
+                                (void*)p_data, sizeof(tBTA_DM_SEC), btif_dm_data_copy);
+
+    /* catch any failed context transfers */
+    ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed\n", status);
+}

+ 2836 - 0
examples/09_a2dp/components/bluedroid_demos/btif/btif_media_task.c

@@ -0,0 +1,2836 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ **
+ **  Name:          btif_media_task.c
+ **
+ **  Description:   This is the multimedia module for the BTIF system.  It
+ **                 contains task implementations AV, HS and HF profiles
+ **                 audio & video processing
+ **
+ ******************************************************************************/
+
+#define LOG_TAG "bt_btif_media"
+
+// #include <assert.h>
+#include "bt_trace.h"
+#include <string.h>
+#include <stdio.h>
+// #include <sys/types.h>
+// #include <sys/stat.h>
+// #include <fcntl.h>
+// #include <unistd.h>
+// #include <pthread.h>
+#include <stdint.h>
+// #include <sys/time.h>
+// #include <errno.h>
+
+#include "bt_target.h"
+#include "fixed_queue.h"
+#include "gki.h"
+#include "bta_api.h"
+#include "btu.h"
+#include "bta_sys.h"
+#include "bta_sys_int.h"
+
+#include "bta_av_api.h"
+#include "a2d_api.h"
+#include "a2d_sbc.h"
+#include "a2d_int.h"
+#include "bta_av_sbc.h"
+#include "bta_av_ci.h"
+#include "l2c_api.h"
+
+#include "btif_av_co.h"
+#include "btif_media.h"
+
+#include "alarm.h"
+// #include "ois/include/log.h"
+#include "bt_trace.h"
+#include "thread.h"
+
+#if (BTA_AV_INCLUDED == TRUE)
+#include "sbc_encoder.h"
+#endif
+
+// #include <hardware/bluetooth.h>
+#include "bt_defs.h"
+#include "audio_a2dp_hw.h"
+#include "btif_av.h"
+#include "btif_sm.h"
+#include "btif_util.h"
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+#include "oi_codec_sbc.h"
+#include "oi_status.h"
+#endif
+#include "stdio.h"
+// #include <dlfcn.h>
+#include "btif_media.h"
+#include "allocator.h"
+#include "bt_utils.h"
+
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+OI_CODEC_SBC_DECODER_CONTEXT context;
+OI_UINT32 contextData[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)];
+OI_INT16 pcmData[15*SBC_MAX_SAMPLES_PER_FRAME*SBC_MAX_CHANNELS];
+#endif
+
+
+/*****************************************************************************
+ **  Constants
+ *****************************************************************************/
+
+#ifndef AUDIO_CHANNEL_OUT_MONO
+#define AUDIO_CHANNEL_OUT_MONO 0x01
+#endif
+
+#ifndef AUDIO_CHANNEL_OUT_STEREO
+#define AUDIO_CHANNEL_OUT_STEREO 0x03
+#endif
+
+/* BTIF media cmd event definition : BTIF_MEDIA_TASK_CMD */
+enum
+{
+    BTIF_MEDIA_START_AA_TX = 1,
+    BTIF_MEDIA_STOP_AA_TX,
+    BTIF_MEDIA_AA_RX_RDY,
+    BTIF_MEDIA_UIPC_RX_RDY,
+    BTIF_MEDIA_SBC_ENC_INIT,
+    BTIF_MEDIA_SBC_ENC_UPDATE,
+    BTIF_MEDIA_SBC_DEC_INIT,
+    BTIF_MEDIA_VIDEO_DEC_INIT,
+    BTIF_MEDIA_FLUSH_AA_TX,
+    BTIF_MEDIA_FLUSH_AA_RX,
+    BTIF_MEDIA_AUDIO_FEEDING_INIT,
+    BTIF_MEDIA_AUDIO_RECEIVING_INIT,
+    BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE,
+    BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK
+};
+
+enum {
+    MEDIA_TASK_STATE_OFF = 0,
+    MEDIA_TASK_STATE_ON = 1,
+    MEDIA_TASK_STATE_SHUTTING_DOWN = 2
+};
+
+enum {
+    SIG_MEDIA_TASK_INIT = 0xf0,
+    SIG_MEDIA_TASK_CLEAN_UP = 0xf1,
+    SIG_MEDIA_TASK_AVK_ALARM_TO = 0xf2,
+    SIG_MEDIA_TASK_AA_ALARM_TO = 0xf3,
+    SIG_MEDIA_TASK_CMD_READY = 0xf4
+};
+
+/* Macro to multiply the media task tick */
+#ifndef BTIF_MEDIA_NUM_TICK
+#define BTIF_MEDIA_NUM_TICK      1
+#endif
+
+/* Media task tick in milliseconds, must be set to multiple of
+   (1000/TICKS_PER_SEC) (10) */
+
+#define BTIF_MEDIA_TIME_TICK                     (20 * BTIF_MEDIA_NUM_TICK)
+#define A2DP_DATA_READ_POLL_MS    (BTIF_MEDIA_TIME_TICK / 2)
+#define BTIF_SINK_MEDIA_TIME_TICK                (20 * BTIF_MEDIA_NUM_TICK)
+
+
+/* buffer pool */
+#define BTIF_MEDIA_AA_POOL_ID GKI_POOL_ID_3
+#define BTIF_MEDIA_AA_BUF_SIZE GKI_BUF3_SIZE
+
+/* offset */
+#if (BTA_AV_CO_CP_SCMS_T == TRUE)
+#define BTIF_MEDIA_AA_SBC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_SBC_HDR_SIZE + 1)
+#else
+#define BTIF_MEDIA_AA_SBC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_SBC_HDR_SIZE)
+#endif
+
+/* Define the bitrate step when trying to match bitpool value */
+#ifndef BTIF_MEDIA_BITRATE_STEP
+#define BTIF_MEDIA_BITRATE_STEP 5
+#endif
+
+/* Middle quality quality setting @ 44.1 khz */
+#define DEFAULT_SBC_BITRATE 328
+
+#ifndef BTIF_A2DP_NON_EDR_MAX_RATE
+#define BTIF_A2DP_NON_EDR_MAX_RATE 229
+#endif
+
+#define USEC_PER_SEC 1000000L
+#define TPUT_STATS_INTERVAL_US (3000*1000)
+
+/*
+ * CONGESTION COMPENSATION CTRL ::
+ *
+ * Thus setting controls how many buffers we will hold in media task
+ * during temp link congestion. Together with the stack buffer queues
+ * it controls much temporary a2dp link congestion we can
+ * compensate for. It however also depends on the default run level of sinks
+ * jitterbuffers. Depending on type of sink this would vary.
+ * Ideally the (SRC) max tx buffer capacity should equal the sinks
+ * jitterbuffer runlevel including any intermediate buffers on the way
+ * towards the sinks codec.
+ */
+
+/* fixme -- define this in pcm time instead of buffer count */
+
+/* The typical runlevel of the tx queue size is ~1 buffer
+   but due to link flow control or thread preemption in lower
+   layers we might need to temporarily buffer up data */
+
+/* 18 frames is equivalent to 6.89*18*2.9 ~= 360 ms @ 44.1 khz, 20 ms mediatick */
+#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ 18
+
+#ifndef MAX_PCM_FRAME_NUM_PER_TICK
+#define MAX_PCM_FRAME_NUM_PER_TICK     14
+#endif
+
+/* In case of A2DP SINK, we will delay start by 5 AVDTP Packets*/
+#define MAX_A2DP_DELAYED_START_FRAME_COUNT 5
+#define PACKET_PLAYED_PER_TICK_48 8
+#define PACKET_PLAYED_PER_TICK_44 7
+#define PACKET_PLAYED_PER_TICK_32 5
+#define PACKET_PLAYED_PER_TICK_16 3
+
+typedef struct
+{
+    UINT16 num_frames_to_be_processed;
+    UINT16 len;
+    UINT16 offset;
+    UINT16 layer_specific;
+} tBT_SBC_HDR;
+
+typedef struct
+{
+    UINT32 aa_frame_counter;
+    INT32  aa_feed_counter;
+    INT32  aa_feed_residue;
+    UINT32 counter;
+    UINT32 bytes_per_tick;  /* pcm bytes read each media task tick */
+} tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE;
+
+typedef union
+{
+    tBTIF_AV_MEDIA_FEEDINGS_PCM_STATE pcm;
+} tBTIF_AV_MEDIA_FEEDINGS_STATE;
+
+typedef struct
+{
+#if (BTA_AV_INCLUDED == TRUE)
+    BUFFER_Q TxAaQ;
+    BUFFER_Q RxSbcQ;
+    BOOLEAN is_tx_timer;
+    BOOLEAN is_rx_timer;
+    UINT16 TxAaMtuSize;
+    UINT32 timestamp;
+    UINT8 TxTranscoding;
+    tBTIF_AV_FEEDING_MODE feeding_mode;
+    tBTIF_AV_MEDIA_FEEDINGS media_feeding;
+    tBTIF_AV_MEDIA_FEEDINGS_STATE media_feeding_state;
+    SBC_ENC_PARAMS encoder;
+    UINT8 busy_level;
+    void* av_sm_hdl;
+    UINT8 a2dp_cmd_pending; /* we can have max one command pending */
+    BOOLEAN tx_flush; /* discards any outgoing data when true */
+    BOOLEAN rx_flush; /* discards any incoming data when true */
+    UINT8 peer_sep;
+    BOOLEAN data_channel_open;
+    UINT8   frames_to_process;
+
+    UINT32  sample_rate;
+    UINT8   channel_count;
+    osi_alarm_t *media_alarm;
+    osi_alarm_t *decode_alarm;
+#endif
+
+} tBTIF_MEDIA_CB;
+
+typedef struct {
+    long long rx;
+    long long rx_tot;
+    long long tx;
+    long long tx_tot;
+    long long ts_prev_us;
+} t_stat;
+
+static UINT64 last_frame_us = 0;
+
+static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
+static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
+static void btif_a2dp_encoder_update(void);
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+extern OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                          const OI_BYTE **frameData,
+                                          unsigned long *frameBytes,
+                                          OI_INT16 *pcmData,
+                                          unsigned long *pcmBytes);
+extern OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                           unsigned long *decoderData,
+                                           unsigned long decoderDataBytes,
+                                           OI_UINT8 maxChannels,
+                                           OI_UINT8 pcmStride,
+                                           OI_BOOL enhanced);
+#endif
+static void btif_media_flush_q(BUFFER_Q *p_q);
+static void btif_media_task_aa_handle_stop_decoding(void );
+static void btif_media_task_aa_rx_flush(void);
+
+static const char *dump_media_event(UINT16 event);
+// static void btif_media_thread_init(void *context);
+// static void btif_media_thread_cleanup(void *context);
+static void btif_media_thread_handle_cmd(fixed_queue_t *queue);
+
+/* Handle incoming media packets A2DP SINK streaming*/
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+static void btif_media_task_handle_inc_media(tBT_SBC_HDR*p_msg);
+#endif
+
+#if (BTA_AV_INCLUDED == TRUE)
+static void btif_media_send_aa_frame(void);
+static void btif_media_task_feeding_state_reset(void);
+static void btif_media_task_aa_start_tx(void);
+static void btif_media_task_aa_stop_tx(void);
+static void btif_media_task_enc_init(BT_HDR *p_msg);
+static void btif_media_task_enc_update(BT_HDR *p_msg);
+static void btif_media_task_audio_feeding_init(BT_HDR *p_msg);
+static void btif_media_task_aa_tx_flush(BT_HDR *p_msg);
+static void btif_media_aa_prep_2_send(UINT8 nb_frame);
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+static void btif_media_task_aa_handle_decoder_reset(BT_HDR *p_msg);
+static void btif_media_task_aa_handle_clear_track(void);
+#endif
+static void btif_media_task_aa_handle_start_decoding(void);
+#endif
+BOOLEAN btif_media_task_clear_track(void);
+static void btif_media_task_handler(void *arg);
+static void btif_media_task_aa_handle_timer(UNUSED_ATTR void *context);
+static void btif_media_task_avk_handle_timer(UNUSED_ATTR void *context);
+static void btif_media_thread_init(UNUSED_ATTR void *context);
+static void btif_media_thread_cleanup(UNUSED_ATTR void *context);
+extern BOOLEAN btif_hf_is_call_idle();
+
+static tBTIF_MEDIA_CB btif_media_cb;
+static int media_task_running = MEDIA_TASK_STATE_OFF;
+
+static fixed_queue_t *btif_media_cmd_msg_queue = NULL;
+// static thread_t *worker_thread;
+static xTaskHandle  xBtifMediaTaskHandle = NULL;
+static QueueHandle_t xBtifMediaQueue = NULL;
+
+/*****************************************************************************
+ **  Misc helper functions
+ *****************************************************************************/
+
+static UINT64 time_now_us()
+{
+    // TODO: implement this function
+    return 0;
+}
+
+static void log_tstamps_us(char *comment)
+{
+    static UINT64 prev_us = 0;
+    const UINT64 now_us = time_now_us();
+    APPL_TRACE_DEBUG("[%s] ts %08llu, diff : %08llu, queue sz %d", comment, now_us, now_us - prev_us,
+                GKI_queue_length(&btif_media_cb.TxAaQ));
+    prev_us = now_us;
+}
+
+UNUSED_ATTR static const char *dump_media_event(UINT16 event)
+{
+    switch(event)
+    {
+        CASE_RETURN_STR(BTIF_MEDIA_START_AA_TX)
+        CASE_RETURN_STR(BTIF_MEDIA_STOP_AA_TX)
+        CASE_RETURN_STR(BTIF_MEDIA_AA_RX_RDY)
+        CASE_RETURN_STR(BTIF_MEDIA_UIPC_RX_RDY)
+        CASE_RETURN_STR(BTIF_MEDIA_SBC_ENC_INIT)
+        CASE_RETURN_STR(BTIF_MEDIA_SBC_ENC_UPDATE)
+        CASE_RETURN_STR(BTIF_MEDIA_SBC_DEC_INIT)
+        CASE_RETURN_STR(BTIF_MEDIA_VIDEO_DEC_INIT)
+        CASE_RETURN_STR(BTIF_MEDIA_FLUSH_AA_TX)
+        CASE_RETURN_STR(BTIF_MEDIA_FLUSH_AA_RX)
+        CASE_RETURN_STR(BTIF_MEDIA_AUDIO_FEEDING_INIT)
+        CASE_RETURN_STR(BTIF_MEDIA_AUDIO_RECEIVING_INIT)
+        CASE_RETURN_STR(BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE)
+        CASE_RETURN_STR(BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK)
+
+        default:
+            return "UNKNOWN MEDIA EVENT";
+    }
+}
+
+/*****************************************************************************
+ **  A2DP CTRL PATH
+ *****************************************************************************/
+
+static const char* dump_a2dp_ctrl_event(UINT8 event)
+{
+    switch(event)
+    {
+        CASE_RETURN_STR(A2DP_CTRL_CMD_NONE)
+        CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY)
+        CASE_RETURN_STR(A2DP_CTRL_CMD_START)
+        CASE_RETURN_STR(A2DP_CTRL_CMD_STOP)
+        CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND)
+        default:
+            return "UNKNOWN MSG ID";
+    }
+}
+
+static void btif_audiopath_detached(void)
+{
+    APPL_TRACE_EVENT("## AUDIO PATH DETACHED ##");
+
+    /*  send stop request only if we are actively streaming and haven't received
+        a stop request. Potentially audioflinger detached abnormally */
+    if (btif_media_cb.is_tx_timer)
+    {
+        /* post stop event and wait for audio path to stop */
+        btif_dispatch_sm_event(BTIF_AV_STOP_STREAM_REQ_EVT, NULL, 0);
+    }
+}
+
+static void a2dp_cmd_acknowledge(int status)
+{
+    UINT8 ack = status;
+
+    APPL_TRACE_EVENT("## a2dp ack : %s, status %d ##",
+          dump_a2dp_ctrl_event(btif_media_cb.a2dp_cmd_pending), status);
+
+    /* sanity check */
+    if (btif_media_cb.a2dp_cmd_pending == A2DP_CTRL_CMD_NONE)
+    {
+        APPL_TRACE_ERROR("warning : no command pending, ignore ack");
+        return;
+    }
+
+    /* clear pending */
+    btif_media_cb.a2dp_cmd_pending = A2DP_CTRL_CMD_NONE;
+
+    /* acknowledge start request */
+    UIPC_Send(UIPC_CH_ID_AV_CTRL, 0, &ack, 1);
+}
+
+
+static void btif_recv_ctrl_data(void)
+{
+    UINT8 cmd = 0;
+    int n;
+    n = UIPC_Read(UIPC_CH_ID_AV_CTRL, NULL, &cmd, 1);
+
+    /* detach on ctrl channel means audioflinger process was terminated */
+    if (n == 0)
+    {
+        APPL_TRACE_EVENT("CTRL CH DETACHED");
+        UIPC_Close(UIPC_CH_ID_AV_CTRL);
+        /* we can operate only on datachannel, if af client wants to
+           do send additional commands the ctrl channel would be reestablished */
+        //btif_audiopath_detached();
+        return;
+    }
+
+    APPL_TRACE_DEBUG("a2dp-ctrl-cmd : %s", dump_a2dp_ctrl_event(cmd));
+
+    btif_media_cb.a2dp_cmd_pending = cmd;
+
+    switch(cmd)
+    {
+        case A2DP_CTRL_CMD_CHECK_READY:
+
+            if (media_task_running == MEDIA_TASK_STATE_SHUTTING_DOWN)
+            {
+                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
+                return;
+            }
+
+            /* check whether av is ready to setup a2dp datapath */
+            if ((btif_av_stream_ready() == TRUE) || (btif_av_stream_started_ready() == TRUE))
+            {
+                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+            }
+            else
+            {
+                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
+            }
+            break;
+
+        case A2DP_CTRL_CMD_START:
+            /* Don't sent START request to stack while we are in call.
+               Some headsets like the Sony MW600, don't allow AVDTP START
+               in call and respond BAD_STATE. */
+            if (!btif_hf_is_call_idle())
+            {
+                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_INCALL_FAILURE);
+                break;
+            }
+
+            if (btif_av_stream_ready() == TRUE)
+            {
+                /* setup audio data channel listener */
+                UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
+
+                /* post start event and wait for audio path to open */
+                btif_dispatch_sm_event(BTIF_AV_START_STREAM_REQ_EVT, NULL, 0);
+
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+                if (btif_media_cb.peer_sep == AVDT_TSEP_SRC)
+                    a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+#endif
+            }
+            else if (btif_av_stream_started_ready())
+            {
+                /* already started, setup audio data channel listener
+                   and ack back immediately */
+                UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
+
+                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+            }
+            else
+            {
+                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
+                break;
+            }
+            break;
+
+        case A2DP_CTRL_CMD_STOP:
+            if (btif_media_cb.peer_sep == AVDT_TSEP_SNK && btif_media_cb.is_tx_timer == FALSE)
+            {
+                /* we are already stopped, just ack back */
+                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+                break;
+            }
+
+            btif_dispatch_sm_event(BTIF_AV_STOP_STREAM_REQ_EVT, NULL, 0);
+            a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+            break;
+
+        case A2DP_CTRL_CMD_SUSPEND:
+            /* local suspend */
+            if (btif_av_stream_started_ready())
+            {
+                btif_dispatch_sm_event(BTIF_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
+            }
+            else
+            {
+                /* if we are not in started state, just ack back ok and let
+                   audioflinger close the channel. This can happen if we are
+                   remotely suspended, clear REMOTE SUSPEND Flag */
+                btif_av_clear_remote_suspend_flag();
+                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+            }
+            break;
+
+        case A2DP_CTRL_GET_AUDIO_CONFIG:
+        {
+            uint32_t sample_rate = btif_media_cb.sample_rate;
+            uint8_t channel_count = btif_media_cb.channel_count;
+
+            a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+            UIPC_Send(UIPC_CH_ID_AV_CTRL, 0, (UINT8 *)&sample_rate, 4);
+            UIPC_Send(UIPC_CH_ID_AV_CTRL, 0, &channel_count, 1);
+            break;
+        }
+
+        default:
+            APPL_TRACE_ERROR("UNSUPPORTED CMD (%d)", cmd);
+            a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
+            break;
+    }
+    APPL_TRACE_DEBUG("a2dp-ctrl-cmd : %s DONE", dump_a2dp_ctrl_event(cmd));
+}
+
+static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event)
+{
+    UNUSED(ch_id);
+
+    APPL_TRACE_DEBUG("A2DP-CTRL-CHANNEL EVENT %s", dump_uipc_event(event));
+
+    switch(event)
+    {
+        case UIPC_OPEN_EVT:
+            /* fetch av statemachine handle */
+            btif_media_cb.av_sm_hdl = btif_av_get_sm_handle();
+            break;
+
+        case UIPC_CLOSE_EVT:
+            /* restart ctrl server unless we are shutting down */
+            if (media_task_running == MEDIA_TASK_STATE_ON)
+                UIPC_Open(UIPC_CH_ID_AV_CTRL , btif_a2dp_ctrl_cb);
+            break;
+
+        case UIPC_RX_DATA_READY_EVT:
+            btif_recv_ctrl_data();
+            break;
+
+        default :
+            APPL_TRACE_ERROR("### A2DP-CTRL-CHANNEL EVENT %d NOT HANDLED ###", event);
+            break;
+    }
+}
+
+static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event)
+{
+    UNUSED(ch_id);
+
+    APPL_TRACE_DEBUG("BTIF MEDIA (A2DP-DATA) EVENT %s", dump_uipc_event(event));
+
+    switch(event)
+    {
+        case UIPC_OPEN_EVT:
+
+            /*  read directly from media task from here on (keep callback for
+                connection events */
+            UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
+            UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
+                       (void *)A2DP_DATA_READ_POLL_MS);
+
+            if (btif_media_cb.peer_sep == AVDT_TSEP_SNK) {
+                /* Start the media task to encode SBC */
+                btif_media_task_start_aa_req();
+
+                /* make sure we update any changed sbc encoder params */
+                btif_a2dp_encoder_update();
+            }
+            btif_media_cb.data_channel_open = TRUE;
+
+            /* ack back when media task is fully started */
+            break;
+
+        case UIPC_CLOSE_EVT:
+            a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+            btif_audiopath_detached();
+            btif_media_cb.data_channel_open = FALSE;
+            break;
+
+        default :
+            APPL_TRACE_ERROR("### A2DP-DATA EVENT %d NOT HANDLED ###", event);
+            break;
+    }
+}
+
+
+/*****************************************************************************
+ **  BTIF ADAPTATION
+ *****************************************************************************/
+
+static UINT16 btif_media_task_get_sbc_rate(void)
+{
+    UINT16 rate = DEFAULT_SBC_BITRATE;
+
+    /* restrict bitrate if a2dp link is non-edr */
+    if (!btif_av_is_peer_edr())
+    {
+        rate = BTIF_A2DP_NON_EDR_MAX_RATE;
+        APPL_TRACE_DEBUG("non-edr a2dp sink detected, restrict rate to %d", rate);
+    }
+
+    return rate;
+}
+
+static void btif_a2dp_encoder_init(void)
+{
+    UINT16 minmtu;
+    tBTIF_MEDIA_INIT_AUDIO msg;
+    tA2D_SBC_CIE sbc_config;
+
+    /* lookup table for converting channel mode */
+    UINT16 codec_mode_tbl[5] = { SBC_JOINT_STEREO, SBC_STEREO, SBC_DUAL, 0, SBC_MONO };
+
+    /* lookup table for converting number of blocks */
+    UINT16 codec_block_tbl[5] = { 16, 12, 8, 0, 4 };
+
+    /* lookup table to convert freq */
+    UINT16 freq_block_tbl[5] = { SBC_sf48000, SBC_sf44100, SBC_sf32000, 0, SBC_sf16000 };
+
+    APPL_TRACE_DEBUG("btif_a2dp_encoder_init");
+
+    /* Retrieve the current SBC configuration (default if currently not used) */
+    bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu);
+    msg.NumOfSubBands = (sbc_config.num_subbands == A2D_SBC_IE_SUBBAND_4) ? 4 : 8;
+    msg.NumOfBlocks = codec_block_tbl[sbc_config.block_len >> 5];
+    msg.AllocationMethod = (sbc_config.alloc_mthd == A2D_SBC_IE_ALLOC_MD_L) ? SBC_LOUDNESS : SBC_SNR;
+    msg.ChannelMode = codec_mode_tbl[sbc_config.ch_mode >> 1];
+    msg.SamplingFreq = freq_block_tbl[sbc_config.samp_freq >> 5];
+    msg.MtuSize = minmtu;
+
+    APPL_TRACE_EVENT("msg.ChannelMode %x", msg.ChannelMode);
+
+    /* Init the media task to encode SBC properly */
+    btif_media_task_enc_init_req(&msg);
+}
+
+static void btif_a2dp_encoder_update(void)
+{
+    UINT16 minmtu;
+    tA2D_SBC_CIE sbc_config;
+    tBTIF_MEDIA_UPDATE_AUDIO msg;
+    UINT8 pref_min;
+    UINT8 pref_max;
+
+    APPL_TRACE_DEBUG("btif_a2dp_encoder_update");
+
+    /* Retrieve the current SBC configuration (default if currently not used) */
+    bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu);
+
+    APPL_TRACE_DEBUG("btif_a2dp_encoder_update: Common min_bitpool:%d(0x%x) max_bitpool:%d(0x%x)",
+            sbc_config.min_bitpool, sbc_config.min_bitpool,
+            sbc_config.max_bitpool, sbc_config.max_bitpool);
+
+    if (sbc_config.min_bitpool > sbc_config.max_bitpool)
+    {
+        APPL_TRACE_ERROR("btif_a2dp_encoder_update: ERROR btif_a2dp_encoder_update min_bitpool > max_bitpool");
+    }
+
+    /* check if remote sink has a preferred bitpool range */
+    if (bta_av_co_get_remote_bitpool_pref(&pref_min, &pref_max) == TRUE)
+    {
+        /* adjust our preferred bitpool with the remote preference if within
+           our capable range */
+
+        if (pref_min < sbc_config.min_bitpool)
+            pref_min = sbc_config.min_bitpool;
+
+        if (pref_max > sbc_config.max_bitpool)
+            pref_max = sbc_config.max_bitpool;
+
+        msg.MinBitPool = pref_min;
+        msg.MaxBitPool = pref_max;
+
+        if ((pref_min != sbc_config.min_bitpool) || (pref_max != sbc_config.max_bitpool))
+        {
+            APPL_TRACE_EVENT("## adjusted our bitpool range to peer pref [%d:%d] ##",
+                pref_min, pref_max);
+        }
+    }
+    else
+    {
+        msg.MinBitPool = sbc_config.min_bitpool;
+        msg.MaxBitPool = sbc_config.max_bitpool;
+    }
+
+    msg.MinMtuSize = minmtu;
+
+    /* Update the media task to encode SBC properly */
+    btif_media_task_enc_update_req(&msg);
+}
+
+
+static void btif_media_task_post(uint32_t sig)
+{
+    BtTaskEvt_t *evt = (BtTaskEvt_t *)osi_malloc(sizeof(BtTaskEvt_t));
+    if (evt == NULL)
+        return;
+
+    evt->sig = sig;
+    evt->par = 0;
+
+    if (xQueueSend(xBtifMediaQueue, &evt, 10/portTICK_RATE_MS) != pdTRUE) {
+            APPL_TRACE_ERROR("xBtifMediaQueue failed\n");
+    }
+}
+
+static void btif_media_task_handler(void *arg)
+{
+    BtTaskEvt_t *e;
+
+    for (;;) {
+        if (pdTRUE == xQueueReceive(xBtifMediaQueue, &e, (portTickType)portMAX_DELAY)) {
+            switch (e->sig) {
+            case SIG_MEDIA_TASK_AVK_ALARM_TO:
+                btif_media_task_avk_handle_timer(NULL);
+                break;
+            case SIG_MEDIA_TASK_AA_ALARM_TO:
+                btif_media_task_aa_handle_timer(NULL);
+                break;
+            case SIG_MEDIA_TASK_CMD_READY:
+                fixed_queue_process(btif_media_cmd_msg_queue);
+            case SIG_MEDIA_TASK_INIT:
+                btif_media_thread_init(NULL);
+                break;
+            case SIG_MEDIA_TASK_CLEAN_UP:
+                btif_media_thread_cleanup(NULL);
+                break;
+            default:
+                APPL_TRACE_ERROR("media task unhandled evt: 0x%x\n", e->sig);
+            }
+        }
+        osi_free(e);
+    }
+}
+
+bool btif_a2dp_start_media_task(void)
+{
+    if (media_task_running != MEDIA_TASK_STATE_OFF)
+    {
+        APPL_TRACE_ERROR("warning : media task already running");
+        return false;
+    }
+
+    APPL_TRACE_EVENT("## A2DP START MEDIA THREAD ##");
+
+    btif_media_cmd_msg_queue = fixed_queue_new(SIZE_MAX);
+    if (btif_media_cmd_msg_queue == NULL) {
+        goto error_exit;
+    }
+    
+    xBtifMediaQueue = xQueueCreate(60, sizeof(void *));
+    if (xBtifMediaQueue == 0) {
+        goto error_exit;
+    }
+    xTaskCreate(btif_media_task_handler, "BtifMediaT", 8192, NULL, configMAX_PRIORITIES - 1, &xBtifMediaTaskHandle);
+    if (xBtifMediaTaskHandle == NULL)
+        goto error_exit;
+    fixed_queue_register_dequeue(btif_media_cmd_msg_queue, btif_media_thread_handle_cmd);
+    btif_media_task_post(SIG_MEDIA_TASK_INIT);
+    
+    APPL_TRACE_EVENT("## A2DP MEDIA THREAD STARTED ##");
+
+    return true;
+
+ error_exit:;
+    APPL_TRACE_ERROR("%s unable to start up media thread", __func__);
+    
+    if (xBtifMediaTaskHandle != NULL) {
+        vTaskDelete(xBtifMediaTaskHandle);
+        xBtifMediaTaskHandle = NULL;
+    }
+
+    if (xBtifMediaQueue != 0) {
+        vQueueDelete(xBtifMediaQueue);
+        xBtifMediaQueue = 0;
+    }
+    fixed_queue_free(btif_media_cmd_msg_queue, NULL);
+    btif_media_cmd_msg_queue = NULL;
+    return false;
+}
+
+void btif_a2dp_stop_media_task(void)
+{
+    APPL_TRACE_EVENT("## A2DP STOP MEDIA THREAD ##");
+
+    // Stop timer
+    osi_alarm_free(btif_media_cb.media_alarm);
+    btif_media_cb.media_alarm = NULL;
+    btif_media_cb.is_tx_timer = FALSE;
+
+    // Exit thread
+    btif_media_task_post(SIG_MEDIA_TASK_CLEAN_UP);
+    vTaskDelete(xBtifMediaTaskHandle);
+    xBtifMediaTaskHandle = NULL;
+    vQueueDelete(xBtifMediaQueue);
+    xBtifMediaQueue = NULL;
+
+    fixed_queue_free(btif_media_cmd_msg_queue, NULL);
+    btif_media_cmd_msg_queue = NULL;
+}
+
+/*****************************************************************************
+**
+** Function        btif_a2dp_on_init
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+
+void btif_a2dp_on_init(void)
+{
+    //tput_mon(1, 0, 1);
+}
+
+
+/*****************************************************************************
+**
+** Function        btif_a2dp_setup_codec
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+
+void btif_a2dp_setup_codec(void)
+{
+    tBTIF_AV_MEDIA_FEEDINGS media_feeding;
+    tBTIF_STATUS status;
+
+    APPL_TRACE_EVENT("## A2DP SETUP CODEC ##");
+
+    GKI_disable();
+
+    /* for now hardcode 44.1 khz 16 bit stereo PCM format */
+    media_feeding.cfg.pcm.sampling_freq = 44100;
+    media_feeding.cfg.pcm.bit_per_sample = 16;
+    media_feeding.cfg.pcm.num_channel = 2;
+    media_feeding.format = BTIF_AV_CODEC_PCM;
+
+    if (bta_av_co_audio_set_codec(&media_feeding, &status))
+    {
+        tBTIF_MEDIA_INIT_AUDIO_FEEDING mfeed;
+
+        /* Init the encoding task */
+        btif_a2dp_encoder_init();
+
+        /* Build the media task configuration */
+        mfeed.feeding = media_feeding;
+        mfeed.feeding_mode = BTIF_AV_FEEDING_ASYNCHRONOUS;
+        /* Send message to Media task to configure transcoding */
+        btif_media_task_audio_feeding_init_req(&mfeed);
+    }
+
+    GKI_enable();
+}
+
+
+/*****************************************************************************
+**
+** Function        btif_a2dp_on_idle
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+
+void btif_a2dp_on_idle(void)
+{
+    APPL_TRACE_EVENT("## ON A2DP IDLE ##");
+    if (btif_media_cb.peer_sep == AVDT_TSEP_SNK)
+    {
+        /* Make sure media task is stopped */
+        btif_media_task_stop_aa_req();
+    }
+
+    bta_av_co_init();
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+    if (btif_media_cb.peer_sep == AVDT_TSEP_SRC)
+    {
+        btif_media_cb.rx_flush = TRUE;
+        btif_media_task_aa_rx_flush_req();
+        btif_media_task_aa_handle_stop_decoding();
+        btif_media_task_clear_track();
+        APPL_TRACE_DEBUG("Stopped BT track");
+    }
+#endif
+}
+
+/*****************************************************************************
+**
+** Function        btif_a2dp_on_open
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+
+void btif_a2dp_on_open(void)
+{
+    APPL_TRACE_EVENT("## ON A2DP OPEN ##");
+
+    /* always use callback to notify socket events */
+    UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_clear_track
+ **
+ ** Description
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+BOOLEAN btif_media_task_clear_track(void)
+{
+    BT_HDR *p_buf;
+
+    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
+    {
+        return FALSE;
+    }
+
+    p_buf->event = BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK;
+
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    return TRUE;
+}
+
+/*****************************************************************************
+**
+** Function        btif_reset_decoder
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+
+void btif_reset_decoder(UINT8 *p_av)
+{
+    APPL_TRACE_EVENT("btif_reset_decoder");
+    APPL_TRACE_DEBUG("btif_reset_decoder p_codec_info[%x:%x:%x:%x:%x:%x]",
+            p_av[1], p_av[2], p_av[3],
+            p_av[4], p_av[5], p_av[6]);
+
+    tBTIF_MEDIA_SINK_CFG_UPDATE *p_buf;
+    if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_SINK_CFG_UPDATE))))
+    {
+        APPL_TRACE_EVENT("btif_reset_decoder No Buffer ");
+        return;
+    }
+
+    memcpy(p_buf->codec_info,p_av, AVDT_CODEC_SIZE);
+    p_buf->hdr.event = BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE;
+
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+}
+
+/*****************************************************************************
+**
+** Function        btif_a2dp_on_started
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+
+BOOLEAN btif_a2dp_on_started(tBTA_AV_START *p_av, BOOLEAN pending_start)
+{
+    BOOLEAN ack = FALSE;
+
+    APPL_TRACE_EVENT("## ON A2DP STARTED ##");
+
+    if (p_av == NULL)
+    {
+        /* ack back a local start request */
+        a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+        return TRUE;
+    }
+
+    if (p_av->status == BTA_AV_SUCCESS)
+    {
+        if (p_av->suspending == FALSE)
+        {
+            if (p_av->initiator)
+            {
+                if (pending_start) {
+                    a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+                    ack = TRUE;
+                }
+            }
+            else
+            {
+                /* we were remotely started,  make sure codec
+                   is setup before datapath is started */
+                btif_a2dp_setup_codec();
+            }
+
+            /* media task is autostarted upon a2dp audiopath connection */
+        }
+    }
+    else if (pending_start)
+    {
+        a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
+        ack = TRUE;
+    }
+    return ack;
+}
+
+
+/*****************************************************************************
+**
+** Function        btif_a2dp_ack_fail
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+
+void btif_a2dp_ack_fail(void)
+{
+    APPL_TRACE_EVENT("## A2DP_CTRL_ACK_FAILURE ##");
+    a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
+}
+
+/*****************************************************************************
+**
+** Function        btif_a2dp_on_stopped
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+
+void btif_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av)
+{
+    APPL_TRACE_EVENT("## ON A2DP STOPPED ##");
+    if (btif_media_cb.peer_sep == AVDT_TSEP_SRC) /*  Handling for A2DP SINK cases*/
+    {
+        btif_media_cb.rx_flush = TRUE;
+        btif_media_task_aa_rx_flush_req();
+        btif_media_task_aa_handle_stop_decoding();
+        UIPC_Close(UIPC_CH_ID_AV_AUDIO);
+        btif_media_cb.data_channel_open = FALSE;
+        return;
+    }
+    /* allow using this api for other than suspend */
+    if (p_av != NULL)
+    {
+        if (p_av->status != BTA_AV_SUCCESS)
+        {
+            APPL_TRACE_EVENT("AV STOP FAILED (%d)", p_av->status);
+
+            if (p_av->initiator)
+                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
+            return;
+        }
+    }
+
+    /* ensure tx frames are immediately suspended */
+    btif_media_cb.tx_flush = 1;
+
+    /* request to stop media task  */
+    btif_media_task_aa_tx_flush_req();
+    btif_media_task_stop_aa_req();
+
+    /* once stream is fully stopped we will ack back */
+}
+
+
+/*****************************************************************************
+**
+** Function        btif_a2dp_on_suspended
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+
+void btif_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av)
+{
+    APPL_TRACE_EVENT("## ON A2DP SUSPENDED ##");
+    if (btif_media_cb.peer_sep == AVDT_TSEP_SRC)
+    {
+        btif_media_cb.rx_flush = TRUE;
+        btif_media_task_aa_rx_flush_req();
+        btif_media_task_aa_handle_stop_decoding();
+        return;
+    }
+
+    /* check for status failures */
+    if (p_av->status != BTA_AV_SUCCESS)
+    {
+        if (p_av->initiator == TRUE)
+            a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
+    }
+
+    /* once stream is fully stopped we will ack back */
+
+    /* ensure tx frames are immediately flushed */
+    btif_media_cb.tx_flush = 1;
+
+    /* stop timer tick */
+    btif_media_task_stop_aa_req();
+}
+
+/* when true media task discards any rx frames */
+void btif_a2dp_set_rx_flush(BOOLEAN enable)
+{
+    APPL_TRACE_EVENT("## DROP RX %d ##", enable);
+    btif_media_cb.rx_flush = enable;
+}
+
+/* when true media task discards any tx frames */
+void btif_a2dp_set_tx_flush(BOOLEAN enable)
+{
+    APPL_TRACE_EVENT("## DROP TX %d ##", enable);
+    btif_media_cb.tx_flush = enable;
+}
+
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+static void btif_media_task_avk_handle_timer(UNUSED_ATTR void *context)
+{
+    UINT8 count;
+    tBT_SBC_HDR *p_msg;
+    int num_sbc_frames;
+    int num_frames_to_process;
+
+    count = btif_media_cb.RxSbcQ._count;
+    if (0 == count)
+    {
+        APPL_TRACE_DEBUG("  QUE  EMPTY ");
+    }
+    else
+    {
+        if (btif_media_cb.rx_flush == TRUE)
+        {
+            btif_media_flush_q(&(btif_media_cb.RxSbcQ));
+            return;
+        }
+
+        num_frames_to_process = btif_media_cb.frames_to_process;
+        APPL_TRACE_DEBUG(" Process Frames + ");
+
+        do
+        {
+            p_msg = (tBT_SBC_HDR *)GKI_getfirst(&(btif_media_cb.RxSbcQ));
+            if (p_msg == NULL)
+                return;
+            num_sbc_frames  = p_msg->num_frames_to_be_processed; /* num of frames in Que Packets */
+            APPL_TRACE_DEBUG(" Frames left in topmost packet %d", num_sbc_frames);
+            APPL_TRACE_DEBUG(" Remaining frames to process in tick %d", num_frames_to_process);
+            APPL_TRACE_DEBUG(" Num of Packets in Que %d", btif_media_cb.RxSbcQ._count);
+
+            if ( num_sbc_frames > num_frames_to_process) /*  Que Packet has more frames*/
+            {
+                 p_msg->num_frames_to_be_processed= num_frames_to_process;
+                 btif_media_task_handle_inc_media(p_msg);
+                 p_msg->num_frames_to_be_processed = num_sbc_frames - num_frames_to_process;
+                 num_frames_to_process = 0;
+                 break;
+            }
+            else                                        /*  Que packet has less frames */
+            {
+                btif_media_task_handle_inc_media(p_msg);
+                p_msg = (tBT_SBC_HDR *)GKI_dequeue(&(btif_media_cb.RxSbcQ));
+                if( p_msg == NULL )
+                {
+                     APPL_TRACE_ERROR("Insufficient data in que ");
+                     break;
+                }
+                num_frames_to_process = num_frames_to_process - p_msg->num_frames_to_be_processed;
+                GKI_freebuf(p_msg);
+            }
+        }while(num_frames_to_process > 0);
+
+        APPL_TRACE_DEBUG(" Process Frames - ");
+    }
+}
+#else
+static void btif_media_task_avk_handle_timer(UNUSED_ATTR void *context) {}
+#endif
+
+static void btif_media_task_aa_handle_timer(UNUSED_ATTR void *context)
+{
+    log_tstamps_us("media task tx timer");
+
+#if (BTA_AV_INCLUDED == TRUE)
+    if(btif_media_cb.is_tx_timer == TRUE)
+    {
+        btif_media_send_aa_frame();
+    }
+    else
+    {
+        APPL_TRACE_ERROR("ERROR Media task Scheduled after Suspend");
+    }
+#endif
+}
+
+#if (BTA_AV_INCLUDED == TRUE)
+static void btif_media_task_aa_handle_uipc_rx_rdy(void)
+{
+    /* process all the UIPC data */
+    btif_media_aa_prep_2_send(0xFF);
+
+    /* send it */
+    LOG_VERBOSE("btif_media_task_aa_handle_uipc_rx_rdy calls bta_av_ci_src_data_ready");
+    bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
+}
+#endif
+
+static void btif_media_thread_init(UNUSED_ATTR void *context) {
+  memset(&btif_media_cb, 0, sizeof(btif_media_cb));
+  UIPC_Init(NULL);
+
+#if (BTA_AV_INCLUDED == TRUE)
+  UIPC_Open(UIPC_CH_ID_AV_CTRL , btif_a2dp_ctrl_cb);
+#endif
+
+  raise_priority_a2dp(TASK_HIGH_MEDIA);
+  media_task_running = MEDIA_TASK_STATE_ON;
+}
+
+static void btif_media_thread_cleanup(UNUSED_ATTR void *context) {
+  /* make sure no channels are restarted while shutting down */
+  media_task_running = MEDIA_TASK_STATE_SHUTTING_DOWN;
+
+  /* this calls blocks until uipc is fully closed */
+  UIPC_Close(UIPC_CH_ID_ALL);
+
+  /* Clear media task flag */
+  media_task_running = MEDIA_TASK_STATE_OFF;
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_send_cmd_evt
+ **
+ ** Description
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+BOOLEAN btif_media_task_send_cmd_evt(UINT16 Evt)
+{
+    BT_HDR *p_buf;
+    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
+    {
+        return FALSE;
+    }
+
+    p_buf->event = Evt;
+
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    return TRUE;
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_flush_q
+ **
+ ** Description
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+static void btif_media_flush_q(BUFFER_Q *p_q)
+{
+    while (!GKI_queue_is_empty(p_q))
+    {
+        GKI_freebuf(GKI_dequeue(p_q));
+    }
+}
+
+static void btif_media_thread_handle_cmd(fixed_queue_t *queue)
+{
+    BT_HDR *p_msg;
+    while (!fixed_queue_is_empty(queue)) {
+        p_msg = (BT_HDR *)fixed_queue_dequeue(queue);
+        LOG_VERBOSE("btif_media_thread_handle_cmd : %d %s", p_msg->event,
+                    dump_media_event(p_msg->event));
+
+        switch (p_msg->event)
+            {
+#if (BTA_AV_INCLUDED == TRUE)
+            case BTIF_MEDIA_START_AA_TX:
+                btif_media_task_aa_start_tx();
+                break;
+            case BTIF_MEDIA_STOP_AA_TX:
+                btif_media_task_aa_stop_tx();
+                break;
+            case BTIF_MEDIA_SBC_ENC_INIT:
+                btif_media_task_enc_init(p_msg);
+                break;
+            case BTIF_MEDIA_SBC_ENC_UPDATE:
+                btif_media_task_enc_update(p_msg);
+                break;
+            case BTIF_MEDIA_AUDIO_FEEDING_INIT:
+                btif_media_task_audio_feeding_init(p_msg);
+                break;
+            case BTIF_MEDIA_FLUSH_AA_TX:
+                btif_media_task_aa_tx_flush(p_msg);
+                break;
+            case BTIF_MEDIA_UIPC_RX_RDY:
+                btif_media_task_aa_handle_uipc_rx_rdy();
+                break;
+            case BTIF_MEDIA_AUDIO_SINK_CFG_UPDATE:
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+                btif_media_task_aa_handle_decoder_reset(p_msg);
+#endif
+                break;
+            case BTIF_MEDIA_AUDIO_SINK_CLEAR_TRACK:
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+                btif_media_task_aa_handle_clear_track();
+#endif
+                break;
+            case BTIF_MEDIA_FLUSH_AA_RX:
+                btif_media_task_aa_rx_flush();
+                break;
+#endif
+            default:
+                APPL_TRACE_ERROR("ERROR in %s unknown event %d", __func__, p_msg->event);
+            }
+        GKI_freebuf(p_msg);
+        LOG_VERBOSE("%s: %s DONE", __func__, dump_media_event(p_msg->event));
+    }
+}
+
+
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_handle_inc_media
+ **
+ ** Description
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+static void btif_media_task_handle_inc_media(tBT_SBC_HDR*p_msg)
+{
+    UINT8 *sbc_start_frame = ((UINT8*)(p_msg + 1) + p_msg->offset + 1);
+    int count;
+    UINT32 pcmBytes, availPcmBytes;
+    OI_INT16 *pcmDataPointer = pcmData; /*Will be overwritten on next packet receipt*/
+    OI_STATUS status;
+    int num_sbc_frames = p_msg->num_frames_to_be_processed;
+    UINT32 sbc_frame_len = p_msg->len - 1;
+    availPcmBytes = 2*sizeof(pcmData);
+
+    if ((btif_media_cb.peer_sep == AVDT_TSEP_SNK) || (btif_media_cb.rx_flush))
+    {
+        APPL_TRACE_DEBUG(" State Changed happened in this tick ");
+        return;
+    }
+
+    // ignore data if no one is listening
+    if (!btif_media_cb.data_channel_open)
+        return;
+
+    APPL_TRACE_DEBUG("Number of sbc frames %d, frame_len %d", num_sbc_frames, sbc_frame_len);
+
+    for(count = 0; count < num_sbc_frames && sbc_frame_len != 0; count ++)
+    {
+        pcmBytes = availPcmBytes;
+        status = OI_CODEC_SBC_DecodeFrame(&context, (const OI_BYTE**)&sbc_start_frame,
+                                                        (OI_UINT32 *)&sbc_frame_len,
+                                                        (OI_INT16 *)pcmDataPointer,
+                                                        (OI_UINT32 *)&pcmBytes);
+        if (!OI_SUCCESS(status)) {
+            APPL_TRACE_ERROR("Decoding failure: %d\n", status);
+            break;
+        }
+        availPcmBytes -= pcmBytes;
+        pcmDataPointer += pcmBytes/2;
+        p_msg->offset += (p_msg->len - 1) - sbc_frame_len;
+        p_msg->len = sbc_frame_len + 1;
+    }
+
+    UIPC_Send(UIPC_CH_ID_AV_AUDIO, 0, (UINT8 *)pcmData, (2*sizeof(pcmData) - availPcmBytes));
+}
+#endif
+
+#if (BTA_AV_INCLUDED == TRUE)
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_enc_init_req
+ **
+ ** Description
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+BOOLEAN btif_media_task_enc_init_req(tBTIF_MEDIA_INIT_AUDIO *p_msg)
+{
+    tBTIF_MEDIA_INIT_AUDIO *p_buf;
+    if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_INIT_AUDIO))))
+    {
+        return FALSE;
+    }
+
+    memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_INIT_AUDIO));
+    p_buf->hdr.event = BTIF_MEDIA_SBC_ENC_INIT;
+
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    return TRUE;
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_enc_update_req
+ **
+ ** Description
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+BOOLEAN btif_media_task_enc_update_req(tBTIF_MEDIA_UPDATE_AUDIO *p_msg)
+{
+    tBTIF_MEDIA_UPDATE_AUDIO *p_buf;
+    if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_UPDATE_AUDIO))))
+    {
+        return FALSE;
+    }
+
+    memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_UPDATE_AUDIO));
+    p_buf->hdr.event = BTIF_MEDIA_SBC_ENC_UPDATE;
+
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    return TRUE;
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_audio_feeding_init_req
+ **
+ ** Description
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+BOOLEAN btif_media_task_audio_feeding_init_req(tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_msg)
+{
+    tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_buf;
+    if (NULL == (p_buf = GKI_getbuf(sizeof(tBTIF_MEDIA_INIT_AUDIO_FEEDING))))
+    {
+        return FALSE;
+    }
+
+    memcpy(p_buf, p_msg, sizeof(tBTIF_MEDIA_INIT_AUDIO_FEEDING));
+    p_buf->hdr.event = BTIF_MEDIA_AUDIO_FEEDING_INIT;
+
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    return TRUE;
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_start_aa_req
+ **
+ ** Description
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+BOOLEAN btif_media_task_start_aa_req(void)
+{
+    BT_HDR *p_buf;
+    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
+    {
+        APPL_TRACE_EVENT("GKI failed");
+        return FALSE;
+    }
+
+    p_buf->event = BTIF_MEDIA_START_AA_TX;
+
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    return TRUE;
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_stop_aa_req
+ **
+ ** Description
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+BOOLEAN btif_media_task_stop_aa_req(void)
+{
+    BT_HDR *p_buf;
+    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
+    {
+        return FALSE;
+    }
+
+    p_buf->event = BTIF_MEDIA_STOP_AA_TX;
+
+    /*
+     * Explicitly check whether the btif_media_cmd_msg_queue is not NULL to
+     * avoid a race condition during shutdown of the Bluetooth stack.
+     * This race condition is triggered when A2DP audio is streaming on
+     * shutdown:
+     * "btif_a2dp_on_stopped() -> btif_media_task_stop_aa_req()" is called
+     * to stop the particular audio stream, and this happens right after
+     * the "cleanup() -> btif_a2dp_stop_media_task()" processing during
+     * the shutdown of the Bluetooth stack.
+     */
+    if (btif_media_cmd_msg_queue != NULL)
+        fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+
+    return TRUE;
+}
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_aa_rx_flush_req
+ **
+ ** Description
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+BOOLEAN btif_media_task_aa_rx_flush_req(void)
+{
+    BT_HDR *p_buf;
+
+    if (GKI_queue_is_empty(&(btif_media_cb.RxSbcQ))== TRUE) /*  Que is already empty */
+        return TRUE;
+
+    if (NULL == (p_buf = GKI_getbuf(sizeof(BT_HDR))))
+    {
+        return FALSE;
+    }
+
+    p_buf->event = BTIF_MEDIA_FLUSH_AA_RX;
+
+    fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+    return TRUE;
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_aa_tx_flush_req
+ **
+ ** Description
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+BOOLEAN btif_media_task_aa_tx_flush_req(void)
+{
+    BT_HDR *p_buf = GKI_getbuf(sizeof(BT_HDR));
+
+    if (p_buf == NULL)
+        return FALSE;
+
+    p_buf->event = BTIF_MEDIA_FLUSH_AA_TX;
+
+    /*
+     * Explicitly check whether the btif_media_cmd_msg_queue is not NULL to
+     * avoid a race condition during shutdown of the Bluetooth stack.
+     * This race condition is triggered when A2DP audio is streaming on
+     * shutdown:
+     * "btif_a2dp_on_stopped() -> btif_media_task_aa_tx_flush_req()" is called
+     * to stop the particular audio stream, and this happens right after
+     * the "cleanup() -> btif_a2dp_stop_media_task()" processing during
+     * the shutdown of the Bluetooth stack.
+     */
+    if (btif_media_cmd_msg_queue != NULL)
+        fixed_queue_enqueue(btif_media_cmd_msg_queue, p_buf);
+
+    return TRUE;
+}
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_aa_rx_flush
+ **
+ ** Description
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+static void btif_media_task_aa_rx_flush(void)
+{
+    /* Flush all enqueued GKI SBC  buffers (encoded) */
+    APPL_TRACE_DEBUG("btif_media_task_aa_rx_flush");
+
+    btif_media_flush_q(&(btif_media_cb.RxSbcQ));
+}
+
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_aa_tx_flush
+ **
+ ** Description
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+static void btif_media_task_aa_tx_flush(BT_HDR *p_msg)
+{
+    UNUSED(p_msg);
+
+    /* Flush all enqueued GKI music buffers (encoded) */
+    APPL_TRACE_DEBUG("btif_media_task_aa_tx_flush");
+
+    btif_media_cb.media_feeding_state.pcm.counter = 0;
+    btif_media_cb.media_feeding_state.pcm.aa_feed_residue = 0;
+
+    btif_media_flush_q(&(btif_media_cb.TxAaQ));
+
+    UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REQ_RX_FLUSH, NULL);
+}
+
+/*******************************************************************************
+ **
+ ** Function       btif_media_task_enc_init
+ **
+ ** Description    Initialize encoding task
+ **
+ ** Returns        void
+ **
+ *******************************************************************************/
+static void btif_media_task_enc_init(BT_HDR *p_msg)
+{
+    tBTIF_MEDIA_INIT_AUDIO *pInitAudio = (tBTIF_MEDIA_INIT_AUDIO *) p_msg;
+
+    APPL_TRACE_DEBUG("btif_media_task_enc_init");
+
+    btif_media_cb.timestamp = 0;
+
+    /* SBC encoder config (enforced even if not used) */
+    btif_media_cb.encoder.s16ChannelMode = pInitAudio->ChannelMode;
+    btif_media_cb.encoder.s16NumOfSubBands = pInitAudio->NumOfSubBands;
+    btif_media_cb.encoder.s16NumOfBlocks = pInitAudio->NumOfBlocks;
+    btif_media_cb.encoder.s16AllocationMethod = pInitAudio->AllocationMethod;
+    btif_media_cb.encoder.s16SamplingFreq = pInitAudio->SamplingFreq;
+
+    btif_media_cb.encoder.u16BitRate = btif_media_task_get_sbc_rate();
+
+    /* Default transcoding is PCM to SBC, modified by feeding configuration */
+    btif_media_cb.TxTranscoding = BTIF_MEDIA_TRSCD_PCM_2_SBC;
+    btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE-BTIF_MEDIA_AA_SBC_OFFSET-sizeof(BT_HDR))
+            < pInitAudio->MtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET
+            - sizeof(BT_HDR)) : pInitAudio->MtuSize;
+
+    APPL_TRACE_EVENT("btif_media_task_enc_init busy %d, mtu %d, peer mtu %d",
+                     btif_media_cb.busy_level, btif_media_cb.TxAaMtuSize, pInitAudio->MtuSize);
+    APPL_TRACE_EVENT("      ch mode %d, subnd %d, nb blk %d, alloc %d, rate %d, freq %d",
+            btif_media_cb.encoder.s16ChannelMode, btif_media_cb.encoder.s16NumOfSubBands,
+            btif_media_cb.encoder.s16NumOfBlocks,
+            btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate,
+            btif_media_cb.encoder.s16SamplingFreq);
+
+    /* Reset entirely the SBC encoder */
+    SBC_Encoder_Init(&(btif_media_cb.encoder));
+    APPL_TRACE_DEBUG("btif_media_task_enc_init bit pool %d", btif_media_cb.encoder.s16BitPool);
+}
+
+/*******************************************************************************
+ **
+ ** Function       btif_media_task_enc_update
+ **
+ ** Description    Update encoding task
+ **
+ ** Returns        void
+ **
+ *******************************************************************************/
+
+static void btif_media_task_enc_update(BT_HDR *p_msg)
+{
+    tBTIF_MEDIA_UPDATE_AUDIO * pUpdateAudio = (tBTIF_MEDIA_UPDATE_AUDIO *) p_msg;
+    SBC_ENC_PARAMS *pstrEncParams = &btif_media_cb.encoder;
+    UINT16 s16SamplingFreq;
+    SINT16 s16BitPool = 0;
+    SINT16 s16BitRate;
+    SINT16 s16FrameLen;
+    UINT8 protect = 0;
+
+    APPL_TRACE_DEBUG("btif_media_task_enc_update : minmtu %d, maxbp %d minbp %d",
+            pUpdateAudio->MinMtuSize, pUpdateAudio->MaxBitPool, pUpdateAudio->MinBitPool);
+
+    /* Only update the bitrate and MTU size while timer is running to make sure it has been initialized */
+    //if (btif_media_cb.is_tx_timer)
+    {
+        btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE -
+                                      BTIF_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR))
+                < pUpdateAudio->MinMtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET
+                - sizeof(BT_HDR)) : pUpdateAudio->MinMtuSize;
+
+        /* Set the initial target bit rate */
+        pstrEncParams->u16BitRate = btif_media_task_get_sbc_rate();
+
+        if (pstrEncParams->s16SamplingFreq == SBC_sf16000)
+            s16SamplingFreq = 16000;
+        else if (pstrEncParams->s16SamplingFreq == SBC_sf32000)
+            s16SamplingFreq = 32000;
+        else if (pstrEncParams->s16SamplingFreq == SBC_sf44100)
+            s16SamplingFreq = 44100;
+        else
+            s16SamplingFreq = 48000;
+
+        do
+        {
+            if (pstrEncParams->s16NumOfBlocks == 0 || pstrEncParams->s16NumOfSubBands == 0
+                || pstrEncParams->s16NumOfChannels == 0)
+            {
+                APPL_TRACE_ERROR("btif_media_task_enc_update() - Avoiding division by zero...");
+                APPL_TRACE_ERROR("btif_media_task_enc_update() - block=%d, subBands=%d, channels=%d",
+                    pstrEncParams->s16NumOfBlocks, pstrEncParams->s16NumOfSubBands,
+                    pstrEncParams->s16NumOfChannels);
+                break;
+            }
+
+            if ((pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) ||
+                (pstrEncParams->s16ChannelMode == SBC_STEREO) )
+            {
+                s16BitPool = (SINT16)( (pstrEncParams->u16BitRate *
+                    pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq)
+                    -( (32 + (4 * pstrEncParams->s16NumOfSubBands *
+                    pstrEncParams->s16NumOfChannels)
+                    + ( (pstrEncParams->s16ChannelMode - 2) *
+                    pstrEncParams->s16NumOfSubBands )   )
+                    / pstrEncParams->s16NumOfBlocks) );
+
+                s16FrameLen = 4 + (4*pstrEncParams->s16NumOfSubBands*
+                    pstrEncParams->s16NumOfChannels)/8
+                    + ( ((pstrEncParams->s16ChannelMode - 2) *
+                    pstrEncParams->s16NumOfSubBands)
+                    + (pstrEncParams->s16NumOfBlocks * s16BitPool) ) / 8;
+
+                s16BitRate = (8 * s16FrameLen * s16SamplingFreq)
+                    / (pstrEncParams->s16NumOfSubBands *
+                    pstrEncParams->s16NumOfBlocks * 1000);
+
+                if (s16BitRate > pstrEncParams->u16BitRate)
+                    s16BitPool--;
+
+                if(pstrEncParams->s16NumOfSubBands == 8)
+                    s16BitPool = (s16BitPool > 255) ? 255 : s16BitPool;
+                else
+                    s16BitPool = (s16BitPool > 128) ? 128 : s16BitPool;
+            }
+            else
+            {
+                s16BitPool = (SINT16)( ((pstrEncParams->s16NumOfSubBands *
+                    pstrEncParams->u16BitRate * 1000)
+                    / (s16SamplingFreq * pstrEncParams->s16NumOfChannels))
+                    -( ( (32 / pstrEncParams->s16NumOfChannels) +
+                    (4 * pstrEncParams->s16NumOfSubBands) )
+                    /   pstrEncParams->s16NumOfBlocks ) );
+
+                pstrEncParams->s16BitPool = (s16BitPool >
+                    (16 * pstrEncParams->s16NumOfSubBands))
+                    ? (16*pstrEncParams->s16NumOfSubBands) : s16BitPool;
+            }
+
+            if (s16BitPool < 0)
+            {
+                s16BitPool = 0;
+            }
+
+            APPL_TRACE_EVENT("bitpool candidate : %d (%d kbps)",
+                         s16BitPool, pstrEncParams->u16BitRate);
+
+            if (s16BitPool > pUpdateAudio->MaxBitPool)
+            {
+                APPL_TRACE_DEBUG("btif_media_task_enc_update computed bitpool too large (%d)",
+                                    s16BitPool);
+                /* Decrease bitrate */
+                btif_media_cb.encoder.u16BitRate -= BTIF_MEDIA_BITRATE_STEP;
+                /* Record that we have decreased the bitrate */
+                protect |= 1;
+            }
+            else if (s16BitPool < pUpdateAudio->MinBitPool)
+            {
+                APPL_TRACE_WARNING("btif_media_task_enc_update computed bitpool too small (%d)", s16BitPool);
+
+                /* Increase bitrate */
+                UINT16 previous_u16BitRate = btif_media_cb.encoder.u16BitRate;
+                btif_media_cb.encoder.u16BitRate += BTIF_MEDIA_BITRATE_STEP;
+                /* Record that we have increased the bitrate */
+                protect |= 2;
+                /* Check over-flow */
+                if (btif_media_cb.encoder.u16BitRate < previous_u16BitRate)
+                    protect |= 3;
+            }
+            else
+            {
+                break;
+            }
+            /* In case we have already increased and decreased the bitrate, just stop */
+            if (protect == 3)
+            {
+                APPL_TRACE_ERROR("btif_media_task_enc_update could not find bitpool in range");
+                break;
+            }
+        } while (1);
+
+        /* Finally update the bitpool in the encoder structure */
+        pstrEncParams->s16BitPool = s16BitPool;
+
+        APPL_TRACE_DEBUG("btif_media_task_enc_update final bit rate %d, final bit pool %d",
+                btif_media_cb.encoder.u16BitRate, btif_media_cb.encoder.s16BitPool);
+
+        /* make sure we reinitialize encoder with new settings */
+        SBC_Encoder_Init(&(btif_media_cb.encoder));
+    }
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_pcm2sbc_init
+ **
+ ** Description      Init encoding task for PCM to SBC according to feeding
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+static void btif_media_task_pcm2sbc_init(tBTIF_MEDIA_INIT_AUDIO_FEEDING * p_feeding)
+{
+    BOOLEAN reconfig_needed = FALSE;
+
+    APPL_TRACE_DEBUG("PCM feeding:");
+    APPL_TRACE_DEBUG("sampling_freq:%d", p_feeding->feeding.cfg.pcm.sampling_freq);
+    APPL_TRACE_DEBUG("num_channel:%d", p_feeding->feeding.cfg.pcm.num_channel);
+    APPL_TRACE_DEBUG("bit_per_sample:%d", p_feeding->feeding.cfg.pcm.bit_per_sample);
+
+    /* Check the PCM feeding sampling_freq */
+    switch (p_feeding->feeding.cfg.pcm.sampling_freq)
+    {
+        case  8000:
+        case 12000:
+        case 16000:
+        case 24000:
+        case 32000:
+        case 48000:
+            /* For these sampling_freq the AV connection must be 48000 */
+            if (btif_media_cb.encoder.s16SamplingFreq != SBC_sf48000)
+            {
+                /* Reconfiguration needed at 48000 */
+                APPL_TRACE_DEBUG("SBC Reconfiguration needed at 48000");
+                btif_media_cb.encoder.s16SamplingFreq = SBC_sf48000;
+                reconfig_needed = TRUE;
+            }
+            break;
+
+        case 11025:
+        case 22050:
+        case 44100:
+            /* For these sampling_freq the AV connection must be 44100 */
+            if (btif_media_cb.encoder.s16SamplingFreq != SBC_sf44100)
+            {
+                /* Reconfiguration needed at 44100 */
+                APPL_TRACE_DEBUG("SBC Reconfiguration needed at 44100");
+                btif_media_cb.encoder.s16SamplingFreq = SBC_sf44100;
+                reconfig_needed = TRUE;
+            }
+            break;
+        default:
+            APPL_TRACE_DEBUG("Feeding PCM sampling_freq unsupported");
+            break;
+    }
+
+    /* Some AV Headsets do not support Mono => always ask for Stereo */
+    if (btif_media_cb.encoder.s16ChannelMode == SBC_MONO)
+    {
+        APPL_TRACE_DEBUG("SBC Reconfiguration needed in Stereo");
+        btif_media_cb.encoder.s16ChannelMode = SBC_JOINT_STEREO;
+        reconfig_needed = TRUE;
+    }
+
+    if (reconfig_needed != FALSE)
+    {
+        APPL_TRACE_DEBUG("btif_media_task_pcm2sbc_init :: mtu %d", btif_media_cb.TxAaMtuSize);
+        APPL_TRACE_DEBUG("ch mode %d, nbsubd %d, nb %d, alloc %d, rate %d, freq %d",
+                btif_media_cb.encoder.s16ChannelMode,
+                btif_media_cb.encoder.s16NumOfSubBands, btif_media_cb.encoder.s16NumOfBlocks,
+                btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate,
+                btif_media_cb.encoder.s16SamplingFreq);
+
+        SBC_Encoder_Init(&(btif_media_cb.encoder));
+    }
+    else
+    {
+        APPL_TRACE_DEBUG("btif_media_task_pcm2sbc_init no SBC reconfig needed");
+    }
+}
+
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_audio_feeding_init
+ **
+ ** Description      Initialize the audio path according to the feeding format
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+static void btif_media_task_audio_feeding_init(BT_HDR *p_msg)
+{
+    tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_feeding = (tBTIF_MEDIA_INIT_AUDIO_FEEDING *) p_msg;
+
+    APPL_TRACE_DEBUG("btif_media_task_audio_feeding_init format:%d", p_feeding->feeding.format);
+
+    /* Save Media Feeding information */
+    btif_media_cb.feeding_mode = p_feeding->feeding_mode;
+    btif_media_cb.media_feeding = p_feeding->feeding;
+
+    /* Handle different feeding formats */
+    switch (p_feeding->feeding.format)
+    {
+        case BTIF_AV_CODEC_PCM:
+            btif_media_cb.TxTranscoding = BTIF_MEDIA_TRSCD_PCM_2_SBC;
+            btif_media_task_pcm2sbc_init(p_feeding);
+            break;
+
+        default :
+            APPL_TRACE_ERROR("unknown feeding format %d", p_feeding->feeding.format);
+            break;
+    }
+}
+
+int btif_a2dp_get_track_frequency(UINT8 frequency) {
+    int freq = 48000;
+    switch (frequency) {
+        case A2D_SBC_IE_SAMP_FREQ_16:
+            freq = 16000;
+            break;
+        case A2D_SBC_IE_SAMP_FREQ_32:
+            freq = 32000;
+            break;
+        case A2D_SBC_IE_SAMP_FREQ_44:
+            freq = 44100;
+            break;
+        case A2D_SBC_IE_SAMP_FREQ_48:
+            freq = 48000;
+            break;
+    }
+    return freq;
+}
+
+int btif_a2dp_get_track_channel_count(UINT8 channeltype) {
+    int count = 1;
+    switch (channeltype) {
+        case A2D_SBC_IE_CH_MD_MONO:
+            count = 1;
+            break;
+        case A2D_SBC_IE_CH_MD_DUAL:
+        case A2D_SBC_IE_CH_MD_STEREO:
+        case A2D_SBC_IE_CH_MD_JOINT:
+            count = 2;
+            break;
+    }
+    return count;
+}
+
+void btif_a2dp_set_peer_sep(UINT8 sep) {
+    btif_media_cb.peer_sep = sep;
+}
+
+static void btif_decode_alarm_cb(UNUSED_ATTR void *context) {
+#if 0
+    thread_post(worker_thread, btif_media_task_avk_handle_timer, NULL);
+#else
+    btif_media_task_post(SIG_MEDIA_TASK_AVK_ALARM_TO);
+    // TODO: btif_media_task_avk_handle_timer
+#endif
+}
+
+static void btif_media_task_aa_handle_stop_decoding(void) {
+  osi_alarm_free(btif_media_cb.decode_alarm);
+  btif_media_cb.decode_alarm = NULL;
+}
+
+static void btif_media_task_aa_handle_start_decoding(void) {
+  if (btif_media_cb.decode_alarm)
+    return;
+
+  btif_media_cb.decode_alarm = osi_alarm_new("dec_timer", btif_decode_alarm_cb, NULL, BTIF_SINK_MEDIA_TIME_TICK, true);
+  if (!btif_media_cb.decode_alarm) {
+    APPL_TRACE_ERROR("%s unable to allocate decode alarm.", __func__);
+    return;
+  }
+
+  osi_alarm_set(btif_media_cb.decode_alarm, BTIF_SINK_MEDIA_TIME_TICK);
+  // alarm_set_periodic(btif_media_cb.decode_alarm, BTIF_SINK_MEDIA_TIME_TICK, btif_decode_alarm_cb, NULL);
+}
+
+#if (BTA_AV_SINK_INCLUDED == TRUE)
+
+static void btif_media_task_aa_handle_clear_track (void)
+{
+    APPL_TRACE_DEBUG("btif_media_task_aa_handle_clear_track");
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_aa_handle_decoder_reset
+ **
+ ** Description
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+static void btif_media_task_aa_handle_decoder_reset(BT_HDR *p_msg)
+{
+    tBTIF_MEDIA_SINK_CFG_UPDATE *p_buf = (tBTIF_MEDIA_SINK_CFG_UPDATE*) p_msg;
+    tA2D_STATUS a2d_status;
+    tA2D_SBC_CIE sbc_cie;
+    OI_STATUS       status;
+    UINT32          freq_multiple = 48*20; /* frequency multiple for 20ms of data , initialize with 48K*/
+    UINT32          num_blocks = 16;
+    UINT32          num_subbands = 8;
+
+    APPL_TRACE_DEBUG("btif_media_task_aa_handle_decoder_reset p_codec_info[%x:%x:%x:%x:%x:%x]",
+            p_buf->codec_info[1], p_buf->codec_info[2], p_buf->codec_info[3],
+            p_buf->codec_info[4], p_buf->codec_info[5], p_buf->codec_info[6]);
+
+    a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_buf->codec_info, FALSE);
+    if (a2d_status != A2D_SUCCESS)
+    {
+        APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
+        return;
+    }
+
+    btif_media_cb.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
+    btif_media_cb.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
+
+    btif_media_cb.rx_flush = FALSE;
+    APPL_TRACE_DEBUG("Reset to sink role");
+    status = OI_CODEC_SBC_DecoderReset(&context, contextData, sizeof(contextData), 2, 2, FALSE);
+    if (!OI_SUCCESS(status)) {
+        APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
+    }
+
+    UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
+
+    switch(sbc_cie.samp_freq)
+    {
+        case A2D_SBC_IE_SAMP_FREQ_16:
+            APPL_TRACE_DEBUG("\tsamp_freq:%d (16000)", sbc_cie.samp_freq);
+            freq_multiple = 16*20;
+            break;
+        case A2D_SBC_IE_SAMP_FREQ_32:
+            APPL_TRACE_DEBUG("\tsamp_freq:%d (32000)", sbc_cie.samp_freq);
+            freq_multiple = 32*20;
+            break;
+        case A2D_SBC_IE_SAMP_FREQ_44:
+            APPL_TRACE_DEBUG("\tsamp_freq:%d (44100)", sbc_cie.samp_freq);
+            freq_multiple = 441*2;
+            break;
+        case A2D_SBC_IE_SAMP_FREQ_48:
+            APPL_TRACE_DEBUG("\tsamp_freq:%d (48000)", sbc_cie.samp_freq);
+            freq_multiple = 48*20;
+            break;
+        default:
+            APPL_TRACE_DEBUG(" Unknown Frequency ");
+            break;
+    }
+
+    switch(sbc_cie.ch_mode)
+    {
+        case A2D_SBC_IE_CH_MD_MONO:
+            APPL_TRACE_DEBUG("\tch_mode:%d (Mono)", sbc_cie.ch_mode);
+            break;
+        case A2D_SBC_IE_CH_MD_DUAL:
+            APPL_TRACE_DEBUG("\tch_mode:%d (DUAL)", sbc_cie.ch_mode);
+            break;
+        case A2D_SBC_IE_CH_MD_STEREO:
+            APPL_TRACE_DEBUG("\tch_mode:%d (STEREO)", sbc_cie.ch_mode);
+            break;
+        case A2D_SBC_IE_CH_MD_JOINT:
+            APPL_TRACE_DEBUG("\tch_mode:%d (JOINT)", sbc_cie.ch_mode);
+            break;
+        default:
+            APPL_TRACE_DEBUG(" Unknown Mode ");
+            break;
+    }
+
+    switch(sbc_cie.block_len)
+    {
+        case A2D_SBC_IE_BLOCKS_4:
+            APPL_TRACE_DEBUG("\tblock_len:%d (4)", sbc_cie.block_len);
+            num_blocks = 4;
+            break;
+        case A2D_SBC_IE_BLOCKS_8:
+            APPL_TRACE_DEBUG("\tblock_len:%d (8)", sbc_cie.block_len);
+            num_blocks = 8;
+            break;
+        case A2D_SBC_IE_BLOCKS_12:
+            APPL_TRACE_DEBUG("\tblock_len:%d (12)", sbc_cie.block_len);
+            num_blocks = 12;
+            break;
+        case A2D_SBC_IE_BLOCKS_16:
+            APPL_TRACE_DEBUG("\tblock_len:%d (16)", sbc_cie.block_len);
+            num_blocks = 16;
+            break;
+        default:
+            APPL_TRACE_DEBUG(" Unknown BlockLen ");
+            break;
+    }
+
+    switch(sbc_cie.num_subbands)
+    {
+        case A2D_SBC_IE_SUBBAND_4:
+            APPL_TRACE_DEBUG("\tnum_subbands:%d (4)", sbc_cie.num_subbands);
+            num_subbands = 4;
+            break;
+        case A2D_SBC_IE_SUBBAND_8:
+            APPL_TRACE_DEBUG("\tnum_subbands:%d (8)", sbc_cie.num_subbands);
+            num_subbands = 8;
+            break;
+        default:
+            APPL_TRACE_DEBUG(" Unknown SubBands ");
+            break;
+    }
+
+    switch(sbc_cie.alloc_mthd)
+    {
+        case A2D_SBC_IE_ALLOC_MD_S:
+            APPL_TRACE_DEBUG("\talloc_mthd:%d (SNR)", sbc_cie.alloc_mthd);
+            break;
+        case A2D_SBC_IE_ALLOC_MD_L:
+            APPL_TRACE_DEBUG("\talloc_mthd:%d (Loudness)", sbc_cie.alloc_mthd);
+            break;
+        default:
+            APPL_TRACE_DEBUG(" Unknown Allocation Method");
+            break;
+    }
+
+    APPL_TRACE_DEBUG("\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool, sbc_cie.max_bitpool);
+
+    btif_media_cb.frames_to_process = ((freq_multiple)/(num_blocks*num_subbands)) + 1;
+    APPL_TRACE_DEBUG(" Frames to be processed in 20 ms %d",btif_media_cb.frames_to_process);
+}
+#endif
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_feeding_state_reset
+ **
+ ** Description      Reset the media feeding state
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+static void btif_media_task_feeding_state_reset(void)
+{
+    /* By default, just clear the entire state */
+    memset(&btif_media_cb.media_feeding_state, 0, sizeof(btif_media_cb.media_feeding_state));
+
+    if (btif_media_cb.TxTranscoding == BTIF_MEDIA_TRSCD_PCM_2_SBC)
+    {
+        btif_media_cb.media_feeding_state.pcm.bytes_per_tick =
+                (btif_media_cb.media_feeding.cfg.pcm.sampling_freq *
+                 btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8 *
+                 btif_media_cb.media_feeding.cfg.pcm.num_channel *
+                 BTIF_MEDIA_TIME_TICK)/1000;
+
+        APPL_TRACE_WARNING("pcm bytes per tick %d",
+                            (int)btif_media_cb.media_feeding_state.pcm.bytes_per_tick);
+    }
+}
+
+static void btif_media_task_alarm_cb(UNUSED_ATTR void *context)
+{
+#if 0
+    thread_post(worker_thread, btif_media_task_aa_handle_timer, NULL);
+#else
+    btif_media_task_post(SIG_MEDIA_TASK_AA_ALARM_TO);
+#endif
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_aa_start_tx
+ **
+ ** Description      Start media task encoding
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+static void btif_media_task_aa_start_tx(void)
+{
+    APPL_TRACE_DEBUG("btif_media_task_aa_start_tx is timer %d, feeding mode %d",
+             btif_media_cb.is_tx_timer, btif_media_cb.feeding_mode);
+
+    /* Use a timer to poll the UIPC, get rid of the UIPC call back */
+    // UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_CBACK, NULL);
+
+    btif_media_cb.is_tx_timer = TRUE;
+    last_frame_us = 0;
+
+    /* Reset the media feeding state */
+    btif_media_task_feeding_state_reset();
+
+    APPL_TRACE_EVENT("starting timer %dms", BTIF_MEDIA_TIME_TICK);
+
+    assert(btif_media_cb.media_alarm == NULL);
+
+    btif_media_cb.media_alarm = osi_alarm_new("media_alarm", btif_media_task_alarm_cb, NULL, BTIF_MEDIA_TIME_TICK, true);
+    if (!btif_media_cb.media_alarm) {
+      APPL_TRACE_ERROR("%s unable to allocate media alarm.", __func__);
+      return;
+    }
+
+    // alarm_set_periodic(btif_media_cb.media_alarm, BTIF_MEDIA_TIME_TICK, btif_media_task_alarm_cb, NULL);
+    osi_alarm_set(btif_media_cb.media_alarm, BTIF_MEDIA_TIME_TICK);
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_aa_stop_tx
+ **
+ ** Description      Stop media task encoding
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+static void btif_media_task_aa_stop_tx(void)
+{
+    APPL_TRACE_DEBUG("%s is_tx_timer: %d", __func__, btif_media_cb.is_tx_timer);
+
+    const bool send_ack = (btif_media_cb.is_tx_timer != FALSE);
+
+    /* Stop the timer first */
+    osi_alarm_free(btif_media_cb.media_alarm);
+    btif_media_cb.media_alarm = NULL;
+    btif_media_cb.is_tx_timer = FALSE;
+
+    UIPC_Close(UIPC_CH_ID_AV_AUDIO);
+
+    /* Try to send acknowldegment once the media stream is
+       stopped. This will make sure that the A2DP HAL layer is
+       un-blocked on wait for acknowledgment for the sent command.
+       This resolves a corner cases AVDTP SUSPEND collision
+       when the DUT and the remote device issue SUSPEND simultaneously
+       and due to the processing of the SUSPEND request from the remote,
+       the media path is torn down. If the A2DP HAL happens to wait
+       for ACK for the initiated SUSPEND, it would never receive it casuing
+       a block/wait. Due to this acknowledgement, the A2DP HAL is guranteed
+       to get the ACK for any pending command in such cases. */
+
+    if (send_ack)
+        a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+
+    /* audio engine stopped, reset tx suspended flag */
+    btif_media_cb.tx_flush = 0;
+    last_frame_us = 0;
+
+    /* Reset the media feeding state */
+    btif_media_task_feeding_state_reset();
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_get_num_aa_frame
+ **
+ ** Description
+ **
+ ** Returns          The number of media frames in this time slice
+ **
+ *******************************************************************************/
+static UINT8 btif_get_num_aa_frame(void)
+{
+    UINT8 result=0;
+
+    switch (btif_media_cb.TxTranscoding)
+    {
+        case BTIF_MEDIA_TRSCD_PCM_2_SBC:
+        {
+            UINT32 pcm_bytes_per_frame = btif_media_cb.encoder.s16NumOfSubBands *
+                             btif_media_cb.encoder.s16NumOfBlocks *
+                             btif_media_cb.media_feeding.cfg.pcm.num_channel *
+                             btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
+
+            UINT32 us_this_tick = BTIF_MEDIA_TIME_TICK * 1000;
+            UINT64 now_us = time_now_us();
+            if (last_frame_us != 0)
+                us_this_tick = (now_us - last_frame_us);
+            last_frame_us = now_us;
+
+            btif_media_cb.media_feeding_state.pcm.counter +=
+                                btif_media_cb.media_feeding_state.pcm.bytes_per_tick *
+                                us_this_tick / (BTIF_MEDIA_TIME_TICK * 1000);
+
+            /* calculate nbr of frames pending for this media tick */
+            result = btif_media_cb.media_feeding_state.pcm.counter/pcm_bytes_per_frame;
+            if (result > MAX_PCM_FRAME_NUM_PER_TICK)
+            {
+                APPL_TRACE_WARNING("%s() - Limiting frames to be sent from %d to %d"
+                    , __FUNCTION__, result, MAX_PCM_FRAME_NUM_PER_TICK);
+                result = MAX_PCM_FRAME_NUM_PER_TICK;
+            }
+            btif_media_cb.media_feeding_state.pcm.counter -= result*pcm_bytes_per_frame;
+
+            LOG_VERBOSE("WRITE %d FRAMES", result);
+        }
+        break;
+
+        default:
+            APPL_TRACE_ERROR("ERROR btif_get_num_aa_frame Unsupported transcoding format 0x%x",
+                    btif_media_cb.TxTranscoding);
+            result = 0;
+            break;
+    }
+
+    return (UINT8)result;
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_sink_enque_buf
+ **
+ ** Description      This function is called by the av_co to fill A2DP Sink Queue
+ **
+ **
+ ** Returns          size of the queue
+ *******************************************************************************/
+UINT8 btif_media_sink_enque_buf(BT_HDR *p_pkt)
+{
+    tBT_SBC_HDR *p_msg;
+
+    if(btif_media_cb.rx_flush == TRUE) /* Flush enabled, do not enque*/
+        return GKI_queue_length(&btif_media_cb.RxSbcQ);
+    if(GKI_queue_length(&btif_media_cb.RxSbcQ) == MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ)
+    {
+        GKI_freebuf(GKI_dequeue(&(btif_media_cb.RxSbcQ)));
+    }
+
+    BTIF_TRACE_VERBOSE("btif_media_sink_enque_buf + ");
+    /* allocate and Queue this buffer */
+    if ((p_msg = (tBT_SBC_HDR *) GKI_getbuf(sizeof(tBT_SBC_HDR) +
+                        p_pkt->offset+ p_pkt->len)) != NULL)
+    {
+        memcpy(p_msg, p_pkt, (sizeof(BT_HDR) + p_pkt->offset + p_pkt->len));
+        p_msg->num_frames_to_be_processed = (*((UINT8*)(p_msg + 1) + p_msg->offset)) & 0x0f;
+        BTIF_TRACE_VERBOSE("btif_media_sink_enque_buf + ", p_msg->num_frames_to_be_processed);
+        GKI_enqueue(&(btif_media_cb.RxSbcQ), p_msg);
+        if(GKI_queue_length(&btif_media_cb.RxSbcQ) == MAX_A2DP_DELAYED_START_FRAME_COUNT)
+        {
+            BTIF_TRACE_DEBUG(" Initiate Decoding ");
+            btif_media_task_aa_handle_start_decoding();
+        }
+    }
+    else
+    {
+        /* let caller deal with a failed allocation */
+        BTIF_TRACE_VERBOSE("btif_media_sink_enque_buf No Buffer left - ");
+    }
+    return GKI_queue_length(&btif_media_cb.RxSbcQ);
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_aa_readbuf
+ **
+ ** Description      This function is called by the av_co to get the next buffer to send
+ **
+ **
+ ** Returns          void
+ *******************************************************************************/
+BT_HDR *btif_media_aa_readbuf(void)
+{
+    return GKI_dequeue(&(btif_media_cb.TxAaQ));
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_aa_read_feeding
+ **
+ ** Description
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+
+BOOLEAN btif_media_aa_read_feeding(tUIPC_CH_ID channel_id)
+{
+    UINT16 event;
+    UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands * \
+                             btif_media_cb.encoder.s16NumOfBlocks;
+    UINT32 read_size;
+    UINT16 sbc_sampling = 48000;
+    UINT32 src_samples;
+    UINT16 bytes_needed = blocm_x_subband * btif_media_cb.encoder.s16NumOfChannels * \
+                          btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
+    static UINT16 up_sampled_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
+            * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * 2];
+    static UINT16 read_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
+            * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS];
+    UINT32 src_size_used;
+    UINT32 dst_size_used;
+    BOOLEAN fract_needed;
+    INT32   fract_max;
+    INT32   fract_threshold;
+    UINT32  nb_byte_read;
+
+    /* Get the SBC sampling rate */
+    switch (btif_media_cb.encoder.s16SamplingFreq)
+    {
+    case SBC_sf48000:
+        sbc_sampling = 48000;
+        break;
+    case SBC_sf44100:
+        sbc_sampling = 44100;
+        break;
+    case SBC_sf32000:
+        sbc_sampling = 32000;
+        break;
+    case SBC_sf16000:
+        sbc_sampling = 16000;
+        break;
+    }
+
+    if (sbc_sampling == btif_media_cb.media_feeding.cfg.pcm.sampling_freq) {
+        read_size = bytes_needed - btif_media_cb.media_feeding_state.pcm.aa_feed_residue;
+        nb_byte_read = UIPC_Read(channel_id, &event,
+                  ((UINT8 *)btif_media_cb.encoder.as16PcmBuffer) +
+                  btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
+                  read_size);
+        if (nb_byte_read == read_size) {
+            btif_media_cb.media_feeding_state.pcm.aa_feed_residue = 0;
+            return TRUE;
+        } else {
+            APPL_TRACE_WARNING("### UNDERFLOW :: ONLY READ %d BYTES OUT OF %d ###",
+                nb_byte_read, read_size);
+            btif_media_cb.media_feeding_state.pcm.aa_feed_residue += nb_byte_read;
+            return FALSE;
+        }
+    }
+
+    /* Some Feeding PCM frequencies require to split the number of sample */
+    /* to read. */
+    /* E.g 128/6=21.3333 => read 22 and 21 and 21 => max = 2; threshold = 0*/
+    fract_needed = FALSE;   /* Default */
+    switch (btif_media_cb.media_feeding.cfg.pcm.sampling_freq)
+    {
+    case 32000:
+    case 8000:
+        fract_needed = TRUE;
+        fract_max = 2;          /* 0, 1 and 2 */
+        fract_threshold = 0;    /* Add one for the first */
+        break;
+    case 16000:
+        fract_needed = TRUE;
+        fract_max = 2;          /* 0, 1 and 2 */
+        fract_threshold = 1;    /* Add one for the first two frames*/
+        break;
+    }
+
+    /* Compute number of sample to read from source */
+    src_samples = blocm_x_subband;
+    src_samples *= btif_media_cb.media_feeding.cfg.pcm.sampling_freq;
+    src_samples /= sbc_sampling;
+
+    /* The previous division may have a remainder not null */
+    if (fract_needed)
+    {
+        if (btif_media_cb.media_feeding_state.pcm.aa_feed_counter <= fract_threshold)
+        {
+            src_samples++; /* for every read before threshold add one sample */
+        }
+
+        /* do nothing if counter >= threshold */
+        btif_media_cb.media_feeding_state.pcm.aa_feed_counter++; /* one more read */
+        if (btif_media_cb.media_feeding_state.pcm.aa_feed_counter > fract_max)
+        {
+            btif_media_cb.media_feeding_state.pcm.aa_feed_counter = 0;
+        }
+    }
+
+    /* Compute number of bytes to read from source */
+    read_size = src_samples;
+    read_size *= btif_media_cb.media_feeding.cfg.pcm.num_channel;
+    read_size *= (btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8);
+
+    /* Read Data from UIPC channel */
+    nb_byte_read = UIPC_Read(channel_id, &event, (UINT8 *)read_buffer, read_size);
+
+    //tput_mon(TRUE, nb_byte_read, FALSE);
+
+    if (nb_byte_read < read_size)
+    {
+        APPL_TRACE_WARNING("### UNDERRUN :: ONLY READ %d BYTES OUT OF %d ###",
+                nb_byte_read, read_size);
+
+        if (nb_byte_read == 0)
+            return FALSE;
+
+        if(btif_media_cb.feeding_mode == BTIF_AV_FEEDING_ASYNCHRONOUS)
+        {
+            /* Fill the unfilled part of the read buffer with silence (0) */
+            memset(((UINT8 *)read_buffer) + nb_byte_read, 0, read_size - nb_byte_read);
+            nb_byte_read = read_size;
+        }
+    }
+
+    /* Initialize PCM up-sampling engine */
+    bta_av_sbc_init_up_sample(btif_media_cb.media_feeding.cfg.pcm.sampling_freq,
+            sbc_sampling, btif_media_cb.media_feeding.cfg.pcm.bit_per_sample,
+            btif_media_cb.media_feeding.cfg.pcm.num_channel);
+
+    /* re-sample read buffer */
+    /* The output PCM buffer will be stereo, 16 bit per sample */
+    dst_size_used = bta_av_sbc_up_sample((UINT8 *)read_buffer,
+            (UINT8 *)up_sampled_buffer + btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
+            nb_byte_read,
+            sizeof(up_sampled_buffer) - btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
+            &src_size_used);
+
+    /* update the residue */
+    btif_media_cb.media_feeding_state.pcm.aa_feed_residue += dst_size_used;
+
+    /* only copy the pcm sample when we have up-sampled enough PCM */
+    if(btif_media_cb.media_feeding_state.pcm.aa_feed_residue >= bytes_needed)
+    {
+        /* Copy the output pcm samples in SBC encoding buffer */
+        memcpy((UINT8 *)btif_media_cb.encoder.as16PcmBuffer,
+                (UINT8 *)up_sampled_buffer,
+                bytes_needed);
+        /* update the residue */
+        btif_media_cb.media_feeding_state.pcm.aa_feed_residue -= bytes_needed;
+
+        if (btif_media_cb.media_feeding_state.pcm.aa_feed_residue != 0)
+        {
+            memcpy((UINT8 *)up_sampled_buffer,
+                   (UINT8 *)up_sampled_buffer + bytes_needed,
+                   btif_media_cb.media_feeding_state.pcm.aa_feed_residue);
+        }
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_aa_prep_sbc_2_send
+ **
+ ** Description
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+static void btif_media_aa_prep_sbc_2_send(UINT8 nb_frame)
+{
+    BT_HDR * p_buf;
+    UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands *
+                             btif_media_cb.encoder.s16NumOfBlocks;
+
+    while (nb_frame)
+    {
+        if (NULL == (p_buf = GKI_getpoolbuf(BTIF_MEDIA_AA_POOL_ID)))
+        {
+            APPL_TRACE_ERROR ("ERROR btif_media_aa_prep_sbc_2_send no buffer TxCnt %d ",
+                                GKI_queue_length(&btif_media_cb.TxAaQ));
+            return;
+        }
+
+        /* Init buffer */
+        p_buf->offset = BTIF_MEDIA_AA_SBC_OFFSET;
+        p_buf->len = 0;
+        p_buf->layer_specific = 0;
+
+        do
+        {
+            /* Write @ of allocated buffer in encoder.pu8Packet */
+            btif_media_cb.encoder.pu8Packet = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len;
+            /* Fill allocated buffer with 0 */
+            memset(btif_media_cb.encoder.as16PcmBuffer, 0, blocm_x_subband
+                    * btif_media_cb.encoder.s16NumOfChannels);
+
+            /* Read PCM data and upsample them if needed */
+            if (btif_media_aa_read_feeding(UIPC_CH_ID_AV_AUDIO))
+            {
+                /* SBC encode and descramble frame */
+                SBC_Encoder(&(btif_media_cb.encoder));
+                A2D_SbcChkFrInit(btif_media_cb.encoder.pu8Packet);
+                A2D_SbcDescramble(btif_media_cb.encoder.pu8Packet, btif_media_cb.encoder.u16PacketLength);
+                /* Update SBC frame length */
+                p_buf->len += btif_media_cb.encoder.u16PacketLength;
+                nb_frame--;
+                p_buf->layer_specific++;
+            }
+            else
+            {
+                APPL_TRACE_WARNING("btif_media_aa_prep_sbc_2_send underflow %d, %d",
+                    nb_frame, btif_media_cb.media_feeding_state.pcm.aa_feed_residue);
+                btif_media_cb.media_feeding_state.pcm.counter += nb_frame *
+                     btif_media_cb.encoder.s16NumOfSubBands *
+                     btif_media_cb.encoder.s16NumOfBlocks *
+                     btif_media_cb.media_feeding.cfg.pcm.num_channel *
+                     btif_media_cb.media_feeding.cfg.pcm.bit_per_sample / 8;
+                /* no more pcm to read */
+                nb_frame = 0;
+
+                /* break read loop if timer was stopped (media task stopped) */
+                if ( btif_media_cb.is_tx_timer == FALSE )
+                {
+                    GKI_freebuf(p_buf);
+                    return;
+                }
+            }
+
+        } while (((p_buf->len + btif_media_cb.encoder.u16PacketLength) < btif_media_cb.TxAaMtuSize)
+                && (p_buf->layer_specific < 0x0F) && nb_frame);
+
+        if(p_buf->len)
+        {
+            /* timestamp of the media packet header represent the TS of the first SBC frame
+               i.e the timestamp before including this frame */
+            *((UINT32 *) (p_buf + 1)) = btif_media_cb.timestamp;
+
+            btif_media_cb.timestamp += p_buf->layer_specific * blocm_x_subband;
+
+            if (btif_media_cb.tx_flush)
+            {
+                APPL_TRACE_DEBUG("### tx suspended, discarded frame ###");
+
+                if (GKI_queue_length(&btif_media_cb.TxAaQ) > 0)
+                    btif_media_flush_q(&(btif_media_cb.TxAaQ));
+
+                GKI_freebuf(p_buf);
+                return;
+            }
+
+            /* Enqueue the encoded SBC frame in AA Tx Queue */
+            GKI_enqueue(&(btif_media_cb.TxAaQ), p_buf);
+        }
+        else
+        {
+            GKI_freebuf(p_buf);
+        }
+    }
+}
+
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_aa_prep_2_send
+ **
+ ** Description
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+
+static void btif_media_aa_prep_2_send(UINT8 nb_frame)
+{
+    // Check for TX queue overflow
+
+    if (nb_frame > MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ)
+        nb_frame = MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ;
+
+    if (GKI_queue_length(&btif_media_cb.TxAaQ) > (MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ - nb_frame))
+    {
+        APPL_TRACE_WARNING("%s() - TX queue buffer count %d/%d", __func__,
+            GKI_queue_length(&btif_media_cb.TxAaQ), MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ - nb_frame);
+    }
+
+    while (GKI_queue_length(&btif_media_cb.TxAaQ) > (MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ - nb_frame))
+        GKI_freebuf(GKI_dequeue(&(btif_media_cb.TxAaQ)));
+
+    // Transcode frame
+
+    switch (btif_media_cb.TxTranscoding)
+    {
+    case BTIF_MEDIA_TRSCD_PCM_2_SBC:
+        btif_media_aa_prep_sbc_2_send(nb_frame);
+        break;
+
+    default:
+        APPL_TRACE_ERROR("%s unsupported transcoding format 0x%x", __func__, btif_media_cb.TxTranscoding);
+        break;
+    }
+}
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_send_aa_frame
+ **
+ ** Description
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+static void btif_media_send_aa_frame(void)
+{
+    UINT8 nb_frame_2_send;
+
+    /* get the number of frame to send */
+    nb_frame_2_send = btif_get_num_aa_frame();
+
+    if (nb_frame_2_send != 0)
+    {
+        /* format and Q buffer to send */
+        btif_media_aa_prep_2_send(nb_frame_2_send);
+    }
+
+    /* send it */
+    LOG_VERBOSE("btif_media_send_aa_frame : send %d frames", nb_frame_2_send);
+    bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
+}
+
+#endif /* BTA_AV_INCLUDED == TRUE */
+
+/*******************************************************************************
+ **
+ ** Function         dump_codec_info
+ **
+ ** Description      Decode and display codec_info (for debug)
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+void dump_codec_info(unsigned char *p_codec)
+{
+    tA2D_STATUS a2d_status;
+    tA2D_SBC_CIE sbc_cie;
+
+    a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_codec, FALSE);
+    if (a2d_status != A2D_SUCCESS)
+    {
+        APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
+        return;
+    }
+
+    APPL_TRACE_DEBUG("dump_codec_info");
+
+    if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_16)
+    {    APPL_TRACE_DEBUG("\tsamp_freq:%d (16000)", sbc_cie.samp_freq);}
+    else  if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_32)
+    {    APPL_TRACE_DEBUG("\tsamp_freq:%d (32000)", sbc_cie.samp_freq);}
+    else  if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_44)
+    {    APPL_TRACE_DEBUG("\tsamp_freq:%d (44.100)", sbc_cie.samp_freq);}
+    else  if (sbc_cie.samp_freq == A2D_SBC_IE_SAMP_FREQ_48)
+    {    APPL_TRACE_DEBUG("\tsamp_freq:%d (48000)", sbc_cie.samp_freq);}
+    else
+    {    APPL_TRACE_DEBUG("\tBAD samp_freq:%d", sbc_cie.samp_freq);}
+
+    if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_MONO)
+    {    APPL_TRACE_DEBUG("\tch_mode:%d (Mono)", sbc_cie.ch_mode);}
+    else  if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_DUAL)
+    {    APPL_TRACE_DEBUG("\tch_mode:%d (Dual)", sbc_cie.ch_mode);}
+    else  if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_STEREO)
+    {    APPL_TRACE_DEBUG("\tch_mode:%d (Stereo)", sbc_cie.ch_mode);}
+    else  if (sbc_cie.ch_mode == A2D_SBC_IE_CH_MD_JOINT)
+    {    APPL_TRACE_DEBUG("\tch_mode:%d (Joint)", sbc_cie.ch_mode);}
+    else
+    {    APPL_TRACE_DEBUG("\tBAD ch_mode:%d", sbc_cie.ch_mode);}
+
+    if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_4)
+    {    APPL_TRACE_DEBUG("\tblock_len:%d (4)", sbc_cie.block_len);}
+    else  if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_8)
+    {    APPL_TRACE_DEBUG("\tblock_len:%d (8)", sbc_cie.block_len);}
+    else  if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_12)
+    {    APPL_TRACE_DEBUG("\tblock_len:%d (12)", sbc_cie.block_len);}
+    else  if (sbc_cie.block_len == A2D_SBC_IE_BLOCKS_16)
+    {    APPL_TRACE_DEBUG("\tblock_len:%d (16)", sbc_cie.block_len);}
+    else
+    {    APPL_TRACE_DEBUG("\tBAD block_len:%d", sbc_cie.block_len);}
+
+    if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_4)
+    {    APPL_TRACE_DEBUG("\tnum_subbands:%d (4)", sbc_cie.num_subbands);}
+    else  if (sbc_cie.num_subbands == A2D_SBC_IE_SUBBAND_8)
+    {    APPL_TRACE_DEBUG("\tnum_subbands:%d (8)", sbc_cie.num_subbands);}
+    else
+    {    APPL_TRACE_DEBUG("\tBAD num_subbands:%d", sbc_cie.num_subbands);}
+
+    if (sbc_cie.alloc_mthd == A2D_SBC_IE_ALLOC_MD_S)
+    {    APPL_TRACE_DEBUG("\talloc_mthd:%d (SNR)", sbc_cie.alloc_mthd);}
+    else  if (sbc_cie.alloc_mthd == A2D_SBC_IE_ALLOC_MD_L)
+    {    APPL_TRACE_DEBUG("\talloc_mthd:%d (Loundess)", sbc_cie.alloc_mthd);}
+    else
+    {    APPL_TRACE_DEBUG("\tBAD alloc_mthd:%d", sbc_cie.alloc_mthd);}
+
+    APPL_TRACE_DEBUG("\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool, sbc_cie.max_bitpool);
+
+}

+ 179 - 0
examples/09_a2dp/components/bluedroid_demos/btif/btif_profile_queue.c

@@ -0,0 +1,179 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *
+ *  Filename:      btif_profile_queue.c
+ *
+ *  Description:   Bluetooth remote device connection queuing implementation.
+ *
+ ******************************************************************************/
+
+// #include <assert.h>
+#include "bt_trace.h"
+#include <string.h>
+// #include <hardware/bluetooth.h>
+#include "bt_defs.h"
+#include <string.h>
+
+#define LOG_TAG "bt_btif_queue"
+#include "btif_common.h"
+#include "btif_profile_queue.h"
+#include "gki.h"
+#include "list.h"
+#include "allocator.h"
+#include "stack_manager.h"
+
+/*******************************************************************************
+**  Local type definitions
+*******************************************************************************/
+
+typedef enum {
+  BTIF_QUEUE_CONNECT_EVT,
+  BTIF_QUEUE_ADVANCE_EVT,
+} btif_queue_event_t;
+
+typedef struct {
+    bt_bdaddr_t bda;
+    uint16_t uuid;
+    bool busy;
+    btif_connect_cb_t connect_cb;
+} connect_node_t;
+
+/*******************************************************************************
+**  Static variables
+*******************************************************************************/
+
+static list_t *connect_queue;
+
+static const size_t MAX_REASONABLE_REQUESTS = 10;
+
+/*******************************************************************************
+**  Queue helper functions
+*******************************************************************************/
+
+static void queue_int_add(connect_node_t *p_param) {
+    if (!connect_queue) {
+        connect_queue = list_new(osi_free);
+        assert(connect_queue != NULL);
+    }
+
+    // Sanity check to make sure we're not leaking connection requests
+    assert(list_length(connect_queue) < MAX_REASONABLE_REQUESTS);
+
+    for (const list_node_t *node = list_begin(connect_queue); node != list_end(connect_queue); node = list_next(node)) {
+        if (((connect_node_t *)list_node(node))->uuid == p_param->uuid) {
+            LOG_INFO("%s dropping duplicate connect request for uuid: %04x", __func__, p_param->uuid);
+            return;
+        }
+    }
+
+    connect_node_t *p_node = osi_malloc(sizeof(connect_node_t));
+    assert(p_node != NULL);
+    memcpy(p_node, p_param, sizeof(connect_node_t));
+    list_append(connect_queue, p_node);
+}
+
+static void queue_int_advance() {
+    if (connect_queue && !list_is_empty(connect_queue))
+        list_remove(connect_queue, list_front(connect_queue));
+}
+
+static void queue_int_handle_evt(UINT16 event, char *p_param) {
+    switch(event) {
+        case BTIF_QUEUE_CONNECT_EVT:
+            queue_int_add((connect_node_t *)p_param);
+            break;
+
+        case BTIF_QUEUE_ADVANCE_EVT:
+            queue_int_advance();
+            break;
+    }
+
+    // if (stack_manager_get_interface()->get_stack_is_running())
+    if (stack_manager_is_stack_running())
+        btif_queue_connect_next();
+}
+
+/*******************************************************************************
+**
+** Function         btif_queue_connect
+**
+** Description      Add a new connection to the queue and trigger the next
+**                  scheduled connection.
+**
+** Returns          BT_STATUS_SUCCESS if successful
+**
+*******************************************************************************/
+bt_status_t btif_queue_connect(uint16_t uuid, const bt_bdaddr_t *bda, btif_connect_cb_t connect_cb) {
+    connect_node_t node;
+    memset(&node, 0, sizeof(connect_node_t));
+    memcpy(&node.bda, bda, sizeof(bt_bdaddr_t));
+    node.uuid = uuid;
+    node.connect_cb = connect_cb;
+
+    return btif_transfer_context(queue_int_handle_evt, BTIF_QUEUE_CONNECT_EVT,
+                          (char *)&node, sizeof(connect_node_t), NULL);
+}
+
+/*******************************************************************************
+**
+** Function         btif_queue_advance
+**
+** Description      Clear the queue's busy status and advance to the next
+**                  scheduled connection.
+**
+** Returns          void
+**
+*******************************************************************************/
+void btif_queue_advance() {
+    btif_transfer_context(queue_int_handle_evt, BTIF_QUEUE_ADVANCE_EVT,
+                          NULL, 0, NULL);
+}
+
+// This function dispatches the next pending connect request. It is called from
+// stack_manager when the stack comes up.
+bt_status_t btif_queue_connect_next(void) {
+    if (!connect_queue || list_is_empty(connect_queue))
+        return BT_STATUS_FAIL;
+
+    connect_node_t *p_head = list_front(connect_queue);
+
+    // If the queue is currently busy, we return success anyway,
+    // since the connection has been queued...
+    if (p_head->busy)
+        return BT_STATUS_SUCCESS;
+
+    p_head->busy = true;
+    return p_head->connect_cb(&p_head->bda, p_head->uuid);
+}
+
+
+/*******************************************************************************
+**
+** Function         btif_queue_release
+**
+** Description      Free up all the queue nodes and set the queue head to NULL
+**
+** Returns          void
+**
+*******************************************************************************/
+void btif_queue_release() {
+    list_free(connect_queue);
+    connect_queue = NULL;
+}

+ 175 - 0
examples/09_a2dp/components/bluedroid_demos/btif/btif_sdp.c

@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2014 Samsung System LSI
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/************************************************************************************
+ *
+ *  Filename:      btif_sdp.c
+ *  Description:   SDP Bluetooth Interface.
+ *                 Implements the generic message handling and search functionality.
+ *                 References btif_sdp_server.c for SDP record creation.
+ *
+ ***********************************************************************************/
+
+#include "btif_sdp.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define LOG_TAG "BTIF_SDP"
+#include "btif_common.h"
+#include "btif_util.h"
+#include "bta_api.h"
+
+#include "bt_sdp_api.h"
+
+/*****************************************************************************
+**  Functions implemented in sdp_server.c
+******************************************************************************/
+bt_status_t sdp_server_init();
+void sdp_server_cleanup();
+void on_create_record_event(int handle);
+void on_remove_record_event(int handle);
+
+// Utility functions:
+int get_sdp_records_size(bluetooth_sdp_record* in_record, int count);
+void copy_sdp_records(bluetooth_sdp_record* in_records,
+        bluetooth_sdp_record* out_records, int count);
+
+
+/*****************************************************************************
+**  Static variables
+******************************************************************************/
+
+static btsdp_callbacks_t *bt_sdp_callbacks = NULL;
+
+static void btif_sdp_search_comp_evt(UINT16 event, char *p_param)
+{
+    bt_sdp_search_comp_t *evt_data = (bt_sdp_search_comp_t *) p_param;
+    bt_bdaddr_t addr;
+    BTIF_TRACE_DEBUG("%s:  event = %d\n", __FUNCTION__, event);
+
+    if (event != BT_SDP_SEARCH_COMP_EVT)
+        return;
+
+    bdcpy(addr.address, evt_data->remote_addr);
+
+    HAL_CBACK(bt_sdp_callbacks, sdp_search_cb, evt_data->status,
+            &addr, (uint8_t*)(evt_data->uuid.uu.uuid128),
+            evt_data->record_count, evt_data->records);
+}
+
+static void sdp_search_comp_copy_cb(UINT16 event, char *p_dest, char *p_src)
+{
+    bt_sdp_search_comp_t *p_dest_data = (bt_sdp_search_comp_t *) p_dest;
+    bt_sdp_search_comp_t *p_src_data = (bt_sdp_search_comp_t *) p_src;
+    if (!p_src)
+        return;
+
+    if (event != BT_SDP_SEARCH_COMP_EVT)
+        return;
+
+    memcpy(p_dest_data, p_src_data, sizeof(bt_sdp_search_comp_t));
+
+    copy_sdp_records(p_src_data->records, p_dest_data->records, p_src_data->record_count);
+}
+
+
+static void sdp_dm_cback(bt_sdp_evt_t event, bt_sdp_t *p_data, void * user_data)
+{
+    switch (event)
+    {
+        case BT_SDP_SEARCH_COMP_EVT:
+        {
+            int size = sizeof(bt_sdp_t);
+            size += get_sdp_records_size(p_data->sdp_search_comp.records,
+                    p_data->sdp_search_comp.record_count);
+
+	    BTIF_TRACE_DEBUG("%s:  stat %d, record_cnt = %d\n", __FUNCTION__, p_data->sdp_search_comp.status, p_data->sdp_search_comp.record_count);
+            /* need to deep copy the record content */
+            btif_transfer_context(btif_sdp_search_comp_evt, event,
+                                    (char*)p_data, size, sdp_search_comp_copy_cb);
+            break;
+        }
+        case BT_SDP_CREATE_RECORD_USER_EVT:
+        {
+            on_create_record_event((int)user_data);
+            break;
+        }
+        case BT_SDP_REMOVE_RECORD_USER_EVT:
+        {
+            on_remove_record_event((int)user_data);
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+bt_status_t BTIF_SdpInit(btsdp_callbacks_t *callbacks)
+{
+    BTIF_TRACE_DEBUG("Sdp Search %s\n", __FUNCTION__);
+
+    bt_sdp_callbacks = callbacks;
+    sdp_server_init();
+
+    btif_enable_service(BTA_SDP_SERVICE_ID);
+
+    return BT_STATUS_SUCCESS;
+}
+
+bt_status_t BTIF_SdpDeinit(void)
+{
+    BTIF_TRACE_DEBUG("Sdp Search %s\n", __FUNCTION__);
+
+    bt_sdp_callbacks = NULL;
+    sdp_server_cleanup();
+    btif_disable_service(BTA_SDP_SERVICE_ID);
+
+    return BT_STATUS_SUCCESS;
+}
+
+bt_status_t BTIF_SdpSearch(bt_bdaddr_t *bd_addr,  const uint8_t* uuid)
+{
+    esp_bt_uuid_t sdp_uuid;
+    sdp_uuid.len = 16;
+    memcpy(sdp_uuid.uu.uuid128, uuid, sizeof(sdp_uuid.uu.uuid128));
+
+    esp_bt_sdp_search(bd_addr->address, &sdp_uuid);
+    return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function         btif_sdp_execute_service
+**
+** Description      Initializes/Shuts down the service
+**
+** Returns          BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_sdp_execute_service(BOOLEAN b_enable)
+{
+    BTIF_TRACE_DEBUG("%s enable:%d\n", __FUNCTION__, b_enable);
+
+    if (b_enable) {
+        esp_bt_sdp_enable(sdp_dm_cback);
+    } else {
+        /* This is called on BT disable so no need to extra cleanup */
+    }
+    return BT_STATUS_SUCCESS;
+}
+

+ 777 - 0
examples/09_a2dp/components/bluedroid_demos/btif/btif_sdp_server.c

@@ -0,0 +1,777 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2014 Samsung System LSI
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/************************************************************************************
+ *
+ *  Filename:      btif_sdp_server.c
+ *  Description:   SDP server Bluetooth Interface to create and remove SDP records.
+ *                 To be used in combination with the RFCOMM/L2CAP(LE) sockets.
+ *
+ *
+ ***********************************************************************************/
+
+#include "btif_sdp.h"
+#include <stdlib.h>
+#include <string.h>
+#define LOG_TAG "BTIF_SDP_SERVER"
+#include "allocator.h"
+#include "btif_common.h"
+#include "bta_sys.h"
+#include "utl.h"
+#include "bt_sdp_api.h"
+
+static pthread_mutex_t sdp_lock;
+
+/**
+ * The need for a state variable have been reduced to two states.
+ * The remaining state control is handled by program flow
+ */
+typedef enum {
+    SDP_RECORD_FREE = 0,
+    SDP_RECORD_ALLOCED,
+} sdp_state_t;
+
+typedef struct {
+  sdp_state_t state;
+  int sdp_handle;
+  bluetooth_sdp_record* record_data;
+} sdp_slot_t;
+
+#define MAX_SDP_SLOTS 128
+static sdp_slot_t sdp_slots[MAX_SDP_SLOTS];
+
+/*****************************************************************************
+ * LOCAL Functions
+ *****************************************************************************/
+static int add_maps_sdp(const bluetooth_sdp_mas_record* rec);
+static int add_mapc_sdp(const bluetooth_sdp_mns_record* rec);
+static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec);
+static int add_opps_sdp(const bluetooth_sdp_ops_record* rec);
+static int add_saps_sdp(const bluetooth_sdp_sap_record* rec);
+bt_status_t remove_sdp_record(int record_id);
+static int free_sdp_slot(int id);
+
+/******************************************************************************
+ * WARNING: Functions below are not called in BTU context.
+ * Introduced to make it possible to create SDP records from JAVA with both a
+ * RFCOMM channel and a L2CAP PSM.
+ * Overall architecture:
+ *  1) JAVA calls createRecord() which returns a pseudo ID which at a later
+ *     point will be linked to a specific SDP handle.
+ *  2) createRecord() requests the BTU task(thread) to call a callback in SDP
+ *     which creates the actual record, and updates the ID<->SDPHandle map
+ *     based on the ID beeing passed to BTA as user_data.
+ *****************************************************************************/
+
+static void init_sdp_slots()
+{
+    int i;
+    memset(sdp_slots, 0, sizeof(sdp_slot_t)*MAX_SDP_SLOTS);
+    /* if SDP_RECORD_FREE is zero - no need to set the value */
+    if(SDP_RECORD_FREE != 0) {
+        for(i = 0; i < MAX_SDP_SLOTS; i++)
+        {
+            sdp_slots[i].state = SDP_RECORD_FREE;
+        }
+    }
+}
+
+bt_status_t sdp_server_init()
+{
+    BTIF_TRACE_DEBUG("Sdp Server %s\n", __FUNCTION__);
+    pthread_mutex_init(&sdp_lock, NULL);
+    init_sdp_slots();
+    return BT_STATUS_SUCCESS;
+}
+
+void sdp_server_cleanup()
+{
+    BTIF_TRACE_DEBUG("Sdp Server %s\n", __FUNCTION__);
+    pthread_mutex_lock(&sdp_lock);
+    int i;
+    for(i = 0; i < MAX_SDP_SLOTS; i++)
+    {
+         /*remove_sdp_record(i); we cannot send messages to the other threads, since they might
+         *                       have been shut down already. Just do local cleanup.
+         */
+        free_sdp_slot(i);
+    }
+    pthread_mutex_unlock(&sdp_lock);
+    pthread_mutex_destroy(&sdp_lock);
+}
+
+int get_sdp_records_size(bluetooth_sdp_record* in_record, int count) {
+    bluetooth_sdp_record* record = in_record;
+    int records_size = 0;
+    int i;
+    for(i=0; i<count; i++) {
+        record = &in_record[i];
+        records_size += sizeof(bluetooth_sdp_record);
+        records_size += record->hdr.service_name_length;
+        if(record->hdr.service_name_length > 0){
+            records_size++; /* + '\0' termination of string */
+        }
+        records_size += record->hdr.user1_ptr_len;
+        records_size += record->hdr.user2_ptr_len;
+    }
+    return records_size;
+}
+
+/* Deep copy all content of in_records into out_records.
+ * out_records must point to a chunk of memory large enough to contain all
+ * the data. Use getSdpRecordsSize() to calculate the needed size. */
+void copy_sdp_records(bluetooth_sdp_record* in_records,
+        bluetooth_sdp_record* out_records, int count) {
+    int i;
+    bluetooth_sdp_record* in_record;
+    bluetooth_sdp_record* out_record;
+    char* free_ptr = (char*)(&out_records[count]); /* set pointer to after the last entry */
+
+    for(i=0; i<count; i++) {
+        in_record = &in_records[i];
+        out_record = &out_records[i];
+        *out_record = *in_record;
+
+        if(in_record->hdr.service_name == NULL || in_record->hdr.service_name_length == 0) {
+            out_record->hdr.service_name = NULL;
+            out_record->hdr.service_name_length = 0;
+        } else {
+            out_record->hdr.service_name = free_ptr; // Update service_name pointer
+            // Copy string
+            memcpy(free_ptr, in_record->hdr.service_name, in_record->hdr.service_name_length);
+            free_ptr += in_record->hdr.service_name_length;
+            *(free_ptr) = '\0'; // Set '\0' termination of string
+            free_ptr++;
+        }
+        if(in_record->hdr.user1_ptr != NULL) {
+            out_record->hdr.user1_ptr = (UINT8*)free_ptr; // Update pointer
+            memcpy(free_ptr, in_record->hdr.user1_ptr, in_record->hdr.user1_ptr_len); // Copy content
+            free_ptr += in_record->hdr.user1_ptr_len;
+        }
+        if(in_record->hdr.user2_ptr != NULL) {
+            out_record->hdr.user2_ptr = (UINT8*)free_ptr; // Update pointer
+            memcpy(free_ptr, in_record->hdr.user2_ptr, in_record->hdr.user2_ptr_len); // Copy content
+            free_ptr += in_record->hdr.user2_ptr_len;
+        }
+    }
+    return;
+}
+
+/* Reserve a slot in sdp_slots, copy data and set a reference to the copy.
+ * The record_data will contain both the record and any data pointed to by
+ * the record.
+ * Currently this covers:
+ *   service_name string,
+ *   user1_ptr and
+ *   user2_ptr. */
+static int alloc_sdp_slot(bluetooth_sdp_record* in_record) {
+    int i;
+    int record_size = get_sdp_records_size(in_record, 1);
+    bluetooth_sdp_record* record = osi_malloc(record_size);
+
+    copy_sdp_records(in_record, record, 1);
+
+    /* We are optimists here, and preallocate the record.
+     * This is to reduce the time we hold the sdp_lock. */
+    pthread_mutex_lock(&sdp_lock);
+    for(i = 0; i < MAX_SDP_SLOTS; i++)
+    {
+        if(sdp_slots[i].state == SDP_RECORD_FREE) {
+            sdp_slots[i].state = SDP_RECORD_ALLOCED;
+            sdp_slots[i].record_data = record;
+            break;
+        }
+    }
+    pthread_mutex_unlock(&sdp_lock);
+    if(i >= MAX_SDP_SLOTS) {
+        APPL_TRACE_ERROR("%s() failed - no more free slots!\n", __func__);
+        /* Rearly the optimist is too optimistic, and cleanup is needed...*/
+        osi_free(record);
+        return -1;
+    }
+    return i;
+}
+
+static int free_sdp_slot(int id) {
+    int handle = -1;
+    bluetooth_sdp_record* record = NULL;
+    if(id >= MAX_SDP_SLOTS) {
+        APPL_TRACE_ERROR("%s() failed - id %d is invalid\n", __func__, id);
+        return handle;
+    }
+    pthread_mutex_lock(&sdp_lock);
+    handle = sdp_slots[id].sdp_handle;
+    sdp_slots[id].sdp_handle = 0;
+    if(sdp_slots[id].state != SDP_RECORD_FREE)
+    {
+        /* safe a copy of the pointer, and free after unlock() */
+        record = sdp_slots[id].record_data;
+    }
+    sdp_slots[id].state = SDP_RECORD_FREE;
+    pthread_mutex_unlock(&sdp_lock);
+
+    if(record != NULL) {
+        osi_free(record);
+    } else {
+        // Record have already been freed
+        handle = -1;
+    }
+    return handle;
+}
+
+/***
+ * Use this to get a reference to a SDP slot AND change the state to
+ * SDP_RECORD_CREATE_INITIATED.
+ */
+static const sdp_slot_t* start_create_sdp(int id) {
+    sdp_slot_t* sdp_slot;
+    if(id >= MAX_SDP_SLOTS) {
+        APPL_TRACE_ERROR("%s() failed - id %d is invalid\n", __func__, id);
+        return NULL;
+    }
+    pthread_mutex_lock(&sdp_lock);
+    if(sdp_slots[id].state == SDP_RECORD_ALLOCED) {
+        sdp_slot = &(sdp_slots[id]);
+    } else {
+        /* The record have been removed before this event occurred - e.g. deinit */
+        sdp_slot = NULL;
+    }
+    pthread_mutex_unlock(&sdp_lock);
+    if(sdp_slot == NULL) {
+        APPL_TRACE_ERROR("%s() failed - state for id %d is \n"
+                "sdp_slots[id].state = %d expected %d\n", __func__,
+                id, sdp_slots[id].state, SDP_RECORD_ALLOCED);
+    }
+    return sdp_slot;
+}
+
+static void set_sdp_handle(int id, int handle) {
+    pthread_mutex_lock(&sdp_lock);
+    sdp_slots[id].sdp_handle = handle;
+    pthread_mutex_unlock(&sdp_lock);
+    BTIF_TRACE_DEBUG("%s() id=%d to handle=0x%08x\n", __FUNCTION__, id, handle);
+}
+
+bt_status_t BTIF_SdpCreateRecord(bluetooth_sdp_record *record, int* record_handle) {
+    int handle;
+
+    handle = alloc_sdp_slot(record);
+    BTIF_TRACE_DEBUG("%s() handle = 0x%08x\n", __FUNCTION__, handle);
+
+    if(handle < 0)
+        return BT_STATUS_FAIL;
+
+    esp_bt_sdp_create_record_by_user((void*) handle);
+
+    *record_handle = handle;
+
+    return BT_STATUS_SUCCESS;
+}
+
+bt_status_t BTIF_SdpRemoveRecord(int record_handle) {
+    int handle;
+
+    /* Get the Record handle, and free the slot */
+    handle = free_sdp_slot(record_handle);
+    BTIF_TRACE_DEBUG("Sdp Server %s id=%d to handle=0x%08x\n",
+            __FUNCTION__, record_handle, handle);
+
+    /* Pass the actual record handle */
+    if(handle > 0) {
+        esp_bt_sdp_remove_record_by_user((void *)handle);
+        return BT_STATUS_SUCCESS;
+    }
+    BTIF_TRACE_DEBUG("Sdp Server %s - record already removed - or never created\n", __FUNCTION__);
+    return BT_STATUS_FAIL;
+}
+
+
+/******************************************************************************
+ * CALLBACK FUNCTIONS
+ * Called in BTA context to create/remove SDP records.
+ ******************************************************************************/
+
+void on_create_record_event(int id) {
+    /*
+     * 1) Fetch the record pointer, and change its state?
+     * 2) switch on the type to create the correct record
+     * 3) Update state on completion
+     * 4) What to do at fail?
+     * */
+    BTIF_TRACE_DEBUG("Sdp Server %s\n", __FUNCTION__);
+    const sdp_slot_t* sdp_slot = start_create_sdp(id);
+    /* In the case we are shutting down, sdp_slot is NULL */
+    if(sdp_slot != NULL) {
+        bluetooth_sdp_record* record = sdp_slot->record_data;
+        int handle = -1;
+        switch(record->hdr.type) {
+        case SDP_TYPE_MAP_MAS:
+            handle = add_maps_sdp(&record->mas);
+            break;
+        case SDP_TYPE_MAP_MNS:
+            handle = add_mapc_sdp(&record->mns);
+            break;
+        case SDP_TYPE_PBAP_PSE:
+            handle = add_pbaps_sdp(&record->pse);
+            break;
+        case SDP_TYPE_OPP_SERVER:
+            handle = add_opps_sdp(&record->ops);
+            break;
+        case SDP_TYPE_SAP_SERVER:
+            handle = add_saps_sdp(&record->sap);
+            break;
+        case SDP_TYPE_PBAP_PCE:
+    //        break; not yet supported
+        default:
+            BTIF_TRACE_DEBUG("Record type %d is not supported\n",record->hdr.type);
+            break;
+        }
+        if(handle != -1) {
+            set_sdp_handle(id, handle);
+        }
+    }
+}
+
+void on_remove_record_event(int handle) {
+    BTIF_TRACE_DEBUG("Sdp Server %s\n", __FUNCTION__);
+
+    // User data carries the actual SDP handle, not the ID.
+    if(handle != -1 && handle != 0) {
+        BOOLEAN result;
+        result = SDP_DeleteRecord( handle );
+        if(result == FALSE) {
+            BTIF_TRACE_ERROR("  Unable to remove handle 0x%08x\n", handle);
+        }
+    }
+}
+
+/****
+ * Below the actual functions accessing BTA context data - hence only call from BTA context!
+ */
+
+/* Create a MAP MAS SDP record based on information stored in a bluetooth_sdp_mas_record */
+static int add_maps_sdp(const bluetooth_sdp_mas_record* rec)
+{
+
+    sdp_proto_elem_t    protoList[3];
+    UINT16              service = UUID_SERVCLASS_MESSAGE_ACCESS;
+    UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+    BOOLEAN             status = TRUE;
+    UINT32              sdp_handle = 0;
+    UINT8               temp[4];
+    UINT8*              p_temp = temp;
+
+    APPL_TRACE_DEBUG("%s(): MASID = 0x%02x, scn 0x%02x, psm = 0x%04x\n  service name %s\n", __func__,
+            rec->mas_instance_id, rec->hdr.rfcomm_channel_number,
+            rec->hdr.l2cap_psm, rec->hdr.service_name);
+
+    APPL_TRACE_DEBUG("  msg_types: 0x%02x, feature_bits: 0x%08x\n",
+            rec->supported_message_types, rec->supported_features);
+
+    if ((sdp_handle = esp_bt_sdp_create_record()) == 0)
+    {
+        APPL_TRACE_ERROR("%s() - Unable to register MAPS Service\n", __func__);
+        return sdp_handle;
+    }
+
+    /* add service class */
+    status &= esp_bt_sdp_add_service_class_id_list(sdp_handle, 1, &service);
+    memset( protoList, 0 , 3*sizeof(sdp_proto_elem_t) );
+
+    /* add protocol list, including RFCOMM scn */
+    protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+    protoList[0].num_params = 0;
+    protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+    protoList[1].num_params = 1;
+    protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
+    protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
+    protoList[2].num_params = 0;
+    status &= esp_bt_sdp_add_protocol_list(sdp_handle, 3, protoList);
+
+    /* Add a name entry */
+    status &= esp_bt_sdp_add_attribute(sdp_handle,
+                    (UINT16)ATTR_ID_SERVICE_NAME,
+                    (UINT8)TEXT_STR_DESC_TYPE,
+                    (UINT32)(rec->hdr.service_name_length + 1),
+                    (UINT8 *)rec->hdr.service_name);
+
+    /* Add in the Bluetooth Profile Descriptor List */
+    status &= esp_bt_sdp_add_profile_dscp_list(sdp_handle,
+                                     UUID_SERVCLASS_MAP_PROFILE,
+                                     rec->hdr.profile_version);
+
+    /* Add MAS instance ID */
+    status &= esp_bt_sdp_add_attribute(sdp_handle, ATTR_ID_MAS_INSTANCE_ID, UINT_DESC_TYPE,
+              (UINT32)1, (UINT8*)&rec->mas_instance_id);
+
+    /* Add supported message types */
+    status &= esp_bt_sdp_add_attribute(sdp_handle, ATTR_ID_SUPPORTED_MSG_TYPE, UINT_DESC_TYPE,
+              (UINT32)1, (UINT8*)&rec->supported_message_types);
+
+    /* Add supported feature */
+    UINT32_TO_BE_STREAM(p_temp, rec->supported_features);
+    status &= esp_bt_sdp_add_attribute(sdp_handle, ATTR_ID_MAP_SUPPORTED_FEATURES,
+            UINT_DESC_TYPE, (UINT32)4, temp);
+
+    /* Add the L2CAP PSM if present */
+    if(rec->hdr.l2cap_psm != -1) {
+        p_temp = temp;// The macro modifies p_temp, hence rewind.
+        UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
+        status &= esp_bt_sdp_add_attribute(sdp_handle, ATTR_ID_GOEP_L2CAP_PSM,
+                UINT_DESC_TYPE, (UINT32)2, temp);
+    }
+
+    /* Make the service browseable */
+    status &= esp_bt_sdp_add_uuid_sequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
+
+    if (!status)
+    {
+        esp_bt_sdp_delete_record(sdp_handle);
+        sdp_handle = 0;
+        APPL_TRACE_ERROR("%s() FAILED\n", __func__);
+    }
+    else
+    {
+        bta_sys_add_uuid(service);  /* UUID_SERVCLASS_MESSAGE_ACCESS */
+        APPL_TRACE_DEBUG("%s():  SDP Registered (handle 0x%08x)\n", __func__, sdp_handle);
+    }
+    return sdp_handle;
+}
+
+
+/* Create a MAP MNS SDP record based on information stored in a bluetooth_sdp_mns_record */
+static int add_mapc_sdp(const bluetooth_sdp_mns_record* rec)
+{
+
+    sdp_proto_elem_t  protoList [3];
+    UINT16              service = UUID_SERVCLASS_MESSAGE_NOTIFICATION;
+    UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+    BOOLEAN             status = TRUE;
+    UINT32              sdp_handle = 0;
+    UINT8               temp[4];
+    UINT8*              p_temp = temp;
+
+    APPL_TRACE_DEBUG("%s(): scn 0x%02x, psm = 0x%04x\n  service name %s\n", __func__,
+            rec->hdr.rfcomm_channel_number, rec->hdr.l2cap_psm, rec->hdr.service_name);
+
+    APPL_TRACE_DEBUG("  feature_bits: 0x%08x\n", rec->supported_features);
+
+    if ((sdp_handle = esp_bt_sdp_create_record()) == 0)
+    {
+        APPL_TRACE_ERROR("%s(): Unable to register MAP Notification Service\n", __func__);
+        return sdp_handle;
+    }
+
+    /* add service class */
+    status &= esp_bt_sdp_add_service_class_id_list(sdp_handle, 1, &service);
+    memset( protoList, 0 , 3*sizeof(sdp_proto_elem_t) );
+
+    /* add protocol list, including RFCOMM scn */
+    protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+    protoList[0].num_params = 0;
+    protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+    protoList[1].num_params = 1;
+    protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
+    protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
+    protoList[2].num_params = 0;
+    status &= esp_bt_sdp_add_protocol_list(sdp_handle, 3, protoList);
+
+    /* Add a name entry */
+    status &= esp_bt_sdp_add_attribute(sdp_handle,
+                    (UINT16)ATTR_ID_SERVICE_NAME,
+                    (UINT8)TEXT_STR_DESC_TYPE,
+                    (UINT32)(rec->hdr.service_name_length + 1),
+                    (UINT8 *)rec->hdr.service_name);
+
+    /* Add in the Bluetooth Profile Descriptor List */
+    status &= esp_bt_sdp_add_profile_dscp_list(sdp_handle,
+                                     UUID_SERVCLASS_MAP_PROFILE,
+                                     rec->hdr.profile_version);
+
+    /* Add supported feature */
+    UINT32_TO_BE_STREAM(p_temp, rec->supported_features);
+    status &= esp_bt_sdp_add_attribute(sdp_handle, ATTR_ID_MAP_SUPPORTED_FEATURES,
+            UINT_DESC_TYPE, (UINT32)4, temp);
+
+    /* Add the L2CAP PSM if present */
+    if(rec->hdr.l2cap_psm != -1) {
+        p_temp = temp;// The macro modifies p_temp, hence rewind.
+        UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
+        status &= esp_bt_sdp_add_attribute(sdp_handle, ATTR_ID_GOEP_L2CAP_PSM,
+                UINT_DESC_TYPE, (UINT32)2, temp);
+    }
+
+    /* Make the service browseable */
+    status &= esp_bt_sdp_add_uuid_sequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
+
+    if (!status)
+    {
+        esp_bt_sdp_delete_record(sdp_handle);
+        sdp_handle = 0;
+        APPL_TRACE_ERROR("%s() FAILED\n", __func__);
+    }
+    else
+    {
+        bta_sys_add_uuid(service);  /* UUID_SERVCLASS_MESSAGE_ACCESS */
+        APPL_TRACE_DEBUG("%s():  SDP Registered (handle 0x%08x)\n", __func__, sdp_handle);
+    }
+    return sdp_handle;
+}
+
+/* Create a PBAP Server SDP record based on information stored in a bluetooth_sdp_pse_record */
+static int add_pbaps_sdp(const bluetooth_sdp_pse_record* rec)
+{
+
+    sdp_proto_elem_t  protoList [3];
+    UINT16              service = UUID_SERVCLASS_PBAP_PSE;
+    UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+    BOOLEAN             status = TRUE;
+    UINT32              sdp_handle = 0;
+    UINT8               temp[4];
+    UINT8*              p_temp = temp;
+
+    APPL_TRACE_DEBUG("%s(): scn 0x%02x, psm = 0x%04x\n  service name %s\n", __func__,
+            rec->hdr.rfcomm_channel_number, rec->hdr.l2cap_psm, rec->hdr.service_name);
+
+    APPL_TRACE_DEBUG("  supported_repositories: 0x%08x, feature_bits: 0x%08x\n",
+            rec->supported_repositories, rec->supported_features);
+
+    if ((sdp_handle = esp_bt_sdp_create_record()) == 0)
+    {
+        APPL_TRACE_ERROR("%s(): Unable to register PBAP Server Service\n", __func__);
+        return sdp_handle;
+    }
+
+    /* add service class */
+    status &= esp_bt_sdp_add_service_class_id_list(sdp_handle, 1, &service);
+    memset( protoList, 0 , 3*sizeof(sdp_proto_elem_t) );
+
+    /* add protocol list, including RFCOMM scn */
+    protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+    protoList[0].num_params = 0;
+    protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+    protoList[1].num_params = 1;
+    protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
+    protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
+    protoList[2].num_params = 0;
+    status &= esp_bt_sdp_add_protocol_list(sdp_handle, 3, protoList);
+
+    /* Add a name entry */
+    status &= esp_bt_sdp_add_attribute(sdp_handle,
+                    (UINT16)ATTR_ID_SERVICE_NAME,
+                    (UINT8)TEXT_STR_DESC_TYPE,
+                    (UINT32)(rec->hdr.service_name_length + 1),
+                    (UINT8 *)rec->hdr.service_name);
+
+    /* Add in the Bluetooth Profile Descriptor List */
+    status &= esp_bt_sdp_add_profile_dscp_list(sdp_handle,
+                                     UUID_SERVCLASS_PHONE_ACCESS,
+                                     rec->hdr.profile_version);
+
+    /* Add supported repositories 1 byte */
+    status &= esp_bt_sdp_add_attribute(sdp_handle, ATTR_ID_SUPPORTED_REPOSITORIES,
+            UINT_DESC_TYPE, (UINT32)1, (UINT8*)&rec->supported_repositories);
+
+    /* Add supported feature 4 bytes*/
+    UINT32_TO_BE_STREAM(p_temp, rec->supported_features);
+    status &= esp_bt_sdp_add_attribute(sdp_handle, ATTR_ID_PBAP_SUPPORTED_FEATURES,
+            UINT_DESC_TYPE, (UINT32)4, temp);
+
+    /* Add the L2CAP PSM if present */
+    if(rec->hdr.l2cap_psm != -1) {
+        p_temp = temp;// The macro modifies p_temp, hence rewind.
+        UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
+        status &= esp_bt_sdp_add_attribute(sdp_handle, ATTR_ID_GOEP_L2CAP_PSM,
+                UINT_DESC_TYPE, (UINT32)2, temp);
+    }
+
+    /* Make the service browseable */
+    status &= esp_bt_sdp_add_uuid_sequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
+
+    if (!status)
+    {
+        esp_bt_sdp_delete_record(sdp_handle);
+        sdp_handle = 0;
+        APPL_TRACE_ERROR("%s() FAILED\n", __func__);
+    }
+    else
+    {
+        bta_sys_add_uuid(service);  /* UUID_SERVCLASS_MESSAGE_ACCESS */
+        APPL_TRACE_DEBUG("%s():  SDP Registered (handle 0x%08x)\n", __func__, sdp_handle);
+    }
+    return sdp_handle;
+}
+
+
+/* Create a OPP Server SDP record based on information stored in a bluetooth_sdp_ops_record */
+static int add_opps_sdp(const bluetooth_sdp_ops_record* rec)
+{
+
+    sdp_proto_elem_t  protoList [3];
+    UINT16              service = UUID_SERVCLASS_OBEX_OBJECT_PUSH;
+    UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+    UINT8               type_len[rec->supported_formats_list_len];
+    UINT8               desc_type[rec->supported_formats_list_len];
+    UINT8              *type_value[rec->supported_formats_list_len];
+    BOOLEAN             status = TRUE;
+    UINT32              sdp_handle = 0;
+    UINT8               temp[4];
+    UINT8*              p_temp = temp;
+    tBTA_UTL_COD        cod;
+    int i,j;
+
+    APPL_TRACE_DEBUG("%s(): scn 0x%02x, psm = 0x%04x\n  service name %s\n", __func__,
+            rec->hdr.rfcomm_channel_number, rec->hdr.l2cap_psm, rec->hdr.service_name);
+
+    APPL_TRACE_DEBUG("  supported formats count: %d\n",
+            rec->supported_formats_list_len);
+
+    if ((sdp_handle = esp_bt_sdp_create_record()) == 0)
+    {
+        APPL_TRACE_ERROR("%s(): Unable to register Object Push Server Service\n", __func__);
+        return sdp_handle;
+    }
+
+    /* add service class */
+    status &= esp_bt_sdp_add_service_class_id_list(sdp_handle, 1, &service);
+    memset( protoList, 0 , 3*sizeof(sdp_proto_elem_t) );
+
+    /* add protocol list, including RFCOMM scn */
+    protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+    protoList[0].num_params = 0;
+    protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+    protoList[1].num_params = 1;
+    protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
+    protoList[2].protocol_uuid = UUID_PROTOCOL_OBEX;
+    protoList[2].num_params = 0;
+    status &= esp_bt_sdp_add_protocol_list(sdp_handle, 3, protoList);
+
+    /* Add a name entry */
+    status &= esp_bt_sdp_add_attribute(sdp_handle,
+                    (UINT16)ATTR_ID_SERVICE_NAME,
+                    (UINT8)TEXT_STR_DESC_TYPE,
+                    (UINT32)(rec->hdr.service_name_length + 1),
+                    (UINT8 *)rec->hdr.service_name);
+
+    /* Add in the Bluetooth Profile Descriptor List */
+    status &= esp_bt_sdp_add_profile_dscp_list(sdp_handle,
+                                     UUID_SERVCLASS_OBEX_OBJECT_PUSH,
+                                     rec->hdr.profile_version);
+
+    /* add sequence for supported types */
+    for (i = 0, j = 0; i < rec->supported_formats_list_len; i++)
+    {
+        type_value[j] = (UINT8 *) &rec->supported_formats_list[i];
+        desc_type[j] = UINT_DESC_TYPE;
+        type_len[j++] = 1;
+    }
+
+    status &= esp_bt_sdp_add_sequence(sdp_handle, (UINT16) ATTR_ID_SUPPORTED_FORMATS_LIST,
+        (UINT8) rec->supported_formats_list_len, desc_type, type_len, type_value);
+
+    /* Add the L2CAP PSM if present */
+    if(rec->hdr.l2cap_psm != -1) {
+        p_temp = temp;// The macro modifies p_temp, hence rewind.
+        UINT16_TO_BE_STREAM(p_temp, rec->hdr.l2cap_psm);
+        status &= esp_bt_sdp_add_attribute(sdp_handle, ATTR_ID_GOEP_L2CAP_PSM,
+                UINT_DESC_TYPE, (UINT32)2, temp);
+    }
+
+    /* Make the service browseable */
+    status &= esp_bt_sdp_add_uuid_sequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
+
+    if (!status)
+    {
+        esp_bt_sdp_delete_record(sdp_handle);
+        sdp_handle = 0;
+        APPL_TRACE_ERROR("%s() FAILED\n", __func__);
+    }
+    else
+    {
+        /* set class of device */
+        cod.service = BTM_COD_SERVICE_OBJ_TRANSFER;
+        utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
+
+        bta_sys_add_uuid(service);  /* UUID_SERVCLASS_OBEX_OBJECT_PUSH */
+        APPL_TRACE_DEBUG("%s():  SDP Registered (handle 0x%08x)\n", __func__, sdp_handle);
+    }
+    return sdp_handle;
+}
+
+// Create a Sim Access Profile SDP record based on information stored in a bluetooth_sdp_sap_record.
+static int add_saps_sdp(const bluetooth_sdp_sap_record* rec)
+{
+    sdp_proto_elem_t  protoList [2];
+    UINT16              services[2];
+    UINT16              browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
+    BOOLEAN             status = TRUE;
+    UINT32              sdp_handle = 0;
+
+    APPL_TRACE_DEBUG("%s(): scn 0x%02x, service name %s\n", __func__,
+            rec->hdr.rfcomm_channel_number, rec->hdr.service_name);
+
+    if ((sdp_handle = esp_bt_sdp_create_record()) == 0)
+    {
+        APPL_TRACE_ERROR("%s(): Unable to register SAPS Service\n", __func__);
+        return sdp_handle;
+    }
+
+    services[0] = UUID_SERVCLASS_SAP;
+    services[1] = UUID_SERVCLASS_GENERIC_TELEPHONY;
+
+    // add service class
+    status &= esp_bt_sdp_add_service_class_id_list(sdp_handle, 2, services);
+    memset(protoList, 0, 2 * sizeof(sdp_proto_elem_t));
+
+    // add protocol list, including RFCOMM scn
+    protoList[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
+    protoList[0].num_params = 0;
+    protoList[1].protocol_uuid = UUID_PROTOCOL_RFCOMM;
+    protoList[1].num_params = 1;
+    protoList[1].params[0] = rec->hdr.rfcomm_channel_number;
+    status &= esp_bt_sdp_add_protocol_list(sdp_handle, 2, protoList);
+
+    // Add a name entry
+    status &= esp_bt_sdp_add_attribute(sdp_handle,
+                    (UINT16)ATTR_ID_SERVICE_NAME,
+                    (UINT8)TEXT_STR_DESC_TYPE,
+                    (UINT32)(rec->hdr.service_name_length + 1),
+                    (UINT8 *)rec->hdr.service_name);
+
+    // Add in the Bluetooth Profile Descriptor List
+    status &= esp_bt_sdp_add_profile_dscp_list(sdp_handle,
+            UUID_SERVCLASS_SAP,
+            rec->hdr.profile_version);
+
+    // Make the service browseable
+    status &= esp_bt_sdp_add_uuid_sequence (sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse);
+
+    if (!status)
+    {
+        esp_bt_sdp_delete_record(sdp_handle);
+        sdp_handle = 0;
+        APPL_TRACE_ERROR("%s(): FAILED deleting record\n", __func__);
+    }
+    else
+    {
+        bta_sys_add_uuid(UUID_SERVCLASS_SAP);
+        APPL_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)\n", __func__, sdp_handle);
+    }
+    return sdp_handle;
+}
+

+ 208 - 0
examples/09_a2dp/components/bluedroid_demos/btif/btif_sm.c

@@ -0,0 +1,208 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+
+/*****************************************************************************
+ *
+ *  Filename:      btif_sm.c
+ *
+ *  Description:   Generic BTIF state machine API
+ *
+ *****************************************************************************/
+
+#define LOG_TAG "bt_btif"
+
+// #include <hardware/bluetooth.h>
+#include "bt_defs.h"
+#include "allocator.h"
+#include "btif_common.h"
+#include "btif_sm.h"
+#include "gki.h"
+
+/*****************************************************************************
+**  Constants & Macros
+******************************************************************************/
+
+
+/*****************************************************************************
+**  Local type definitions
+******************************************************************************/
+typedef struct {
+    btif_sm_state_t         state;
+    btif_sm_handler_t       *p_handlers;
+} btif_sm_cb_t;
+
+/*****************************************************************************
+**  Static variables
+******************************************************************************/
+
+/*****************************************************************************
+**  Static functions
+******************************************************************************/
+
+/*****************************************************************************
+**  Externs
+******************************************************************************/
+
+/*****************************************************************************
+**  Functions
+******************************************************************************/
+
+/*****************************************************************************
+**
+** Function     btif_sm_init
+**
+** Description  Initializes the state machine with the state handlers
+**              The caller should ensure that the table and the corresponding
+**              states match. The location that 'p_handlers' points to shall
+**              be available until the btif_sm_shutdown API is invoked.
+**
+** Returns      Returns a pointer to the initialized state machine handle.
+**
+******************************************************************************/
+
+btif_sm_handle_t btif_sm_init(const btif_sm_handler_t *p_handlers, btif_sm_state_t initial_state)
+{
+    btif_sm_cb_t *p_cb;
+
+    if (p_handlers == NULL)
+    {
+        BTIF_TRACE_ERROR("%s : p_handlers is NULL", __FUNCTION__);
+        return NULL;
+    }
+
+    p_cb = (btif_sm_cb_t *)osi_malloc(sizeof(btif_sm_cb_t));
+    p_cb->state = initial_state;
+    p_cb->p_handlers = (btif_sm_handler_t*)p_handlers;
+
+    /* Send BTIF_SM_ENTER_EVT to the initial state */
+    p_cb->p_handlers[initial_state](BTIF_SM_ENTER_EVT, NULL);
+
+    return (btif_sm_handle_t)p_cb;
+}
+
+/*****************************************************************************
+**
+** Function     btif_sm_shutdown
+**
+** Description  Tears down the state machine
+**
+** Returns      None
+**
+******************************************************************************/
+void btif_sm_shutdown(btif_sm_handle_t handle)
+{
+    btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
+
+    if (p_cb == NULL)
+    {
+        BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
+        return;
+    }
+    osi_free(p_cb);
+}
+
+/*****************************************************************************
+**
+** Function     btif_sm_get_state
+**
+** Description  Fetches the current state of the state machine
+**
+** Returns      Current state
+**
+******************************************************************************/
+btif_sm_state_t btif_sm_get_state(btif_sm_handle_t handle)
+{
+    btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
+
+    if (p_cb == NULL)
+    {
+        BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
+        return 0;
+    }
+
+    return p_cb->state;
+}
+
+/*****************************************************************************
+**
+** Function     btif_sm_dispatch
+**
+** Description  Dispatches the 'event' along with 'data' to the current state handler
+**
+** Returns      BT_STATUS_SUCCESS on success
+**              BT_STATUS_UNHANDLED if event was not processed
+**              BT_STATUS_FAIL otherwise
+**
+******************************************************************************/
+bt_status_t btif_sm_dispatch(btif_sm_handle_t handle, btif_sm_event_t event,
+                                void *data)
+{
+    bt_status_t status = BT_STATUS_SUCCESS;
+
+    btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
+
+    if (p_cb == NULL)
+    {
+        BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
+        return BT_STATUS_FAIL;
+    }
+
+    if (p_cb->p_handlers[p_cb->state](event, data) == FALSE)
+        return BT_STATUS_UNHANDLED;
+
+    return status;
+}
+
+/*****************************************************************************
+**
+** Function     btif_sm_change_state
+**
+** Description  Make a transition to the new 'state'. The 'BTIF_SM_EXIT_EVT'
+**              shall be invoked before exiting the current state. The
+**              'BTIF_SM_ENTER_EVT' shall be invoked before entering the new state
+**
+** Returns      BT_STATUS_SUCCESS on success
+**              BT_STATUS_UNHANDLED if event was not processed
+**              BT_STATUS_FAIL otherwise
+**
+******************************************************************************/
+bt_status_t btif_sm_change_state(btif_sm_handle_t handle, btif_sm_state_t state)
+{
+    bt_status_t status = BT_STATUS_SUCCESS;
+    btif_sm_cb_t *p_cb = (btif_sm_cb_t*)handle;
+
+    if (p_cb == NULL)
+    {
+        BTIF_TRACE_ERROR("%s : Invalid handle", __FUNCTION__);
+        return BT_STATUS_FAIL;
+    }
+
+    /* Send exit event to the current state */
+    if (p_cb->p_handlers[p_cb->state](BTIF_SM_EXIT_EVT, NULL) == FALSE)
+        status = BT_STATUS_UNHANDLED;
+
+    /* Change to the new state */
+    p_cb->state = state;
+
+    /* Send enter event to the new state */
+    if (p_cb->p_handlers[p_cb->state](BTIF_SM_ENTER_EVT, NULL) == FALSE)
+        status = BT_STATUS_UNHANDLED;
+
+    return status;
+}

+ 159 - 0
examples/09_a2dp/components/bluedroid_demos/btif/btif_util.c

@@ -0,0 +1,159 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2014 The Android Open Source Project
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/************************************************************************************
+ *
+ *  Filename:      btif_util.c
+ *
+ *  Description:   Miscellaneous helper functions
+ *
+ *
+ ***********************************************************************************/
+
+// #include <hardware/bluetooth.h>
+// #include <hardware/bt_hf.h>
+// #include <hardware/bt_av.h>
+// #include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+
+#define LOG_TAG "bt_btif_util"
+// #include "btif_common.h"
+// #include "bta_api.h"
+// #include "gki.h"
+// #include "btu.h"
+// #include "bte.h"
+// #include "btif_dm.h"
+#include "btif_util.h"
+// #include "bta_ag_api.h"
+// #include "bta_av_api.h"
+// #include "bta_hh_api.h"
+// #include "bta_hf_client_api.h"
+// #include "avrc_defs.h"
+#include "bt_defs.h"
+
+/************************************************************************************
+**  Constants & Macros
+************************************************************************************/
+#define ISDIGIT(a)  ((a>='0') && (a<='9'))
+#define ISXDIGIT(a) (((a>='0') && (a<='9'))||((a>='A') && (a<='F'))||((a>='a') && (a<='f')))
+
+/************************************************************************************
+**  Local type definitions
+************************************************************************************/
+
+/************************************************************************************
+**  Static variables
+************************************************************************************/
+
+/************************************************************************************
+**  Static functions
+************************************************************************************/
+
+/************************************************************************************
+**  Externs
+************************************************************************************/
+
+/************************************************************************************
+**  Functions
+************************************************************************************/
+
+/*****************************************************************************
+**   Logging helper functions
+*****************************************************************************/
+
+UINT32 devclass2uint(DEV_CLASS dev_class)
+{
+    UINT32 cod = 0;
+
+    if(dev_class != NULL)
+    {
+        /* if COD is 0, irrespective of the device type set it to Unclassified device */
+        cod = (dev_class[2]) | (dev_class[1] << 8) | (dev_class[0] << 16);
+    }
+    return cod;
+}
+void uint2devclass(UINT32 cod, DEV_CLASS dev_class)
+{
+    dev_class[2] = (UINT8)cod;
+    dev_class[1] = (UINT8)(cod >> 8);
+    dev_class[0] = (UINT8)(cod >> 16);
+}
+
+static const UINT8  sdp_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+                                       0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB};
+
+void uuid16_to_uuid128(uint16_t uuid16, bt_uuid_t* uuid128)
+{
+    uint16_t uuid16_bo;
+    memset(uuid128, 0, sizeof(bt_uuid_t));
+
+    memcpy(uuid128->uu, sdp_base_uuid, MAX_UUID_SIZE);
+    uuid16_bo = ntohs(uuid16);
+    memcpy(uuid128->uu + 2, &uuid16_bo, sizeof(uint16_t));
+}
+
+void string_to_uuid(char *str, bt_uuid_t *p_uuid)
+{
+    uint32_t uuid0, uuid4;
+    uint16_t uuid1, uuid2, uuid3, uuid5;
+
+    sscanf(str, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
+                &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
+
+    uuid0 = htonl(uuid0);
+    uuid1 = htons(uuid1);
+    uuid2 = htons(uuid2);
+    uuid3 = htons(uuid3);
+    uuid4 = htonl(uuid4);
+    uuid5 = htons(uuid5);
+
+    memcpy(&(p_uuid->uu[0]), &uuid0, 4);
+    memcpy(&(p_uuid->uu[4]), &uuid1, 2);
+    memcpy(&(p_uuid->uu[6]), &uuid2, 2);
+    memcpy(&(p_uuid->uu[8]), &uuid3, 2);
+    memcpy(&(p_uuid->uu[10]), &uuid4, 4);
+    memcpy(&(p_uuid->uu[14]), &uuid5, 2);
+
+    return;
+
+}
+
+void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str)
+{
+    uint32_t uuid0, uuid4;
+    uint16_t uuid1, uuid2, uuid3, uuid5;
+
+    memcpy(&uuid0, &(p_uuid->uu[0]), 4);
+    memcpy(&uuid1, &(p_uuid->uu[4]), 2);
+    memcpy(&uuid2, &(p_uuid->uu[6]), 2);
+    memcpy(&uuid3, &(p_uuid->uu[8]), 2);
+    memcpy(&uuid4, &(p_uuid->uu[10]), 4);
+    memcpy(&uuid5, &(p_uuid->uu[14]), 2);
+
+    sprintf((char *)str, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
+            ntohl(uuid0), ntohs(uuid1),
+            ntohs(uuid2), ntohs(uuid3),
+            ntohl(uuid4), ntohs(uuid5));
+    return;
+}
+

+ 88 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/btif_api.h

@@ -0,0 +1,88 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *
+ *  Filename:      btif_api.h
+ *
+ *  Description:   Main API header file for all BTIF functions accessed
+ *                 from main bluetooth HAL. All HAL extensions will not
+ *                 require headerfiles as they would be accessed through
+ *                 callout/callins.
+ *
+ *******************************************************************************/
+
+#ifndef BTIF_API_H
+#define BTIF_API_H
+
+#include "btif_common.h"
+#include "btif_dm.h"
+
+/*******************************************************************************
+**  BTIF CORE API
+********************************************************************************/
+
+/*******************************************************************************
+**
+** Function         btif_init_bluetooth
+**
+** Description      Creates BTIF task and prepares BT scheduler for startup
+**
+** Returns          bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_init_bluetooth(void);
+
+/*******************************************************************************
+**
+** Function         btif_enable_bluetooth
+**
+** Description      Performs chip power on and kickstarts OS scheduler
+**
+** Returns          bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_enable_bluetooth(void);
+
+/*******************************************************************************
+**
+** Function         btif_disable_bluetooth
+**
+** Description      Inititates shutdown of Bluetooth system.
+**                  Any active links will be dropped and device entering
+**                  non connectable/discoverable mode
+**
+** Returns          void
+**
+*******************************************************************************/
+bt_status_t btif_disable_bluetooth(void);
+
+/*******************************************************************************
+**
+** Function         btif_shutdown_bluetooth
+**
+** Description      Finalizes BT scheduler shutdown and terminates BTIF
+**                  task.
+**
+**
+** Returns          void
+**
+*******************************************************************************/
+bt_status_t btif_shutdown_bluetooth(void);
+
+#endif /* BTIF_API_H */

+ 154 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/btif_av.h

@@ -0,0 +1,154 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *
+ *  Filename:      btif_av.h
+ *
+ *  Description:   Main API header file for all BTIF AV functions accessed
+ *                 from internal stack.
+ *
+ *******************************************************************************/
+
+#ifndef BTIF_AV_H
+#define BTIF_AV_H
+
+#include "btif_common.h"
+#include "btif_sm.h"
+#include "bta_av_api.h"
+
+
+/*******************************************************************************
+**  Type definitions for callback functions
+********************************************************************************/
+
+typedef enum {
+    /* Reuse BTA_AV_XXX_EVT - No need to redefine them here */
+    BTIF_AV_CONNECT_REQ_EVT = BTA_AV_MAX_EVT,
+    BTIF_AV_DISCONNECT_REQ_EVT,
+    BTIF_AV_START_STREAM_REQ_EVT,
+    BTIF_AV_STOP_STREAM_REQ_EVT,
+    BTIF_AV_SUSPEND_STREAM_REQ_EVT,
+    BTIF_AV_SINK_CONFIG_REQ_EVT,
+} btif_av_sm_event_t;
+
+
+/*******************************************************************************
+**  BTIF AV API
+********************************************************************************/
+
+/*******************************************************************************
+**
+** Function         btif_av_get_sm_handle
+**
+** Description      Fetches current av SM handle
+**
+** Returns          None
+**
+*******************************************************************************/
+
+btif_sm_handle_t btif_av_get_sm_handle(void);
+
+/*******************************************************************************
+**
+** Function         btif_av_stream_ready
+**
+** Description      Checks whether AV is ready for starting a stream
+**
+** Returns          None
+**
+*******************************************************************************/
+
+BOOLEAN btif_av_stream_ready(void);
+
+/*******************************************************************************
+**
+** Function         btif_av_stream_started_ready
+**
+** Description      Checks whether AV ready for media start in streaming state
+**
+** Returns          None
+**
+*******************************************************************************/
+
+BOOLEAN btif_av_stream_started_ready(void);
+
+/*******************************************************************************
+**
+** Function         btif_dispatch_sm_event
+**
+** Description      Send event to AV statemachine
+**
+** Returns          None
+**
+*******************************************************************************/
+
+/* used to pass events to AV statemachine from other tasks */
+void btif_dispatch_sm_event(btif_av_sm_event_t event, void *p_data, int len);
+
+/*******************************************************************************
+**
+** Function         btif_av_init
+**
+** Description      Initializes btif AV if not already done
+**
+** Returns          bt_status_t
+**
+*******************************************************************************/
+
+bt_status_t btif_av_init(void);
+
+/*******************************************************************************
+**
+** Function         btif_av_is_connected
+**
+** Description      Checks if av has a connected sink
+**
+** Returns          BOOLEAN
+**
+*******************************************************************************/
+
+BOOLEAN btif_av_is_connected(void);
+
+
+/*******************************************************************************
+**
+** Function         btif_av_is_peer_edr
+**
+** Description      Check if the connected a2dp device supports
+**                  EDR or not. Only when connected this function
+**                  will accurately provide a true capability of
+**                  remote peer. If not connected it will always be false.
+**
+** Returns          TRUE if remote device is capable of EDR
+**
+*******************************************************************************/
+
+BOOLEAN btif_av_is_peer_edr(void);
+
+/******************************************************************************
+**
+** Function         btif_av_clear_remote_suspend_flag
+**
+** Description      Clears remote suspended flag
+**
+** Returns          Void
+********************************************************************************/
+void btif_av_clear_remote_suspend_flag(void);
+
+#endif /* BTIF_AV_H */

+ 210 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/btif_av_api.h

@@ -0,0 +1,210 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/*****************************************************************************
+ **
+ **  Name:           btif_av_api.h
+ **
+ **  Description:    This is the public interface file for the advanced
+ **                  audio/video streaming (AV) subsystem of BTIF, Broadcom's
+ **                  Bluetooth application layer for mobile phones.
+ **
+ *****************************************************************************/
+
+#ifndef BTIF_AV_API_H
+#define BTIF_AV_API_H
+
+#include "bt_target.h"
+#include "bta_av_api.h"
+#include "uipc.h"
+
+#include "btif_media.h"
+#include "a2d_api.h"
+#include "a2d_sbc.h"
+
+
+/*****************************************************************************
+ **  Constants and data types
+ *****************************************************************************/
+
+/* Codec type */
+#define BTIF_AV_CODEC_NONE       0xFF
+#define BTIF_AV_CODEC_SBC        A2D_MEDIA_CT_SBC        /* SBC media codec type */
+
+#define BTIF_AV_CODEC_PCM        0x5                     /* Raw PCM */
+
+typedef UINT8 tBTIF_AV_CODEC_ID;
+
+/* AV features masks */
+#define BTIF_AV_FEAT_RCTG        BTA_AV_FEAT_RCTG      /* remote control target */
+#define BTIF_AV_FEAT_RCCT        BTA_AV_FEAT_RCCT      /* remote control controller */
+#define BTIF_AV_FEAT_METADATA    BTA_AV_FEAT_METADATA  /* remote control Metadata Transfer command/response */
+
+typedef UINT16 tBTIF_AV_FEAT;
+
+/* AV channel values */
+#define BTIF_AV_CHNL_MSK         BTA_AV_CHNL_MSK
+#define BTIF_AV_CHNL_AUDIO       BTA_AV_CHNL_AUDIO       /* audio channel */
+#define BTIF_AV_CHNL_VIDEO       BTA_AV_CHNL_VIDEO       /* video channel */
+typedef UINT8 tBTIF_AV_CHNL;
+
+typedef UINT8 tBTIF_AV_HNDL;
+
+/* Operation id list for BTIF_AvRemoteCmd */
+#define BTIF_AV_ID_SELECT      0x00    /* select */
+#define BTIF_AV_ID_UP          0x01    /* up */
+#define BTIF_AV_ID_DOWN        0x02    /* down */
+#define BTIF_AV_ID_LEFT        0x03    /* left */
+#define BTIF_AV_ID_RIGHT       0x04    /* right */
+#define BTIF_AV_ID_RIGHT_UP    0x05    /* right-up */
+#define BTIF_AV_ID_RIGHT_DOWN  0x06    /* right-down */
+#define BTIF_AV_ID_LEFT_UP     0x07    /* left-up */
+#define BTIF_AV_ID_LEFT_DOWN   0x08    /* left-down */
+#define BTIF_AV_ID_ROOT_MENU   0x09    /* root menu */
+#define BTIF_AV_ID_SETUP_MENU  0x0A    /* setup menu */
+#define BTIF_AV_ID_CONT_MENU   0x0B    /* contents menu */
+#define BTIF_AV_ID_FAV_MENU    0x0C    /* favorite menu */
+#define BTIF_AV_ID_EXIT        0x0D    /* exit */
+#define BTIF_AV_ID_0           0x20    /* 0 */
+#define BTIF_AV_ID_1           0x21    /* 1 */
+#define BTIF_AV_ID_2           0x22    /* 2 */
+#define BTIF_AV_ID_3           0x23    /* 3 */
+#define BTIF_AV_ID_4           0x24    /* 4 */
+#define BTIF_AV_ID_5           0x25    /* 5 */
+#define BTIF_AV_ID_6           0x26    /* 6 */
+#define BTIF_AV_ID_7           0x27    /* 7 */
+#define BTIF_AV_ID_8           0x28    /* 8 */
+#define BTIF_AV_ID_9           0x29    /* 9 */
+#define BTIF_AV_ID_DOT         0x2A    /* dot */
+#define BTIF_AV_ID_ENTER       0x2B    /* enter */
+#define BTIF_AV_ID_CLEAR       0x2C    /* clear */
+#define BTIF_AV_ID_CHAN_UP     0x30    /* channel up */
+#define BTIF_AV_ID_CHAN_DOWN   0x31    /* channel down */
+#define BTIF_AV_ID_PREV_CHAN   0x32    /* previous channel */
+#define BTIF_AV_ID_SOUND_SEL   0x33    /* sound select */
+#define BTIF_AV_ID_INPUT_SEL   0x34    /* input select */
+#define BTIF_AV_ID_DISP_INFO   0x35    /* display information */
+#define BTIF_AV_ID_HELP        0x36    /* help */
+#define BTIF_AV_ID_PAGE_UP     0x37    /* page up */
+#define BTIF_AV_ID_PAGE_DOWN   0x38    /* page down */
+#define BTIF_AV_ID_POWER       0x40    /* power */
+#define BTIF_AV_ID_VOL_UP      0x41    /* volume up */
+#define BTIF_AV_ID_VOL_DOWN    0x42    /* volume down */
+#define BTIF_AV_ID_MUTE        0x43    /* mute */
+#define BTIF_AV_ID_PLAY        0x44    /* play */
+#define BTIF_AV_ID_STOP        0x45    /* stop */
+#define BTIF_AV_ID_PAUSE       0x46    /* pause */
+#define BTIF_AV_ID_RECORD      0x47    /* record */
+#define BTIF_AV_ID_REWIND      0x48    /* rewind */
+#define BTIF_AV_ID_FAST_FOR    0x49    /* fast forward */
+#define BTIF_AV_ID_EJECT       0x4A    /* eject */
+#define BTIF_AV_ID_FORWARD     0x4B    /* forward */
+#define BTIF_AV_ID_BACKWARD    0x4C    /* backward */
+#define BTIF_AV_ID_ANGLE       0x50    /* angle */
+#define BTIF_AV_ID_SUBPICT     0x51    /* subpicture */
+#define BTIF_AV_ID_F1          0x71    /* F1 */
+#define BTIF_AV_ID_F2          0x72    /* F2 */
+#define BTIF_AV_ID_F3          0x73    /* F3 */
+#define BTIF_AV_ID_F4          0x74    /* F4 */
+#define BTIF_AV_ID_F5          0x75    /* F5 */
+#define BTIF_AV_ID_VENDOR      0x7E    /* vendor unique */
+#define BTIF_AV_KEYPRESSED_RELEASE 0x80
+
+typedef UINT8 tBTIF_AV_RC;
+
+/* State flag for pass through command */
+#define BTIF_AV_STATE_PRESS      0    /* key pressed */
+#define BTIF_AV_STATE_RELEASE    1  /* key released */
+
+typedef UINT8 tBTIF_AV_STATE;
+
+typedef UINT8 tBTIF_AV_RC_HNDL;
+
+/* Command codes for BTIF_AvVendorCmd */
+#define BTIF_AV_CMD_CTRL         0
+#define BTIF_AV_CMD_STATUS       1
+#define BTIF_AV_CMD_SPEC_INQ     2
+#define BTIF_AV_CMD_NOTIF        3
+#define BTIF_AV_CMD_GEN_INQ      4
+
+typedef UINT8 tBTIF_AV_CMD;
+
+/* AV callback events */
+#define BTIF_AV_OPEN_EVT         0       /* connection opened */
+#define BTIF_AV_CLOSE_EVT        1       /* connection closed */
+#define BTIF_AV_START_EVT        2       /* stream data transfer started */
+#define BTIF_AV_STOP_EVT         3       /* stream data transfer stopped */
+#define BTIF_AV_RC_OPEN_EVT      4       /* remote control channel open */
+#define BTIF_AV_RC_CLOSE_EVT     5       /* remote control channel closed */
+#define BTIF_AV_REMOTE_CMD_EVT   6      /* remote control command */
+#define BTIF_AV_REMOTE_RSP_EVT   7      /* remote control response */
+#define BTIF_AV_META_MSG_EVT     8      /* metadata messages */
+
+typedef UINT8 tBTIF_AV_EVT;
+
+#define BTIF_AV_FEEDING_ASYNCHRONOUS 0   /* asynchronous feeding, use tx av timer */
+#define BTIF_AV_FEEDING_SYNCHRONOUS  1   /* synchronous feeding, no av tx timer */
+
+#define BTIF_AV_MAX_SYNCHRONOUS_LATENCY 80 /* max latency in ms for BTIF_AV_FEEDING_SYNCHRONOUS */
+#define BTIF_AV_MIN_SYNCHRONOUS_LATENCY 4 /* min latency in ms for BTIF_AV_FEEDING_SYNCHRONOUS */
+
+typedef UINT8 tBTIF_AV_FEEDING_MODE;
+
+#define BTIF_AV_CHANNEL_MODE_MONO    A2D_SBC_IE_CH_MD_MONO
+#define BTIF_AV_CHANNEL_MODE_STEREO  A2D_SBC_IE_CH_MD_STEREO
+#define BTIF_AV_CHANNEL_MODE_JOINT   A2D_SBC_IE_CH_MD_JOINT
+#define BTIF_AV_CHANNEL_MODE_DUAL    A2D_SBC_IE_CH_MD_DUAL
+
+typedef UINT8 tBTIF_AV_CHANNEL_MODE;
+
+/**
+ * Structure used to configure the AV codec capabilities/config
+ */
+typedef struct
+{
+    tBTIF_AV_CODEC_ID id;            /* Codec ID (in terms of BTIF) */
+    UINT8 info[AVDT_CODEC_SIZE];     /* Codec info (can be config or capabilities) */
+} tBTIF_AV_CODEC_INFO;
+
+/**
+ * Structure used to configure the AV media feeding
+ */
+typedef struct
+{
+    UINT16 sampling_freq;   /* 44100, 48000 etc */
+    UINT16 num_channel;     /* 1 for mono or 2 stereo */
+    UINT8  bit_per_sample;  /* Number of bits per sample (8, 16) */
+} tBTIF_AV_MEDIA_FEED_CFG_PCM;
+
+typedef union
+{
+    tBTIF_AV_MEDIA_FEED_CFG_PCM pcm;     /* Raw PCM feeding format */
+}tBTIF_AV_MEDIA_FEED_CFG;
+
+typedef struct
+{
+    tBTIF_AV_CODEC_ID format;        /* Media codec identifier */
+    tBTIF_AV_MEDIA_FEED_CFG cfg;     /* Media codec configuration */
+} tBTIF_AV_MEDIA_FEEDINGS;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BTIF_AV_API_H */

+ 174 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/btif_av_co.h

@@ -0,0 +1,174 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef BTIF_AV_CO_H
+#define BTIF_AV_CO_H
+
+#include "btif_media.h"
+
+/*******************************************************************************
+**  Constants & Macros
+********************************************************************************/
+
+enum
+{
+    BTIF_SV_AV_AA_SBC_INDEX = 0,
+    BTIF_SV_AV_AA_SBC_SINK_INDEX,
+    BTIF_SV_AV_AA_SEP_INDEX  /* Last index */
+};
+
+
+/*******************************************************************************
+**  Functions
+********************************************************************************/
+
+/*******************************************************************************
+ **
+ ** Function         bta_av_co_cp_is_active
+ **
+ ** Description      Get the current configuration of content protection
+ **
+ ** Returns          TRUE if the current streaming has CP, FALSE otherwise
+ **
+ *******************************************************************************/
+BOOLEAN bta_av_co_cp_is_active(void);
+
+/*******************************************************************************
+ **
+ ** Function         bta_av_co_cp_get_flag
+ **
+ ** Description      Get content protection flag
+ **                  BTA_AV_CP_SCMS_COPY_NEVER
+ **                  BTA_AV_CP_SCMS_COPY_ONCE
+ **                  BTA_AV_CP_SCMS_COPY_FREE
+ **
+ ** Returns          The current flag value
+ **
+ *******************************************************************************/
+UINT8 bta_av_co_cp_get_flag(void);
+
+/*******************************************************************************
+ **
+ ** Function         bta_av_co_cp_set_flag
+ **
+ ** Description      Set content protection flag
+ **                  BTA_AV_CP_SCMS_COPY_NEVER
+ **                  BTA_AV_CP_SCMS_COPY_ONCE
+ **                  BTA_AV_CP_SCMS_COPY_FREE
+ **
+ ** Returns          TRUE if setting the SCMS flag is supported else FALSE
+ **
+ *******************************************************************************/
+BOOLEAN bta_av_co_cp_set_flag(UINT8 cp_flag);
+
+/*******************************************************************************
+ **
+ ** Function         bta_av_co_audio_codec_reset
+ **
+ ** Description      Reset the current codec configuration
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+void bta_av_co_audio_codec_reset(void);
+
+/*******************************************************************************
+ **
+ ** Function         bta_av_co_audio_codec_supported
+ **
+ ** Description      Check if all opened connections are compatible with a codec
+ **                  configuration
+ **
+ ** Returns          TRUE if all opened devices support this codec, FALSE otherwise
+ **
+ *******************************************************************************/
+BOOLEAN bta_av_co_audio_codec_supported(tBTIF_STATUS *p_status);
+
+/*******************************************************************************
+ **
+ ** Function         bta_av_co_audio_set_codec
+ **
+ ** Description      Set the current codec configuration from the feeding type.
+ **                  This function is starting to modify the configuration, it
+ **                  should be protected.
+ **
+ ** Returns          TRUE if successful, FALSE otherwise
+ **
+ *******************************************************************************/
+BOOLEAN bta_av_co_audio_set_codec(const tBTIF_AV_MEDIA_FEEDINGS *p_feeding, tBTIF_STATUS *p_status);
+
+/*******************************************************************************
+ **
+ ** Function         bta_av_co_audio_get_sbc_config
+ **
+ ** Description      Retrieves the SBC codec configuration.  If the codec in use
+ **                  is not SBC, return the default SBC codec configuration.
+ **
+ ** Returns          TRUE if codec is SBC, FALSE otherwise
+ **
+ *******************************************************************************/
+BOOLEAN bta_av_co_audio_get_sbc_config(tA2D_SBC_CIE *p_sbc_config, UINT16 *p_minmtu);
+
+/*******************************************************************************
+ **
+ ** Function         bta_av_co_audio_discard_config
+ **
+ ** Description      Discard the codec configuration of a connection
+ **
+ ** Returns          Nothing
+ **
+ *******************************************************************************/
+void bta_av_co_audio_discard_config(tBTA_AV_HNDL hndl);
+
+/*******************************************************************************
+ **
+ ** Function         bta_av_co_init
+ **
+ ** Description      Initialization
+ **
+ ** Returns          Nothing
+ **
+ *******************************************************************************/
+void bta_av_co_init(void);
+
+
+/*******************************************************************************
+ **
+ ** Function         bta_av_co_peer_cp_supported
+ **
+ ** Description      Checks if the peer supports CP
+ **
+ ** Returns          TRUE if the peer supports CP
+ **
+ *******************************************************************************/
+BOOLEAN bta_av_co_peer_cp_supported(tBTA_AV_HNDL hndl);
+
+/*******************************************************************************
+ **
+ ** Function         bta_av_co_get_remote_bitpool_pref
+ **
+ ** Description      Check if remote side did a setconfig within the limits
+ **                  of our exported bitpool range. If set we will set the
+ **                  remote preference.
+ **
+ ** Returns          TRUE if config set, FALSE otherwize
+ **
+ *******************************************************************************/
+BOOLEAN bta_av_co_get_remote_bitpool_pref(UINT8 *min, UINT8 *max);
+
+#endif

+ 125 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/btif_common.h

@@ -0,0 +1,125 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2014 The Android Open Source Project
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef BTIF_COMMON_H
+#define BTIF_COMMON_H
+
+#include <stdlib.h>
+// #include <hardware/bluetooth.h>
+
+#include "bt_types.h"
+#include "bta_api.h"
+#include "osi.h"
+
+// #include "osi/include/log.h"
+
+/*******************************************************************************
+**  Constants & Macros
+********************************************************************************/
+#define ASSERTC(cond, msg, val) if (!(cond)) { LOG_ERROR( \
+    "### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, val);}
+
+/* Calculate start of event enumeration; id is top 8 bits of event */
+#define BTIF_SIG_START(id)       ((id) << 8)
+
+/* For upstream the MSB bit is always SET */
+#define BTIF_SIG_CB_BIT   (0x8000)
+#define BTIF_SIG_CB_START(id)    (((id) << 8) | BTIF_SIG_CB_BIT)
+
+/* BTIF sub-systems */
+#define BTIF_CORE           0
+#define BTIF_DM             1
+// #define BTIF_HFP            2
+// #define BTIF_AV             3
+// #define BTIF_PAN            4
+// #define BTIF_HF_CLIENT      5
+
+#define HAL_CBACK(P_CB, P_CBACK, ...)\
+    if (P_CB && P_CB->P_CBACK) {            \
+        BTIF_TRACE_API("HAL %s->%s", #P_CB, #P_CBACK); \
+        P_CB->P_CBACK(__VA_ARGS__);         \
+    }                                       \
+    else {                                  \
+        ASSERTC(0, "Callback is NULL", 0);  \
+    }
+
+/**
+ * BTIF events for requests that require context switch to btif task
+ * on downstreams path
+ */
+enum
+{
+    BTIF_CORE_API_START = BTIF_SIG_START(BTIF_CORE),
+    /* add here */
+
+    BTIF_DM_API_START = BTIF_SIG_START(BTIF_DM),
+    BTIF_DM_ENABLE_SERVICE,
+    BTIF_DM_DISABLE_SERVICE,
+    /* add here */
+    
+};
+
+enum {
+    SIG_BTIF_WORK = 0xff
+};  
+
+/*******************************************************************************
+**  Type definitions for callback functions
+********************************************************************************/
+
+typedef void (tBTIF_CBACK) (UINT16 event, char *p_param);
+typedef void (tBTIF_COPY_CBACK) (UINT16 event, char *p_dest, char *p_src);
+
+
+/*******************************************************************************
+**  Type definitions and return values
+********************************************************************************/
+
+/* this type handles all btif context switches between BTU and HAL */
+typedef struct
+{
+    BT_HDR               hdr;
+    tBTIF_CBACK*         p_cb;    /* context switch callback */
+
+    /* parameters passed to callback */
+    UINT16               event;   /* message event id */
+    char                 p_param[0]; /* parameter area needs to be last */
+} tBTIF_CONTEXT_SWITCH_CBACK;
+
+
+/*******************************************************************************
+**  Functions
+********************************************************************************/
+
+bt_status_t btif_transfer_context (tBTIF_CBACK *p_cback, UINT16 event, char* p_params,
+                                    int param_len, tBTIF_COPY_CBACK *p_copy_cback);
+tBTA_SERVICE_MASK btif_get_enabled_services_mask(void);
+bt_status_t btif_enable_service(tBTA_SERVICE_ID service_id);
+bt_status_t btif_disable_service(tBTA_SERVICE_ID service_id);
+int btif_is_enabled(void);
+
+/**
+ * BTIF_Events
+ */
+void btif_enable_bluetooth_evt(tBTA_STATUS status);
+void btif_disable_bluetooth_evt(void);
+
+
+
+#endif /* BTIF_COMMON_H */

+ 32 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/btif_dm.h

@@ -0,0 +1,32 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef BTIF_DM_H
+#define BTIF_DM_H
+
+#include "bta_api.h"
+/************************************************************************************
+**  Functions
+********************************************************************************/
+
+/**
+ * BTIF callback to switch context from bte to btif
+ */
+void bte_dm_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data);
+
+#endif

+ 282 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/btif_media.h

@@ -0,0 +1,282 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *
+ *  Filename:      btif_media.h
+ *
+ *  Description:   This is the audio module for the BTIF system.
+ *
+ *******************************************************************************/
+
+#ifndef BTIF_MEDIA_H
+#define BTIF_MEDIA_H
+
+#include <stdbool.h>
+
+#include "bta_api.h"
+#include "gki.h"
+#include "btif_av_api.h"
+#include "audio_a2dp_hw.h"
+
+/*******************************************************************************
+ **  Constants
+ *******************************************************************************/
+
+/* Generic part */
+#define BTIF_SUCCESS                         0
+
+/**
+ * AV (Audio Video source) Errors
+ */
+#define BTIF_ERROR_SRV_AV_NOT_ENABLED        700     /* AV is not enabled */
+#define BTIF_ERROR_SRV_AV_FEEDING_NOT_SUPPORTED 701  /* Requested Feeding not supported */
+#define BTIF_ERROR_SRV_AV_BUSY               702     /* Another operation ongoing */
+#define BTIF_ERROR_SRV_AV_NOT_OPENED         703     /* No AV link opened */
+#define BTIF_ERROR_SRV_AV_NOT_STARTED        704     /* AV is not started */
+#define BTIF_ERROR_SRV_AV_CP_NOT_SUPPORTED   705     /* Content protection is not supported by all headsets */
+
+/* Transcoding definition for TxTranscoding and RxTranscoding */
+#define BTIF_MEDIA_TRSCD_OFF             0
+#define BTIF_MEDIA_TRSCD_PCM_2_SBC       1  /* Tx */
+
+
+/*******************************************************************************
+ **  Data types
+ *******************************************************************************/
+
+typedef int tBTIF_STATUS;
+
+/* tBTIF_MEDIA_INIT_AUDIO msg structure */
+typedef struct
+{
+        BT_HDR hdr;
+        UINT16 SamplingFreq; /* 16k, 32k, 44.1k or 48k*/
+        UINT8 ChannelMode; /* mono, dual, stereo or joint stereo*/
+        UINT8 NumOfSubBands; /* 4 or 8 */
+        UINT8 NumOfBlocks; /* 4, 8, 12 or 16*/
+        UINT8 AllocationMethod; /* loudness or SNR*/
+        UINT16 MtuSize; /* peer mtu size */
+} tBTIF_MEDIA_INIT_AUDIO;
+
+#if (BTA_AV_INCLUDED == TRUE)
+/* tBTIF_MEDIA_UPDATE_AUDIO msg structure */
+typedef struct
+{
+        BT_HDR hdr;
+        UINT16 MinMtuSize; /* Minimum peer mtu size */
+        UINT8 MaxBitPool; /* Maximum peer bitpool */
+        UINT8 MinBitPool; /* Minimum peer bitpool */
+} tBTIF_MEDIA_UPDATE_AUDIO;
+
+/* tBTIF_MEDIA_INIT_AUDIO_FEEDING msg structure */
+typedef struct
+{
+        BT_HDR hdr;
+        tBTIF_AV_FEEDING_MODE feeding_mode;
+        tBTIF_AV_MEDIA_FEEDINGS feeding;
+} tBTIF_MEDIA_INIT_AUDIO_FEEDING;
+
+typedef struct
+{
+        BT_HDR hdr;
+        UINT8 codec_info[AVDT_CODEC_SIZE];
+} tBTIF_MEDIA_SINK_CFG_UPDATE;
+#endif
+
+/*******************************************************************************
+ **  Public functions
+ *******************************************************************************/
+
+/*******************************************************************************
+ **
+ ** Function         btif_av_task
+ **
+ ** Description
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+extern void btif_media_task(void);
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_enc_init_req
+ **
+ ** Description      Request to initialize the media task encoder
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+extern BOOLEAN btif_media_task_enc_init_req(tBTIF_MEDIA_INIT_AUDIO * p_msg);
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_enc_update_req
+ **
+ ** Description      Request to update the media task encoder
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+#if (BTA_AV_INCLUDED == TRUE)
+extern BOOLEAN btif_media_task_enc_update_req(tBTIF_MEDIA_UPDATE_AUDIO * p_msg);
+#endif
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_start_aa_req
+ **
+ ** Description      Request to start audio encoding task
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+extern BOOLEAN btif_media_task_start_aa_req(void);
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_stop_aa_req
+ **
+ ** Description      Request to stop audio encoding task
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+extern BOOLEAN btif_media_task_stop_aa_req(void);
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_aa_rx_flush_req
+ **
+ ** Description      Request to flush audio decoding pipe
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+extern BOOLEAN btif_media_task_aa_rx_flush_req(void);
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_aa_tx_flush_req
+ **
+ ** Description      Request to flush audio encoding pipe
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+extern BOOLEAN btif_media_task_aa_tx_flush_req(void);
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_aa_readbuf
+ **
+ ** Description      Read an audio GKI buffer from the BTIF media TX queue
+ **
+ ** Returns          pointer on a GKI aa buffer ready to send
+ **
+ *******************************************************************************/
+extern BT_HDR *btif_media_aa_readbuf(void);
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_sink_enque_buf
+ **
+ ** Description      This function is called by the av_co to fill A2DP Sink Queue
+ **
+ **
+ ** Returns          size of the queue
+ *******************************************************************************/
+ UINT8 btif_media_sink_enque_buf(BT_HDR *p_buf);
+
+
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_aa_writebuf
+ **
+ ** Description      Enqueue a Advance Audio media GKI buffer to be processed by btif media task.
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+extern void btif_media_aa_writebuf(BT_HDR *pBuf, UINT32 timestamp, UINT16 seq_num);
+
+/*******************************************************************************
+ **
+ ** Function         btif_media_av_writebuf
+ **
+ ** Description      Enqueue a video media GKI buffer to be processed by btif media task.
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+extern BOOLEAN btif_media_av_writebuf(UINT8 *p_media, UINT32 media_len,
+                                     UINT32 timestamp, UINT16 seq_num);
+
+#if (BTA_AV_INCLUDED == TRUE)
+/*******************************************************************************
+ **
+ ** Function         btif_media_task_audio_feeding_init_req
+ **
+ ** Description      Request to initialize audio feeding
+ **
+ ** Returns          TRUE is success
+ **
+ *******************************************************************************/
+
+extern BOOLEAN btif_media_task_audio_feeding_init_req(tBTIF_MEDIA_INIT_AUDIO_FEEDING *p_msg);
+#endif
+
+/*******************************************************************************
+ **
+ ** Function         dump_codec_info
+ **
+ ** Description      Decode and display codec_info (for debug)
+ **
+ ** Returns          void
+ **
+ *******************************************************************************/
+extern void dump_codec_info(unsigned char *p_codec);
+
+/**
+ * Local adaptation helper functions between btif and media task
+ */
+
+bool btif_a2dp_start_media_task(void);
+void btif_a2dp_stop_media_task(void);
+
+void btif_a2dp_on_init(void);
+void btif_a2dp_setup_codec(void);
+void btif_a2dp_on_idle(void);
+void btif_a2dp_on_open(void);
+BOOLEAN btif_a2dp_on_started(tBTA_AV_START *p_av, BOOLEAN pending_start);
+void btif_a2dp_ack_fail(void);
+void btif_a2dp_on_stop_req(void);
+void btif_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av);
+void btif_a2dp_on_suspend(void);
+void btif_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av);
+void btif_a2dp_set_tx_flush(BOOLEAN enable);
+void btif_a2dp_set_rx_flush(BOOLEAN enable);
+void btif_media_check_iop_exceptions(UINT8 *peer_bda);
+void btif_reset_decoder(UINT8 *p_av);
+
+int btif_a2dp_get_track_frequency(UINT8 frequency);
+int btif_a2dp_get_track_channel_count(UINT8 channeltype);
+void btif_a2dp_set_peer_sep(UINT8 sep);
+
+#endif

+ 37 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/btif_profile_queue.h

@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *
+ *  Filename:      btif_profile_queue.h
+ *
+ *  Description:   Bluetooth remote device connection queuing
+ *
+ *******************************************************************************/
+
+#ifndef BTIF_PROFILE_QUEUE_H
+#define BTIF_PROFILE_QUEUE_H
+
+typedef bt_status_t (*btif_connect_cb_t) (bt_bdaddr_t *bda, uint16_t uuid);
+
+bt_status_t btif_queue_connect(uint16_t uuid, const bt_bdaddr_t *bda, btif_connect_cb_t connect_cb);
+void btif_queue_advance();
+bt_status_t btif_queue_connect_next(void);
+void btif_queue_release();
+
+#endif

+ 38 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/btif_sdp.h

@@ -0,0 +1,38 @@
+#ifndef __BTIF_SDP_H__
+#define __BTIF_SDP_H__
+
+#include "bt_sdp.h"
+
+/** Callback for SDP search */
+typedef void (*btsdp_search_callback)(bt_status_t status, bt_bdaddr_t *bd_addr, uint8_t* uuid, int num_records, bluetooth_sdp_record *records);
+
+typedef struct {
+    btsdp_search_callback  sdp_search_cb;
+} btsdp_callbacks_t;
+
+/** Register BT SDP search callbacks */
+bt_status_t BTIF_SdpInit(btsdp_callbacks_t *callbacks);
+
+/** Unregister BT SDP */
+bt_status_t BTIF_SdpDeinit(void);
+
+/** Search for SDP records with specific uuid on remote device */
+bt_status_t BTIF_SdpSearch(bt_bdaddr_t *bd_addr,  const uint8_t* uuid);
+
+/**
+ * Use listen in the socket interface to create rfcomm and/or l2cap PSM channels,
+ * (without UUID and service_name and set the BTSOCK_FLAG_NO_SDP flag in flags).
+ * Then use createSdpRecord to create the SDP record associated with the rfcomm/l2cap channels.
+ *
+ * Returns a handle to the SDP record, which can be parsed to remove_sdp_record.
+ *
+ * record           (in) The SDP record to create
+ * record_handle    (out)The corresponding record handle will be written to this pointer.
+ */
+bt_status_t BTIF_SdpCreateRecord(bluetooth_sdp_record *record, int* record_handle);
+
+/** Remove a SDP record created by BTIF_SdpCreateRecord */
+bt_status_t BTIF_SdpRemoveRecord(int record_handle);
+
+
+#endif /* __BTIF_SDP_H__ */

+ 118 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/btif_sm.h

@@ -0,0 +1,118 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/*****************************************************************************
+ *
+ *  Filename:      btif_sm.h
+ *
+ *  Description:   Generic BTIF state machine API
+ *
+ *****************************************************************************/
+
+#ifndef BTIF_SM_H
+#define BTIF_SM_H
+
+/*****************************************************************************
+**  Constants & Macros
+******************************************************************************/
+
+/* Generic Enter/Exit state machine events */
+#define BTIF_SM_ENTER_EVT 0xFFFF
+#define BTIF_SM_EXIT_EVT  0xFFFE
+
+
+/*****************************************************************************
+**  Type definitions and return values
+******************************************************************************/
+typedef UINT32 btif_sm_state_t;
+typedef UINT32 btif_sm_event_t;
+typedef void* btif_sm_handle_t;
+typedef BOOLEAN(*btif_sm_handler_t)(btif_sm_event_t event, void *data);
+
+
+/*****************************************************************************
+**  Functions
+**
+**  NOTE: THESE APIs SHOULD BE INVOKED ONLY IN THE BTIF CONTEXT
+**
+******************************************************************************/
+
+/*****************************************************************************
+**
+** Function     btif_sm_init
+**
+** Description  Initializes the state machine with the state handlers
+**              The caller should ensure that the table and the corresponding
+**              states match. The location that 'p_handlers' points to shall
+**              be available until the btif_sm_shutdown API is invoked.
+**
+** Returns      Returns a pointer to the initialized state machine handle.
+**
+******************************************************************************/
+btif_sm_handle_t btif_sm_init(const btif_sm_handler_t *p_handlers,
+                               btif_sm_state_t initial_state);
+
+/*****************************************************************************
+**
+** Function     btif_sm_shutdown
+**
+** Description  Tears down the state machine
+**
+** Returns      None
+**
+******************************************************************************/
+void btif_sm_shutdown(btif_sm_handle_t handle);
+
+/*****************************************************************************
+**
+** Function     btif_sm_get_state
+**
+** Description  Fetches the current state of the state machine
+**
+** Returns      Current state
+**
+******************************************************************************/
+btif_sm_state_t btif_sm_get_state(btif_sm_handle_t handle);
+
+/*****************************************************************************
+**
+** Function     btif_sm_dispatch
+**
+** Description  Dispatches the 'event' along with 'data' to the current state handler
+**
+** Returns      Returns BT_STATUS_OK on success, BT_STATUS_FAIL otherwise
+**
+******************************************************************************/
+bt_status_t btif_sm_dispatch(btif_sm_handle_t handle, btif_sm_event_t event,
+                                void *data);
+
+/*****************************************************************************
+**
+** Function     btif_sm_change_state
+**
+** Description  Make a transition to the new 'state'. The 'BTIF_SM_EXIT_EVT'
+**              shall be invoked before exiting the current state. The
+**              'BTIF_SM_ENTER_EVT' shall be invoked before entering the new state
+**
+**
+** Returns      Returns BT_STATUS_OK on success, BT_STATUS_FAIL otherwise
+**
+******************************************************************************/
+bt_status_t btif_sm_change_state(btif_sm_handle_t handle, btif_sm_state_t state);
+
+#endif /* BTIF_SM_H */

+ 31 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/btif_stack_manager.h

@@ -0,0 +1,31 @@
+#ifndef __BTIF_STACK_MANAGER_H__
+#define __BTIF_STACK_MANAGER_H__
+
+#include "bt_defs.h"
+
+/** Bluetooth Adapter State */
+typedef enum {
+    BT_STATE_OFF,
+    BT_STATE_ON
+}   bt_state_t;
+
+/** Bluetooth Interface callbacks */
+
+/** Bluetooth Enable/Disable Callback. */
+typedef void (*adapter_state_changed_callback)(bt_state_t state);
+
+
+/** Bluetooth Device callback structure. */
+typedef struct {
+    adapter_state_changed_callback adapter_state_changed_cb;
+} bt_callbacks_t;
+
+bt_status_t BTIF_InitStack(bt_callbacks_t *cb);
+
+bt_status_t BTIF_EnableStack(void);
+
+bt_status_t BTIF_DisableStack(void);
+
+bt_status_t BTIF_CleanUpStack(void);
+
+#endif /* __BTIF_STACK_MANAGER_H__ */

+ 53 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/btif_util.h

@@ -0,0 +1,53 @@
+/******************************************************************************
+ *
+ *  Copyright (c) 2014 The Android Open Source Project
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef BTIF_UTIL_H
+#define BTIF_UTIL_H
+
+// #include <hardware/bluetooth.h>
+// #include <hardware/bt_hf.h>
+#include <stdbool.h>
+// #include <sys/time.h>
+
+#include "bt_types.h"
+// #include "bt_utils.h"
+#include "bt_defs.h"
+
+/*******************************************************************************
+**  Constants & Macros
+********************************************************************************/
+#define CASE_RETURN_STR(const) case const: return #const;
+/*******************************************************************************
+**  Type definitions for callback functions
+********************************************************************************/
+
+typedef char bdstr_t[18];
+
+
+/*******************************************************************************
+**  Functions
+********************************************************************************/
+UINT32 devclass2uint(DEV_CLASS dev_class);
+void uint2devclass(UINT32 dev, DEV_CLASS dev_class);
+void uuid16_to_uuid128(uint16_t uuid16, bt_uuid_t* uuid128);
+
+void uuid_to_string_legacy(bt_uuid_t *p_uuid, char *str);
+void string_to_uuid(char *str, bt_uuid_t *p_uuid);
+
+#endif /* BTIF_UTIL_H */

+ 29 - 0
examples/09_a2dp/components/bluedroid_demos/btif/include/stack_manager.h

@@ -0,0 +1,29 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 Google, Inc.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef __STACK_MANAGER_H__
+#define __STACK_MANAGER_H__
+
+#include <stdbool.h>
+#include "future.h"
+
+bool stack_manager_is_stack_running(void);
+
+future_t *stack_manager_get_hack_future(void);
+
+#endif /* __STACK_MANAGER_H__*/

+ 160 - 0
examples/09_a2dp/components/bluedroid_demos/btif/stack_manager.c

@@ -0,0 +1,160 @@
+#include <stdbool.h>
+#include <stdint.h>
+#include "btif_stack_manager.h"
+#include "stack_manager.h"
+#include "bt_defs.h"
+#include "bt_trace.h"
+#include "future.h"
+#include "btif_common.h"
+#include "btif_api.h"
+#include "btif_dm.h"
+
+/************************************************************************************
+**  Constants & Macros
+************************************************************************************/
+/************************************************************************************
+**  Local type definitions
+************************************************************************************/
+/************************************************************************************
+**  Static variables
+************************************************************************************/
+static bool stack_is_initialized = false;
+static bool stack_is_running = false;
+static bt_callbacks_t *bt_hal_cbacks = NULL;
+static future_t *hack_future = NULL;
+
+static bt_status_t event_init_stack(bt_callbacks_t *cb);
+static bt_status_t event_start_up_stack(void);
+static bt_status_t event_shut_down_stack(void);
+static bt_status_t event_clean_up_stack(void);
+static void event_signal_stack_up(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param);
+static void event_signal_stack_down(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param);
+
+static bt_status_t event_init_stack(bt_callbacks_t *cb)
+{
+    bt_status_t ret;
+    if (!stack_is_initialized) {
+        hack_future = future_new();
+        ret = btif_init_bluetooth();
+        if (future_await(hack_future) != FUTURE_SUCCESS) {
+            return BT_STATUS_FAIL;
+        }
+        if (ret == BT_STATUS_SUCCESS) {
+            bt_hal_cbacks = cb;            
+            stack_is_initialized = true;
+        }
+        return ret;
+    }
+    else {
+        return BT_STATUS_DONE;
+    }
+}
+
+static bt_status_t event_start_up_stack(void)
+{
+    if (!stack_is_initialized) {
+        LOG_DEBUG("%s stack not initialized yet.\n", __func__);
+        return BT_STATUS_NOT_READY;
+    }
+    
+    if (stack_is_running) {
+        LOG_DEBUG("%s stack already brought up.\n", __func__);
+        return BT_STATUS_DONE;
+    }
+
+    LOG_DEBUG("%s is bringing up the stack.\n", __func__);
+    hack_future = future_new();
+
+    btif_enable_bluetooth();
+
+    if (future_await(hack_future) != FUTURE_SUCCESS) {
+        stack_is_running = true; // So stack shutdown actually happens
+        event_shut_down_stack();
+        return BT_STATUS_FAIL;
+    }
+
+    stack_is_running = true;
+    LOG_DEBUG("%s finished\n", __func__);
+    btif_transfer_context(event_signal_stack_up, 0, NULL, 0, NULL);
+    return BT_STATUS_SUCCESS;
+}
+
+static bt_status_t event_shut_down_stack(void)
+{
+    if (!stack_is_running) {
+        LOG_DEBUG("%s stack is already brought down.\n", __func__);
+        return BT_STATUS_DONE;
+    }
+
+    LOG_DEBUG("%s is bringing down the stack.\n", __func__);
+    hack_future = future_new();
+    stack_is_running = false;
+
+    btif_disable_bluetooth();
+
+    future_await(hack_future);
+
+    LOG_DEBUG("%s finished.\n", __func__);
+    btif_transfer_context(event_signal_stack_down, 0, NULL, 0, NULL);
+    return BT_STATUS_SUCCESS;
+}
+
+static bt_status_t event_clean_up_stack(void)
+{
+    if (!stack_is_initialized) {
+        LOG_DEBUG("%s found the stack already in a clean state.\n", __func__);
+        return BT_STATUS_DONE;
+    }
+
+    if (stack_is_running) {
+        event_shut_down_stack();
+    }
+    
+    LOG_DEBUG("%s is cleaning up the stack.\n", __func__);
+    
+    stack_is_initialized = false;
+
+    btif_shutdown_bluetooth();
+
+    return BT_STATUS_SUCCESS;
+}
+
+static void event_signal_stack_up(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param)
+{
+    HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON);
+}
+
+static void event_signal_stack_down(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param)
+{
+    HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);
+}
+
+bt_status_t BTIF_InitStack(bt_callbacks_t *cb)
+{
+    return event_init_stack(cb);
+}
+
+bt_status_t BTIF_EnableStack(void)
+{
+    return event_start_up_stack();
+}
+
+bt_status_t BTIF_DisableStack(void)
+{
+    return event_shut_down_stack();
+}
+
+bt_status_t BTIF_CleanUpStack(void)
+{
+    return event_clean_up_stack();
+}
+
+bool stack_manager_is_stack_running(void)
+{
+    return stack_is_running;
+}
+
+future_t *stack_manager_get_hack_future(void)
+{
+    return hack_future;
+}

+ 29 - 0
examples/09_a2dp/components/bluedroid_demos/component.mk

@@ -0,0 +1,29 @@
+#
+# Main Makefile. This is basically the same as a component makefile.
+#
+# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, 
+# this will take the sources in the src/ directory, compile them and link them into 
+# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
+# please read the ESP-IDF documents if you need to do this.
+#
+
+COMPONENT_ADD_INCLUDEDIRS :=	\
+				udrv/include				\
+				btif/include				\
+				audio_a2dp_hw/include			\
+				embdrv/sbc/encoder/include		\
+				embdrv/sbc/decoder/include		\
+				include					\
+
+COMPONENT_SRCDIRS :=	\
+			app_core				\
+			app_project				\
+			udrv/ulinux				\
+			embdrv/sbc/encoder			\
+			embdrv/sbc/decoder			\
+			btif
+
+CFLAGS += -Wno-error=unused-label -Wno-error=return-type -Wno-error=missing-braces -Wno-error=pointer-sign -Wno-error=parentheses -I./include
+
+
+include $(IDF_PATH)/make/component_common.mk

+ 86 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_assert.h

@@ -0,0 +1,86 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef _OI_ASSERT_H
+#define _OI_ASSERT_H
+/** @file
+  This file provides macros and functions for compile-time and run-time assertions.
+
+  When the OI_DEBUG preprocessor value is defined, the macro OI_ASSERT is compiled into
+  the program, providing for a runtime assertion failure check.
+  C_ASSERT is a macro that can be used to perform compile time checks.
+*/
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+
+/** \addtogroup Debugging Debugging APIs */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef OI_DEBUG
+
+/** The macro OI_ASSERT takes a condition argument. If the asserted condition
+    does not evaluate to true, the OI_ASSERT macro calls the host-dependent function,
+    OI_AssertFail(), which reports the failure and generates a runtime error.
+*/
+void OI_AssertFail(char* file, int line, char* reason);
+
+
+#define OI_ASSERT(condition) \
+    { if (!(condition)) OI_AssertFail(__FILE__, __LINE__, #condition); }
+
+#define OI_ASSERT_FAIL(msg) \
+    { OI_AssertFail(__FILE__, __LINE__, msg); }
+
+#else
+
+
+#define OI_ASSERT(condition)
+#define OI_ASSERT_FAIL(msg)
+
+#endif
+
+
+/**
+   C_ASSERT() can be used to perform many compile-time assertions: type sizes, field offsets, etc.
+   An assertion failure results in compile time error C2118: negative subscript.
+   Unfortunately, this elegant macro doesn't work with GCC, so it's all commented out
+   for now. Perhaps later.....
+*/
+
+#ifndef C_ASSERT
+// #define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
+// #define C_ASSERT(e)
+#endif
+
+
+/*****************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif /* _OI_ASSERT_H */
+

+ 123 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_bitstream.h

@@ -0,0 +1,123 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef _OI_BITSTREAM_H
+#define _OI_BITSTREAM_H
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+
+/**
+@file
+Function prototypes and macro definitions for manipulating input and output
+bitstreams.
+
+@ingroup codec_internal
+*/
+
+/**
+@addtogroup codec_internal
+@{
+*/
+
+#include "oi_codec_sbc_private.h"
+#include "oi_stddefs.h"
+
+INLINE void OI_BITSTREAM_ReadInit(OI_BITSTREAM *bs, const OI_BYTE *buffer);
+
+INLINE void OI_BITSTREAM_WriteInit(OI_BITSTREAM *bs, OI_BYTE *buffer);
+
+INLINE OI_UINT32 OI_BITSTREAM_ReadUINT(OI_BITSTREAM *bs, OI_UINT bits);
+
+INLINE OI_UINT8 OI_BITSTREAM_ReadUINT4Aligned(OI_BITSTREAM *bs);
+
+INLINE OI_UINT8 OI_BITSTREAM_ReadUINT8Aligned(OI_BITSTREAM *bs);
+
+INLINE void OI_BITSTREAM_WriteUINT(OI_BITSTREAM *bs,
+                                   OI_UINT16 value,
+                                   OI_UINT bits);
+
+/*
+ * Use knowledge that the bitstream is aligned to optimize the write of a byte
+ */
+PRIVATE void OI_BITSTREAM_WriteUINT8Aligned(OI_BITSTREAM *bs,
+                                            OI_UINT8 datum);
+
+/*
+ * Use knowledge that the bitstream is aligned to optimize the write pair of nibbles
+ */
+PRIVATE void OI_BITSTREAM_Write2xUINT4Aligned(OI_BITSTREAM *bs,
+                                              OI_UINT8 datum1,
+                                              OI_UINT8 datum2);
+
+/** Internally the bitstream looks ahead in the stream. When
+ * OI_SBC_ReadScalefactors() goes to temporarily break the abstraction, it will
+ * need to know where the "logical" pointer is in the stream.
+ */
+#define OI_BITSTREAM_GetWritePtr(bs) ((bs)->ptr.w - 3)
+#define OI_BITSTREAM_GetReadPtr(bs) ((bs)->ptr.r - 3)
+
+/** This is declared here as a macro because decoder.c breaks the bitsream
+ * encapsulation for efficiency reasons.
+ */
+#define OI_BITSTREAM_READUINT(result, bits, ptr, value, bitPtr) \
+do { \
+    OI_ASSERT((bits) <= 16); \
+    OI_ASSERT((bitPtr) < 16); \
+    OI_ASSERT((bitPtr) >= 8); \
+    \
+    result = (value) << (bitPtr); \
+    result >>= 32 - (bits); \
+    \
+    bitPtr += (bits); \
+    while (bitPtr >= 16) { \
+        value = ((value) << 8) | *ptr++; \
+        bitPtr -= 8; \
+    } \
+    OI_ASSERT((bits == 0) || (result < (1u << (bits)))); \
+} while (0)
+
+
+#define OI_BITSTREAM_WRITEUINT(ptr, value, bitPtr, datum, bits) \
+do {\
+    bitPtr -= bits;\
+    value |= datum << bitPtr;\
+    \
+    while (bitPtr <= 16) {\
+        bitPtr += 8;\
+        *ptr++ = (OI_UINT8)(value >> 24);\
+        value <<= 8;\
+    }\
+} while (0)
+
+#define OI_BITSTREAM_WRITEFLUSH(ptr, value, bitPtr) \
+do {\
+    while (bitPtr < 32) {\
+        bitPtr += 8;\
+        *ptr++ = (OI_UINT8)(value >> 24);\
+        value <<= 8;\
+    }\
+} while (0)
+
+/**
+@}
+*/
+
+#endif /* _OI_BITSTREAM_H */

+ 229 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_bt_spec.h

@@ -0,0 +1,229 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef _OI_BT_SPEC_H
+#define _OI_BT_SPEC_H
+/**
+ * @file
+ *
+ * This file contains common definitions from the Bluetooth specification.
+ *
+ */
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+#include "oi_stddefs.h"
+
+/** \addtogroup Misc Miscellaneous APIs */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** The maximum number of active slaves in a piconet. */
+#define OI_BT_MAX_ACTIVE_SLAVES 7
+
+/** the number of bytes in a Bluetooth device address (BD_ADDR) */
+#define OI_BD_ADDR_BYTE_SIZE   6
+
+/**
+ * 48-bit Bluetooth device address
+ *
+ * Because 48-bit integers may not be supported on all platforms, the
+ * address is defined as an array of bytes. This array is big-endian,
+ * meaning that
+ *  - array[0] contains bits 47-40,
+ *  - array[1] contains bits 39-32,
+ *  - array[2] contains bits 31-24,
+ *  - array[3] contains bits 23-16,
+ *  - array[4] contains bits 15-8, and
+ *  - array[5] contains bits 7-0.
+ */
+typedef struct  {
+    OI_UINT8    addr[OI_BD_ADDR_BYTE_SIZE] ;   /**< Bluetooth device address represented as an array of 8-bit values */
+} OI_BD_ADDR ;
+
+/**
+ * @name Data types for working with UUIDs
+ * UUIDs are 16 bytes (128 bits).
+ *
+ * To avoid having to pass around 128-bit values all the time, 32-bit and 16-bit
+ * UUIDs are defined, along with a mapping from the shorter versions to the full
+ * version.
+ *
+ * @{
+ */
+
+/**
+ * 16-bit representation of a 128-bit UUID
+ */
+typedef OI_UINT16 OI_UUID16;
+
+/**
+ * 32-bit representation of a 128-bit UUID
+ */
+typedef OI_UINT32 OI_UUID32;
+
+/**
+ * number of bytes in a 128 bit UUID
+ */
+#define OI_BT_UUID128_SIZE  16
+
+/**
+ * number of bytes in IPv6 style addresses
+ */
+#define OI_BT_IPV6ADDR_SIZE  16
+
+/**
+ * type definition for a 128-bit UUID
+ *
+ * To simplify conversion between 128-bit UUIDs and 16-bit and 32-bit UUIDs,
+ * the most significant 32 bits are stored with the same endian-ness as is
+ * native on the target (local) device. The remainder of the 128-bit UUID is
+ * stored as bytes in big-endian order.
+ */
+typedef struct {
+    OI_UINT32 ms32bits;                                    /**< most significant 32 bits of 128-bit UUID */
+    OI_UINT8 base[OI_BT_UUID128_SIZE - sizeof(OI_UINT32)]; /**< remainder of 128-bit UUID, array of 8-bit values */
+} OI_UUID128;
+
+/** @} */
+
+/** number of bytes in a link key */
+#define OI_BT_LINK_KEY_SIZE    16
+
+/**
+ * type definition for a baseband link key
+ *
+ * Because 128-bit integers may not be supported on all platforms, we define
+ * link keys as an array of bytes. Unlike the Bluetooth device address,
+ * the link key is stored in little-endian order, meaning that
+ *  - array[0]  contains bits 0  - 7,
+ *  - array[1]  contains bits 8  - 15,
+ *  - array[2]  contains bits 16 - 23,
+ *  - array[3]  contains bits 24 - 31,
+ *  - array[4]  contains bits 32 - 39,
+ *  - array[5]  contains bits 40 - 47,
+ *  - array[6]  contains bits 48 - 55,
+ *  - array[7]  contains bits 56 - 63,
+ *  - array[8]  contains bits 64 - 71,
+ *  - array[9]  contains bits 72 - 79,
+ *  - array[10] contains bits 80 - 87,
+ *  - array[11] contains bits 88 - 95,
+ *  - array[12] contains bits 96 - 103,
+ *  - array[13] contains bits 104- 111,
+ *  - array[14] contains bits 112- 119, and
+ *  - array[15] contains bits 120- 127.
+ */
+typedef struct {
+    OI_UINT8    key[OI_BT_LINK_KEY_SIZE] ;   /**< link key represented as an array of 8-bit values */
+} OI_LINK_KEY ;
+
+
+/** Out-of-band data size - C and R values are 16-bytes each */
+#define OI_BT_OOB_NUM_BYTES     16
+
+typedef struct {
+    OI_UINT8    value[OI_BT_OOB_NUM_BYTES] ;   /**< same struct used for C and R values */
+} OI_OOB_DATA ;
+
+
+/**
+ * link key types
+ */
+typedef enum  {
+    OI_LINK_KEY_TYPE_COMBO              = 0,    /**< combination key */
+    OI_LINK_KEY_TYPE_LOCAL_UNIT         = 1,    /**< local unit key */
+    OI_LINK_KEY_TYPE_REMOTE_UNIT        = 2,    /**< remote unit key */
+    OI_LINK_KEY_TYPE_DEBUG_COMBO        = 3,    /**< debug combination key */
+    OI_LINK_KEY_TYPE_UNAUTHENTICATED    = 4,    /**< Unauthenticated */
+    OI_LINK_KEY_TYPE_AUTHENTICATED      = 5,    /**< Authenticated */
+    OI_LINK_KEY_TYPE_CHANGED_COMBO      = 6     /**< Changed */
+
+} OI_BT_LINK_KEY_TYPE ;
+
+
+/** amount of space allocated for a PIN (personal indentification number) in bytes */
+#define OI_BT_PIN_CODE_SIZE    16
+
+/** data type for a PIN (PINs are treated as strings, so endianness does not apply.) */
+typedef struct  {
+    OI_UINT8    pin[OI_BT_PIN_CODE_SIZE] ; /**< PIN represented as an array of 8-bit values */
+} OI_PIN_CODE ;
+
+/** maximum number of SCO connections per device, which is 3 as of version 2.0+EDR
+    of the Bluetooth specification (see sec 4.3 of vol 2 part B) */
+#define OI_BT_MAX_SCO_CONNECTIONS  3
+
+/** data type for clock offset */
+typedef OI_UINT16   OI_BT_CLOCK_OFFSET ;
+
+/** data type for a LM handle */
+typedef OI_UINT16 OI_HCI_LM_HANDLE;
+
+/** opaque data type for a SCO or ACL connection handle */
+typedef struct _OI_HCI_CONNECTION *OI_HCI_CONNECTION_HANDLE;
+
+/** data type for HCI Error Code, as defined in oi_hcispec.h */
+typedef OI_UINT8    OI_HCI_ERROR_CODE ;
+
+/**
+ * The Bluetooth device type is indicated by a 24-bit bitfield, represented as a
+ * 32-bit number in the stack. The bit layout and values for device class are specified
+ * in the file oi_bt_assigned_nos.h and in the Bluetooth "Assigned Numbers" specification
+ * at http://www.bluetooth.org/assigned-numbers/.
+ */
+typedef OI_UINT32   OI_BT_DEVICE_CLASS ;
+
+#define OI_BT_DEV_CLASS_FORMAT_MASK        0x000003    /**< Bits 0-1 contain format type. */
+#define OI_BT_DEV_CLASS_MINOR_DEVICE_MASK  0x0000FC    /**< Bits 2-7 contain minor device class value. */
+#define OI_BT_DEV_CLASS_MAJOR_DEVICE_MASK  0x001F00    /**< Bits 8-12 contain major device class value. */
+#define OI_BT_DEV_CLASS_MAJOR_SERVICE_MASK 0xFFE000    /**< Bits 13-23 contain major service class value. */
+
+/** There is currently only one device class format defined, type 00. */
+#define OI_BT_DEV_CLASS_FORMAT_TYPE        00
+
+/** Bit 13 in device class indicates limited discoverability mode (GAP v2.0+EDR, section 4.1.2.2) */
+#define OI_BT_DEV_CLASS_LIMITED_DISCO_BIT  BIT13
+
+/** macro to test validity of the Device Class Format */
+#define OI_BT_VALID_DEVICE_CLASS_FORMAT(class) (OI_BT_DEV_CLASS_FORMAT_TYPE == ((class) & OI_BT_DEV_CLASS_FORMAT_MASK))
+
+/** the time between baseband clock ticks, currently 625 microseconds (one slot) */
+#define OI_BT_TICK 625
+/** some macros to convert to/from baseband clock ticks - use no floating point! */
+#define OI_SECONDS_TO_BT_TICKS(secs)    ((secs)*1600)
+#define OI_BT_TICKS_TO_SECONDS(ticks)   ((ticks)/1600)
+#define OI_MSECS_TO_BT_TICKS(msecs)     (((msecs)*8)/5)
+#define OI_BT_TICKS_TO_MSECS(ticks)     (((ticks)*5)/8)
+
+/** EIR byte order */
+#define OI_EIR_BYTE_ORDER   OI_LITTLE_ENDIAN_BYTE_ORDER
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+/*****************************************************************************/
+#endif /* _OI_BT_SPEC_H */

+ 484 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_codec_sbc.h

@@ -0,0 +1,484 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+#ifndef _OI_CODEC_SBC_CORE_H
+#define _OI_CODEC_SBC_CORE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+@file
+Declarations of codec functions, data types, and macros.
+
+@ingroup codec_lib
+*/
+
+/**
+@addtogroup codec_lib
+@{
+*/
+
+/* Non-BM3 users of of the codec must include oi_codec_sbc_bm3defs.h prior to
+ * including this file, or else these includes will fail because the BM3 SDK is
+ * not in the include path */
+#ifndef _OI_CODEC_SBC_BM3DEFS_H
+#include "oi_stddefs.h"
+#include "oi_status.h"
+#endif
+
+#include <stdint.h>
+
+#define SBC_MAX_CHANNELS 2
+#define SBC_MAX_BANDS 8
+#define SBC_MAX_BLOCKS 16
+#define SBC_MIN_BITPOOL 2   /**< Minimum size of the bit allocation pool used to encode the stream */
+#define SBC_MAX_BITPOOL 250 /**< Maximum size of the bit allocation pool used to encode the stream */
+#define SBC_MAX_ONE_CHANNEL_BPS 320000
+#define SBC_MAX_TWO_CHANNEL_BPS 512000
+
+
+#define SBC_WBS_BITRATE 62000
+#define SBC_WBS_BITPOOL 27
+#define SBC_WBS_NROF_BLOCKS 16
+#define SBC_WBS_FRAME_LEN 62
+#define SBC_WBS_SAMPLES_PER_FRAME 128
+
+
+#define SBC_HEADER_LEN 4
+#define SBC_MAX_FRAME_LEN (SBC_HEADER_LEN + \
+                             ((SBC_MAX_BANDS * SBC_MAX_CHANNELS / 2) + \
+                              (SBC_MAX_BANDS + SBC_MAX_BLOCKS * SBC_MAX_BITPOOL + 7)/8))
+#define SBC_MAX_SAMPLES_PER_FRAME   (SBC_MAX_BANDS * SBC_MAX_BLOCKS)
+
+#define SBC_MAX_SCALEFACTOR_BYTES ((4*(SBC_MAX_CHANNELS * SBC_MAX_BANDS) + 7)/8)
+
+#define OI_SBC_SYNCWORD 0x9c
+#define OI_SBC_ENHANCED_SYNCWORD 0x9d
+
+/**@name Sampling frequencies */
+/**@{*/
+#define SBC_FREQ_16000 0 /**< The sampling frequency is 16 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
+#define SBC_FREQ_32000 1 /**< The sampling frequency is 32 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
+#define SBC_FREQ_44100 2 /**< The sampling frequency is 44.1 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
+#define SBC_FREQ_48000 3 /**< The sampling frequency is 48 kHz. One possible value for the @a frequency parameter of OI_CODEC_SBC_EncoderConfigure() */
+/**@}*/
+
+/**@name Channel modes */
+/**@{*/
+#define SBC_MONO 0         /**< The mode of the encoded channel is mono. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */
+#define SBC_DUAL_CHANNEL 1 /**< The mode of the encoded channel is dual-channel. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */
+#define SBC_STEREO 2       /**< The mode of the encoded channel is stereo. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */
+#define SBC_JOINT_STEREO 3 /**< The mode of the encoded channel is joint stereo. One possible value for the @a mode parameter of OI_CODEC_SBC_EncoderConfigure() */
+/**@}*/
+
+/**@name Subbands */
+/**@{*/
+#define SBC_SUBBANDS_4  0 /**< The encoded stream has 4 subbands. One possible value for the @a subbands parameter of OI_CODEC_SBC_EncoderConfigure()*/
+#define SBC_SUBBANDS_8  1 /**< The encoded stream has 8 subbands. One possible value for the @a subbands parameter of OI_CODEC_SBC_EncoderConfigure() */
+/**@}*/
+
+/**@name Block lengths */
+/**@{*/
+#define SBC_BLOCKS_4    0 /**< A block size of 4 blocks was used to encode the stream. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
+#define SBC_BLOCKS_8    1 /**< A block size of 8 blocks was used to encode the stream is. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
+#define SBC_BLOCKS_12   2 /**< A block size of 12 blocks was used to encode the stream. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
+#define SBC_BLOCKS_16   3 /**< A block size of 16 blocks was used to encode the stream. One possible value for the @a blocks parameter of OI_CODEC_SBC_EncoderConfigure() */
+/**@}*/
+
+/**@name Bit allocation methods */
+/**@{*/
+#define SBC_LOUDNESS 0    /**< The bit allocation method. One possible value for the @a loudness parameter of OI_CODEC_SBC_EncoderConfigure() */
+#define SBC_SNR 1         /**< The bit allocation method. One possible value for the @a loudness parameter of OI_CODEC_SBC_EncoderConfigure() */
+/**@}*/
+
+/**
+@}
+
+@addtogroup codec_internal
+@{
+*/
+
+typedef OI_INT16 SBC_BUFFER_T;
+
+
+/** Used internally. */
+typedef struct {
+    OI_UINT16 frequency;    /**< The sampling frequency. Input parameter. */
+    OI_UINT8 freqIndex;
+
+    OI_UINT8 nrof_blocks;   /**< The block size used to encode the stream. Input parameter. */
+    OI_UINT8 blocks;
+
+
+    OI_UINT8 nrof_subbands; /**< The number of subbands of the encoded stream. Input parameter. */
+    OI_UINT8 subbands;
+
+    OI_UINT8 mode;          /**< The mode of the encoded channel. Input parameter. */
+    OI_UINT8 nrof_channels; /**< The number of channels of the encoded stream. */
+
+    OI_UINT8 alloc;         /**< The bit allocation method. Input parameter. */
+    OI_UINT8 bitpool;       /**< Size of the bit allocation pool used to encode the stream. Input parameter. */
+    OI_UINT8 crc;           /**< Parity check byte used for error detection. */
+    OI_UINT8 join;          /**< Whether joint stereo has been used. */
+    OI_UINT8 enhanced;
+    OI_UINT8 min_bitpool;   /**< This value is only used when encoding. SBC_MAX_BITPOOL if variable
+                                 bitpools are disallowed, otherwise the minimum bitpool size that will
+                                 be used by the bit allocator.  */
+
+    OI_UINT8 cachedInfo;    /**< Information about the previous frame */
+} OI_CODEC_SBC_FRAME_INFO;
+
+/** Used internally. */
+typedef struct {
+    const OI_CHAR *codecInfo;
+    OI_CODEC_SBC_FRAME_INFO frameInfo;
+    OI_INT8 scale_factor[SBC_MAX_CHANNELS*SBC_MAX_BANDS];
+    OI_UINT32 frameCount;
+    OI_INT32 *subdata;
+
+    SBC_BUFFER_T *filterBuffer[SBC_MAX_CHANNELS];
+    OI_INT32 filterBufferLen;
+    OI_UINT filterBufferOffset;
+
+    union {
+        OI_UINT8 uint8[SBC_MAX_CHANNELS*SBC_MAX_BANDS];
+        OI_UINT32 uint32[SBC_MAX_CHANNELS*SBC_MAX_BANDS/4];
+    } bits;
+    OI_UINT8 maxBitneed;    /**< Running maximum bitneed */
+    OI_BYTE formatByte;
+    OI_UINT8 pcmStride;
+    OI_UINT8 maxChannels;
+} OI_CODEC_SBC_COMMON_CONTEXT;
+
+
+/*
+ * A smaller value reduces RAM usage at the expense of increased CPU usage. Values in the range
+ * 27..50 are recommended, beyond 50 there is a diminishing return on reduced CPU usage.
+ */
+#define SBC_CODEC_MIN_FILTER_BUFFERS 16
+#define SBC_CODEC_FAST_FILTER_BUFFERS 27
+
+/* Expands to the number of OI_UINT32s needed to ensure enough memory to encode
+ * or decode streams of numChannels channels, using numBuffers buffers.
+ * Example:
+ * OI_UINT32 decoderData[CODEC_DATA_WORDS(SBC_MAX_CHANNELS, SBC_DECODER_FAST_SYNTHESIS_BUFFERS)];
+ * */
+#define CODEC_DATA_WORDS(numChannels, numBuffers) \
+    ((\
+        (sizeof(OI_INT32) * SBC_MAX_BLOCKS * numChannels * SBC_MAX_BANDS) \
+         + (sizeof(SBC_BUFFER_T) * SBC_MAX_CHANNELS * SBC_MAX_BANDS * numBuffers) \
+         + (sizeof (OI_UINT32) - 1) \
+    ) / sizeof(OI_UINT32))
+
+/** Opaque parameter to decoding functions; maintains decoder context. */
+typedef struct {
+    OI_CODEC_SBC_COMMON_CONTEXT common;
+    OI_UINT8 limitFrameFormat;              /* Boolean, set by OI_CODEC_SBC_DecoderLimit() */
+    OI_UINT8 restrictSubbands;
+    OI_UINT8 enhancedEnabled;
+    OI_UINT8 bufferedBlocks;
+} OI_CODEC_SBC_DECODER_CONTEXT;
+
+typedef struct {
+    OI_UINT32 data[CODEC_DATA_WORDS(1, SBC_CODEC_FAST_FILTER_BUFFERS)];
+} OI_CODEC_SBC_CODEC_DATA_MONO;
+
+typedef struct {
+    OI_UINT32 data[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)];
+} OI_CODEC_SBC_CODEC_DATA_STEREO;
+
+/**
+@}
+
+@addtogroup codec_lib
+@{
+*/
+
+/**
+ * This function resets the decoder. The context must be reset when
+ * changing streams, or if the following stream parameters change:
+ * number of subbands, stereo mode, or frequency.
+ *
+ * @param context   Pointer to the decoder context structure to be reset.
+ *
+ * @param enhanced  If true, enhanced SBC operation is enabled. If enabled,
+ *                  the codec will recognize the alternative syncword for
+ *                  decoding an enhanced SBC stream. Enhancements should not
+ *                  be enabled unless the stream is known to be generated
+ *                  by an enhanced encoder, or there is a small possibility
+ *                  for decoding glitches if synchronization were to be lost.
+ */
+OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                    OI_UINT32 *decoderData,
+                                    OI_UINT32 decoderDataBytes,
+                                    OI_UINT8 maxChannels,
+                                    OI_UINT8 pcmStride,
+                                    OI_BOOL enhanced);
+
+/**
+ * This function restricts the kind of SBC frames that the Decoder will
+ * process.  Its use is optional.  If used, it must be called after
+ * calling OI_CODEC_SBC_DecoderReset(). After it is called, any calls
+ * to OI_CODEC_SBC_DecodeFrame() with SBC frames that do not conform
+ * to the Subband and Enhanced SBC setting will be rejected with an
+ * OI_STATUS_INVALID_PARAMETERS return.
+ *
+ * @param context   Pointer to the decoder context structure to be limited.
+ *
+ * @param enhanced  If true, all frames passed to the decoder must be
+ *                  Enhanced SBC frames. If false, all frames must be
+ *                  standard SBC frames.
+ *
+ * @param subbands  May be set to SBC_SUBBANDS_4 or SBC_SUBBANDS_8. All
+ *                  frames passed to the decoder must be encoded with
+ *                  the requested number of subbands.
+ *
+ */
+OI_STATUS OI_CODEC_SBC_DecoderLimit(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                    OI_BOOL enhanced,
+                                    OI_UINT8 subbands);
+
+/**
+ * This function sets the decoder parameters for a raw decode where the decoder parameters are not
+ * available in the sbc data stream. OI_CODEC_SBC_DecoderReset must be called
+ * prior to calling this function.
+ *
+ * @param context        Decoder context structure. This must be the context must be
+ *                       used each time a frame is decoded.
+ *
+ * @param enhanced       Set to TRUE to enable Qualcomm proprietary
+ *                       quality enhancements.
+ *
+ * @param frequency      One of SBC_FREQ_16000, SBC_FREQ_32000, SBC_FREQ_44100,
+ *                       SBC_FREQ_48000
+ *
+ * @param mode           One of SBC_MONO, SBC_DUAL_CHANNEL, SBC_STEREO,
+ *                       SBC_JOINT_STEREO
+ *
+ * @param subbands       One of SBC_SUBBANDS_4, SBC_SUBBANDS_8
+ *
+ * @param blocks         One of SBC_BLOCKS_4, SBC_BLOCKS_8, SBC_BLOCKS_12,
+ *                       SBC_BLOCKS_16
+ *
+ * @param alloc          One of SBC_LOUDNESS, SBC_SNR
+ *
+ * @param maxBitpool     The maximum bitpool size for this context
+ */
+OI_STATUS OI_CODEC_SBC_DecoderConfigureRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                           OI_BOOL enhanced,
+                                           OI_UINT8 frequency,
+                                           OI_UINT8 mode,
+                                           OI_UINT8 subbands,
+                                           OI_UINT8 blocks,
+                                           OI_UINT8 alloc,
+                                           OI_UINT8 maxBitpool);
+
+/**
+ * Decode one SBC frame. The frame has no header bytes. The context must have been previously
+ * initialized by calling  OI_CODEC_SBC_DecoderConfigureRaw().
+ *
+ * @param context       Pointer to a decoder context structure. The same context
+ *                      must be used each time when decoding from the same stream.
+ *
+ * @param bitpool       The actual bitpool size for this frame. Must be <= the maxbitpool specified
+ *                      in the call to OI_CODEC_SBC_DecoderConfigureRaw(),
+ *
+ * @param frameData     Address of a pointer to the SBC data to decode. This
+ *                      value will be updated to point to the next frame after
+ *                      successful decoding.
+ *
+ * @param frameBytes    Pointer to a UINT32 containing the number of available
+ *                      bytes of frame data. This value will be updated to reflect
+ *                      the number of bytes remaining after a decoding operation.
+ *
+ * @param pcmData       Address of an array of OI_INT16 pairs, which will be
+ *                      populated with the decoded audio data. This address
+ *                      is not updated.
+ *
+ * @param pcmBytes      Pointer to a UINT32 in/out parameter. On input, it
+ *                      should contain the number of bytes available for pcm
+ *                      data. On output, it will contain the number of bytes
+ *                      written. Note that this differs from the semantics of
+ *                      frameBytes.
+ */
+OI_STATUS OI_CODEC_SBC_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                 OI_UINT8 bitpool,
+                                 const OI_BYTE **frameData,
+                                 OI_UINT32 *frameBytes,
+                                 OI_INT16 *pcmData,
+                                 OI_UINT32 *pcmBytes);
+
+/**
+ * Decode one SBC frame.
+ *
+ * @param context       Pointer to a decoder context structure. The same context
+ *                      must be used each time when decoding from the same stream.
+ *
+ * @param frameData     Address of a pointer to the SBC data to decode. This
+ *                      value will be updated to point to the next frame after
+ *                      successful decoding.
+ *
+ * @param frameBytes    Pointer to a UINT32 containing the number of available
+ *                      bytes of frame data. This value will be updated to reflect
+ *                      the number of bytes remaining after a decoding operation.
+ *
+ * @param pcmData       Address of an array of OI_INT16 pairs, which will be
+ *                      populated with the decoded audio data. This address
+ *                      is not updated.
+ *
+ * @param pcmBytes      Pointer to a UINT32 in/out parameter. On input, it
+ *                      should contain the number of bytes available for pcm
+ *                      data. On output, it will contain the number of bytes
+ *                      written. Note that this differs from the semantics of
+ *                      frameBytes.
+ */
+OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                   const OI_BYTE **frameData,
+                                   OI_UINT32 *frameBytes,
+                                   OI_INT16 *pcmData,
+                                   OI_UINT32 *pcmBytes);
+
+/**
+ * Calculate the number of SBC frames but don't decode. CRC's are not checked,
+ * but the Sync word is found prior to count calculation.
+ *
+ * @param frameData     Pointer to the SBC data.
+ *
+ * @param frameBytes    Number of bytes avaiable in the frameData buffer
+ *
+ */
+OI_UINT8 OI_CODEC_SBC_FrameCount(OI_BYTE  *frameData,
+                                 OI_UINT32 frameBytes);
+
+/**
+ * Analyze an SBC frame but don't do the decode.
+ *
+ * @param context       Pointer to a decoder context structure. The same context
+ *                      must be used each time when decoding from the same stream.
+ *
+ * @param frameData     Address of a pointer to the SBC data to decode. This
+ *                      value will be updated to point to the next frame after
+ *                      successful decoding.
+ *
+ * @param frameBytes    Pointer to a UINT32 containing the number of available
+ *                      bytes of frame data. This value will be updated to reflect
+ *                      the number of bytes remaining after a decoding operation.
+ *
+ */
+OI_STATUS OI_CODEC_SBC_SkipFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                 const OI_BYTE **frameData,
+                                 OI_UINT32 *frameBytes);
+
+/* Common functions */
+
+/**
+  Calculate the frame length.
+
+  @param frame The frame whose length to calculate
+
+  @return the length of an individual encoded frame in
+  bytes
+  */
+OI_UINT16 OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame);
+
+
+/**
+ * Calculate the maximum bitpool size that fits within a given frame length.
+ *
+ * @param frame     The frame to calculate the bitpool size for
+ * @param frameLen  The frame length to fit the bitpool to
+ *
+ * @return the maximum bitpool that will fit in the specified frame length
+ */
+OI_UINT16 OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO *frame,
+                                        OI_UINT16 frameLen);
+
+/**
+  Calculate the bit rate.
+
+  @param frame The frame whose bit rate to calculate
+
+  @return the approximate bit rate in bits per second,
+  assuming that stream parameters are constant
+  */
+OI_UINT32 OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame);
+
+/**
+  Calculate decoded audio data length for one frame.
+
+  @param frame The frame whose audio data length to calculate
+
+  @return length of decoded audio data for a
+  single frame, in bytes
+  */
+OI_UINT16 OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT *common);
+
+/**
+ * Get the codec version text.
+ *
+ * @return  pointer to text string containing codec version text
+ *
+ */
+OI_CHAR *OI_CODEC_Version(void);
+
+
+/**
+@}
+
+@addtogroup codec_internal
+@{
+*/
+
+extern const OI_CHAR* const OI_CODEC_SBC_FreqText[];
+extern const OI_CHAR* const OI_CODEC_SBC_ModeText[];
+extern const OI_CHAR* const OI_CODEC_SBC_SubbandsText[];
+extern const OI_CHAR* const OI_CODEC_SBC_BlocksText[];
+extern const OI_CHAR* const OI_CODEC_SBC_AllocText[];
+
+/**
+@}
+
+@addtogroup codec_lib
+@{
+*/
+
+#ifdef OI_DEBUG
+void OI_CODEC_SBC_DumpConfig(OI_CODEC_SBC_FRAME_INFO *frameInfo);
+#else
+#define OI_CODEC_SBC_DumpConfig(f)
+#endif
+
+/**
+@}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _OI_CODEC_SBC_CORE_H */
+
+

+ 229 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_codec_sbc_private.h

@@ -0,0 +1,229 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef _OI_CODEC_SBC_PRIVATE_H
+#define _OI_CODEC_SBC_PRIVATE_H
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+/**
+@file
+Function prototypes and macro definitions used internally by the codec.
+
+@ingroup codec_internal
+*/
+
+/**
+@addtogroup codec_internal
+@{
+*/
+
+#ifdef USE_RESTRICT_KEYWORD
+#define RESTRICT restrict
+#else
+#define RESTRICT
+#endif
+
+#ifdef CODEC_DEBUG
+#include <stdio.h>
+#define ERROR(x) do { printf x; printf("\n"); } while (0)
+#else
+#define ERROR(x)
+#endif
+
+#ifdef TRACE_EXECUTION
+#define TRACE(x) do { printf x; printf("\n"); } while (0)
+#else
+#define TRACE(x)
+#endif
+
+#ifndef PRIVATE
+#define PRIVATE
+#endif
+
+#ifndef INLINE
+#define INLINE
+#endif
+
+#include "oi_assert.h"
+#include "oi_codec_sbc.h"
+
+#ifndef OI_SBC_SYNCWORD
+#define OI_SBC_SYNCWORD 0x9c
+#endif
+
+#ifndef DIVIDE
+#define DIVIDE(a, b) ((a) / (b))
+#endif
+
+typedef union {
+    OI_UINT8 uint8[SBC_MAX_BANDS];
+    OI_UINT32 uint32[SBC_MAX_BANDS / 4];
+} BITNEED_UNION1;
+
+typedef union {
+    OI_UINT8 uint8[2 * SBC_MAX_BANDS];
+    OI_UINT32 uint32[2 * SBC_MAX_BANDS / 4];
+} BITNEED_UNION2;
+
+static const OI_UINT16 freq_values[] =    { 16000, 32000, 44100, 48000 };
+static const OI_UINT8 block_values[] =    { 4, 8, 12, 16 };
+static const OI_UINT8 channel_values[] =  { 1, 2, 2, 2 };
+static const OI_UINT8 band_values[] =     { 4, 8 };
+
+
+#define TEST_MODE_SENTINEL "OINA"
+#define TEST_MODE_SENTINEL_LENGTH 4
+
+/** Used internally. */
+typedef struct {
+    union {
+        const OI_UINT8 *r;
+        OI_UINT8 *w;
+    } ptr;
+    OI_UINT32 value;
+    OI_UINT bitPtr;
+} OI_BITSTREAM;
+
+
+#define VALID_INT16(x) (((x) >= OI_INT16_MIN) && ((x) <= OI_INT16_MAX))
+#define VALID_INT32(x) (((x) >= OI_INT32_MIN) && ((x) <= OI_INT32_MAX))
+
+#define DCTII_8_SHIFT_IN 0
+#define DCTII_8_SHIFT_OUT 16-DCTII_8_SHIFT_IN
+
+#define DCTII_8_SHIFT_0 (DCTII_8_SHIFT_OUT)
+#define DCTII_8_SHIFT_1 (DCTII_8_SHIFT_OUT)
+#define DCTII_8_SHIFT_2 (DCTII_8_SHIFT_OUT)
+#define DCTII_8_SHIFT_3 (DCTII_8_SHIFT_OUT)
+#define DCTII_8_SHIFT_4 (DCTII_8_SHIFT_OUT)
+#define DCTII_8_SHIFT_5 (DCTII_8_SHIFT_OUT)
+#define DCTII_8_SHIFT_6 (DCTII_8_SHIFT_OUT-1)
+#define DCTII_8_SHIFT_7 (DCTII_8_SHIFT_OUT-2)
+
+#define DCT_SHIFT 15
+
+#define DCTIII_4_SHIFT_IN 2
+#define DCTIII_4_SHIFT_OUT 15
+
+#define DCTIII_8_SHIFT_IN 3
+#define DCTIII_8_SHIFT_OUT 14
+
+OI_UINT computeBitneed(OI_CODEC_SBC_COMMON_CONTEXT *common,
+                              OI_UINT8 *bitneeds,
+                              OI_UINT ch,
+                              OI_UINT *preferredBitpool);
+
+void oneChannelBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common,
+                                    BITNEED_UNION1 *bitneeds,
+                                    OI_UINT ch,
+                                    OI_UINT bitcount);
+
+
+OI_INT adjustToFitBitpool(const OI_UINT bitpool,
+                                 OI_UINT32 *bitneeds,
+                                 const OI_UINT subbands,
+                                 OI_UINT bitcount,
+                                 OI_UINT *excess);
+
+INLINE OI_INT allocAdjustedBits(OI_UINT8 *dest,
+                                OI_INT bits,
+                                OI_INT excess);
+
+INLINE OI_INT allocExcessBits(OI_UINT8 *dest,
+                              OI_INT excess);
+
+PRIVATE OI_UINT32 internal_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame);
+
+PRIVATE OI_UINT16 internal_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame);
+
+void monoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common);
+
+typedef void (*BIT_ALLOC)(OI_CODEC_SBC_COMMON_CONTEXT *common);
+
+PRIVATE OI_STATUS internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                     OI_UINT8 bitpool,
+                                     const OI_BYTE **frameData,
+                                     OI_UINT32 *frameBytes,
+                                     OI_INT16 *pcmData,
+                                     OI_UINT32 *pcmBytes);
+
+INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                       OI_UINT32 *decoderData,
+                                       OI_UINT32 decoderDataBytes,
+                                       OI_BYTE maxChannels,
+                                       OI_BYTE pcmStride,
+                                       OI_BOOL enhanced);
+
+INLINE OI_UINT16 OI_SBC_CalculateFrameAndHeaderlen(OI_CODEC_SBC_FRAME_INFO *frame, OI_UINT *headerLen_);
+
+PRIVATE OI_UINT32 OI_SBC_MaxBitpool(OI_CODEC_SBC_FRAME_INFO *frame);
+
+PRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *frame);
+PRIVATE OI_UINT8 OI_SBC_CalculateChecksum(OI_CODEC_SBC_FRAME_INFO *frame, OI_BYTE const *data);
+
+/* Transform functions */
+PRIVATE void shift_buffer(SBC_BUFFER_T *dest, SBC_BUFFER_T *src, OI_UINT wordCount);
+PRIVATE void cosineModulateSynth4(SBC_BUFFER_T * RESTRICT out, OI_INT32 const * RESTRICT in);
+PRIVATE void SynthWindow40_int32_int32_symmetry_with_sum(OI_INT16 *pcm, SBC_BUFFER_T buffer[80], OI_UINT strideShift);
+
+INLINE void dct3_4(OI_INT32 * RESTRICT out, OI_INT32 const * RESTRICT in);
+PRIVATE void analyze4_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 40],
+                                OI_INT16 *pcm,
+                                OI_UINT strideShift,
+                                OI_INT32 subband[4]);
+
+INLINE void dct3_8(OI_INT32 * RESTRICT out, OI_INT32 const * RESTRICT in);
+
+PRIVATE void analyze8_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 80],
+                                OI_INT16 *pcm,
+                                OI_UINT strideShift,
+                                OI_INT32 subband[8]);
+
+#ifdef SBC_ENHANCED
+PRIVATE void analyze8_enhanced_generated(SBC_BUFFER_T analysisBuffer[RESTRICT 112],
+                                         OI_INT16 *pcm,
+                                         OI_UINT strideShift,
+                                         OI_INT32 subband[8]);
+#endif
+
+/* Decoder functions */
+
+INLINE  void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data);
+PRIVATE void OI_SBC_ReadScalefactors(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *b, OI_BITSTREAM *bs);
+PRIVATE void OI_SBC_ReadSamples(OI_CODEC_SBC_DECODER_CONTEXT *common, OI_BITSTREAM *ob);
+PRIVATE void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT *common, OI_BITSTREAM *global_bs);
+PRIVATE void OI_SBC_SynthFrame(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT start_block, OI_UINT nrof_blocks);
+INLINE OI_INT32 OI_SBC_Dequant(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits);
+PRIVATE OI_BOOL OI_SBC_ExamineCommandPacket(OI_CODEC_SBC_DECODER_CONTEXT *context, const OI_BYTE *data, OI_UINT32 len);
+PRIVATE void OI_SBC_GenerateTestSignal(OI_INT16 pcmData[][2], OI_UINT32 sampleCount);
+
+PRIVATE void OI_SBC_ExpandFrameFields(OI_CODEC_SBC_FRAME_INFO *frame);
+PRIVATE OI_STATUS OI_CODEC_SBC_Alloc(OI_CODEC_SBC_COMMON_CONTEXT *common,
+                                     OI_UINT32 *codecDataAligned,
+                                     OI_UINT32 codecDataBytes,
+                                     OI_UINT8 maxChannels,
+                                     OI_UINT8 pcmStride);
+/**
+@}
+*/
+
+#endif /* _OI_CODEC_SBC_PRIVATE_H */
+

+ 43 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_common.h

@@ -0,0 +1,43 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef _OI_COMMON_H
+#define _OI_COMMON_H
+/**
+ * @file
+ *
+ * This file is used to group commonly used BLUEmagic 3.0 software
+ * header files.
+ *
+ * This file should be included in application source code along with the header
+ * files for the specific modules of the protocol stack being used.
+ */
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+#include "oi_bt_spec.h"
+#include "oi_stddefs.h"
+#include "oi_status.h"
+#include "oi_time.h"
+#include "oi_osinterface.h"
+
+
+/*****************************************************************************/
+#endif /* _OI_COMMON_H */

+ 505 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_cpu_dep.h

@@ -0,0 +1,505 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef _OI_CPU_DEP_H
+#define _OI_CPU_DEP_H
+/**
+ * @file
+ * This file contains definitions for characteristics of the target CPU and
+ * compiler, including primitive data types and endianness.
+ *
+ * This file defines the byte order and primitive data types for various
+ * CPU families. The preprocessor symbol 'CPU' must be defined to be an
+ * appropriate value or this header will generate a compile-time error.
+ *
+ * @note The documentation for this header file uses the x86 family of processors
+ * as an illustrative example for CPU/compiler-dependent data type definitions.
+ * Go to the source code of this header file to see the details of primitive type
+ * definitions for each platform.
+ *
+ * Additional information is available in the @ref data_types_docpage section.
+ */
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \addtogroup Misc Miscellaneous APIs */
+/**@{*/
+
+/** @name Definitions indicating family of target OI_CPU_TYPE
+ *  @{
+ */
+
+#define OI_CPU_X86         1 /**< x86 processor family */
+#define OI_CPU_ARM         2 /**< ARM processor family.
+                                  @deprecated Use #OI_CPU_ARM7_LEND or
+                                  #OI_CPU_ARM7_BEND. */
+#define OI_CPU_ARC         3 /**< ARC processor family.
+                                  @deprecated Use #OI_CPU_ARC_LEND or
+                                  #OI_CPU_ARC_BEND. */
+#define OI_CPU_SH3         4 /**< Hitachi SH-3 processor family */
+#define OI_CPU_H8          5 /**< Hitachi H8 processor family */
+#define OI_CPU_MIPS        6 /**< MIPS processor family */
+#define OI_CPU_SPARC       7 /**< SPARC processor family */
+#define OI_CPU_M68000      8 /**< Motorola M68000 processor family */
+#define OI_CPU_PPC         9 /**< PowerPC (PPC) processor family */
+#define OI_CPU_SH4_7750   10 /**< Hitachi SH7750 series in SH-4 processor family */
+#define OI_CPU_SH2        11 /**< Hitachi SH-2 processor family */
+#define OI_CPU_ARM7_LEND  12 /**< ARM7, little-endian */
+#define OI_CPU_ARM7_BEND  13 /**< ARM7, big-endian */
+#define OI_CPU_GDM1202    14 /**< GCT GDM1202 */
+#define OI_CPU_ARC_LEND   15 /**< ARC processor family, little-endian */
+#define OI_CPU_ARC_BEND   16 /**< ARC processor family, big-endian */
+#define OI_CPU_M30833F    17 /**< Mitsubishi M308 processor family */
+#define OI_CPU_CR16C      18 /**< National Semiconductor 16 bit processor family */
+#define OI_CPU_M64111     19 /**< Renesas M64111 processor (M32R family) */
+#define OI_CPU_ARMV5_LEND 20 //*< ARM5, little-endian */
+
+#define OI_CPU_TYPE 12
+
+#ifndef OI_CPU_TYPE
+    #error "OI_CPU_TYPE type not defined"
+#endif
+
+/**@}*/
+
+
+/** @name Definitions indicating byte-wise endianness of target CPU
+ *  @{
+ */
+
+#define OI_BIG_ENDIAN_BYTE_ORDER    0  /**< Multiple-byte values are stored in memory beginning with the most significant byte at the lowest address.  */
+#define OI_LITTLE_ENDIAN_BYTE_ORDER 1  /**< Multiple-byte values are stored in memory beginning with the least significant byte at the lowest address. */
+
+/**@}*/
+
+
+/** @name  CPU/compiler-independent primitive data type definitions
+ *  @{
+ */
+
+typedef int             OI_BOOL;  /**< Boolean values use native integer data type for target CPU. */
+typedef int             OI_INT;   /**< Integer values use native integer data type for target CPU. */
+typedef unsigned int    OI_UINT;  /**< Unsigned integer values use native unsigned integer data type for target CPU. */
+typedef unsigned char   OI_BYTE;  /**< Raw bytes type uses native character data type for target CPU. */
+
+/**@}*/
+
+
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_X86
+
+#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER  /**< x86 platform byte ordering is little-endian */
+
+/** @name CPU/compiler-dependent primitive data type definitions for x86 processor family
+ *  @{
+ */
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for x86 processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for x86 processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for x86 processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for x86 processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for x86 processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for x86 processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_ARM
+/* This CPU type is deprecated (removed from use). Instead, use OI_CPU_ARM7_LEND or OI_CPU_ARM7_BEND for
+   little-endian or big-endian configurations of the ARM7, respectively. */
+#error OI_CPU_ARM is deprecated
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_ARC
+/* This CPU type is deprecated (removed from use). Instead, use OI_CPU_ARC_LEND or OI_CPU_ARC_BEND for
+   little-endian or big-endian configurations of the ARC, respectively. */
+#error OI_CPU_ARC is deprecated
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_SH3
+/* The Hitachi SH C compiler defines _LIT or _BIG, depending on the endianness
+    specified to the compiler on the command line. */
+#if defined(_LIT)
+    #define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER  /**< If _LIT is defined, SH-3 platform byte ordering is little-endian. */
+#elif defined(_BIG)
+    #define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER     /**< If _BIG is defined, SH-3 platform byte ordering is big-endian. */
+#else
+    #error SH compiler endianness undefined
+#endif
+
+/** @name CPU/compiler-dependent primitive data type definitions for SH-3 processor family
+ *  @{
+ */
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for SH-3 processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for SH-3 processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for SH-3 processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for SH-3 processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for SH-3 processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for SH-3 processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+
+#endif
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_SH2
+
+#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER /**< SH-2 platform byte ordering is big-endian. */
+
+/** @name  CPU/compiler-dependent primitive data type definitions for SH-2 processor family
+ *  @{
+ */
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for SH-2 processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for SH-2 processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for SH-2 processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for SH-2 processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for SH-2 processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for SH-2 processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+
+#endif
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_H8
+#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
+#error basic types not defined
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_MIPS
+#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
+/** @name  CPU/compiler-dependent primitive data type definitions for MIPS processor family
+ *  @{
+ */
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_SPARC
+#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
+#error basic types not defined
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_M68000
+#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER  /**< M68000 platform byte ordering is big-endian. */
+
+/** @name  CPU/compiler-dependent primitive data type definitions for M68000 processor family
+ *  @{
+ */
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for M68000 processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for M68000 processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for M68000 processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for M68000 processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for M68000 processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for M68000 processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_PPC
+#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
+
+
+/** @name  CPU/compiler-dependent primitive data type definitions for PPC 8XX processor family
+ *  @{
+ */
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for PPC8XX processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for PPC8XX processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for PPC8XX processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for PPC8XX processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for PPC8XX processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for PPC8XX processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_SH4_7750
+#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER  /**< SH7750 platform byte ordering is big-endian. */
+
+/** @name   CPU/compiler-dependent primitive data type definitions for SH7750 processor series of the SH-4 processor family
+ *  @{
+ */
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for SH7750 SH-4 processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for SH7750 SH-4 processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for SH7750 SH-4 processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for SH7750 SH-4 processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for SH7750 SH-4 processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for SH7750 SH-4 processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_ARM7_LEND
+#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
+
+/** @name   little-endian CPU/compiler-dependent primitive data type definitions for the ARM7 processor family
+ *  @{
+ */
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */
+
+typedef void * OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_ARM7_BEND
+#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
+/** @name   big-endian CPU/compiler-dependent primitive data type definitions for the ARM7 processor family
+ *  @{
+ */
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */
+
+typedef void * OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_GDM1202
+#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_ARC_LEND
+
+#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
+
+/** @name CPU/compiler-dependent primitive data type definitions for ARC processor family
+ *  @{
+ */
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for ARC processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for ARC processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for ARC processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for ARC processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARC processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARC processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_ARC_BEND
+
+#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
+
+/** @name CPU/compiler-dependent primitive data type definitions for ARC processor family
+ *  @{
+ */
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for ARC processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for ARC processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for ARC processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for ARC processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARC processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARC processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_M30833F
+
+#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
+
+/** @name CPU/compiler-dependent primitive data type definitions for Mitsubishi M308 processor family
+ *  @{
+ */
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for M308 processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for M308 processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for M308 processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for M308 processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for M308 processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for M308 processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_CR16C
+
+#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
+
+/** @name CPU/compiler-dependent primitive data type definitions for National Semicnductor processor family
+ *  @{
+ */
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for CR16C processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for CR16C processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for CR16C processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for CR16C processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for CR16C processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for CR16C processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_M64111
+
+#define OI_CPU_BYTE_ORDER OI_BIG_ENDIAN_BYTE_ORDER
+
+/** @name CPU/compiler-dependent primitive data type definitions for Renesas M32R processor family
+ *  @{
+ */
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for M64111 processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for M64111 processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for M64111 processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for M64111 processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for M64111 processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for M64111 processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+#endif
+
+/*********************************************************************************/
+
+#if OI_CPU_TYPE==OI_CPU_ARMV5_LEND
+#define OI_CPU_BYTE_ORDER OI_LITTLE_ENDIAN_BYTE_ORDER
+
+/** @name   little-endian CPU/compiler-dependent primitive data type definitions for the ARM7 processor family
+ *  @{
+ */
+
+typedef signed char     OI_INT8;   /**< 8-bit signed integer values use native signed character data type for ARM7 processor. */
+typedef signed short    OI_INT16;  /**< 16-bit signed integer values use native signed short integer data type for ARM7 processor. */
+typedef signed long     OI_INT32;  /**< 32-bit signed integer values use native signed long integer data type for ARM7 processor. */
+typedef unsigned char   OI_UINT8;  /**< 8-bit unsigned integer values use native unsigned character data type for ARM7 processor. */
+typedef unsigned short  OI_UINT16; /**< 16-bit unsigned integer values use native unsigned short integer data type for ARM7 processor. */
+typedef unsigned long   OI_UINT32; /**< 32-bit unsigned integer values use native unsigned long integer data type for ARM7 processor. */
+
+typedef OI_UINT32 OI_ELEMENT_UNION; /**< Type for first element of a union to support all data types up to pointer width. */
+
+/**@}*/
+
+#endif
+
+/*********************************************************************************/
+
+
+#ifndef OI_CPU_BYTE_ORDER
+    #error "Byte order (endian-ness) not defined"
+#endif
+
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*********************************************************************************/
+#endif /* _OI_CPU_DEP_H */

+ 171 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_modules.h

@@ -0,0 +1,171 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef _OI_MODULES_H
+#define _OI_MODULES_H
+/**
+ * @file
+ *
+ * Enumeration type defining the inidivual stack components.
+ *
+ */
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+
+/** \addtogroup Misc Miscellaneous APIs */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * This enumeration lists constants for referencing the components of
+ * the BLUEmagic 3.0 protocol stack, profiles, and other functionalities.
+ *
+ * In order to distinguish types of modules, items are grouped with markers to
+ * delineate start and end of the groups
+ *
+ * The module type is used for various purposes:
+ *      identification in debug print statements
+ *      access to initialization flags
+ *      access to the configuration table
+ */
+
+typedef enum {
+    /* profiles and protocols  --> Updates to oi_debug.c and oi_config_table.c */
+
+                                /*   XX --> Keep Enum values up-to-date! */
+    OI_MODULE_AT,               /**< 00 AT command processing */
+    OI_MODULE_A2DP,             /**< 01 Advanced Audio Distribution Profile */
+    OI_MODULE_AVCTP,            /**< 02 Audio-Visual Control Transport Profile */
+    OI_MODULE_AVDTP,            /**< 03 Audio-Visual Distribution Protocol */
+    OI_MODULE_AVRCP,            /**< 04 Audio-Visual Remote Control Profile */
+    OI_MODULE_BIP_CLI,          /**< 05 Basic Imaging Profile protocol client */
+    OI_MODULE_BIP_SRV,          /**< 06 Basic Imaging Profile protocol server */
+    OI_MODULE_BNEP,             /**< 07 Bluetooth Network Encapsulation Protocol */
+    OI_MODULE_BPP_SENDER,       /**< 08 Basic Printing Profile */
+    OI_MODULE_BPP_PRINTER,      /**< 09 Basic Printing Profile */
+    OI_MODULE_CTP,              /**< 10 Cordless Telephony Profile */
+    OI_MODULE_DUN,              /**< 11 Dial-Up Networking Profile */
+    OI_MODULE_FAX,              /**< 12 Fax Profile */
+    OI_MODULE_FTP_CLI,          /**< 13 File Transfer Profile protocol client */
+    OI_MODULE_FTP_SRV,          /**< 14 File Transfer Profile protocol server */
+    OI_MODULE_HANDSFREE,        /**< 15 Hands-Free Profile */
+    OI_MODULE_HANDSFREE_AG,     /**< 16 Hands-Free Profile */
+    OI_MODULE_HCRP_CLI,         /**< 17 Hardcopy Cable Replacement Profile */
+    OI_MODULE_HCRP_SRV,         /**< 18 Hardcopy Cable Replacement Profile */
+    OI_MODULE_HEADSET,          /**< 19 Headset Profile */
+    OI_MODULE_HEADSET_AG,       /**< 20 Headset Profile */
+    OI_MODULE_HID,              /**< 21 Human Interface Device profile */
+    OI_MODULE_INTERCOM,         /**< 22 Intercom Profile */
+    OI_MODULE_OBEX_CLI,         /**< 23 OBEX protocol client, Generic Object Exchange Profile */
+    OI_MODULE_OBEX_SRV,         /**< 24 OBEX protocol server, Generic Object Exchange Profile */
+    OI_MODULE_OPP_CLI,          /**< 25 Object Push Profile protocol client */
+    OI_MODULE_OPP_SRV,          /**< 26 Object Push Profile protocol server */
+    OI_MODULE_PAN,              /**< 27 PAN profile */
+    OI_MODULE_PBAP_CLI,         /**< 28 Phonebook Access Profile client */
+    OI_MODULE_PBAP_SRV,         /**< 29 Phonebook Access Profile server */
+    OI_MODULE_SAP_CLI,          /**< 30 SIM Access Profile */
+    OI_MODULE_SAP_SRV,          /**< 31 SIM Access Profile */
+    OI_MODULE_SPP,              /**< 32 Serial Port Profile */
+    OI_MODULE_SYNC_CLI,         /**< 33 Synchronization Profile */
+    OI_MODULE_SYNC_SRV,         /**< 34 Synchronization Profile */
+    OI_MODULE_SYNC_CMD_CLI,     /**< 35 Synchronization Profile */
+    OI_MODULE_SYNC_CMD_SRV,     /**< 36 Synchronization Profile */
+    OI_MODULE_SYNCML,           /**< 37 SyncML Profile */
+    OI_MODULE_TCS,              /**< 38 TCS Binary */
+    OI_MODULE_VDP,              /**< 39 Video Distribution Profile */
+
+    /* corestack components   --> Updates to oi_debug.c and oi_config_table.c */
+
+    OI_MODULE_COMMON_CONFIG,    /**< 40 Common configuration, module has no meaning other than for config struct */
+    OI_MODULE_CMDCHAIN,         /**< 41 Command chaining utility */
+    OI_MODULE_DISPATCH,         /**< 42 Dispatcher */
+    OI_MODULE_DATAELEM,         /**< 43 Data Elements, marshaller */
+    OI_MODULE_DEVMGR,           /**< 44 Device Manager */
+    OI_MODULE_DEVMGR_MODES,     /**< 45 Device Manager connectability/discoverability modes */
+    OI_MODULE_HCI,              /**< 46 Host Controller Interface command layer */
+    OI_MODULE_L2CAP,            /**< 47 L2CAP */
+    OI_MODULE_MEMMGR,           /**< 48 modules that do memory management */
+    OI_MODULE_POLICYMGR,        /**< 49 Policy Manager */
+    OI_MODULE_RFCOMM,           /**< 50 RFCOMM */
+    OI_MODULE_RFCOMM_SD,        /**< 51 RFCOMM Service discovery */
+    OI_MODULE_SDP_CLI,          /**< 52 Service Discovery Protocol client */
+    OI_MODULE_SDP_SRV,          /**< 53 Service Discovery Protocol server */
+    OI_MODULE_SDPDB,            /**< 54 Service Discovery Protocol database */
+    OI_MODULE_SECMGR,           /**< 55 Security Manager */
+    OI_MODULE_SNIFFLOG,         /**< 56 sniff log */
+    OI_MODULE_SUPPORT,          /**< 57 support functions, including CThru Dispatcher, time functions, and stack initialization */
+    OI_MODULE_TRANSPORT,        /**< 58 transport layer between HCI command layer and driver */
+    OI_MODULE_TEST,             /**< 59 used to debug output from internal test programs */
+    OI_MODULE_XML,              /**< 60 XML/CSS parser */
+
+    OI_MODULE_DI,               /**< 61 Device Identification Profile */
+
+    // bhapi components  --> Updates to oi_debug.c
+
+    OI_MODULE_BHAPI,            /**< 62 BLUEmagic Host API generic */
+    OI_MODULE_BHCLI,            /**< 63 BLUEmagic Host API client side */
+    OI_MODULE_BHSRV,            /**< 64 BLUEmagic Host API server side */
+    OI_MODULE_MSGQ,             /**< 65 module that handles message queuing */
+    OI_MODULE_BHAPI_TRANSPORT,  /**< 66 module that handles message queuing */
+    OI_MODULE_BLST_SRV,         /**< 67 module that provides server side BHAPI Lightweight Serial Transport */
+    OI_MODULE_BLST_CLI,         /**< 68 module that provides client side BHAPI Lightweight Serial Transport */
+
+    // OEM files --> Updates to oi_debug.c
+    OI_MODULE_OEM,              /**< 69 Application Memory allocation */
+
+    // Application glue --> Updates to oi_debug.c
+    OI_MODULE_APP,              /**< 70 Application Memory allocation */
+
+    /* various pieces of code depend on these last 2 elements occuring in a specific order:
+       OI_MODULE_ALL must be the 2nd to last element
+       OI_MODULE_UNKNOWN must be the last element
+       */
+    OI_MODULE_ALL,              /**< 71 special value identifying all modules - used for control of debug print statements */
+    OI_MODULE_UNKNOWN           /**< 72 special value - used for debug print statements */
+} OI_MODULE;
+
+/**
+ * This constant is the number of actual modules in the list.  ALL and UNKNOWN are
+ * special values that are not actually modules.
+ * Used for debug print and memmgr profiling
+ */
+#define OI_NUM_MODULES  OI_MODULE_ALL
+
+
+/**
+ * This constant is the number of profile and core components.  It is used to size
+ * the initialization and configuration tables.
+ */
+#define OI_NUM_STACK_MODULES    OI_MODULE_BHAPI
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif /* _OI_MODULES_H */
+

+ 197 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_osinterface.h

@@ -0,0 +1,197 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef _OI_OSINTERFACE_H
+#define _OI_OSINTERFACE_H
+/**
+ @file
+ * This file provides the platform-independent interface for functions for which
+ * implementation is platform-specific.
+ *
+ * The functions in this header file define the operating system or hardware
+ * services needed by the BLUEmagic 3.0 protocol stack. The
+ * actual implementation of these services is platform-dependent.
+ *
+ */
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+#include "oi_stddefs.h"
+#include "oi_time.h"
+#include "oi_status.h"
+#include "oi_modules.h"
+
+/** \addtogroup Misc Miscellaneous APIs */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Terminates execution.
+ *
+ * @param reason  Reason for termination
+ */
+void OI_FatalError(OI_STATUS reason);
+
+/**
+ * This function logs an error.
+ *
+ * When built for release mode, BLUEmagic 3 errors are logged to
+ * this function. (in debug mode, errors are logged via
+ * OI_Print()).
+ *
+ * @param module Module in which the error was detected (see
+ *                oi_modules.h)
+ * @param lineno Line number of the C file OI_SLOG_ERROR called
+ * @param status Status code associated with the error event
+ */
+void OI_LogError(OI_MODULE module, OI_INT lineno, OI_STATUS status);
+
+/**
+ * This function initializes the debug code handling.
+ *
+ * When built for debug mode, this function performs platform
+ * dependent initialization to handle message codes passed in
+ * via OI_SetMsgCode().
+ */
+void OI_InitDebugCodeHandler(void);
+
+
+/**
+ * This function reads the time from the real time clock.
+ *
+ * All timing in BM3 is relative, typically a granularity
+ * of 5 or 10 msecs is adequate.
+ *
+ * @param[out] now  Pointer to the buffer to which the current
+ *       time will be returned
+ */
+void OI_Time_Now(OI_TIME *now);
+
+/**
+ * This function causes the current thread to sleep for the
+ * specified amount of time. This function must be called
+ * without the stack access token.
+ *
+ * @note BM3 corestack and profiles never suspend and never call
+ * OI_Sleep. The use of OI_Sleep is limited to applications and
+ * platform-specific code.
+ *
+ * If your port and applications never use OI_Sleep, this function can be left unimplemented.
+ *
+ * @param milliseconds  Number of milliseconds to sleep
+ */
+void OI_Sleep(OI_UINT32 milliseconds);
+
+
+/**
+ * Defines for message type codes.
+ */
+#define OI_MSG_CODE_APPLICATION               0   /**< Application output */
+#define OI_MSG_CODE_ERROR                     1   /**< Error message output */
+#define OI_MSG_CODE_WARNING                   2   /**< Warning message output */
+#define OI_MSG_CODE_TRACE                     3   /**< User API function trace output */
+#define OI_MSG_CODE_PRINT1                    4   /**< Catagory 1 debug print output */
+#define OI_MSG_CODE_PRINT2                    5   /**< Catagory 2 debug print output */
+#define OI_MSG_CODE_HEADER                    6   /**< Error/Debug output header */
+
+/**
+ * This function is used to indicate the type of text being output with
+ * OI_Print(). For the Linux and Win32 platforms, it will set
+ * the color of the text. Other possible uses could be to insert
+ * HTML style tags, add some other message type indication, or
+ * be completely ignored altogether.
+ *
+ * @param code  OI_MSG_CODE_* indicating setting the message type.
+ */
+void OI_SetMsgCode(OI_UINT8 code);
+
+/**
+ * All output from OI_Printf() and all debug output is sent to OI_Print.
+ * Typically, if the platform has a console, OI_Print() is sent to stdout.
+ * Embedded platforms typically send OI_Print() output to a serial port.
+ *
+ * @param str  String to print
+ */
+void OI_Print(OI_CHAR const *str);
+
+/**
+ *  In cases where OI_Print() is sending output to a logfile in addition to console,
+ *  it is desirable to also put console input into the logfile.
+ *  This function can be called by the console input process.
+ *
+ *  @note This is an optional API which is strictly
+ *  between the platform-specific stack_console and osinterface
+ *  modules. This API need only be implemented on those
+ *  platforms where is serves a useful purpose, e.g., win32.
+ *
+ * @param str  Console input string
+ */
+
+void OI_Print_ConsoleInput(OI_CHAR const *str);
+
+/**
+ *  This function computes the CRC16 of the program image.
+ */
+OI_UINT16  OI_ProgramImageCRC16(void);
+
+/**
+ * Writes an integer to stdout in hex. This macro is intended
+ * for selective use when debugging in small memory
+ * configurations or other times when it is not possible to use
+ * OI_DBGPRINT.
+ *
+ * @param n  the integer to print
+ */
+
+#define OI_Print_Int(n) \
+{ \
+    static const OI_CHAR _digits[] = "0123456789ABCDEF"; \
+    OI_CHAR _buf[9]; \
+    OI_CHAR *_str = &_buf[8]; \
+    OI_UINT32 _i = n; \
+    *_str = 0; \
+    do { *(--_str) = _digits[(_i & 0xF)]; _i >>= 4; } while (_i); \
+    OI_Print(_str); \
+}
+
+/**
+ *  Application Dynamic Memory allocation.
+ *
+ *  These APIs are provided for application use on those
+ *  platforms which have no dynamic memory support. Memory is
+ *  allocated from the pool-based heap managed by the stack's
+ *  internal memory manager.
+ */
+void *OI_APP_Malloc(OI_INT32 size);
+void OI_APP_Free(void *ptr);
+
+/*****************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif /* _OI_OSINTERFACE_H */
+

+ 579 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_status.h

@@ -0,0 +1,579 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef _OI_STATUS_H
+#define _OI_STATUS_H
+/**
+ * @file
+ * This file contains status codes for BLUEmagic 3.0 software.
+ */
+
+#include "oi_stddefs.h"
+
+/** \addtogroup Misc Miscellaneous APIs */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+   /** test it **/
+
+/**
+ * OI_STATUS must fit in 16 bits, so status codes can range from 0 to 66535, inclusive.
+ */
+
+typedef enum {
+    OI_STATUS_SUCCESS                      = 0,   /**< function call succeeded alias for #OI_OK */
+    OI_OK                                  = 0,   /**< function call succeeded alias for #OI_STATUS_SUCCESS */
+    OI_STATUS_INVALID_PARAMETERS           = 101, /**< invalid function input parameters */
+    OI_STATUS_NOT_IMPLEMENTED              = 102, /**< attempt to use an unimplemented function */
+    OI_STATUS_NOT_INITIALIZED              = 103, /**< data not initialized */
+    OI_STATUS_NO_RESOURCES                 = 104, /**< generic resource allocation failure status */
+    OI_STATUS_INTERNAL_ERROR               = 105, /**< internal inconsistency */
+    OI_STATUS_OUT_OF_MEMORY                = 106, /**< generally, OI_Malloc failed */
+    OI_ILLEGAL_REENTRANT_CALL              = 107, /**< violation of non-reentrant module policy */
+    OI_STATUS_INITIALIZATION_FAILED        = 108, /**< module initialization failed */
+    OI_STATUS_INITIALIZATION_PENDING       = 109, /**< inititialization not yet complete */
+    OI_STATUS_NO_SCO_SUPPORT               = 110, /**< SCO operation rejected; system not configured for SCO */
+    OI_STATUS_OUT_OF_STATIC_MEMORY         = 111, /**< static malloc failed */
+    OI_TIMEOUT                             = 112, /**< generic timeout */
+    OI_OS_ERROR                            = 113, /**< some operating system error */
+    OI_FAIL                                = 114, /**< generic failure */
+    OI_STRING_FORMAT_ERROR                 = 115, /**< error in VarString formatting string */
+    OI_STATUS_PENDING                      = 116, /**< The operation is pending. */
+    OI_STATUS_INVALID_COMMAND              = 117, /**< The command was invalid. */
+    OI_BUSY_FAIL                           = 118, /**< command rejected due to busy */
+    OI_STATUS_ALREADY_REGISTERED           = 119, /**< The registration has already been performed. */
+    OI_STATUS_NOT_FOUND                    = 120, /**< The referenced resource was not found. */
+    OI_STATUS_NOT_REGISTERED               = 121, /**< not registered */
+    OI_STATUS_NOT_CONNECTED                = 122, /**< not connected */
+    OI_CALLBACK_FUNCTION_REQUIRED          = 123, /**< A callback function parameter was required. */
+    OI_STATUS_MBUF_OVERFLOW                = 124, /**< There is no room to add another buffer to an mbuf. */
+    OI_STATUS_MBUF_UNDERFLOW               = 125, /**< There was an attempt to pull too many bytes from an mbuf. */
+    OI_STATUS_CONNECTION_EXISTS            = 126, /**< connection exists */
+    OI_STATUS_NOT_CONFIGURED               = 127, /**< module not configured */
+    OI_LOWER_STACK_ERROR                   = 128, /**< An error was reported by lower stack API. This is used for embedded platforms. */
+    OI_STATUS_RESET_IN_PROGRESS            = 129, /**< Request failed/rejected because we're busy resetting. */
+    OI_STATUS_ACCESS_DENIED                = 130, /**< Generic access denied error. */
+    OI_STATUS_DATA_ERROR                   = 131, /**< Generic data error. */
+    OI_STATUS_INVALID_ROLE                 = 132, /**< The requested role was invalid. */
+    OI_STATUS_ALREADY_CONNECTED            = 133, /**< The requested connection is already established. */
+    OI_STATUS_PARSE_ERROR                  = 134, /**< Parse error */
+    OI_STATUS_END_OF_FILE                  = 135, /**< End of file */
+    OI_STATUS_READ_ERROR                   = 136, /**< Generic read error */
+    OI_STATUS_WRITE_ERROR                  = 137, /**< Generic write error */
+    OI_STATUS_NEGOTIATION_FAILURE          = 138, /**< Error in negotiation */
+    OI_STATUS_READ_IN_PROGRESS             = 139, /**< A read is already in progress */
+    OI_STATUS_ALREADY_INITIALIZED          = 140, /**< Initialization has already been done */
+    OI_STATUS_STILL_CONNECTED              = 141, /**< The service cannot be shutdown because there are still active connections. */
+    OI_STATUS_MTU_EXCEEDED                 = 142, /**< The packet is too big */
+    OI_STATUS_LINK_TERMINATED              = 143, /**< The link was terminated */
+    OI_STATUS_PIN_CODE_TOO_LONG            = 144, /**< Application gave us a pin code that is too long */
+    OI_STATUS_STILL_REGISTERED             = 145, /**< The service cannot be shutdown because there are still active registrations. */
+    OI_STATUS_SPEC_VIOLATION               = 146, /**< Some application behavior contrary to BT specifications */
+
+
+    OI_STATUS_PSM_ALREADY_REGISTERED       = 402, /**< L2CAP: The specified PSM has already been registered. */
+    OI_STATUS_INVALID_CID                  = 403, /**< L2CAP: CID is invalid or no longer valid (connection terminated) */
+    OI_STATUS_CID_NOT_FOUND                = 404, /**< L2CAP: CID does not represent a current connection */
+    OI_STATUS_CHANNEL_NOT_FOUND            = 406, /**< L2CAP: CID does not represent a current connection */
+    OI_STATUS_PSM_NOT_FOUND                = 407, /**< L2CAP: PSM not found */
+    OI_STATUS_INVALID_STATE                = 408, /**< L2CAP: invalid state */
+    OI_STATUS_WRITE_IN_PROGRESS            = 410, /**< L2CAP: write in progress */
+    OI_STATUS_INVALID_PACKET               = 411, /**< L2CAP: invalid packet */
+    OI_STATUS_SEND_COMPLETE                = 412, /**< L2CAP: send is complete */
+    OI_STATUS_INVALID_HANDLE               = 414, /**< L2CAP: handle is invalid */
+    OI_STATUS_GROUP_FULL                   = 418, /**< L2CAP: No more members can be added to the specified group. */
+    OI_STATUS_DEVICE_ALREADY_IN_GROUP      = 423, /**< L2CAP: The device already exists in the group. */
+    OI_STATUS_DUPLICATE_GROUP              = 425, /**< L2CAP: attempt to add more than one group */
+    OI_STATUS_EMPTY_GROUP                  = 426, /**< L2CAP: group is empty */
+    OI_STATUS_PACKET_NOT_FOUND             = 427, /**< L2CAP: packet not found */
+    OI_STATUS_BUFFER_TOO_SMALL             = 428, /**< L2CAP: The buffer size is too small. */
+    OI_STATUS_IDENTIFIER_NOT_FOUND         = 429, /**< L2CAP: identifier not found */
+
+    OI_L2CAP_DISCONNECT_LOWER_LAYER        = 430, /**< L2CAP: The lower level forced a disconnect. */
+    OI_L2CAP_DISCONNECT_REMOTE_REQUEST     = 431, /**< L2CAP: The remote device requested a disconnect. */
+    OI_L2CAP_GROUP_ADD_CONNECT_FAIL        = 433, /**< L2CAP: Group add connect faiL */
+    OI_L2CAP_GROUP_REMOVE_FAILURE          = 434, /**< L2CAP: Group remove failure */
+    OI_L2CAP_DATA_WRITE_ERROR_LINK_TERM    = 435, /**< L2CAP: Data write error LINK_TERM */
+    OI_L2CAP_DISCONNECT_LOCAL_REQUEST      = 436, /**< L2CAP: Disconnect local request */
+
+    OI_L2CAP_CONNECT_TIMEOUT               = 437, /**< L2CAP: Connect timeout */
+    OI_L2CAP_DISCONNECT_TIMEOUT            = 439, /**< L2CAP: Disconnect timeout */
+    OI_L2CAP_PING_TIMEOUT                  = 440, /**< L2CAP: Ping timeout */
+    OI_L2CAP_GET_INFO_TIMEOUT              = 441, /**< L2CAP: Get info timeout */
+    OI_L2CAP_INVALID_ADDRESS               = 444, /**< L2CAP: Invalid address */
+    OI_L2CAP_CMD_REJECT_RCVD               = 445, /**< L2CAP: remote sent us 'command reject' response */
+
+    OI_L2CAP_CONNECT_BASE                  = 450, /**< L2CAP: Connect base */
+    OI_L2CAP_CONNECT_PENDING               = 451, /**< L2CAP: Connect pending */
+    OI_L2CAP_CONNECT_REFUSED_INVALID_PSM   = 452, /**< L2CAP: Connect refused invalid PSM */
+    OI_L2CAP_CONNECT_REFUSED_SECURITY      = 453, /**< L2CAP: Connect refused security */
+    OI_L2CAP_CONNECT_REFUSED_NO_RESOURCES  = 454, /**< L2CAP: Connect refused no resources */
+
+    OI_L2CAP_CONFIG_BASE                   = 460, /**< L2CAP: Config base */
+    OI_L2CAP_CONFIG_FAIL_INVALID_PARAMETERS= 461, /**< L2CAP: Config fail invalid parameters */
+    OI_L2CAP_CONFIG_FAIL_NO_REASON         = 462, /**< L2CAP: Config fail no reason */
+    OI_L2CAP_CONFIG_FAIL_UNKNOWN_OPTIONS   = 463, /**< L2CAP: Config fail unknown options */
+
+    OI_L2CAP_GET_INFO_BASE                 = 470, /**< L2CAP: Get info base */
+    OI_L2CAP_GET_INFO_NOT_SUPPORTED        = 471, /**< L2CAP: Get info not supported */
+    OI_L2CAP_MTU_EXCEEDED                  = 472, /**< L2CAP: The MTU of the channel was exceeded */
+    OI_L2CAP_INVALID_PSM                   = 482, /**< L2CAP: Invalid PSM */
+    OI_L2CAP_INVALID_MTU                   = 483, /**< L2CAP: Invalid MTU */
+    OI_L2CAP_INVALID_FLUSHTO               = 484, /**< L2CAP: Invalid flush timeout */
+
+    OI_HCI_NO_SUCH_CONNECTION               = 601, /**< HCI: caller specified a non-existent connection handle */
+    OI_HCI_CB_LIST_FULL                     = 603, /**< HCI: callback list is full, cannot attempt to send command */
+    OI_HCI_EVENT_UNDERRUN                   = 605, /**< HCI: parsing event packet, premature end-of-parameters */
+    OI_HCI_UNKNOWN_EVENT_CODE               = 607, /**< HCI: event received - event code is unknown */
+    OI_HCI_BAD_EVENT_PARM_LEN               = 608, /**< HCI: event - parameter length is incorrect */
+    OI_HCI_CMD_QUEUE_FULL                   = 611, /**< HCI: command queue is full */
+    OI_HCI_SHORT_EVENT                      = 612, /**< HCI: event received, missing event code and/or parm len */
+    OI_HCI_TRANSMIT_NOT_READY               = 613, /**< HCI: ACL/SCO transmit request failed - busy or no buffers available */
+    OI_HCI_ORPHAN_SENT_EVENT                = 614, /**< HCI: got spurious 'sent' event from transport layer */
+    OI_HCI_CMD_TABLE_ERROR                  = 615, /**< HCI: inconsistency in the internal command table */
+    OI_HCI_UNKNOWN_CMD_ID                   = 616, /**< HCI: HciApi Command - unknown command id */
+    OI_HCI_UNEXPECTED_EVENT                 = 619, /**< HCI: event received which only occurs in response to our cmd */
+    OI_HCI_EVENT_TABLE_ERROR                = 620, /**< HCI: inconsistency in the internal event table */
+    OI_HCI_EXPECTED_EVENT_TIMOUT            = 621, /**< HCI: timed out waiting for an expected event */
+    OI_HCI_NO_CMD_DESC_FOR_OPCODE           = 622, /**< HCI: event opcode is not known */
+    OI_HCI_INVALID_OPCODE_ERROR             = 623, /**< HCI: command opcode is invalid */
+    OI_HCI_FLOW_CONTROL_DISABLED            = 624, /**< HCI: can not use host flow control APIs if disabled in configuration */
+    OI_HCI_TX_COMPLETE                      = 625, /**< HCI: packet delivery to Host Controler complete */
+    OI_HCI_TX_ERROR                         = 626, /**< HCI: failed to deliver packet to Host Controler */
+    OI_HCI_DEVICE_NOT_INITIALIZED           = 627, /**< HCI: commands from upper layers disallowed until device is up and running */
+    OI_HCI_UNSUPPORTED_COMMAND              = 628, /**< HCI: command requested is not supported by local device */
+    OI_HCI_PASSTHROUGH_ERROR                = 629, /**< HCI: Error processing passthrough command */
+    OI_HCI_PASSTHROUGH_ALREADY_SET          = 630, /**< HCI: Passthrough mode already enabled */
+    OI_HCI_RESET_FAILURE                    = 631, /**< HCI: failed to reset the device/baseband */
+    OI_HCI_TRANSPORT_RESET                  = 632, /**< HCI: some operation failed because of a reset in the transport */
+    OI_HCIERR_HCIIFC_INIT_FAILURE           = 633, /**< HCI: failed to initialize transport layer interface */
+
+    OI_HCIERR_FIRST_ERROR_VALUE                = 701, /**< marker for first HCI protocol error */
+    OI_HCIERR_UNKNOWN_HCI_COMMAND              = 701, /**< HCI: protocol error 0x01 */
+    OI_HCIERR_NO_CONNECTION                    = 702, /**< HCI: protocol error 0x02 */
+    OI_HCIERR_HARDWARE_FAILURE                 = 703, /**< HCI: protocol error 0x03 */
+    OI_HCIERR_PAGE_TIMEOUT                     = 704, /**< HCI: protocol error 0x04 */
+    OI_HCIERR_AUTHENTICATION_FAILURE           = 705, /**< HCI: protocol error 0x05 */
+    OI_HCIERR_KEY_MISSING                      = 706, /**< HCI: protocol error 0x06 */
+    OI_HCIERR_MEMORY_FULL                      = 707, /**< HCI: protocol error 0x07 */
+    OI_HCIERR_CONNECTION_TIMEOUT               = 708, /**< HCI: protocol error 0x08 */
+    OI_HCIERR_MAX_NUM_OF_CONNECTIONS           = 709, /**< HCI: protocol error 0x09 */
+    OI_HCIERR_MAX_NUM_OF_SCO_CONNECTIONS       = 710, /**< HCI: protocol error 0x0A */
+    OI_HCIERR_ACL_CONNECTION_ALREADY_EXISTS    = 711, /**< HCI: protocol error 0x0B */
+    OI_HCIERR_COMMAND_DISALLOWED               = 712, /**< HCI: protocol error 0x0C */
+    OI_HCIERR_HOST_REJECTED_RESOURCES          = 713, /**< HCI: protocol error 0x0D */
+    OI_HCIERR_HOST_REJECTED_SECURITY           = 714, /**< HCI: protocol error 0x0E */
+    OI_HCIERR_HOST_REJECTED_PERSONAL_DEVICE    = 715, /**< HCI: protocol error 0x0F */
+    OI_HCIERR_HOST_TIMEOUT                     = 716, /**< HCI: protocol error 0x10 */
+    OI_HCIERR_UNSUPPORTED                      = 717, /**< HCI: protocol error 0x11 */
+    OI_HCIERR_INVALID_PARAMETERS               = 718, /**< HCI: protocol error 0x12 */
+    OI_HCIERR_OTHER_END_USER_DISCONNECT        = 719, /**< HCI: protocol error 0x13 */
+    OI_HCIERR_OTHER_END_LOW_RESOURCES          = 720, /**< HCI: protocol error 0x14 */
+    OI_HCIERR_OTHER_END_POWERING_OFF           = 721, /**< HCI: protocol error 0x15 */
+    OI_HCIERR_CONNECTION_TERMINATED_LOCALLY    = 722, /**< HCI: protocol error 0x16 */
+    OI_HCIERR_REPEATED_ATTEMPTS                = 723, /**< HCI: protocol error 0x17 */
+    OI_HCIERR_PAIRING_NOT_ALLOWED              = 724, /**< HCI: protocol error 0x18 */
+    OI_HCIERR_UNKNOWN_LMP_PDU                  = 725, /**< HCI: protocol error 0x19 */
+    OI_HCIERR_UNSUPPORTED_REMOTE_FEATURE       = 726, /**< HCI: protocol error 0x1A */
+    OI_HCIERR_SCO_OFFSET_REJECTED              = 727, /**< HCI: protocol error 0x1B */
+    OI_HCIERR_SCO_INTERVAL_REJECTED            = 728, /**< HCI: protocol error 0x1C */
+    OI_HCIERR_SCO_AIR_MODE_REJECTED            = 729, /**< HCI: protocol error 0x1D */
+    OI_HCIERR_INVALID_LMP_PARMS                = 730, /**< HCI: protocol error 0x1E */
+    OI_HCIERR_UNSPECIFIED_ERROR                = 731, /**< HCI: protocol error 0x1F */
+    OI_HCIERR_UNSUPPORTED_LMP_PARAMETERS       = 732, /**< HCI: protocol error 0x20 */
+    OI_HCIERR_ROLE_CHANGE_NOT_ALLOWED          = 733, /**< HCI: protocol error 0x21 */
+    OI_HCIERR_LMP_RESPONSE_TIMEOUT             = 734, /**< HCI: protocol error 0x22 */
+    OI_HCIERR_LMP_ERROR_TRANS_COLLISION        = 735, /**< HCI: protocol error 0x23 */
+    OI_HCIERR_LMP_PDU_NOT_ALLOWED              = 736, /**< HCI: protocol error 0x24 */
+    OI_HCIERR_ENCRYPTION_MODE_NOT_ACCEPTABLE   = 737, /**< HCI: protocol error 0x25 */
+    OI_HCIERR_UNIT_KEY_USED                    = 738, /**< HCI: protocol error 0x26 */
+    OI_HCIERR_QOS_NOT_SUPPORTED                = 739, /**< HCI: protocol error 0x27 */
+    OI_HCIERR_INSTANT_PASSED                   = 740, /**< HCI: protocol error 0x28 */
+    OI_HCIERR_UNIT_KEY_PAIRING_UNSUPPORTED     = 741, /**< HCI: protocol error 0x29 */
+    OI_HCIERR_DIFFERENT_TRANS_COLLISION        = 742, /**< HCI: protocol error 0x2A */
+    OI_HCIERR_RESERVED_2B                      = 743, /**< HCI: protocol error 0x2B */
+    OI_HCIERR_QOS_UNACCEPTABLE_PARAMETER       = 744, /**< HCI: protocol error 0x2C */
+    OI_HCIERR_QOS_REJECTED                     = 745, /**< HCI: protocol error 0x2D */
+    OI_HCIERR_CHANNEL_CLASSIFICATION_NS        = 746, /**< HCI: protocol error 0x2E */
+    OI_HCIERR_INSUFFICIENT_SECURITY            = 747, /**< HCI: protocol error 0x2F */
+    OI_HCIERR_PARM_OUT_OF_MANDATORY_RANGE      = 748, /**< HCI: protocol error 0x30 */
+    OI_HCIERR_RESERVED_31                      = 749, /**< HCI: protocol error 0x31 */
+    OI_HCIERR_ROLE_SWITCH_PENDING              = 750, /**< HCI: protocol error 0x32 */
+    OI_HCIERR_RESERVED_33                      = 751, /**< HCI: protocol error 0x33 */
+    OI_HCIERR_RESERVED_SLOT_VIOLATION          = 752, /**< HCI: protocol error 0x34 */
+    OI_HCIERR_ROLE_SWITCH_FAILED               = 753, /**< HCI: protocol error 0x35 */
+    OI_HCIERR_EIR_TOO_LARGE                    = 754, /**< HCI: protocol error 0x36 */
+    OI_HCIERR_SSP_NOT_SUPPORTED_BY_HOST        = 755, /**< HCI: protocol error 0x37 */
+    OI_HCIERR_HOST_BUSY_PAIRING                = 756, /**< HCI: protocol error 0x38 */
+
+    OI_HCIERR_UNKNOWN_ERROR                    = 757, /**< HCI: unknown error code */
+    OI_HCIERR_LAST_ERROR_VALUE                 = 757, /**< marker for last HCI protocol error */
+
+    OI_SDP_SPEC_ERROR                    = 800, /**< SDP: Base error status for mapping OI_STATUS codes to SDP errors */
+    OI_SDP_INVALID_SERVICE_RECORD_HANDLE = (OI_SDP_SPEC_ERROR + 2), /**< SDP: protocol error Invalid Service Record Handle */
+    OI_SDP_INVALID_REQUEST_SYNTAX        = (OI_SDP_SPEC_ERROR + 3), /**< SDP: protocol error Invalid Request Syntax */
+    OI_SDP_INVALID_PDU_SIZE              = (OI_SDP_SPEC_ERROR + 4), /**< SDP: protocol error Invalid PDU Size */
+    OI_SDP_INVALID_CONTINUATION_STATE    = (OI_SDP_SPEC_ERROR + 5), /**< SDP: protocol error Invalid Continuation State */
+    OI_SDP_INSUFFICIENT_RESOURCES        = (OI_SDP_SPEC_ERROR + 6), /**< SDP: protocol error Insufficient Resources */
+    OI_SDP_ERROR                         = 807, /**< SDP: server returned an error code */
+    OI_SDP_CORRUPT_DATA_ELEMENT          = 808, /**< SDP: Invalid or corrupt data element representation */
+    OI_SDP_SERVER_NOT_CONNECTED          = 810, /**< SDP: Attempt to disconnect from an unconnected server */
+    OI_SDP_ACCESS_DENIED                 = 811, /**< SDP: Server denied access to server */
+    OI_SDP_ATTRIBUTES_OUT_OF_ORDER       = 812, /**< SDP: Attributes in attribute list not in ascending order */
+    OI_SDP_DEVICE_DOES_NOT_SUPPORT_SDP   = 813, /**< SDP: Tried to connect to a device that does not support SDP */
+    OI_SDP_NO_MORE_DATA                  = 815, /**< SDP: Server does not have more continuation data */
+    OI_SDP_REQUEST_PARAMS_TOO_LONG       = 816, /**< SDP: Parameters for a request exceed the L2CAP buffer size */
+    OI_SDP_REQUEST_PENDING               = 817, /**< SDP: Cannot make a request when another request is being processed */
+    OI_SDP_SERVER_CONNECT_FAILED         = 819, /**< SDP: Failed attempt to connect to an SDP server */
+    OI_SDP_SERVER_TOO_MANY_CONNECTIONS   = 821, /**< SDP: Exceeded maximum number of simultaneous server connections */
+    OI_SDP_NO_MATCHING_SERVICE_RECORD    = 823, /**< SDP: No service record matched the UUID list */
+    OI_SDP_PARTIAL_RESPONSE              = 824, /**< SDP: Internal use only */
+    OI_SDP_ILLEGAL_ARGUMENT              = 825, /**< SDP: Illegal argument passed to an SDP function */
+    OI_SDP_ATTRIBUTE_NOT_FOUND           = 826, /**< SDP: A requested attribute was not found in a service record */
+    OI_SDP_DATABASE_OUT_OF_RESOURCES     = 827, /**< SDP: server database is out of memory */
+    OI_SDP_SHORT_PDU                     = 829, /**< SDP: Not enough bytes in the packet */
+    OI_SDP_TRANSACTION_ID_MISMATCH       = 830, /**< SDP: Transaction Id was not as expected */
+    OI_SDP_UNEXPECTED_RESPONSE_PDU_ID    = 831, /**< SDP: Did not expect this response PDU */
+    OI_SDP_REQUEST_TIMEOUT               = 832, /**< SDP: Did not get a response within the timeout period */
+    OI_SDP_INVALID_RESPONSE_SYNTAX       = 833, /**< SDP: Response is not correctly formatted */
+    OI_SDP_CONNECTION_TIMEOUT            = 834, /**< SDP: Connection attempt timed out at a lower layer */
+    OI_SDP_RESPONSE_DATA_ERROR           = 835, /**< SDP: Response to a service request appears to be corrupt */
+    OI_SDP_TOO_MANY_ATTRIBUTE_BYTES      = 836, /**< SDP: Response contained more bytes than requested. */
+    OI_SDP_TOO_MANY_SERVICE_RECORDS      = 837, /**< SDP: Response contained more service records than requested. */
+    OI_SDP_INVALID_CONNECTION_ID         = 838, /**< SDP: Invalid connection ID in an SDP request */
+    OI_SDP_CANNOT_SET_ATTRIBUTE          = 839, /**< SDP: Attempt to set a dynamic attribute value failed */
+    OI_SDP_BADLY_FORMED_ATTRIBUTE_VALUE  = 840, /**< SDP: An attribute value has the wrong type or structure */
+    OI_SDP_NO_ATTRIBUTE_LIST_TO_REMOVE   = 841, /**< SDP: Attempt to remove a non-existent attribute list from a service record */
+    OI_SDP_ATTRIBUTE_LIST_ALREADY_ADDED  = 842, /**< SDP: An attribute list has already been added to the service record */
+    OI_SDP_DATA_ELEMENT_TRUNCATED        = 843, /**< SDP: Data element truncated (too few bytes) */
+
+    OI_RFCOMM_WRITE_IN_PROGRESS          = 901, /**< RFCOMM: Write in progress */
+    OI_RFCOMM_INVALID_BAUDRATE           = 903, /**< RFCOMM: Invalid baudrate */
+    OI_RFCOMM_INVALID_DATABIT            = 904, /**< RFCOMM: Invalid databit */
+    OI_RFCOMM_INVALID_STOPBIT            = 905, /**< RFCOMM: Invalid stopbit */
+    OI_RFCOMM_INVALID_PARITY             = 906, /**< RFCOMM: Invalid parity */
+    OI_RFCOMM_INVALID_PARITYTYPE         = 907, /**< RFCOMM: Invalid paritytype */
+    OI_RFCOMM_INVALID_FLOWCONTROL        = 908, /**< RFCOMM: Invalid flowcontrol */
+    OI_RFCOMM_SESSION_EXISTS             = 909, /**< RFCOMM: Session exists */
+    OI_RFCOMM_INVALID_CHANNEL            = 910, /**< RFCOMM: Invalid channel */
+    OI_RFCOMM_DLCI_EXISTS                = 911, /**< RFCOMM: DLCI exists */
+    OI_RFCOMM_LINK_NOT_FOUND             = 912, /**< RFCOMM: Link not found */
+    OI_RFCOMM_REMOTE_REJECT              = 913, /**< RFCOMM: Remote reject */
+    OI_RFCOMM_TEST_IN_PROGRESS           = 915, /**< RFCOMM: Test in progress */
+    OI_RFCOMM_SESSION_NOT_FOUND          = 916, /**< RFCOMM: Session not found */
+    OI_RFCOMM_INVALID_PACKET             = 917, /**< RFCOMM: Invalid packet */
+    OI_RFCOMM_FRAMESIZE_EXCEEDED         = 918, /**< RFCOMM: Framesize exceeded */
+    OI_RFCOMM_INVALID_DLCI               = 920, /**< RFCOMM: Invalid dlci */
+    OI_RFCOMM_SERVER_NOT_REGISTERED      = 921, /**< RFCOMM: Server not registered */
+    OI_RFCOMM_CREDIT_ERROR               = 922, /**< RFCOMM: Credit error */
+    OI_RFCOMM_NO_CHANNEL_NUMBER          = 923, /**< RFCOMM: No channel number */
+    OI_RFCOMM_QUERY_IN_PROGRESS          = 924, /**< RFCOMM: Query in progress */
+    OI_RFCOMM_SESSION_SHUTDOWN           = 925, /**< RFCOMM: Session shutdown */
+    OI_RFCOMM_LOCAL_DEVICE_DISCONNECTED  = 926, /**< RFCOMM: Local device disconnected */
+    OI_RFCOMM_REMOTE_DEVICE_DISCONNECTED = 927, /**< RFCOMM: Remote device disconnected */
+    OI_RFCOMM_OUT_OF_SERVER_CHANNELS     = 928, /**< RFCOMM: Out of server channels */
+
+    OI_DISPATCH_INVALID_CB_HANDLE        = 1001, /**< Dispatcher was handed an invalid callback handle */
+    OI_DISPATCH_TABLE_OVERFLOW           = 1002, /**< Dispatcher table is full */
+
+    OI_TEST_UNKNOWN_TEST                 = 1101, /**< TEST: Unknown test */
+    OI_TEST_FAIL                         = 1102, /**< TEST: Fail */
+
+    OI_HCITRANS_CANNOT_CONNECT_TO_DEVICE   = 1201, /**< TRANSPORT: Cannot connect to device */
+    OI_HCITRANS_BUFFER_TOO_SMALL           = 1203, /**< TRANSPORT: Buffer too small */
+    OI_HCITRANS_NULL_DEVICE_HANDLE         = 1204, /**< TRANSPORT: Null device handle */
+    OI_HCITRANS_IO_ERROR                   = 1205, /**< TRANSPORT: IO error */
+    OI_HCITRANS_DEVICE_NOT_READY           = 1206, /**< TRANSPORT: Device not ready */
+    OI_HCITRANS_FUNCTION_NOT_SUPPORTED     = 1207, /**< TRANSPORT: Function not supporteD */
+    OI_HCITRANS_ACCESS_DENIED              = 1209, /**< TRANSPORT: win32 */
+    OI_HCITRANS_ACL_DATA_ERROR             = 1210, /**< TRANSPORT: ACL data error */
+    OI_HCITRANS_SCO_DATA_ERROR             = 1211, /**< TRANSPORT: SCO data error */
+    OI_HCITRANS_EVENT_DATA_ERROR           = 1212, /**< TRANSPORT: HCI event data error */
+    OI_HCITRANS_INTERNAL_ERROR             = 1214, /**< TRANSPORT: Internal error in the transport */
+    OI_HCITRANS_LINK_NOT_ACTIVE            = 1215, /**< TRANSPORT: Link to the device is not currently active */
+    OI_HCITRANS_INITIALIZING               = 1216, /**< TRANSPORT: Transport is initializing */
+
+    OI_DEVMGR_NO_CONNECTION                = 1301, /**< DEVMGR: No connection */
+    OI_DEVMGR_HARDWARE_ERROR               = 1305, /**< DEVMGR: error reported by HCI */
+    OI_DEVMGR_PENDING_CONNECT_LIST_FULL    = 1307, /**< DEVMGR: Pending connect list full */
+    OI_DEVMGR_CONNECTION_LIST_FULL         = 1309, /**< DEVMGR: Connection list full */
+    OI_DEVMGR_NO_SUCH_CONNECTION           = 1310, /**< DEVMGR: No such connection */
+    OI_DEVMGR_INQUIRY_IN_PROGRESS          = 1311, /**< DEVMGR: Inquiry in progress */
+    OI_DEVMGR_PERIODIC_INQUIRY_ACTIVE      = 1312, /**< DEVMGR: Periodic inquiry active */
+    OI_DEVMGR_NO_INQUIRIES_ACTIVE          = 1313, /**< DEVMGR: can not cancel/exit if not active */
+    OI_DEVMGR_DUPLICATE_CONNECTION         = 1314, /**< DEVMGR: internal error */
+    OI_DEVMGR_DUPLICATE_EVENT_CALLBACK     = 1316, /**< DEVMGR: attempt to register same callback twice */
+    OI_DEVMGR_EVENT_CALLBACK_LIST_FULL     = 1317, /**< DEVMGR: can not register event callback, list is full */
+    OI_DEVMGR_EVENT_CALLBACK_NOT_FOUND     = 1318, /**< DEVMGR: attempt to unregister callback failed */
+    OI_DEVMGR_BUSY                         = 1319, /**< DEVMGR: some operations can only execute one at a time */
+    OI_DEVMGR_ENUM_UNEXPECTED_INQ_COMPLETE = 1320, /**< DEVMGR: inquiry complete event in inappropriate enumeration state */
+    OI_DEVMGR_ENUM_UNEXPECTED_INQ_RESULT   = 1321, /**< DEVMGR: inquiry result event in inappropriate enumeration state */
+    OI_DEVMGR_ENUM_DATABASE_FULL           = 1322, /**< DEVMGR: device enumeration, database is full, couldn't add a new device */
+    OI_DEVMGR_ENUM_INQUIRIES_OVERLAP       = 1323, /**< DEVMGR: device enumeration, periodic inquiries occurring too close together */
+    OI_DEVMGR_UNKNOWN_LINK_TYPE            = 1324, /**< DEVMGR: HCI connect request with unkown link type */
+    OI_DEVMGR_PARAM_IO_ACTIVE              = 1325, /**< DEVMGR: request for parameter read/write while param read/write active */
+    OI_DEVMGR_UNKNOWN_IAC_LAP              = 1326, /**< DEVMGR: unrecognized IAC LAP */
+    OI_DEVMGR_SCO_ALREADY_REGISTERED       = 1327, /**< DEVMGR: only one application can use SCO */
+    OI_DEVMGR_SCO_NOT_REGISTERED           = 1328, /**< DEVMGR: SCO applications must register before using the API */
+    OI_DEVMGR_SCO_WITHOUT_ACL              = 1329, /**< DEVMGR: Got SCO connection but there is no underlying ACL connection */
+    OI_DEVMGR_NO_SUPPORT                   = 1330, /**< DEVMGR: Request is not supported by the device */
+    OI_DEVMGR_WRITE_POLICY_FAILED          = 1331, /**< DEVMGR: connection attempt failed - unable to write link policy */
+    OI_DEVMGR_NOT_IN_MASTER_MODE           = 1332, /**< DEVMGR: OI_DEVMGR EndMasterMode without prior OI_DEVMGR_BeginMasterMode */
+    OI_DEVMGR_POLICY_VIOLATION             = 1333, /**< DEVMGR: low-power request is rejected - link policy does not allow it */
+    OI_DEVMGR_BUSY_TIMEOUT                 = 1334, /**< DEVMGR: queued operation timed out while in the queue; \n
+        timeout configurable via @ref OI_CONFIG_DEVMGR::connectQueueTimeoutSecs "connectQueueTimeoutSecs" */
+    OI_DEVMGR_REENCRYPT_FAILED             = 1335, /**< DEVMGR: failed to re-encrypt link after role switch */
+    OI_DEVMGR_ROLE_POLICY_CONFLICT         = 1336, /**< DEVMGR: requested role conflicts with current policy */
+    OI_DEVMGR_BAD_INTERVAL                 = 1337, /**< DEVMGR: current linkTO outside range of requested min/max interval */
+    OI_DEVMGR_INVALID_SCO_HANDLE           = 1338, /**< DEVMGR: HCI SCO event, invalid handle */
+    OI_DEVMGR_CONNECTION_OVERLAP           = 1339, /**< DEVMGR: Connection failed due to race condition with remote side */
+    OI_DEVMGR_ORPHAN_SUBRATE_COMPLETE      = 1340, /**< DEVMGR: sniff subrate complete, but no callback */
+    OI_DEVMGR_EIR_RESPONSE_2_LARGE         = 1341, /**< DEVMGR: eir builder, response length would exceed spec max */
+
+    OI_SECMGR_NO_POLICY                    = 1401, /**< SECMGR: no security policy has been established */
+    OI_SECMGR_INTERNAL_ERROR               = 1402, /**< SECMGR: internal inconsistency */
+    OI_SECMGR_ORPHANED_CALLBACK            = 1403, /**< SECMGR: we've been called back, but CB context is gone */
+    OI_SECMGR_BUSY                         = 1404, /**< SECMGR: configure and access request cannot be concurrent */
+    OI_SECMGR_DEVICE_NOT_TRUSTED           = 1405, /**< SECMGR: l2cap access denied - device is not trusted */
+    OI_SECMGR_DEVICE_ENCRYPT_FAIL          = 1407, /**< SECMGR: l2cap access denied - failed to start encryption */
+    OI_SECMGR_DISCONNECTED_FAIL            = 1408, /**< SECMGR: l2cap access denied - disconnected */
+    OI_SECMGR_ACCESS_PENDING               = 1409, /**< SECMGR: l2cap access request is still pending  */
+    OI_SECMGR_PIN_CODE_TOO_SHORT           = 1410, /**< SECMGR: Higher-layer process gave us a pin code that is too short */
+    OI_SECMGR_UNKNOWN_ENCRYPT_VALUE        = 1411, /**< SECMGR: got EncryptionChange event, unknown encryption enable value */
+    OI_SECMGR_INVALID_POLICY               = 1412, /**< SECMGR: the specified security policy is not valid for security mode */
+    OI_SECMGR_AUTHORIZATION_FAILED         = 1413, /**< SECMGR: device authorization failed */
+    OI_SECMGR_ENCRYPTION_FAILED            = 1414, /**< SECMGR: device encryption failed */
+    OI_SECMGR_UNIT_KEY_UNSUPPORTED         = 1415, /**< SECMGR: authentication failed due to non-support of unit keys */
+    OI_SECMGR_NOT_REGISTERED               = 1416, /**< SECMGR: required registrations have not yet occurred */
+    OI_SECMGR_ILLEGAL_WRITE_SSP_MODE       = 1417, /**< SECMGR: 2.1 HCI spec does not allow SSP mode to be disabled */
+    OI_SECMGR_INVALID_SEC_LEVEL            = 1418, /**< SECMGR: security level for a service is not a valid value */
+    OI_SECMGR_INSUFFICIENT_LINK_KEY        = 1419, /**< SECMGR: link key type is not sufficient to meet service requirements */
+    OI_SECMGR_INVALID_KEY_TYPE             = 1420, /**< SECMGR: link key type is not a valid value */
+    OI_SECMGR_SSP_NOT_ENCRYPTED            = 1421, /**< SECMGR: ssp required encryption on incoming link */
+    OI_SECMGR_ORPHAN_EVENT                 = 1422, /**< SECMGR: some HCI security event unrelated to current processes */
+    OI_SECMGR_NOT_BONDABLE                 = 1423, /**< SECMGR: not in bondable mode */
+
+    OI_TCS_INVALID_ELEMENT_TYPE            = 1602, /**< TCS: element type is invalid */
+    OI_TCS_INVALID_PACKET                  = 1603, /**< TCS: packet is invalide */
+    OI_TCS_CALL_IN_PROGRESS                = 1604, /**< TCS: call is in progress */
+    OI_TCS_NO_CALL_IN_PROGRESS             = 1605, /**< TCS: no call in progress */
+
+    OI_OBEX_CONTINUE                       = 1701, /**< OBEX: Continue processing OBEX request */
+    OI_OBEX_COMMAND_ERROR                  = 1702, /**< OBEX: An unrecognized OBEX command opcode */
+    OI_OBEX_CONNECTION_TIMEOUT             = 1703, /**< OBEX: Timeout waiting for a response to a request */
+    OI_OBEX_CONNECT_FAILED                 = 1704, /**< OBEX: An OBEX connection request did not succeed */
+    OI_OBEX_DISCONNECT_FAILED              = 1705, /**< OBEX: A disconnect failed probably because the connection did not exist */
+    OI_OBEX_ERROR                          = 1706, /**< OBEX: Unspecified OBEX error */
+    OI_OBEX_INCOMPLETE_PACKET              = 1707, /**< OBEX: Packet too short or corrupt */
+    OI_OBEX_LENGTH_REQUIRED                = 1708, /**< OBEX: Length header required in OBEX command */
+    OI_OBEX_NOT_CONNECTED                  = 1709, /**< OBEX: No connection to OBEX server */
+    OI_OBEX_NO_MORE_CONNECTIONS            = 1710, /**< OBEX: Reached max connections limit */
+    OI_OBEX_OPERATION_IN_PROGRESS          = 1711, /**< OBEX: Another operation is still in progress on a connection */
+    OI_OBEX_PUT_RESPONSE_ERROR             = 1712, /**< OBEX: An error in the response to a PUT command */
+    OI_OBEX_GET_RESPONSE_ERROR             = 1713, /**< OBEX: An error in the response to a GET command */
+    OI_OBEX_REQUIRED_HEADER_NOT_FOUND      = 1714, /**< OBEX: packet was missing a required header */
+    OI_OBEX_SERVICE_UNAVAILABLE            = 1715, /**< OBEX: Unown OBEX target or required service */
+    OI_OBEX_TOO_MANY_HEADER_BYTES          = 1716, /**< OBEX: Headers will not fit in single OBEX packet */
+    OI_OBEX_UNKNOWN_COMMAND                = 1717, /**< OBEX: Unrecognized OBEX command */
+    OI_OBEX_UNSUPPORTED_VERSION            = 1718, /**< OBEX: Version mismatch */
+    OI_OBEX_CLIENT_ABORTED_COMMAND         = 1719, /**< OBEX: server received abort command */
+    OI_OBEX_BAD_PACKET                     = 1720, /**< OBEX: Any malformed OBEX packet */
+    OI_OBEX_BAD_REQUEST                    = 1721, /**< OBEX: Maps to OBEX response of the same name */
+    OI_OBEX_OBJECT_OVERFLOW                = 1723, /**< OBEX: Too many bytes received. */
+    OI_OBEX_NOT_FOUND                      = 1724, /**< OBEX: Maps to obex response of same name */
+    OI_OBEX_ACCESS_DENIED                  = 1735, /**< OBEX: Object could not be read or written. */
+    OI_OBEX_VALUE_NOT_ACCEPTABLE           = 1736, /**< OBEX: Value in a command was not in the acceptable range. */
+    OI_OBEX_PACKET_OVERFLOW                = 1737, /**< OBEX: Buffer will not fit in a single OBEX packet. */
+    OI_OBEX_NO_SUCH_FOLDER                 = 1738, /**< OBEX: Error returned by a setpath operation. */
+    OI_OBEX_NAME_REQUIRED                  = 1739, /**< OBEX: Name must be non-null and non-empty. */
+    OI_OBEX_PASSWORD_TOO_LONG              = 1740, /**< OBEX: Password exceeds implementation imposed length limit. */
+    OI_OBEX_PRECONDITION_FAILED            = 1741, /**< OBEX: response Precondition Failed */
+    OI_OBEX_UNAUTHORIZED                   = 1742, /**< OBEX: authentication was not successful. */
+    OI_OBEX_NOT_IMPLEMENTED                = 1743, /**< OBEX: Unimplemented feature. */
+    OI_OBEX_INVALID_AUTH_DIGEST            = 1744, /**< OBEX: An authentication digest was bad. */
+    OI_OBEX_INVALID_OPERATION              = 1745, /**< OBEX: Operation not allowed at this time. */
+    OI_OBEX_DATABASE_FULL                  = 1746, /**< OBEX: Sync database full. */
+    OI_OBEX_DATABASE_LOCKED                = 1747, /**< OBEX: Sync database locked. */
+    OI_OBEX_INTERNAL_SERVER_ERROR          = 1748, /**< OBEX: response Internal Server Error */
+    OI_OBEX_UNSUPPORTED_MEDIA_TYPE         = 1749, /**< OBEX: response Unsupported Media Type */
+    OI_OBEX_PARTIAL_CONTENT                = 1750, /**< OBEX: response Partial Content */
+    OI_OBEX_METHOD_NOT_ALLOWED             = 1751, /**< OBEX: response Method Not Allowed */
+    OI_OBEXSRV_INCOMPLETE_GET              = 1752, /**< OBEX: Indicates to a GET handler that the request phase is still in progress */
+    OI_OBEX_FOLDER_BROWSING_NOT_ALLOWED    = 1753, /**< OBEX: Indicates that an FTP server does not allow folder browsing */
+    OI_OBEX_SERVER_FORCED_DISCONNECT       = 1754, /**< OBEX: connection was forcibly terminated by the server */
+    OI_OBEX_OFS_ERROR                      = 1755, /**< OBEX: OPP object file system error occurred */
+    OI_OBEX_FILEOP_ERROR                   = 1756, /**< OBEX: FTP/PBAP file operation system error occurred */
+    OI_OBEX_USERID_TOO_LONG                = 1757, /**< OBEX: User Id exceeds spec limited length limit. */
+
+    OI_HANDSFREE_EVENT_REPORTING_DISABLED  = 1801, /**< HANDSFREE: Event reporting disabled */
+    OI_HANDSFREE_NOT_CONNECTED             = 1802, /**< HANDSFREE: Not connected */
+    OI_HANDSFREE_SERVICE_NOT_STARTED       = 1803, /**< HANDSFREE: Cannot connect to handsfree AG if handsfree service not started */
+    OI_HANDSFREE_AG_SERVICE_NOT_STARTED    = 1804, /**< HANDSFREE: Cannot connect to handsfree device if handsfree AG service not started */
+    OI_HANDSFREE_COMMAND_IN_PROGRESS       = 1805, /**< HANDSFREE: Cannot accept a command at this time */
+    OI_HANDSFREE_AUDIO_ALREADY_CONNECTED   = 1806, /**< HANDSFREE: Audio is already connected */
+    OI_HANDSFREE_AUDIO_NOT_CONNECTED       = 1807, /**< HANDSFREE: Audio is not connected */
+    OI_HANDSFREE_FEATURE_NOT_SUPPORTED     = 1808, /**< HANDSFREE: Local or remote feature not supported for requested command */
+
+    OI_HEADSET_SERVICE_NOT_STARTED         = 1901, /**< HEADSET: Cannot connect to headset AG if headset service not started */
+    OI_HEADSET_AG_SERVICE_NOT_STARTED      = 1902, /**< HEADSET: Cannot connect to headset device if headset AG service not started */
+    OI_HEADSET_COMMAND_IN_PROGRESS         = 1903, /**< HEADSET: Cannot accept a command at this time */
+
+    OI_BNEP_INVALID_MTU                             = 2001, /**< BNEP: The remote device cannot support the minimum BNEP MTU */
+    OI_BNEP_SETUP_TIMEOUT                           = 2002, /**< BNEP: The setup request timed out. */
+    OI_BNEP_SERVICE_NOT_REGISTERED                  = 2003, /**< BNEP: The requested service was not found. */
+    OI_BNEP_INVALID_HANDLE                          = 2004, /**< BNEP: The specified connection handle is not valid. */
+    OI_BNEP_RESPONSE_TIMEOUT                        = 2005, /**< BNEP: The timer for receiving a response has expired. */
+    OI_BNEP_INVALID_CONNECTION                      = 2006, /**< BNEP: Invalid connection */
+    OI_BNEP_INVALID_FILTER                          = 2007, /**< BNEP: The supplied filter was invalid. */
+    OI_BNEP_CONNECTION_EXISTS                       = 2008, /**< BNEP: An attempt was made to create a duplicate connection. */
+    OI_BNEP_NOT_INITIALIZED                         = 2009, /**< BNEP: Init has not been called */
+    OI_BNEP_CONNECT_BASE                            = 2010, /**< BNEP: connection response codes */
+    OI_BNEP_CONNECT_FAILED_INVALID_DEST_UUID        = 2011, /**< BNEP: connect response code Invalid Dest UUID */
+    OI_BNEP_CONNECT_FAILED_INVALID_SOURCE_UUID      = 2012, /**< BNEP: connect response code Invalid Source UUID */
+    OI_BNEP_CONNECT_FAILED_INVALID_UUID_SIZE        = 2013, /**< BNEP: connect response code Invalid UUID Size */
+    OI_BNEP_CONNECT_FAILED_NOT_ALLOWED              = 2014, /**< BNEP: connect response code Not Allowed */
+    OI_BNEP_FILTER_NET_BASE                         = 2020, /**< BNEP: filter response codes */
+    OI_BNEP_FILTER_NET_UNSUPPORTED_REQUEST          = 2021, /**< BNEP: filter response code Unsupported Request */
+    OI_BNEP_FILTER_NET_FAILED_INVALID_PROTOCOL_TYPE = 2022, /**< BNEP: filter response code Invalid Protocol Type */
+    OI_BNEP_FILTER_NET_FAILED_MAX_LIMIT_REACHED     = 2023, /**< BNEP: filter response code Max Limit Reached */
+    OI_BNEP_FILTER_NET_FAILED_SECURITY              = 2024, /**< BNEP: filter response code Security */
+    OI_BNEP_FILTER_MULTI_BASE                       = 2030, /**< BNEP: multicast response codes */
+    OI_BNEP_FILTER_MULTI_UNSUPPORTED_REQUEST        = 2031, /**< BNEP: multicast response code Unsupported Request */
+    OI_BNEP_FILTER_MULTI_FAILED_INVALID_ADDRESS     = 2032, /**< BNEP: multicast response code Invalid Address */
+    OI_BNEP_FILTER_MULTI_FAILED_MAX_LIMIT_REACHED   = 2033, /**< BNEP: multicast response code Max Limit Reached */
+    OI_BNEP_FILTER_MULTI_FAILED_SECURITY            = 2034, /**< BNEP: multicast response code Security */
+    OI_BNEP_LOCAL_DEVICE_MUST_BE_MASTER             = 2040, /**< BNEP: Device must be master of the piconet for this function */
+    OI_BNEP_PACKET_FILTERED_OUT                     = 2041, /**< BNEP: Packet did not pass current filters */
+
+    OI_NETIFC_UP_FAILED                    = 2101, /**< NETIFC: Could not bring up network interface */
+    OI_NETIFC_COULD_NOT_CREATE_THREAD      = 2102, /**< NETIFC: Network interface could not create a read thread */
+    OI_NETIFC_INITIALIZATION_FAILED        = 2103, /**< NETIFC: Error in network interface initialization */
+    OI_NETIFC_INTERFACE_ALREADY_UP         = 2104, /**< NETIFC: Network interface is already up */
+    OI_NETIFC_INTERFACE_NOT_UP             = 2105, /**< NETIFC: Network interface is not up */
+    OI_NETIFC_PACKET_TOO_BIG               = 2106, /**< NETIFC: The packet is too big */
+
+    OI_PAN_ROLE_ALREADY_REGISTERED         = 2201, /**< PAN: This PAN role was already registered */
+    OI_PAN_ROLE_NOT_ALLOWED                = 2202, /**< PAN: The PAN role is not currently allowed */
+    OI_PAN_INCOMPATIBLE_ROLES              = 2203, /**< PAN: Only certain local and remote role combinations are permitted */
+    OI_PAN_INVALID_ROLE                    = 2204, /**< PAN: Role specified is not one the defined PAN roles */
+    OI_PAN_CONNECTION_IN_PROGRESS          = 2205, /**< PAN: A PAN connection is currently being established */
+    OI_PAN_USER_ALREADY_CONNECTED          = 2206, /**< PAN: PAN user role only allows a single connection */
+    OI_PAN_DEVICE_CONNECTED                = 2207, /**< PAN: A PAN connection already exists to specified device */
+
+    OI_CODEC_SBC_NO_SYNCWORD               = 2301, /**< CODEC: Couldn't find an SBC SYNCWORD */
+    OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA    = 2302, /**< CODEC: Not enough data provided to decode an SBC header */
+    OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA      = 2303, /**< CODEC: Decoded the header, but not enough data to contain the rest of the frame */
+    OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA     = 2304, /**< CODEC: Not enough audio data for this frame */
+    OI_CODEC_SBC_CHECKSUM_MISMATCH         = 2305, /**< CODEC: The frame header didn't match the checksum */
+    OI_CODEC_SBC_PARTIAL_DECODE            = 2306, /**< CODEC: Decoding was successful, but frame data still remains. Next call will provide audio without consuming input data. */
+
+    OI_FIFOQ_QUEUE_NOT_ALIGNED             = 2401, /**< FIFOQ: queue must be 32-bit aligned */
+    OI_FIFOQ_INVALID_Q                     = 2402, /**< FIFOQ: queue parameter is not a valid queue */
+    OI_FIFOQ_BUF_TOO_LARGE                 = 2403, /**< FIFOQ: attempt to queue a buffer which is too large */
+    OI_FIFOQ_FULL                          = 2404, /**< FIFOQ: enqueue() failed, queue is full */
+    OI_FIFOQ_NOT_ALLOCATED                 = 2405, /**< FIFOQ: Enqueue QBuf() failed, buffer not allocated */
+    OI_FIFOQ_INVALID_DATA_PTR              = 2406, /**< FIFOQ: Enqueue QBuf() failed, data pointer does not match */
+
+    OI_HID_HOST_SERVICE_NOT_STARTED        = 2601, /**< HID: Cannot connect to a HID device unless HID host is started */
+    OI_HID_DEVICE_SERVICE_NOT_STARTED      = 2602, /**< HID: Cannot connect to a HID host unless HID device is started */
+
+    OI_AT_ERROR                            = 2701, /**< AT: ERROR response */
+    OI_AT_NO_CARRIER                       = 2702, /**< AT: NO CARRIER response */
+    OI_AT_BUSY                             = 2703, /**< AT: BUSY response */
+    OI_AT_NO_ANSWER                        = 2704, /**< AT: NO ANSWER response */
+    OI_AT_DELAYED                          = 2705, /**< AT: DELAYED response */
+    OI_AT_BLACKLISTED                      = 2706, /**< AT: BLACKLISTED response */
+    OI_AT_CME_ERROR                        = 2707, /**< AT: +CME ERROR response */
+    OI_AT_CMS_ERROR                        = 2708, /**< AT: +CMS ERROR response */
+
+    OI_BLST_CHARACTER_TIMEOUT              = 2801, /**< BLST: Timeout expired while waiting for a character from the client. */
+    OI_BLST_ACKNOWLDGE_TIMEOUT             = 2802, /**< BLST: Timeout expired while waiting for event acknowledgment from the client */
+    OI_BLST_TX_NOT_READY                   = 2803, /**< BLST: BLST is not ready to send a BHAPI message to the client. */
+    OI_BLST_TX_BUSY                        = 2804, /**< BLST: BLST transmit buffer is in use. */
+
+    OI_AVDTP_CONNECTION_SEQ_ERROR          = 2901, /**< AVDTP: sequencing of signalling/media channel connections broken. */
+    OI_AVDTP_OUT_OF_RESOURCES              = 2902, /**< AVDTP: Tried to allocate too many endpoints or signalling channels. */
+
+    OI_PBAP_REPOSITORY_NOT_SET             = 3001, /**< PBAP: Phonebook repository must be set for operation to complete. */
+    OI_PBAP_PHONEBOOK_NOT_SET              = 3002, /**< PBAP: Phonebook be set for operation to complete. */
+
+    OI_AADP_BAD_ENDPOINT                   = 3101, /**< AADP: Invalid local endpoint specified */
+    OI_AADP_BAD_STATE                      = 3102, /**< AADP: AADP State is not correct for this operation. */
+
+    OI_UNICODE_INVALID_SOURCE              = 3200, /**< Unicode Conversion: Source string has invalid character encoding. */
+    OI_UNICODE_SOURCE_EXHAUSTED            = 3201, /**< Unicode Conversion: Incomplete Unicode character at end of source buffer. */
+    OI_UNICODE_DESTINATION_EXHAUSTED       = 3202, /**< Unicode Conversion: Destination buffer not large enough to hold resulting Unicode string. */
+
+    OI_AVRCP_TOO_MANY_CONNECTIONS          = 3300, /**< AVRCP: Exceeded maximum number of simultaneous AVCTP connections. */
+    OI_AVRCP_NOT_IMPLEMENTED               = 3301, /**< AVRCP: The target does not implement the command specified by the opcode and operand. */
+    OI_AVRCP_REJECTED                      = 3302, /**< AVRCP: The target cannot respond because of invalid operands in command packet. */
+    OI_AVRCP_INVALID_RESPONSE              = 3303, /**< AVRCP: The controller received the response with invalid parameters */
+    OI_AVRCP_RESPONSE_PACKET_OVERFLOW      = 3304, /**< AVRCP: The response message does not fir in one AVRCP packet (512 bytes), has to be fragmented. */
+    OI_AVRCP_RESPONSE_INVALID_PDU          = 3305, /**< AVRCP: Command rejected: target received a PDU that it did not understand. */
+    OI_AVRCP_RESPONSE_INVALID_PARAMETER    = 3306, /**< AVRCP: Command rejected: target received a PDU with a parameter ID that it did not understand. */
+    OI_AVRCP_RESPONSE_PARAMETER_NOT_FOUND  = 3307, /**< AVRCP: Command rejected: specified parameter not found, sent if the parameter ID is understood, but content is wrong or corrupted.*/
+    OI_AVRCP_RESPONSE_INTERNAL_ERROR       = 3308, /**< AVRCP: Command rejected: target detected other error conditions. */
+    OI_MAX_BM3_STATUS_VAL,       /* Maximum BM3 status code */
+
+    /* Status code values reserved for BM3 SDK platform-specific implementations */
+    OI_STATUS_RESERVED_FOR_BCOT = 9000,
+
+    /* Status code values reserved for BHAPI products */
+    OI_STATUS_RESERVED_FOR_BHAPI = 9200,
+
+    /* Status code values reserved for Soundabout products */
+    OI_STATUS_RESERVED_FOR_SOUNDABOUT= 9400,
+
+    /*
+     * Status code values greater than or equal to this value are reserved for use by applications.
+     * However, because of differences between compilers, and differences between 16-bit and 32-bit
+     * platforms custom status codes should be in the 16-bit range, so status codes can range from 0
+     * to 65534, inclusive (65535 is reserved)
+     */
+    OI_STATUS_RESERVED_FOR_APPS = 10000,
+
+
+
+    OI_STATUS_NONE = 0xffff     /**< Special status code to indicate that there is no status. (Only to be used for special cases involving OI_SLOG_ERROR() and OI_SLOG_WARNING().) */
+
+} OI_STATUS;
+
+
+/* Remeber to update the #define below when new reserved blocks are added to
+ * the list above. */
+#define OI_NUM_RESERVED_STATUS_BLOCKS 4 /**< Number of status code blocks reserved, including user apps */
+
+
+/**
+ * Test for success
+ */
+#define OI_SUCCESS(x)    ((x) == OI_OK)
+
+/*****************************************************************************/
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif /* _OI_STATUS_H */
+

+ 232 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_stddefs.h

@@ -0,0 +1,232 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef OI_STDDEFS_H
+#define OI_STDDEFS_H
+/**
+ * @file
+ * This file contains BM3 standard type definitions.
+ *
+ */
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+#include "oi_cpu_dep.h"
+
+/** \addtogroup Misc Miscellaneous APIs */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef FALSE
+#define FALSE 0         /**< This define statement sets FALSE as a preprocessor alias for 0. */
+#endif
+
+#ifndef TRUE
+#define TRUE (!FALSE)  /**< This define statement sets TRUE as a preprocessor alias for !FALSE. */
+#endif
+
+#ifdef HEW_TOOLCHAIN
+    #ifdef NULL
+        #undef NULL         /**< Override HEW toolchain NULL definition */
+    #endif
+    #define NULL 0          /**< HEW toolchain does not allow us to compare (void*) type to function pointer */
+#else
+    #ifndef NULL
+        #define NULL ((void*)0) /**< This define statement sets NULL as a preprocessor alias for (void*)0 */
+    #endif
+#endif
+
+/**
+ * @name  Maximum and minimum values for basic types
+ * @{
+ */
+#define OI_INT8_MIN   ((OI_INT8)0x80)          /**< decimal value: -128 */
+#define OI_INT8_MAX   ((OI_INT8)0x7F)          /**< decimal value: 127 */
+#define OI_INT16_MIN  ((OI_INT16)0x8000)       /**< decimal value: -32768 */
+#define OI_INT16_MAX  ((OI_INT16)0x7FFF)       /**< decimal value: 32767 */
+#define OI_INT32_MIN  ((OI_INT32)0x80000000)   /**< decimal value: -2,147,483,648 */
+#define OI_INT32_MAX  ((OI_INT32)0x7FFFFFFF)   /**< decimal value: 2,147,483,647 */
+#define OI_UINT8_MIN  ((OI_UINT8)0)            /**< decimal value: 0 */
+#define OI_UINT8_MAX  ((OI_UINT8)0xFF)         /**< decimal value: 255 */
+#define OI_UINT16_MIN ((OI_UINT16)0)           /**< decimal value: 0 */
+#define OI_UINT16_MAX ((OI_UINT16)0xFFFF)      /**< decimal value: 65535 */
+#define OI_UINT32_MIN ((OI_UINT32)0)           /**< decimal value: 0 */
+#define OI_UINT32_MAX ((OI_UINT32)0xFFFFFFFF)  /**< decimal value: 4,294,967,295 */
+
+/**
+ * @}
+ */
+
+/**
+ * @name  Integer types required by the Service Discovery Protocol
+ * @{
+ */
+
+/** unsigned 64-bit integer as a structure of two unsigned 32-bit integers */
+typedef struct {
+    OI_UINT32 I1; /**< most significant 32 bits */
+    OI_UINT32 I2; /**< least significant 32 bits */
+} OI_UINT64;
+
+#define OI_UINT64_MIN { (OI_UINT32)0x00000000, (OI_UINT32)0x00000000 }
+#define OI_UINT64_MAX { (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF }
+
+/** signed 64-bit integer as a structure of one unsigned 32-bit integer and one signed 32-bit integer */
+typedef struct {
+    OI_INT32  I1; /**< most significant 32 bits  as a signed integer */
+    OI_UINT32 I2; /**< least significant 32 bits as an unsigned integer */
+} OI_INT64;
+
+#define OI_INT64_MIN { (OI_INT32)0x80000000, (OI_UINT32)0x00000000 }
+#define OI_INT64_MAX { (OI_INT32)0X7FFFFFFF, (OI_UINT32)0XFFFFFFFF }
+
+/** unsigned 128-bit integer as a structure of four unsigned 32-bit integers */
+typedef struct {
+    OI_UINT32 I1; /**< most significant 32 bits */
+    OI_UINT32 I2; /**< second-most significant 32 bits */
+    OI_UINT32 I3; /**< third-most significant 32 bits */
+    OI_UINT32 I4; /**< least significant 32 bits */
+} OI_UINT128;
+
+#define OI_UINT128_MIN { (OI_UINT32)0x00000000, (OI_UINT32)0x00000000,  (OI_UINT32)0x00000000, (OI_UINT32)0x00000000 }
+#define OI_UINT128_MAX { (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF,  (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF }
+
+/** signed 128-bit integer as a structure of three unsigned 32-bit integers and one signed 32-bit integer */
+typedef struct {
+    OI_INT32  I1;  /**< most significant 32 bits as a signed integer */
+    OI_UINT32 I2;  /**< second-most significant 32 bits as an unsigned integer */
+    OI_UINT32 I3;  /**< third-most significant 32 bits as an unsigned integer */
+    OI_UINT32 I4;  /**< least significant 32 bits as an unsigned integer */
+} OI_INT128;
+
+#define OI_INT128_MIN { (OI_UINT32)0x80000000, (OI_UINT32)0x00000000,  (OI_UINT32)0x00000000, (OI_UINT32)0x00000000 }
+#define OI_INT128_MAX { (OI_UINT32)0X7FFFFFFF, (OI_UINT32)0XFFFFFFFF,  (OI_UINT32)0XFFFFFFFF, (OI_UINT32)0XFFFFFFFF }
+
+/**
+ * @}
+ */
+
+
+/**
+ * type for ASCII character data items
+ */
+typedef char OI_CHAR;
+
+/**
+ * type for double-byte character data items
+ */
+typedef OI_UINT16 OI_CHAR16;
+
+/**
+ * types for UTF encoded strings.
+ */
+typedef OI_UINT8  OI_UTF8;
+typedef OI_UINT16 OI_UTF16;
+typedef OI_UINT32 OI_UTF32;
+
+
+/**
+ * @name Single-bit operation macros
+ * @{
+ * In these macros, x is the data item for which a bit is to be tested or set and y specifies which bit
+ * is to be tested or set.
+ */
+
+/** This macro's value is TRUE if the bit specified by y is set in data item x. */
+#define OI_BIT_TEST(x,y)   ((x) & (y))
+
+/** This macro's value is TRUE if the bit specified by y is not set in data item x. */
+#define OI_BIT_CLEAR_TEST(x,y)  (((x) & (y)) == 0)
+
+/** This macro sets the bit specified by y in data item x. */
+#define OI_BIT_SET(x,y)    ((x) |= (y))
+
+/** This macro clears the bit specified by y in data item x. */
+#define OI_BIT_CLEAR(x,y)  ((x) &= ~(y))
+
+/** @} */
+
+/**
+ * The OI_ARRAYSIZE macro is set to the number of elements in an array
+ * (instead of the number of bytes, which is returned by sizeof()).
+ */
+
+#ifndef OI_ARRAYSIZE
+#define OI_ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
+#endif
+
+/**
+ * @name Preprocessor aliases for individual bit positions
+ *      Bits are defined here only if they are not already defined.
+ * @{
+ */
+
+#ifndef BIT0
+
+#define BIT0   0x00000001  /**< preprocessor alias for 32-bit value with bit 0 set, used to specify this single bit */
+#define BIT1   0x00000002  /**< preprocessor alias for 32-bit value with bit 1 set, used to specify this single bit */
+#define BIT2   0x00000004  /**< preprocessor alias for 32-bit value with bit 2 set, used to specify this single bit */
+#define BIT3   0x00000008  /**< preprocessor alias for 32-bit value with bit 3 set, used to specify this single bit */
+#define BIT4   0x00000010  /**< preprocessor alias for 32-bit value with bit 4 set, used to specify this single bit */
+#define BIT5   0x00000020  /**< preprocessor alias for 32-bit value with bit 5 set, used to specify this single bit */
+#define BIT6   0x00000040  /**< preprocessor alias for 32-bit value with bit 6 set, used to specify this single bit */
+#define BIT7   0x00000080  /**< preprocessor alias for 32-bit value with bit 7 set, used to specify this single bit */
+#define BIT8   0x00000100  /**< preprocessor alias for 32-bit value with bit 8 set, used to specify this single bit */
+#define BIT9   0x00000200  /**< preprocessor alias for 32-bit value with bit 9 set, used to specify this single bit */
+#define BIT10  0x00000400  /**< preprocessor alias for 32-bit value with bit 10 set, used to specify this single bit */
+#define BIT11  0x00000800  /**< preprocessor alias for 32-bit value with bit 11 set, used to specify this single bit */
+#define BIT12  0x00001000  /**< preprocessor alias for 32-bit value with bit 12 set, used to specify this single bit */
+#define BIT13  0x00002000  /**< preprocessor alias for 32-bit value with bit 13 set, used to specify this single bit */
+#define BIT14  0x00004000  /**< preprocessor alias for 32-bit value with bit 14 set, used to specify this single bit */
+#define BIT15  0x00008000  /**< preprocessor alias for 32-bit value with bit 15 set, used to specify this single bit */
+#define BIT16  0x00010000  /**< preprocessor alias for 32-bit value with bit 16 set, used to specify this single bit */
+#define BIT17  0x00020000  /**< preprocessor alias for 32-bit value with bit 17 set, used to specify this single bit */
+#define BIT18  0x00040000  /**< preprocessor alias for 32-bit value with bit 18 set, used to specify this single bit */
+#define BIT19  0x00080000  /**< preprocessor alias for 32-bit value with bit 19 set, used to specify this single bit */
+#define BIT20  0x00100000  /**< preprocessor alias for 32-bit value with bit 20 set, used to specify this single bit */
+#define BIT21  0x00200000  /**< preprocessor alias for 32-bit value with bit 21 set, used to specify this single bit */
+#define BIT22  0x00400000  /**< preprocessor alias for 32-bit value with bit 22 set, used to specify this single bit */
+#define BIT23  0x00800000  /**< preprocessor alias for 32-bit value with bit 23 set, used to specify this single bit */
+#define BIT24  0x01000000  /**< preprocessor alias for 32-bit value with bit 24 set, used to specify this single bit */
+#define BIT25  0x02000000  /**< preprocessor alias for 32-bit value with bit 25 set, used to specify this single bit */
+#define BIT26  0x04000000  /**< preprocessor alias for 32-bit value with bit 26 set, used to specify this single bit */
+#define BIT27  0x08000000  /**< preprocessor alias for 32-bit value with bit 27 set, used to specify this single bit */
+#define BIT28  0x10000000  /**< preprocessor alias for 32-bit value with bit 28 set, used to specify this single bit */
+#define BIT29  0x20000000  /**< preprocessor alias for 32-bit value with bit 29 set, used to specify this single bit */
+#define BIT30  0x40000000  /**< preprocessor alias for 32-bit value with bit 30 set, used to specify this single bit */
+#define BIT31  0x80000000  /**< preprocessor alias for 32-bit value with bit 31 set, used to specify this single bit */
+
+#endif  /* BIT0 et al */
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+/*****************************************************************************/
+#endif /* OI_STDDEFS_H */

+ 208 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_string.h

@@ -0,0 +1,208 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef OI_STRING_H
+#define OI_STRING_H
+/**
+ * @file
+ * This file contains BM3 supplied portable string.h functions
+ *
+ */
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+#include "oi_cpu_dep.h"
+#include "oi_stddefs.h"
+
+#if defined(USE_NATIVE_MEMCPY) || defined(USE_NATIVE_MALLOC)
+#include <string.h>
+#endif
+
+/** \addtogroup Misc Miscellaneous APIs */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * If we are using Native malloc(), we must also use
+ * native Ansi string.h functions for memory manipulation.
+ */
+#ifdef USE_NATIVE_MALLOC
+#ifndef USE_NATIVE_MEMCPY
+#define USE_NATIVE_MEMCPY
+#endif
+#endif
+
+#ifdef USE_NATIVE_MEMCPY
+
+#define OI_MemCopy(to, from, size)    memcpy((to), (from), (size))
+#define OI_MemSet(block, val, size)   memset((block), (val), (size))
+#define OI_MemZero(block, size)       memset((block), 0, (size))
+#define OI_MemCmp(s1, s2, n)          memcmp((s1), (s2), (n))
+#define OI_Strcpy(dest, src)          strcpy((dest),(src))
+#define OI_Strcat(dest, src)          strcat((dest),(src))
+#define OI_StrLen(str)                strlen((str))
+#define OI_Strcmp(s1, s2)             strcmp((s1), (s2))
+#define OI_Strncmp(s1, s2, n)         strncmp((s1), (s2), (n))
+
+#else
+
+/*
+ * OI_MemCopy
+ *
+ * Copy an arbitrary number of bytes from one memory address to another.
+ * The underlying implementation is the ANSI memmove() or equivalant, so
+ * overlapping memory copies will work correctly.
+ */
+void OI_MemCopy(void *To, void const *From, OI_UINT32 Size);
+
+
+/*
+ * OI_MemSet
+ *
+ * Sets all bytes in a block of memory to the same value
+ */
+void OI_MemSet(void *Block, OI_UINT8 Val, OI_UINT32 Size);
+
+
+/*
+ * OI_MemZero
+ *
+ * Sets all bytes in a block of memory to zero
+ */
+void OI_MemZero(void *Block, OI_UINT32 Size);
+
+
+/*
+ * OI_MemCmp
+ *
+ * Compare two blocks of memory
+ *
+ * Returns:
+ *        0, if s1 == s2
+ *      < 0, if s1 < s2
+ *      > 0, if s2 > s2
+ */
+OI_INT OI_MemCmp(void const *s1, void const *s2, OI_UINT32 n);
+
+/*
+ * OI_Strcpy
+ *
+ * Copies the Null terminated string from pStr to pDest, and
+ * returns pDest.
+ */
+
+OI_CHAR* OI_Strcpy(OI_CHAR *pDest,
+                   OI_CHAR const *pStr);
+
+/*
+ * OI_Strcat
+ *
+ * Concatonates the pStr string to the end of pDest, and
+ * returns pDest.
+ */
+
+OI_CHAR* OI_Strcat(OI_CHAR *pDest,
+                   OI_CHAR const *pStr) ;
+
+/*
+ * OI_StrLen
+ *
+ * Calculates the number of OI_CHARs in pStr (not including
+ * the Null terminator) and returns the value.
+ */
+OI_UINT OI_StrLen(OI_CHAR const *pStr) ;
+
+/*
+ * OI_Strcmp
+ *
+ * Compares two Null terminated strings
+ *
+ * Returns:
+ *        0, if s1 == s2
+ *      < 0, if s1 < s2
+ *      > 0, if s2 > s2
+ */
+OI_INT OI_Strcmp(OI_CHAR const *s1,
+                 OI_CHAR const *s2);
+
+/*
+ * OI_Strncmp
+ *
+ * Compares the first "len" OI_CHARs of strings s1 and s2.
+ *
+ * Returns:
+ *        0, if s1 == s2
+ *      < 0, if s1 < s2
+ *      > 0, if s2 > s2
+ */
+OI_INT OI_Strncmp(OI_CHAR const *s1,
+                  OI_CHAR const *s2,
+                  OI_UINT32      len);
+
+
+#endif /* USE_NATIVE_MEMCPY */
+
+/*
+ * OI_StrcmpInsensitive
+ *
+ * Compares two Null terminated strings, treating
+ * the Upper and Lower case of 'A' through 'Z' as
+ * equivilent.
+ *
+ * Returns:
+ *        0, if s1 == s2
+ *      < 0, if s1 < s2
+ *      > 0, if s2 > s2
+ */
+OI_INT OI_StrcmpInsensitive(OI_CHAR const *s1,
+                            OI_CHAR const *s2);
+
+/*
+ * OI_StrncmpInsensitive
+ *
+ * Compares the first "len" OI_CHARs of strings s1 and s2,
+ * treating the Upper and Lower case of 'A' through 'Z' as
+ * equivilent.
+ *
+ *
+ * Returns:
+ *        0, if s1 == s2
+ *      < 0, if s1 < s2
+ *      > 0, if s2 > s2
+ */
+OI_INT OI_StrncmpInsensitive(OI_CHAR const *s1,
+                             OI_CHAR const *s2,
+                             OI_UINT        len);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+/*****************************************************************************/
+#endif /* OI_STRING_H */
+

+ 200 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_time.h

@@ -0,0 +1,200 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef _OI_TIME_H
+#define _OI_TIME_H
+/** @file
+ *
+ * This file provides time type definitions and interfaces to time-related functions.
+ *
+ * The stack maintains a 64-bit real-time millisecond clock. The choice of
+ * milliseconds is for convenience, not accuracy.
+ *
+ * Timeouts are specified as tenths of seconds in a 32-bit value. Timeout values
+ * specified by the Bluetooth specification are usually muliple seconds, so
+ * accuracy to a tenth of a second is more than adequate.
+ *
+ * This file also contains macros to convert between seconds and the Link
+ * Manager's 1.28-second units.
+ *
+ */
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+#include "oi_stddefs.h"
+
+
+/** \addtogroup Misc Miscellaneous APIs */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/**
+ * Within the core stack timeouts are specified in intervals of tenths of seconds
+ */
+
+typedef OI_UINT16 OI_INTERVAL;
+#define OI_INTERVALS_PER_SECOND     10
+#define MSECS_PER_OI_INTERVAL       (1000 / OI_INTERVALS_PER_SECOND)
+
+/** maximum interval (54 min 36.7 sec) */
+#define OI_MAX_INTERVAL   0x7fff
+
+
+/**
+ * Macro to convert seconds to OI_INTERVAL time units
+ */
+
+#define OI_SECONDS(n)    ((OI_INTERVAL) ((n) * OI_INTERVALS_PER_SECOND))
+
+/**
+ * Macro to convert milliseconds to OI_INTERVAL time units (Rounded Up)
+ */
+
+#define OI_MSECONDS(n)   ((OI_INTERVAL) ((n + MSECS_PER_OI_INTERVAL - 1) / MSECS_PER_OI_INTERVAL))
+
+/**
+ * Macro to convert minutes to OI_INTERVAL time units
+ */
+
+#define OI_MINUTES(n)    ((OI_INTERVAL) ((n) * OI_SECONDS(60)))
+
+/** Convert an OI_INTERVAL to milliseconds. */
+#define OI_INTERVAL_TO_MILLISECONDS(i) ((i) * MSECS_PER_OI_INTERVAL)
+
+/**
+ * The stack depends on relative not absolute time. Any mapping between the
+ * stack's real-time clock and absolute time and date is implementation-dependent.
+ */
+
+typedef struct {
+    OI_INT32 seconds;
+    OI_INT16 mseconds;
+} OI_TIME;
+
+/**
+ * Convert an OI_TIME to milliseconds.
+ *
+ * @param t  the time to convert
+ *
+ * @return the time in milliseconds
+ */
+OI_UINT32 OI_Time_ToMS(OI_TIME *t);
+
+
+/**
+ * This function compares two time values.
+ *
+ * @param T1 first time to compare.
+ *
+ * @param T2 second time to compare.
+ *
+ * @return
+ @verbatim
+     -1 if t1 < t2
+      0 if t1 = t2
+     +1 if t1 > t2
+ @endverbatim
+ */
+
+OI_INT16 OI_Time_Compare(OI_TIME *T1,
+                         OI_TIME *T2);
+
+
+/**
+ * This function returns the interval between two times to a granularity of 0.1 seconds.
+ *
+ * @param Sooner a time value more recent that Later
+ *
+ * @param Later a time value later than Sooner
+ *
+ * @note The result is an OI_INTERVAL value so this function only works for time intervals
+ * that are less than about 71 minutes.
+ *
+ * @return the time interval between the two times = (Later - Sooner)
+ */
+
+OI_INTERVAL OI_Time_Interval(OI_TIME *Sooner,
+                             OI_TIME *Later);
+
+
+
+/**
+ * This function returns the interval between two times to a granularity of milliseconds.
+ *
+ * @param Sooner a time value more recent that Later
+ *
+ * @param Later a time value later than Sooner
+ *
+ * @note The result is an OI_UINT32 value so this function only works for time intervals
+ * that are less than about 50 days.
+ *
+ * @return the time interval between the two times = (Later - Sooner)
+ */
+
+OI_UINT32 OI_Time_IntervalMsecs(OI_TIME *Sooner,
+                                OI_TIME *Later);
+
+
+
+/**
+ * This function answers the question, Have we reached or gone past the target time?
+ *
+ * @param pTargetTime   target time
+ *
+ * @return  TRUE means time now is at or past target time
+ *          FALSE means target time is still some time in the future
+ */
+
+OI_BOOL  OI_Time_NowReachedTime(OI_TIME *pTargetTime);
+
+/**
+ *  Convert seconds to the Link Manager 1.28-second units
+ *  Approximate by using 1.25 conversion factor.
+ */
+
+#define OI_SECONDS_TO_LM_TIME_UNITS(lmUnits) ((lmUnits)<4?(lmUnits):(lmUnits)-((lmUnits)>>2))
+
+
+/**
+ *  Convert Link Manager 1.28-second units to seconds.
+ *  Approximate by using 1.25 conversion factor.
+ */
+
+#define OI_LM_TIME_UNITS_TO_SECONDS(lmUnits) ((lmUnits) + ((lmUnits)>>2))
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+/* Include for OI_Time_Now() prototype
+ * Must be included at end to obtain OI_TIME typedef
+ */
+#include "oi_osinterface.h"
+
+/*****************************************************************************/
+#endif /* _OI_TIME_H */
+

+ 377 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/include/oi_utils.h

@@ -0,0 +1,377 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef _OI_UTILS_H
+#define _OI_UTILS_H
+/**
+ * @file
+ *
+ * This file provides the interface for utility functions.
+ * Among the utilities are strlen (string length), strcmp (string compare), and
+ * other string manipulation functions. These are provided for those plaforms
+ * where this functionality is not available in stdlib.
+ */
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+#include <stdarg.h>
+#include "oi_common.h"
+#include "oi_string.h"
+#include "oi_bt_spec.h"
+
+/** \addtogroup Misc Miscellaneous APIs */
+/**@{*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Opaque type for a callback function handle. See OI_ScheduleCallbackFunction()
+ */
+typedef OI_UINT32 OI_CALLBACK_HANDLE;
+
+
+/**
+ * Function prototype for a timed procedure callback.
+ *
+ * @param arg                 Value that was passed into the OI_ScheduleCallback() function
+ *
+ */
+typedef void (*OI_SCHEDULED_CALLBACK)(void *arg);
+
+
+/**
+ * Registers a function to be called when a timeout expires. This API uses BLUEmagic's internal
+ * function dispatch mechanism, so applications that make extensive use of this facility may need to
+ * increase the value of DispatchTableSize in the configuration block for the dispatcher (see
+ * oi_bt_stack_config.h).
+ *
+ * @param callbackFunction    The function that will be called when the timeout expires
+ *
+ * @param arg                 Value that will be returned as the parameter to the callback function.
+ *
+ * @param timeout             A timeout expressed in OI_INTERVALs (tenths of seconds). This can be
+ *                            zero in which case the callback function will be called as soon as
+ *                            possible.
+ *
+ * @param handle              NULL or a pointer receive the callback handle.
+ *
+ * @return                    OI_OK if the function was reqistered, or an error status.
+ */
+OI_STATUS OI_ScheduleCallbackFunction(OI_SCHEDULED_CALLBACK callbackFunction,
+                                      void                 *arg,
+                                      OI_INTERVAL           timeout,
+                                      OI_CALLBACK_HANDLE   *handle);
+
+
+/**
+ * Cancels a function registered with OI_ScheduleCallbackFunction() before its timer expires.
+ *
+ * @param handle              handle returned by  OI_ScheduleCallbackFunction().
+ *
+ * @return                    OI_OK if the function was cancelled, or an error status.
+ */
+OI_STATUS OI_CancelCallbackFunction(OI_CALLBACK_HANDLE handle);
+
+
+/**
+ * Registers a function to be called when a timeout expires. This version does not return a handle
+ * so can only be canceled by calling OI_CancelCallback().
+ *
+ * @param callbackFunction    The function that will be called when the timeout expires
+ *
+ * @param arg                 Value that will be returned as the parameter to the callback function.
+ *
+ * @param timeout             A timeout expressed in OI_INTERVALs (tenths of seconds). This can be
+ *                            zero in which case the callback function will be called as soon as
+ *                            possible.
+ *
+ * @return                    OI_OK if the function was reqistered, or an error status.
+ */
+#define OI_ScheduleCallback(f, a, t)  OI_ScheduleCallbackFunction(f, a, t, NULL);
+
+
+/**
+ * Cancels a function registered with OI_ScheduleCallback() before its timer expires. This
+ * function will cancel the first entry matches the indicated callback function pointer.
+ *
+ * @param callbackFunction    The function that was originally registered
+ *
+ * @return                    OI_OK if the function was cancelled, or an error status.
+ */
+OI_STATUS OI_CancelCallback(OI_SCHEDULED_CALLBACK callbackFunction);
+
+
+/**
+ * Parse a Bluetooth device address from the specified string.
+ *
+ * @param str   the string to parse
+ * @param addr  the parsed address, if successful
+ *
+ * @return TRUE if an address was successfully parsed, FALSE otherwise
+ */
+
+OI_BOOL OI_ParseBdAddr(const OI_CHAR *str,
+                       OI_BD_ADDR    *addr) ;
+
+/**
+ * Printf function for platforms which have no stdio or printf available.
+ * OI_Printf supports the basic formatting types, with the exception of
+ * floating point types. Additionally, OI_Printf supports several formats
+ * specific to BLUEmagic 3.0 software:
+ *
+ * \%!   prints the string for an #OI_STATUS value.
+ *       @code OI_Printf("There was an error %!", status); @endcode
+ *
+ * \%@   prints a hex dump of a buffer.
+ *       Requires a pointer to the buffer and a signed integer length
+ *       (0 for default length). If the buffer is large, only an excerpt will
+ *       be printed.
+ *       @code OI_Printf("Contents of buffer %@", buffer, sizeof(buffer)); @endcode
+ *
+ * \%:   prints a Bluetooth address in the form "HH:HH:HH:HH:HH:HH".
+ *       Requires a pointer to an #OI_BD_ADDR.
+ *       @code OI_Printf("Bluetooth address %:", &bdaddr); @endcode
+ *
+ * \%^   decodes and prints a data element as formatted XML.
+ *       Requires a pointer to an #OI_DATAELEM.
+ *       @code OI_Printf("Service attribute list is:\n%^", &attributes); @endcode
+ *
+ * \%/   prints the base file name of a path, that is, the final substring
+ *       following a '/' or '\\' character. Requires a pointer to a null
+ *       terminated string.
+ *       @code OI_Printf("File %/", "c:\\dir1\\dir2\\file.txt"); @endcode
+ *
+ * \%~   prints a string, escaping characters as needed to display it in
+ *       ASCII. Requires a pointer to an #OI_PSTR and an #OI_UNICODE_ENCODING
+ *       parameter.
+ *       @code OI_Printf("Identifier %~", &id, OI_UNICODE_UTF16_BE); @endcode
+ *
+ * \%[   inserts an ANSI color escape sequence. Requires a single character
+ *       identifying the color to select. Colors are red (r/R), green (g/G),
+ *       blue (b/B), yellow (y/Y), cyan (c/C), magenta (m/M), white (W),
+ *       light-gray (l/L), dark-gray (d/D), and black (0). The lower case is
+ *       dim, the upper case is bright (except in the case of light-gray and
+ *       dark-gray, where bright and dim are identical). Any other value will
+ *       select the default color.
+ *       @code OI_Printf("%[red text %[black %[normal\n", 'r', '0', 0); @endcode
+ *
+ * \%a   same as \%s, except '\\r' and '\\n' are output as "<cr>" and "<lf>".
+ *       \%?a is valid, but \%la is not.
+ *
+ * \%b   prints an integer in base 2.
+ *       @code OI_Printf("Bits are %b", I); @endcode
+ *
+ * \%lb  prints a long integer in base 2.
+ *
+ * \%?b  prints the least significant N bits of an integer (or long integer)
+ *       in base 2. Requires the integer and a length N.
+ *       @code OI_Printf("Bottom 4 bits are: %?b", I, 4); @endcode
+ *
+ * \%B   prints an integer as boolean text, "TRUE" or "FALSE".
+ *       @code OI_Printf("The value 0 is %B, the value 1 is %B", 0, 1); @endcode
+ *
+ * \%?s  prints a substring up to a specified maximum length.
+ *       Requires a pointer to a string and a length parameter.
+ *       @code OI_Printf("String prefix is %?s", str, 3); @endcode
+ *
+ * \%ls  same as \%S.
+ *
+ * \%S   prints a UTF16 string as UTF8 (plain ASCII, plus 8-bit char sequences
+ *       where needed). Requires a pointer to #OI_CHAR16. \%?S is valid. The
+ *       length parameter is in OI_CHAR16 characters.
+ *
+ * \%T   prints time, formatted as "secs.msecs".
+ *       Requires pointer to #OI_TIME struct, NULL pointer prints current time.
+ *       @code OI_Printf("The time now is %T", NULL); @endcode
+ *
+ *  @param format   The format string
+ *
+ */
+void OI_Printf(const OI_CHAR *format, ...);
+
+
+/**
+ * Var-args version OI_Printf
+ *
+ * @param format   Same as for OI_Printf.
+ *
+ * @param argp     Var-args list.
+ */
+void OI_VPrintf(const OI_CHAR *format, va_list argp);
+
+
+/**
+ * Writes a formatted string to a buffer. This function supports the same format specifiers as
+ * OI_Printf().
+ *
+ * @param buffer   Destination buffer for the formatted string.
+ *
+ * @param bufLen   The length of the destination buffer.
+ *
+ * @param format   The format string
+ *
+ * @return   Number of characters written or -1 in the case of an error.
+ */
+OI_INT32 OI_SNPrintf(OI_CHAR *buffer,
+                    OI_UINT16 bufLen,
+                    const OI_CHAR* format, ...);
+
+
+/**
+ * Var-args version OI_SNPrintf
+ *
+ * @param buffer   Destination buffer for the formatted string.
+ *
+ * @param bufLen   The length of the destination buffer.
+ *
+ * @param format   The format string
+ *
+ * @param argp     Var-args list.
+ *
+ * @return   Number of characters written or -1 in the case of an error.
+ */
+OI_INT32 OI_VSNPrintf(OI_CHAR *buffer,
+                     OI_UINT16 bufLen,
+                     const OI_CHAR *format, va_list argp);
+
+
+/**
+ * Convert a string to an integer.
+ *
+ * @param str  the string to parse
+ *
+ * @return the integer value of the string or 0 if the string could not be parsed
+ */
+OI_INT OI_atoi(const OI_CHAR *str);
+
+
+/**
+ * Parse a signed integer in a string.
+ *
+ * Skips leading whitespace (space and tabs only) and parses a decimal or hex string. Hex string
+ * must be prefixed by "0x". Returns pointer to first character following the integer. Returns the
+ * pointer passed in if the string does not describe an integer.
+ *
+ * @param str    String to parse.
+ *
+ * @param val    Pointer to receive the parsed integer value.
+ *
+ * @return       A pointer to the first character following the integer or the pointer passed in.
+ */
+const OI_CHAR* OI_ScanInt(const OI_CHAR *str,
+                          OI_INT32 *val);
+
+
+/**
+ * Parse an unsigned integer in a string.
+ *
+ * Skips leading whitespace (space and tabs only) and parses a decimal or hex string. Hex string
+ * must be prefixed by "0x". Returns pointer to first character following the integer. Returns the
+ * pointer passed in if the string does not describe an integer.
+ *
+ * @param str    String to parse.
+ *
+ * @param val    Pointer to receive the parsed unsigned integer value.
+ *
+ * @return       A pointer to the first character following the unsigned integer or the pointer passed in.
+ */
+const OI_CHAR* OI_ScanUInt(const OI_CHAR *str,
+                           OI_UINT32 *val);
+
+/**
+ * Parse a whitespace delimited substring out of a string.
+ *
+ * @param str     Input string to parse.
+ * @param outStr  Buffer to return the substring
+ * @param len     Length of outStr
+ *
+ *
+ * @return       A pointer to the first character following the substring or the pointer passed in.
+ */
+const OI_CHAR* OI_ScanStr(const OI_CHAR *str,
+                          OI_CHAR *outStr,
+                          OI_UINT16 len);
+
+
+/**
+ * Parse a string for one of a set of alternative value. Skips leading whitespace (space and tabs
+ * only) and parses text matching one of the alternative strings. Returns pointer to first character
+ * following the matched text.
+ *
+ * @param str    String to parse.
+ *
+ * @param alts   Alternative matching strings separated by '|'
+ *
+ * @param index  Pointer to receive the index of the matching alternative, return value is -1 if
+ *               there is no match.
+ *
+ * @return       A pointer to the first character following the matched value or the pointer passed in
+ *               if there was no matching text.
+ */
+const OI_CHAR* OI_ScanAlt(const OI_CHAR *str,
+                          const OI_CHAR *alts,
+                          OI_INT *index);
+
+/**
+ * Parse a string for a BD Addr. Skips leading whitespace (space and tabs only) and parses a
+ * Bluetooth device address with nibbles optionally separated by colons. Return pointet to first
+ * character following the BD Addr.
+ *
+ * @param str    String to parse.
+ *
+ * @param addr   Pointer to receive the Bluetooth device address
+ *
+ * @return       A pointer to the first character following the BD Addr or the pointer passed in.
+ */
+const OI_CHAR* OI_ScanBdAddr(const OI_CHAR *str,
+                             OI_BD_ADDR *addr);
+
+
+/** Get a character from a digit integer value (0 - 9). */
+#define OI_DigitToChar(d) ((d) + '0')
+
+/**
+ * Determine Maximum and Minimum between two arguments.
+ *
+ * @param a  1st value
+ * @param b  2nd value
+ *
+ * @return the max or min value between a & b
+ */
+#define OI_MAX(a, b) (((a) < (b)) ? (b) : (a) )
+#define OI_MIN(a, b) (((a) > (b)) ? (b) : (a) )
+
+/**
+ * Compare two BD_ADDRs
+ * SAME_BD_ADDR - Boolean: TRUE if they are the same address
+ */
+
+#define SAME_BD_ADDR(x, y)      (0 == OI_MemCmp((x),(y),OI_BD_ADDR_BYTE_SIZE) )
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif /* _OI_UTILS_H */
+

+ 78 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/alloc.c

@@ -0,0 +1,78 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#include <stdlib.h>
+#include <oi_codec_sbc_private.h>
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+PRIVATE OI_STATUS OI_CODEC_SBC_Alloc(OI_CODEC_SBC_COMMON_CONTEXT *common,
+                                     OI_UINT32 *codecDataAligned,
+                                     OI_UINT32 codecDataBytes,
+                                     OI_UINT8 maxChannels,
+                                     OI_UINT8 pcmStride)
+{
+    int i;
+    size_t filterBufferCount;
+    size_t subdataSize;
+    OI_BYTE *codecData = (OI_BYTE*)codecDataAligned;
+
+    if (maxChannels < 1 || maxChannels > 2) {
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+
+    if (pcmStride < 1 || pcmStride > maxChannels) {
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+
+    common->maxChannels = maxChannels;
+    common->pcmStride = pcmStride;
+
+    /* Compute sizes needed for the memory regions, and bail if we don't have
+     * enough memory for them. */
+    subdataSize = maxChannels * sizeof(common->subdata[0]) * SBC_MAX_BANDS * SBC_MAX_BLOCKS;
+    if (subdataSize > codecDataBytes) {
+        return OI_STATUS_OUT_OF_MEMORY;
+    }
+
+    filterBufferCount = (codecDataBytes - subdataSize) / (sizeof(common->filterBuffer[0][0]) * SBC_MAX_BANDS * maxChannels);
+    if (filterBufferCount < SBC_CODEC_MIN_FILTER_BUFFERS) {
+        return OI_STATUS_OUT_OF_MEMORY;
+    }
+    common->filterBufferLen = filterBufferCount * SBC_MAX_BANDS;
+
+    /* Allocate memory for the subband data */
+    common->subdata = (OI_INT32*)codecData;
+    codecData += subdataSize;
+    OI_ASSERT(codecDataBytes >= subdataSize);
+    codecDataBytes -= subdataSize;
+
+    /* Allocate memory for the synthesis buffers */
+    for (i = 0; i < maxChannels; ++i) {
+        size_t allocSize = common->filterBufferLen * sizeof(common->filterBuffer[0][0]);
+        common->filterBuffer[i] = (SBC_BUFFER_T*)codecData;
+        OI_ASSERT(codecDataBytes >= allocSize);
+        codecData += allocSize;
+        codecDataBytes -= allocSize;
+    }
+
+    return OI_OK;
+}

+ 165 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/bitalloc-sbc.c

@@ -0,0 +1,165 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+/** @file
+@ingroup codec_internal
+*/
+
+/**@addgroup codec_internal*/
+/**@{*/
+
+#include <oi_codec_sbc_private.h>
+
+static void dualBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
+{
+    OI_UINT bitcountL;
+    OI_UINT bitcountR;
+    OI_UINT bitpoolPreferenceL = 0;
+    OI_UINT bitpoolPreferenceR = 0;
+    BITNEED_UNION1 bitneedsL;
+    BITNEED_UNION1 bitneedsR;
+
+    bitcountL = computeBitneed(common, bitneedsL.uint8, 0, &bitpoolPreferenceL);
+    bitcountR = computeBitneed(common, bitneedsR.uint8, 1, &bitpoolPreferenceR);
+
+    oneChannelBitAllocation(common, &bitneedsL, 0, bitcountL);
+    oneChannelBitAllocation(common, &bitneedsR, 1, bitcountR);
+}
+
+static void stereoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
+{
+    const OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
+    BITNEED_UNION2 bitneeds;
+    OI_UINT excess;
+    OI_INT bitadjust;
+    OI_UINT bitcount;
+    OI_UINT sbL;
+    OI_UINT sbR;
+    OI_UINT bitpoolPreference = 0;
+
+    bitcount = computeBitneed(common, &bitneeds.uint8[0], 0, &bitpoolPreference);
+    bitcount += computeBitneed(common, &bitneeds.uint8[nrof_subbands], 1, &bitpoolPreference);
+
+    {
+        OI_UINT ex;
+        bitadjust = adjustToFitBitpool(common->frameInfo.bitpool, bitneeds.uint32, 2 * nrof_subbands, bitcount, &ex);
+        /* We want the compiler to put excess into a register */
+        excess = ex;
+    }
+    sbL = 0;
+    sbR = nrof_subbands;
+    while (sbL < nrof_subbands) {
+        excess = allocAdjustedBits(&common->bits.uint8[sbL], bitneeds.uint8[sbL] + bitadjust, excess);
+        ++sbL;
+        excess = allocAdjustedBits(&common->bits.uint8[sbR], bitneeds.uint8[sbR] + bitadjust, excess);
+        ++sbR;
+    }
+    sbL = 0;
+    sbR = nrof_subbands;
+    while (excess) {
+        excess = allocExcessBits(&common->bits.uint8[sbL], excess);
+        ++sbL;
+        if (!excess) {
+            break;
+        }
+        excess = allocExcessBits(&common->bits.uint8[sbR], excess);
+        ++sbR;
+    }
+
+}
+
+static const BIT_ALLOC balloc[] = {
+    monoBitAllocation,    /* SBC_MONO */
+    dualBitAllocation,    /* SBC_DUAL_CHANNEL */
+    stereoBitAllocation,  /* SBC_STEREO */
+    stereoBitAllocation   /* SBC_JOINT_STEREO */
+};
+
+
+PRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
+{
+    OI_ASSERT(common->frameInfo.bitpool <= OI_SBC_MaxBitpool(&common->frameInfo));
+    OI_ASSERT(common->frameInfo.mode < OI_ARRAYSIZE(balloc));
+
+    /*
+     * Using an array of function pointers prevents the compiler from creating a suboptimal
+     * monolithic inlined bit allocation function.
+     */
+    balloc[common->frameInfo.mode](common);
+}
+
+OI_UINT32 OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame)
+{
+    return internal_CalculateBitrate(frame);
+}
+
+/*
+ * Return the current maximum bitneed and clear it.
+ */
+OI_UINT8 OI_CODEC_SBC_GetMaxBitneed(OI_CODEC_SBC_COMMON_CONTEXT *common)
+{
+    OI_UINT8 max = common->maxBitneed;
+
+    common->maxBitneed = 0;
+    return max;
+}
+
+/*
+ * Calculates the bitpool size for a given frame length
+ */
+OI_UINT16 OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO *frame,
+                                        OI_UINT16 frameLen)
+{
+    OI_UINT16 nrof_subbands = frame->nrof_subbands;
+    OI_UINT16 nrof_blocks = frame->nrof_blocks;
+    OI_UINT16 hdr;
+    OI_UINT16 bits;
+
+    if (frame->mode == SBC_JOINT_STEREO) {
+        hdr = 9 * nrof_subbands;
+    } else {
+        if (frame->mode == SBC_MONO) {
+            hdr = 4 * nrof_subbands;
+        } else {
+            hdr = 8 * nrof_subbands;
+        }
+        if (frame->mode == SBC_DUAL_CHANNEL) {
+            nrof_blocks *= 2;
+        }
+    }
+    bits = 8 * (frameLen - SBC_HEADER_LEN) - hdr;
+    return DIVIDE(bits, nrof_blocks);
+}
+
+OI_UINT16 OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT *common)
+{
+    return sizeof(OI_INT16) * common->pcmStride * common->frameInfo.nrof_subbands * common->frameInfo.nrof_blocks;
+}
+
+
+OI_UINT16 OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame)
+{
+    return internal_CalculateFramelen(frame);
+}
+
+/**@}*/

+ 392 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/bitalloc.c

@@ -0,0 +1,392 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+ ***********************************************************************************/
+
+/**
+@file
+
+The functions in this file relate to the allocation of available bits to
+subbands within the SBC/eSBC frame, along with support functions for computing
+frame length and bitrate.
+
+@ingroup codec_internal
+*/
+
+/**
+@addtogroup codec_internal
+@{
+*/
+
+#include "oi_utils.h"
+#include <oi_codec_sbc_private.h>
+
+OI_UINT32 OI_SBC_MaxBitpool(OI_CODEC_SBC_FRAME_INFO *frame)
+{
+    switch (frame->mode) {
+        case SBC_MONO:
+        case SBC_DUAL_CHANNEL:
+            return 16 * frame->nrof_subbands;
+        case SBC_STEREO:
+        case SBC_JOINT_STEREO:
+            return 32 * frame->nrof_subbands;
+    }
+
+    ERROR(("Invalid frame mode %d", frame->mode));
+    OI_ASSERT(FALSE);
+    return 0; /* Should never be reached */
+}
+
+
+PRIVATE OI_UINT16 internal_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame)
+{
+    OI_UINT16 nbits = frame->nrof_blocks * frame->bitpool;
+    OI_UINT16 nrof_subbands = frame->nrof_subbands;
+    OI_UINT16 result = nbits;
+
+    if (frame->mode == SBC_JOINT_STEREO) {
+        result += nrof_subbands + (8 * nrof_subbands);
+    } else {
+        if (frame->mode == SBC_DUAL_CHANNEL) { result += nbits; }
+        if (frame->mode == SBC_MONO) { result += 4*nrof_subbands; } else { result += 8*nrof_subbands; }
+    }
+    return SBC_HEADER_LEN + (result + 7) / 8;
+}
+
+
+PRIVATE OI_UINT32 internal_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame)
+{
+    OI_UINT blocksbands;
+    blocksbands = frame->nrof_subbands * frame->nrof_blocks;
+
+    return DIVIDE(8 * internal_CalculateFramelen(frame) * frame->frequency, blocksbands);
+}
+
+
+INLINE OI_UINT16 OI_SBC_CalculateFrameAndHeaderlen(OI_CODEC_SBC_FRAME_INFO *frame, OI_UINT *headerLen_)
+{
+    OI_UINT headerLen = SBC_HEADER_LEN + frame->nrof_subbands * frame->nrof_channels/2;
+
+    if (frame->mode == SBC_JOINT_STEREO) { headerLen++; }
+
+    *headerLen_ = headerLen;
+    return internal_CalculateFramelen(frame);
+}
+
+
+#define MIN(x, y)  ((x) < (y) ? (x) : (y))
+
+
+/*
+ * Computes the bit need for each sample and as also returns a counts of bit needs that are greater
+ * than one. This count is used in the first phase of bit allocation.
+ *
+ * We also compute a preferred bitpool value that this is the minimum bitpool needed to guarantee
+ * lossless representation of the audio data. The preferred bitpool may be larger than the bits
+ * actually required but the only input we have are the scale factors. For example, it takes 2 bits
+ * to represent values in the range -1 .. +1 but the scale factor is 0. To guarantee lossless
+ * representation we add 2 to each scale factor and sum them to come up with the preferred bitpool.
+ * This is not ideal because 0 requires 0 bits but we currently have no way of knowing this.
+ *
+ * @param bitneed       Array to return bitneeds for each subband
+ *
+ * @param ch            Channel 0 or 1
+ *
+ * @param preferredBitpool  Returns the number of reserved bits
+ *
+ * @return              The SBC bit need
+ *
+ */
+OI_UINT computeBitneed(OI_CODEC_SBC_COMMON_CONTEXT *common,
+                              OI_UINT8 *bitneeds,
+                              OI_UINT ch,
+                              OI_UINT *preferredBitpool)
+{
+    static const OI_INT8 offset4[4][4] = {
+        { -1, 0, 0, 0 },
+        { -2, 0, 0, 1 },
+        { -2, 0, 0, 1 },
+        { -2, 0, 0, 1 }
+    };
+
+    static const OI_INT8 offset8[4][8] = {
+        { -2, 0, 0, 0, 0, 0, 0, 1 },
+        { -3, 0, 0, 0, 0, 0, 1, 2 },
+        { -4, 0, 0, 0, 0, 0, 1, 2 },
+        { -4, 0, 0, 0, 0, 0, 1, 2 }
+    };
+
+    const OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
+    OI_UINT sb;
+    OI_INT8 *scale_factor = &common->scale_factor[ch ? nrof_subbands : 0];
+    OI_UINT bitcount = 0;
+    OI_UINT8 maxBits = 0;
+    OI_UINT8 prefBits = 0;
+
+    if (common->frameInfo.alloc == SBC_SNR) {
+        for (sb = 0; sb < nrof_subbands; sb++) {
+            OI_INT bits = scale_factor[sb];
+            if (bits > maxBits) {
+                maxBits = bits;
+            }
+            if ((bitneeds[sb] = bits) > 1) {
+                bitcount += bits;
+            }
+            prefBits += 2 + bits;
+        }
+    } else {
+        const OI_INT8 *offset;
+        if (nrof_subbands == 4) {
+            offset = offset4[common->frameInfo.freqIndex];
+        } else {
+            offset = offset8[common->frameInfo.freqIndex];
+        }
+        for (sb = 0; sb < nrof_subbands; sb++) {
+            OI_INT bits = scale_factor[sb];
+            if (bits > maxBits) {
+                maxBits = bits;
+            }
+            prefBits += 2 + bits;
+            if (bits) {
+                bits -= offset[sb];
+                if (bits > 0) {
+                    bits /= 2;
+                }
+                bits += 5;
+            }
+            if ((bitneeds[sb] = bits) > 1) {
+                bitcount += bits;
+            }
+        }
+    }
+    common->maxBitneed = OI_MAX(maxBits, common->maxBitneed);
+    *preferredBitpool += prefBits;
+    return bitcount;
+}
+
+
+/*
+ * Explanation of the adjustToFitBitpool inner loop.
+ *
+ * The inner loop computes the effect of adjusting the bit allocation up or
+ * down. Allocations must be 0 or in the range 2..16. This is accomplished by
+ * the following code:
+ *
+ *           for (s = bands - 1; s >= 0; --s) {
+ *              OI_INT bits = bitadjust + bitneeds[s];
+ *              bits = bits < 2 ? 0 : bits;
+ *              bits = bits > 16 ? 16 : bits;
+ *              count += bits;
+ *          }
+ *
+ * This loop can be optimized to perform 4 operations at a time as follows:
+ *
+ * Adjustment is computed as a 7 bit signed value and added to the bitneed.
+ *
+ * Negative allocations are zeroed by masking. (n & 0x40) >> 6 puts the
+ * sign bit into bit 0, adding this to 0x7F give us a mask of 0x80
+ * for -ve values and 0x7F for +ve values.
+ *
+ * n &= 0x7F + (n & 0x40) >> 6)
+ *
+ * Allocations greater than 16 are truncated to 16. Adjusted allocations are in
+ * the range 0..31 so we know that bit 4 indicates values >= 16. We use this bit
+ * to create a mask that zeroes bits 0 .. 3 if bit 4 is set.
+ *
+ * n &= (15 + (n >> 4))
+ *
+ * Allocations of 1 are disallowed. Add and shift creates a mask that
+ * eliminates the illegal value
+ *
+ * n &= ((n + 14) >> 4) | 0x1E
+ *
+ * These operations can be performed in 8 bits without overflowing so we can
+ * operate on 4 values at once.
+ */
+
+
+/*
+ * Encoder/Decoder
+ *
+ * Computes adjustment +/- of bitneeds to fill bitpool and returns overall
+ * adjustment and excess bits.
+ *
+ * @param bitpool   The bitpool we have to work within
+ *
+ * @param bitneeds  An array of bit needs (more acturately allocation prioritities) for each
+ *                  subband across all blocks in the SBC frame
+ *
+ * @param subbands  The number of subbands over which the adkustment is calculated. For mono and
+ *                  dual mode this is 4 or 8, for stereo or joint stereo this is 8 or 16.
+ *
+ * @param bitcount  A starting point for the adjustment
+ *
+ * @param excess    Returns the excess bits after the adjustment
+ *
+ * @return   The adjustment.
+ */
+OI_INT adjustToFitBitpool(const OI_UINT bitpool,
+                                 OI_UINT32 *bitneeds,
+                                 const OI_UINT subbands,
+                                 OI_UINT bitcount,
+                                 OI_UINT *excess)
+{
+    OI_INT maxBitadjust = 0;
+    OI_INT bitadjust = (bitcount > bitpool) ? -8 : 8;
+    OI_INT chop = 8;
+
+    /*
+     * This is essentially a binary search for the optimal adjustment value.
+     */
+    while ((bitcount != bitpool) && chop) {
+        OI_UINT32 total = 0;
+        OI_UINT count;
+        OI_UINT32 adjust4;
+        OI_INT i;
+
+        adjust4 = bitadjust & 0x7F;
+        adjust4 |= (adjust4 << 8);
+        adjust4 |= (adjust4 << 16);
+
+        for (i = (subbands / 4 - 1); i >= 0; --i) {
+            OI_UINT32 mask;
+            OI_UINT32 n = bitneeds[i] + adjust4;
+            mask = 0x7F7F7F7F + ((n & 0x40404040) >> 6);
+            n &= mask;
+            mask = 0x0F0F0F0F + ((n & 0x10101010) >> 4);
+            n &= mask;
+            mask = (((n + 0x0E0E0E0E) >> 4) | 0x1E1E1E1E);
+            n &= mask;
+            total += n;
+        }
+
+        count = (total & 0xFFFF) + (total >> 16);
+        count = (count & 0xFF) + (count >> 8);
+
+        chop >>= 1;
+        if (count > bitpool) {
+            bitadjust -= chop;
+        } else {
+            maxBitadjust = bitadjust;
+            bitcount = count;
+            bitadjust += chop;
+        }
+    }
+
+    *excess = bitpool - bitcount;
+
+    return maxBitadjust;
+}
+
+
+/*
+ * The bit allocator trys to avoid single bit allocations except as a last resort. So in the case
+ * where a bitneed of 1 was passed over during the adsjustment phase 2 bits are now allocated.
+ */
+INLINE OI_INT allocAdjustedBits(OI_UINT8 *dest,
+                                OI_INT bits,
+                                OI_INT excess)
+{
+    if (bits < 16) {
+        if (bits > 1) {
+            if (excess) {
+                ++bits;
+                --excess;
+            }
+        } else if ((bits == 1) && (excess > 1)) {
+            bits = 2;
+            excess -= 2;
+        } else {
+            bits  = 0;
+        }
+    } else {
+        bits = 16;
+    }
+    *dest = (OI_UINT8)bits;
+    return excess;
+}
+
+
+/*
+ * Excess bits not allocated by allocaAdjustedBits are allocated round-robin.
+ */
+INLINE OI_INT allocExcessBits(OI_UINT8 *dest,
+                              OI_INT excess)
+{
+    if (*dest < 16) {
+        *dest += 1;
+        return excess - 1;
+    } else {
+        return excess;
+    }
+}
+
+void oneChannelBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common,
+                                    BITNEED_UNION1 *bitneeds,
+                                    OI_UINT ch,
+                                    OI_UINT bitcount)
+{
+    const OI_UINT8 nrof_subbands = common->frameInfo.nrof_subbands;
+    OI_UINT excess;
+    OI_UINT sb;
+    OI_INT bitadjust;
+    OI_UINT8 RESTRICT *allocBits;
+
+
+    {
+        OI_UINT ex;
+        bitadjust = adjustToFitBitpool(common->frameInfo.bitpool, bitneeds->uint32, nrof_subbands, bitcount, &ex);
+        /* We want the compiler to put excess into a register */
+        excess = ex;
+    }
+
+    /*
+     * Allocate adjusted bits
+     */
+    allocBits = &common->bits.uint8[ch ? nrof_subbands : 0];
+
+    sb = 0;
+    while (sb < nrof_subbands) {
+        excess = allocAdjustedBits(&allocBits[sb], bitneeds->uint8[sb] + bitadjust, excess);
+        ++sb;
+    }
+    sb = 0;
+    while (excess) {
+        excess = allocExcessBits(&allocBits[sb], excess);
+        ++sb;
+    }
+}
+
+
+void monoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
+{
+    BITNEED_UNION1 bitneeds;
+    OI_UINT bitcount;
+    OI_UINT bitpoolPreference = 0;
+
+    bitcount = computeBitneed(common, bitneeds.uint8, 0, &bitpoolPreference);
+
+    oneChannelBitAllocation(common, &bitneeds, 0, bitcount);
+}
+
+/**
+@}
+*/

+ 92 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/bitstream-decode.c

@@ -0,0 +1,92 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+/**
+@file
+Functions for manipulating input bitstreams.
+
+@ingroup codec_internal
+*/
+
+/**
+@addtogroup codec_internal
+@{
+*/
+
+#include "oi_stddefs.h"
+#include "oi_bitstream.h"
+#include "oi_assert.h"
+
+PRIVATE void OI_BITSTREAM_ReadInit(OI_BITSTREAM *bs,
+                                   const OI_BYTE *buffer)
+{
+    bs->value = ((OI_INT32)buffer[0] << 16) | ((OI_INT32)buffer[1] << 8) | (buffer[2]);
+    bs->ptr.r = buffer + 3;
+    bs->bitPtr = 8;
+}
+
+PRIVATE OI_UINT32 OI_BITSTREAM_ReadUINT(OI_BITSTREAM *bs, OI_UINT bits)
+{
+    OI_UINT32 result;
+
+    OI_BITSTREAM_READUINT(result, bits, bs->ptr.r, bs->value, bs->bitPtr);
+
+    return result;
+}
+
+PRIVATE OI_UINT8 OI_BITSTREAM_ReadUINT4Aligned(OI_BITSTREAM *bs)
+{
+    OI_UINT32 result;
+
+    OI_ASSERT(bs->bitPtr < 16);
+    OI_ASSERT(bs->bitPtr % 4 == 0);
+
+    if (bs->bitPtr == 8) {
+        result = bs->value << 8;
+        bs->bitPtr = 12;
+    } else {
+        result = bs->value << 12;
+        bs->value = (bs->value << 8) | *bs->ptr.r++;
+        bs->bitPtr = 8;
+    }
+    result >>= 28;
+    OI_ASSERT(result < (1u << 4));
+    return (OI_UINT8)result;
+}
+
+PRIVATE OI_UINT8 OI_BITSTREAM_ReadUINT8Aligned(OI_BITSTREAM *bs)
+{
+    OI_UINT32 result;
+    OI_ASSERT(bs->bitPtr == 8);
+
+    result = bs->value >> 16;
+    bs->value = (bs->value << 8) | *bs->ptr.r++;
+
+    return (OI_UINT8)result;
+}
+
+/**
+@}
+*/
+
+

+ 140 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/decoder-oina.c

@@ -0,0 +1,140 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2006 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+ ***********************************************************************************/
+
+/**
+@file
+This file exposes OINA-specific interfaces to decoder functions.
+
+@ingroup codec_internal
+*/
+
+/**
+@addtogroup codec_internal
+@{
+*/
+
+
+#include <oi_codec_sbc_private.h>
+
+OI_STATUS OI_CODEC_SBC_DecoderConfigureRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                           OI_BOOL enhanced,
+                                           OI_UINT8 frequency,
+                                           OI_UINT8 mode,
+                                           OI_UINT8 subbands,
+                                           OI_UINT8 blocks,
+                                           OI_UINT8 alloc,
+                                           OI_UINT8 maxBitpool)
+{
+    if (frequency > SBC_FREQ_48000) {
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+
+    if (enhanced) {
+#ifdef SBC_ENHANCED
+        if (subbands != SBC_SUBBANDS_8) {
+            return OI_STATUS_INVALID_PARAMETERS;
+        }
+#else
+        return OI_STATUS_INVALID_PARAMETERS;
+#endif
+    }
+
+    if (mode > SBC_JOINT_STEREO) {
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+
+    if (subbands > SBC_SUBBANDS_8) {
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+
+    if (blocks > SBC_BLOCKS_16) {
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+
+    if (alloc > SBC_SNR) {
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+
+#ifdef SBC_ENHANCED
+    context->common.frameInfo.enhanced = enhanced;
+#else
+    context->common.frameInfo.enhanced = FALSE;
+#endif
+    context->common.frameInfo.freqIndex = frequency;
+    context->common.frameInfo.mode = mode;
+    context->common.frameInfo.subbands = subbands;
+    context->common.frameInfo.blocks = blocks;
+    context->common.frameInfo.alloc = alloc;
+    context->common.frameInfo.bitpool = maxBitpool;
+
+    OI_SBC_ExpandFrameFields(&context->common.frameInfo);
+
+    if (context->common.frameInfo.nrof_channels >= context->common.pcmStride) {
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+
+    return OI_OK;
+}
+
+
+
+OI_STATUS OI_CODEC_SBC_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                 OI_UINT8 bitpool,
+                                 const OI_BYTE **frameData,
+                                 OI_UINT32 *frameBytes,
+                                 OI_INT16 *pcmData,
+                                 OI_UINT32 *pcmBytes)
+{
+    return internal_DecodeRaw(context,
+                              bitpool,
+                              frameData,
+                              frameBytes,
+                              pcmData,
+                              pcmBytes);
+}
+
+OI_STATUS OI_CODEC_SBC_DecoderLimit(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                    OI_BOOL                       enhanced,
+                                    OI_UINT8                      subbands)
+{
+	if (enhanced)
+	{
+#ifdef SBC_ENHANCED
+        context->enhancedEnabled = TRUE;
+#else
+        context->enhancedEnabled = FALSE;
+#endif
+	}
+	else
+	{
+        context->enhancedEnabled = FALSE;
+	}
+    context->restrictSubbands = subbands;
+    context->limitFrameFormat = TRUE;
+    return OI_OK;
+}
+
+
+/**
+@}
+*/

+ 227 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/decoder-private.c

@@ -0,0 +1,227 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+ ***********************************************************************************/
+
+/**
+@file
+This file drives SBC decoding.
+
+@ingroup codec_internal
+*/
+
+/**
+@addtogroup codec_internal
+@{
+*/
+
+#include "oi_codec_sbc_private.h"
+#include "oi_bitstream.h"
+#include <stdio.h>
+
+OI_CHAR * const OI_Codec_Copyright = "Copyright 2002-2007 Open Interface North America, Inc. All rights reserved";
+
+INLINE OI_STATUS internal_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                       OI_UINT32 *decoderData,
+                                       OI_UINT32 decoderDataBytes,
+                                       OI_BYTE maxChannels,
+                                       OI_BYTE pcmStride,
+                                       OI_BOOL enhanced)
+{
+    OI_UINT i;
+    OI_STATUS status;
+
+    for (i = 0; i < sizeof(*context); i++) {
+        ((char *)context)[i] = 0;
+    }
+
+#ifdef SBC_ENHANCED
+    context->enhancedEnabled = enhanced ? TRUE : FALSE;
+#else
+    context->enhancedEnabled = FALSE;
+    if (enhanced){
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+#endif
+
+    status = OI_CODEC_SBC_Alloc(&context->common, decoderData, decoderDataBytes, maxChannels, pcmStride);
+
+    if (!OI_SUCCESS(status)) {
+        return status;
+    }
+
+    context->common.codecInfo = OI_Codec_Copyright;
+    context->common.maxBitneed = 0;
+    context->limitFrameFormat = FALSE;
+    OI_SBC_ExpandFrameFields(&context->common.frameInfo);
+
+    /*PLATFORM_DECODER_RESET(context);*/
+
+    return OI_OK;
+}
+
+
+
+
+/**
+ * Read the SBC header up to but not including the joint stereo mask.  The syncword has already been
+ * examined, and the enhanced mode flag set, by FindSyncword.
+ */
+INLINE void OI_SBC_ReadHeader(OI_CODEC_SBC_COMMON_CONTEXT *common, const OI_BYTE *data)
+{
+    OI_CODEC_SBC_FRAME_INFO *frame = &common->frameInfo;
+    OI_UINT8 d1;
+
+
+    OI_ASSERT(data[0] == OI_SBC_SYNCWORD || data[0] == OI_SBC_ENHANCED_SYNCWORD);
+
+    /* Avoid filling out all these strucutures if we already remember the values
+     * from last time. Just in case we get a stream corresponding to data[1] ==
+     * 0, DecoderReset is responsible for ensuring the lookup table entries have
+     * already been populated
+     */
+    d1 = data[1];
+    if (d1 != frame->cachedInfo) {
+
+        frame->freqIndex = (d1 & (BIT7 | BIT6)) >> 6;
+        frame->frequency = freq_values[frame->freqIndex];
+
+        frame->blocks = (d1 & (BIT5 | BIT4)) >> 4;
+        frame->nrof_blocks = block_values[frame->blocks];
+
+        frame->mode = (d1 & (BIT3 | BIT2)) >> 2;
+        frame->nrof_channels = channel_values[frame->mode];
+
+        frame->alloc = (d1 & BIT1) >> 1;
+
+        frame->subbands = (d1 & BIT0);
+        frame->nrof_subbands = band_values[frame->subbands];
+
+        frame->cachedInfo = d1;
+    }
+    /*
+     * For decode, the bit allocator needs to know the bitpool value
+     */
+    frame->bitpool = data[2];
+    frame->crc = data[3];
+}
+
+
+#define LOW(x)  ((x)& 0xf)
+#define HIGH(x) ((x) >> 4)
+
+/*
+ * Read scalefactor values and prepare the bitstream for OI_SBC_ReadSamples
+ */
+PRIVATE void OI_SBC_ReadScalefactors(OI_CODEC_SBC_COMMON_CONTEXT *common,
+                             const OI_BYTE *b,
+                             OI_BITSTREAM *bs)
+{
+    OI_UINT i = common->frameInfo.nrof_subbands * common->frameInfo.nrof_channels;
+    OI_INT8 *scale_factor = common->scale_factor;
+    OI_UINT f;
+
+    if (common->frameInfo.nrof_subbands == 8 || common->frameInfo.mode != SBC_JOINT_STEREO) {
+        if (common->frameInfo.mode == SBC_JOINT_STEREO) {
+            common->frameInfo.join = *b++;
+        } else {
+            common->frameInfo.join = 0;
+        }
+        i /= 2;
+        do {
+            *scale_factor++ = HIGH(f = *b++);
+            *scale_factor++ = LOW(f);
+        } while (--i);
+        /*
+         * In this case we know that the scale factors end on a byte boundary so all we need to do
+         * is initialize the bitstream.
+         */
+        OI_BITSTREAM_ReadInit(bs, b);
+    } else {
+        OI_ASSERT(common->frameInfo.nrof_subbands == 4 && common->frameInfo.mode == SBC_JOINT_STEREO);
+        common->frameInfo.join = HIGH(f = *b++);
+        i = (i - 1) / 2;
+        do {
+            *scale_factor++ = LOW(f);
+            *scale_factor++ = HIGH(f = *b++);
+        } while (--i);
+        *scale_factor++ = LOW(f);
+        /*
+         * In 4-subband joint stereo mode, the joint stereo information ends on a half-byte
+         * boundary, so it's necessary to use the bitstream abstraction to read it, since
+         * OI_SBC_ReadSamples will need to pick up in mid-byte.
+         */
+        OI_BITSTREAM_ReadInit(bs, b);
+        *scale_factor++ = OI_BITSTREAM_ReadUINT4Aligned(bs);
+    }
+}
+
+/** Read quantized subband samples from the input bitstream and expand them. */
+PRIVATE void OI_SBC_ReadSamples(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
+{
+    OI_CODEC_SBC_COMMON_CONTEXT *common = &context->common;
+    OI_UINT nrof_blocks = common->frameInfo.nrof_blocks;
+    OI_INT32 * RESTRICT s = common->subdata;
+    OI_UINT8 *ptr = global_bs->ptr.w;
+    OI_UINT32 value = global_bs->value;
+    OI_UINT bitPtr = global_bs->bitPtr;
+
+    const OI_UINT iter_count = common->frameInfo.nrof_channels * common->frameInfo.nrof_subbands / 4;
+    do {
+        OI_UINT i;
+        for (i = 0; i < iter_count; ++i) {
+            OI_UINT32 sf_by4 = ((OI_UINT32*)common->scale_factor)[i];
+            OI_UINT32 bits_by4 = common->bits.uint32[i];
+            OI_UINT n;
+            for (n = 0; n < 4; ++n) {
+                OI_INT32 dequant;
+                OI_UINT bits;
+                OI_INT sf;
+
+                if (OI_CPU_BYTE_ORDER == OI_LITTLE_ENDIAN_BYTE_ORDER) {
+                    bits = bits_by4 & 0xFF;
+                    bits_by4 >>= 8;
+                    sf = sf_by4 & 0xFF;
+                    sf_by4 >>= 8;
+                } else {
+                    bits = (bits_by4 >> 24) & 0xFF;
+                    bits_by4 <<= 8;
+                    sf = (sf_by4 >> 24) & 0xFF;
+                    sf_by4 <<= 8;
+                }
+                if (bits) {
+                    OI_UINT32 raw;
+                    OI_BITSTREAM_READUINT(raw, bits, ptr, value, bitPtr);
+                    dequant = OI_SBC_Dequant(raw, sf, bits);
+                } else {
+                    dequant = 0;
+                }
+                *s++ = dequant;
+            }
+        }
+    } while (--nrof_blocks);
+}
+
+
+
+/**
+@}
+*/

+ 465 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/decoder-sbc.c

@@ -0,0 +1,465 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2006 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+ ***********************************************************************************/
+
+/** @file
+@ingroup codec_internal
+*/
+
+/**@addtogroup codec_internal */
+/**@{*/
+
+#include "oi_codec_sbc_private.h"
+#include "oi_bitstream.h"
+
+#define SPECIALIZE_READ_SAMPLES_JOINT
+
+/**
+ * Scans through a buffer looking for a codec syncword. If the decoder has been
+ * set for enhanced operation using OI_CODEC_SBC_DecoderReset(), it will search
+ * for both a standard and an enhanced syncword.
+ */
+PRIVATE OI_STATUS FindSyncword(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                               const OI_BYTE **frameData,
+                               OI_UINT32 *frameBytes)
+{
+#ifdef SBC_ENHANCED
+    OI_BYTE search1 = OI_SBC_SYNCWORD;
+    OI_BYTE search2 = OI_SBC_ENHANCED_SYNCWORD;
+#endif // SBC_ENHANCED
+
+    if (*frameBytes == 0) {
+        return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
+    }
+
+#ifdef SBC_ENHANCED
+    if (context->limitFrameFormat && context->enhancedEnabled){
+        /* If the context is restricted, only search for specified SYNCWORD */
+        search1 = search2;
+    } else if (context->enhancedEnabled == FALSE) {
+        /* If enhanced is not enabled, only search for classic SBC SYNCWORD*/
+        search2 = search1;
+    }
+    while (*frameBytes && (**frameData != search1) && (**frameData != search2)) {
+        (*frameBytes)--;
+        (*frameData)++;
+    }
+    if (*frameBytes) {
+        /* Syncword found, *frameData points to it, and *frameBytes correctly
+         * reflects the number of bytes available to read, including the
+         * syncword. */
+        context->common.frameInfo.enhanced = (**frameData == OI_SBC_ENHANCED_SYNCWORD);
+        return OI_OK;
+    } else {
+        /* No syncword was found anywhere in the provided input data.
+         * *frameData points past the end of the original input, and
+         * *frameBytes is 0. */
+        return OI_CODEC_SBC_NO_SYNCWORD;
+    }
+#else  // SBC_ENHANCED
+    while (*frameBytes && (**frameData != OI_SBC_SYNCWORD)) {
+        (*frameBytes)--;
+        (*frameData)++;
+    }
+    if (*frameBytes) {
+        /* Syncword found, *frameData points to it, and *frameBytes correctly
+         * reflects the number of bytes available to read, including the
+         * syncword. */
+        context->common.frameInfo.enhanced = FALSE;
+        return OI_OK;
+    } else {
+        /* No syncword was found anywhere in the provided input data.
+         * *frameData points past the end of the original input, and
+         * *frameBytes is 0. */
+        return OI_CODEC_SBC_NO_SYNCWORD;
+    }
+#endif // SBC_ENHANCED
+}
+
+static OI_STATUS DecodeBody(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                            const OI_BYTE *bodyData,
+                            OI_INT16 *pcmData,
+                            OI_UINT32 *pcmBytes,
+                            OI_BOOL allowPartial)
+{
+    OI_BITSTREAM bs;
+    OI_UINT frameSamples = context->common.frameInfo.nrof_blocks * context->common.frameInfo.nrof_subbands;
+    OI_UINT decode_block_count;
+
+    /*
+     * Based on the header data, make sure that there is enough room to write the output samples.
+     */
+    if (*pcmBytes < (sizeof(OI_INT16) * frameSamples * context->common.pcmStride) && !allowPartial) {
+        /* If we're not allowing partial decodes, we need room for the entire
+         * codec frame */
+        TRACE(("-OI_CODEC_SBC_Decode: OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA"));
+        return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA;
+    } else if (*pcmBytes < sizeof (OI_INT16) * context->common.frameInfo.nrof_subbands * context->common.pcmStride) {
+        /* Even if we're allowing partials, we can still only decode on a frame
+         * boundary */
+        return OI_CODEC_SBC_NOT_ENOUGH_AUDIO_DATA;
+    }
+
+    if (context->bufferedBlocks == 0) {
+        TRACE(("Reading scalefactors"));
+        OI_SBC_ReadScalefactors(&context->common, bodyData, &bs);
+
+        TRACE(("Computing bit allocation"));
+        OI_SBC_ComputeBitAllocation(&context->common);
+
+        TRACE(("Reading samples"));
+        if (context->common.frameInfo.mode == SBC_JOINT_STEREO) {
+            OI_SBC_ReadSamplesJoint(context, &bs);
+        } else {
+            OI_SBC_ReadSamples(context, &bs);
+        }
+
+        context->bufferedBlocks = context->common.frameInfo.nrof_blocks;
+    }
+
+    if (allowPartial) {
+        decode_block_count = *pcmBytes / sizeof(OI_INT16) / context->common.pcmStride / context->common.frameInfo.nrof_subbands;
+
+        if (decode_block_count > context->bufferedBlocks) {
+            decode_block_count = context->bufferedBlocks;
+        }
+
+    } else {
+        decode_block_count = context->common.frameInfo.nrof_blocks;
+    }
+
+    TRACE(("Synthesizing frame"));
+    {
+        OI_UINT start_block = context->common.frameInfo.nrof_blocks - context->bufferedBlocks;
+        OI_SBC_SynthFrame(context, pcmData, start_block, decode_block_count);
+    }
+
+    OI_ASSERT(context->bufferedBlocks >= decode_block_count);
+    context->bufferedBlocks -= decode_block_count;
+
+    frameSamples = decode_block_count * context->common.frameInfo.nrof_subbands;
+
+    /*
+     * When decoding mono into a stride-2 array, copy pcm data to second channel
+     */
+    if (context->common.frameInfo.nrof_channels == 1 && context->common.pcmStride == 2) {
+        OI_UINT i;
+        for (i = 0; i < frameSamples; ++i) {
+            pcmData[2*i+1] = pcmData[2*i];
+        }
+    }
+
+    /*
+     * Return number of pcm bytes generated by the decode operation.
+     */
+    *pcmBytes = frameSamples * sizeof(OI_INT16) * context->common.pcmStride;
+    if (context->bufferedBlocks > 0) {
+        return OI_CODEC_SBC_PARTIAL_DECODE;
+    } else {
+        return OI_OK;
+    }
+}
+
+PRIVATE OI_STATUS internal_DecodeRaw(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                     OI_UINT8 bitpool,
+                                     const OI_BYTE **frameData,
+                                     OI_UINT32 *frameBytes,
+                                     OI_INT16 *pcmData,
+                                     OI_UINT32 *pcmBytes)
+{
+    OI_STATUS status;
+    OI_UINT bodyLen;
+
+    TRACE(("+OI_CODEC_SBC_DecodeRaw"));
+
+    if (context->bufferedBlocks == 0) {
+        /*
+         * The bitallocator needs to know the bitpool value.
+         */
+        context->common.frameInfo.bitpool = bitpool;
+        /*
+         * Compute the frame length and check we have enough frame data to proceed
+         */
+        bodyLen = OI_CODEC_SBC_CalculateFramelen(&context->common.frameInfo) - SBC_HEADER_LEN;
+        if (*frameBytes < bodyLen) {
+            TRACE(("-OI_CODEC_SBC_Decode: OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA"));
+            return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
+        }
+    } else {
+        bodyLen = 0;
+    }
+    /*
+     * Decode the SBC data. Pass TRUE to DecodeBody to allow partial decoding of
+     * tones.
+     */
+    status = DecodeBody(context, *frameData, pcmData, pcmBytes, TRUE);
+    if (OI_SUCCESS(status) || status == OI_CODEC_SBC_PARTIAL_DECODE) {
+        *frameData += bodyLen;
+        *frameBytes -= bodyLen;
+    }
+    TRACE(("-OI_CODEC_SBC_DecodeRaw: %d", status));
+    return status;
+}
+
+OI_STATUS OI_CODEC_SBC_DecoderReset(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                    OI_UINT32 *decoderData,
+                                    OI_UINT32 decoderDataBytes,
+                                    OI_UINT8 maxChannels,
+                                    OI_UINT8 pcmStride,
+                                    OI_BOOL enhanced)
+{
+    return internal_DecoderReset(context, decoderData, decoderDataBytes, maxChannels, pcmStride, enhanced);
+}
+
+OI_STATUS OI_CODEC_SBC_DecodeFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                   const OI_BYTE **frameData,
+                                   OI_UINT32 *frameBytes,
+                                   OI_INT16 *pcmData,
+                                   OI_UINT32 *pcmBytes)
+{
+    OI_STATUS status;
+    OI_UINT framelen;
+    OI_UINT8 crc;
+
+    TRACE(("+OI_CODEC_SBC_DecodeFrame"));
+
+    TRACE(("Finding syncword"));
+    status = FindSyncword(context, frameData, frameBytes);
+    if (!OI_SUCCESS(status)) {
+        return status;
+    }
+
+    /* Make sure enough data remains to read the header. */
+    if (*frameBytes < SBC_HEADER_LEN) {
+        TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA"));
+        return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
+    }
+
+    TRACE(("Reading Header"));
+    OI_SBC_ReadHeader(&context->common, *frameData);
+
+    /*
+     * Some implementations load the decoder into RAM and use overlays for 4 vs 8 subbands. We need
+     * to ensure that the SBC parameters for this frame are compatible with the restrictions imposed
+     * by the loaded overlays.
+     */
+    if (context->limitFrameFormat && (context->common.frameInfo.subbands != context->restrictSubbands)) {
+        ERROR(("SBC parameters incompatible with loaded overlay"));
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+
+    if (context->common.frameInfo.nrof_channels > context->common.maxChannels) {
+        ERROR(("SBC parameters incompatible with number of channels specified during reset"));
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+
+    if (context->common.pcmStride < 1 || context->common.pcmStride > 2) {
+        ERROR(("PCM stride not set correctly during reset"));
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+
+    /*
+     * At this point a header has been read. However, it's possible that we found a false syncword,
+     * so the header data might be invalid. Make sure we have enough bytes to read in the
+     * CRC-protected header, but don't require we have the whole frame. That way, if it turns out
+     * that we're acting on bogus header data, we don't stall the decoding process by waiting for
+     * data that we don't actually need.
+     */
+    framelen = OI_CODEC_SBC_CalculateFramelen(&context->common.frameInfo);
+    if (*frameBytes < framelen) {
+        TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA"));
+        return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
+    }
+
+    TRACE(("Calculating checksum"));
+
+    crc = OI_SBC_CalculateChecksum(&context->common.frameInfo, *frameData);
+    if (crc != context->common.frameInfo.crc) {
+        TRACE(("CRC Mismatch:  calc=%02x read=%02x\n", crc, context->common.frameInfo.crc));
+        TRACE(("-OI_CODEC_SBC_DecodeFrame: OI_CODEC_SBC_CHECKSUM_MISMATCH"));
+        return OI_CODEC_SBC_CHECKSUM_MISMATCH;
+    }
+
+#ifdef OI_DEBUG
+    /*
+     * Make sure the bitpool values are sane.
+     */
+    if ((context->common.frameInfo.bitpool < SBC_MIN_BITPOOL) && !context->common.frameInfo.enhanced) {
+        ERROR(("Bitpool too small: %d (must be >= 2)", context->common.frameInfo.bitpool));
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+    if (context->common.frameInfo.bitpool > OI_SBC_MaxBitpool(&context->common.frameInfo)) {
+        ERROR(("Bitpool too large: %d (must be <= %ld)", context->common.frameInfo.bitpool, OI_SBC_MaxBitpool(&context->common.frameInfo)));
+        return OI_STATUS_INVALID_PARAMETERS;
+    }
+#endif
+
+    /*
+     * Now decode the SBC data. Partial decode is not yet implemented for an SBC
+     * stream, so pass FALSE to decode body to have it enforce the old rule that
+     * you have to decode a whole packet at a time.
+     */
+    status = DecodeBody(context, *frameData + SBC_HEADER_LEN, pcmData, pcmBytes, FALSE);
+    if (OI_SUCCESS(status)) {
+        *frameData += framelen;
+        *frameBytes -= framelen;
+    }
+    TRACE(("-OI_CODEC_SBC_DecodeFrame: %d", status));
+
+    return status;
+}
+
+OI_STATUS OI_CODEC_SBC_SkipFrame(OI_CODEC_SBC_DECODER_CONTEXT *context,
+                                 const OI_BYTE **frameData,
+                                 OI_UINT32 *frameBytes)
+{
+    OI_STATUS status;
+    OI_UINT framelen;
+    OI_UINT headerlen;
+    OI_UINT8 crc;
+
+    status = FindSyncword(context, frameData, frameBytes);
+    if (!OI_SUCCESS(status)) {
+        return status;
+    }
+    if (*frameBytes < SBC_HEADER_LEN) {
+        return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
+    }
+    OI_SBC_ReadHeader(&context->common, *frameData);
+    framelen = OI_SBC_CalculateFrameAndHeaderlen(&context->common.frameInfo, &headerlen);
+    if (*frameBytes < headerlen) {
+        return OI_CODEC_SBC_NOT_ENOUGH_HEADER_DATA;
+    }
+    crc = OI_SBC_CalculateChecksum(&context->common.frameInfo, *frameData);
+    if (crc != context->common.frameInfo.crc) {
+        return OI_CODEC_SBC_CHECKSUM_MISMATCH;
+    }
+    if (*frameBytes < framelen) {
+        return OI_CODEC_SBC_NOT_ENOUGH_BODY_DATA;
+    }
+    context->bufferedBlocks = 0;
+    *frameData += framelen;
+    *frameBytes -= framelen;
+    return OI_OK;
+}
+
+OI_UINT8 OI_CODEC_SBC_FrameCount(OI_BYTE  *frameData,
+                                 OI_UINT32 frameBytes)
+{
+    OI_UINT8 mode;
+    OI_UINT8 blocks;
+    OI_UINT8 subbands;
+    OI_UINT8 frameCount = 0;
+    OI_UINT  frameLen;
+
+    while (frameBytes){
+        while (frameBytes && ((frameData[0] & 0xFE) != 0x9C)){
+            frameData++;
+            frameBytes--;
+        }
+
+        if (frameBytes < SBC_HEADER_LEN) {
+            return frameCount;
+        }
+
+        /* Extract and translate required fields from Header */
+        subbands = mode = blocks = frameData[1];;
+        mode = (mode & (BIT3 | BIT2)) >> 2;
+        blocks = block_values[(blocks & (BIT5 | BIT4)) >> 4];
+        subbands = band_values[(subbands & BIT0)];
+
+        /* Inline logic to avoid corrupting context */
+        frameLen = blocks * frameData[2];
+        switch (mode){
+            case SBC_JOINT_STEREO:
+                frameLen += subbands + (8 * subbands);
+                break;
+
+            case SBC_DUAL_CHANNEL:
+                frameLen *= 2;
+                /* fall through */
+
+            default:
+                if (mode == SBC_MONO){
+                    frameLen += 4*subbands;
+                } else {
+                    frameLen += 8*subbands;
+                }
+        }
+
+        frameCount++;
+        frameLen = SBC_HEADER_LEN + (frameLen + 7) / 8;
+        if (frameBytes > frameLen){
+            frameBytes -= frameLen;
+            frameData += frameLen;
+        } else {
+            frameBytes = 0;
+        }
+    }
+    return frameCount;
+}
+
+/** Read quantized subband samples from the input bitstream and expand them. */
+
+#ifdef SPECIALIZE_READ_SAMPLES_JOINT
+
+PRIVATE void OI_SBC_ReadSamplesJoint4(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
+{
+#define NROF_SUBBANDS 4
+#include "readsamplesjoint.inc"
+#undef NROF_SUBBANDS
+}
+
+PRIVATE void OI_SBC_ReadSamplesJoint8(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
+{
+#define NROF_SUBBANDS 8
+#include "readsamplesjoint.inc"
+#undef NROF_SUBBANDS
+}
+
+typedef void (*READ_SAMPLES)(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs);
+
+static const READ_SAMPLES SpecializedReadSamples[] = {
+    OI_SBC_ReadSamplesJoint4,
+    OI_SBC_ReadSamplesJoint8
+};
+
+#endif /* SPECIALIZE_READ_SAMPLES_JOINT */
+
+
+PRIVATE void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_BITSTREAM *global_bs)
+{
+    OI_CODEC_SBC_COMMON_CONTEXT *common = &context->common;
+    OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
+#ifdef SPECIALIZE_READ_SAMPLES_JOINT
+    OI_ASSERT((nrof_subbands >> 3u) <= 1u);
+    SpecializedReadSamples[nrof_subbands >> 3](context, global_bs);
+#else
+
+#define NROF_SUBBANDS nrof_subbands
+#include "readsamplesjoint.inc"
+#undef NROF_SUBBANDS
+#endif /* SPECIALIZE_READ_SAMPLES_JOINT */
+}
+
+/**@}*/
+

+ 210 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/dequant.c

@@ -0,0 +1,210 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+/**
+ @file
+
+ Dequantizer for SBC decoder; reconstructs quantized representation of subband samples.
+
+ @ingroup codec_internal
+ */
+
+/**
+@addtogroup codec_internal
+@{
+*/
+
+/**
+ This function is a fixed-point approximation of a modification of the following
+ dequantization operation defined in the spec, as inferred from section 12.6.4:
+
+ @code
+ dequant = 2^(scale_factor+1) * ((raw * 2.0 + 1.0) / ((2^bits) - 1) - 1)
+
+ 2 <= bits <= 16
+ 0 <= raw < (2^bits)-1   (the -1 is because quantized values with all 1's are forbidden)
+
+ -65535 < dequant < 65535
+ @endcode
+
+ The code below computes the dequantized value divided by a scaling constant
+ equal to about 1.38. This constant is chosen to ensure that the entry in the
+ dequant_long_scaled table for 16 bits is as accurate as possible, since it has
+ the least relative precision available to it due to its small magnitude.
+
+ This routine outputs in Q16.15 format.
+
+ The helper array dequant_long is defined as follows:
+
+ @code
+ dequant_long_long[bits] = round(2^31 * 1/((2^bits - 1) / 1.38...)  for 2 <= bits <= 16
+ @endcode
+
+
+ Additionally, the table entries have the following property:
+
+ @code
+ dequant_long_scaled[bits] <= 2^31 / ((2^bits - 1))  for 2 <= bits <= 16
+ @endcode
+
+ Therefore
+
+ @code
+ d = 2 * raw + 1              1 <= d <= 2^bits - 2
+
+ d' = d * dequant_long[bits]
+
+                  d * dequant_long_scaled[bits] <= (2^bits - 2) * (2^31 / (2^bits - 1))
+                  d * dequant_long_scaled[bits] <= 2^31 * (2^bits - 2)/(2^bits - 1) < 2^31
+ @endcode
+
+ Therefore, d' doesn't overflow a signed 32-bit value.
+
+ @code
+
+ d' =~ 2^31 * (raw * 2.0 + 1.0) / (2^bits - 1) / 1.38...
+
+ result = d' - 2^31/1.38... =~ 2^31 * ((raw * 2.0 + 1.0) / (2^bits - 1) - 1) / 1.38...
+
+ result is therefore a scaled approximation to dequant. It remains only to
+ turn 2^31 into 2^(scale_factor+1). Since we're aiming for Q16.15 format,
+ this is achieved by shifting right by (15-scale_factor):
+
+  (2^31 * x) >> (15-scale_factor) =~ 2^(31-15+scale_factor) * x = 2^15 * 2^(1+scale_factor) * x
+ @endcode
+
+ */
+
+#include <oi_codec_sbc_private.h>
+
+#ifndef SBC_DEQUANT_LONG_SCALED_OFFSET
+#define SBC_DEQUANT_LONG_SCALED_OFFSET 1555931970
+#endif
+
+#ifndef SBC_DEQUANT_LONG_UNSCALED_OFFSET
+#define SBC_DEQUANT_LONG_UNSCALED_OFFSET 2147483648
+#endif
+
+#ifndef SBC_DEQUANT_SCALING_FACTOR
+#define SBC_DEQUANT_SCALING_FACTOR 1.38019122262781f
+#endif
+
+const OI_UINT32 dequant_long_scaled[17];
+const OI_UINT32 dequant_long_unscaled[17];
+
+/** Scales x by y bits to the right, adding a rounding factor.
+ */
+#ifndef SCALE
+#define SCALE(x, y) (((x) + (1 <<((y)-1))) >> (y))
+#endif
+
+#ifdef DEBUG_DEQUANTIZATION
+
+#include <math.h>
+
+INLINE float dequant_float(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits)
+{
+    float result = (1 << (scale_factor+1)) * ((raw * 2.0f + 1.0f) / ((1 << bits) - 1.0f) - 1.0f);
+
+    result /= SBC_DEQUANT_SCALING_FACTOR;
+
+    /* Unless the encoder screwed up, all correct dequantized values should
+     * satisfy this inequality. Non-compliant encoders which generate quantized
+     * values with all 1-bits set can, theoretically, trigger this assert. This
+     * is unlikely, however, and only an issue in debug mode.
+     */
+    OI_ASSERT(fabs(result) < 32768 * 1.6);
+
+    return result;
+}
+
+#endif
+
+
+INLINE OI_INT32 OI_SBC_Dequant(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits)
+{
+    OI_UINT32 d;
+    OI_INT32 result;
+
+    OI_ASSERT(scale_factor <= 15);
+    OI_ASSERT(bits <= 16);
+
+    if (bits <= 1) {
+        return 0;
+    }
+
+    d = (raw * 2) + 1;
+    d *= dequant_long_scaled[bits];
+    result = d - SBC_DEQUANT_LONG_SCALED_OFFSET;
+
+#ifdef DEBUG_DEQUANTIZATION
+    {
+        OI_INT32 integerized_float_result;
+        float float_result;
+
+        float_result = dequant_float(raw, scale_factor, bits);
+        integerized_float_result = (OI_INT32)floor(0.5f+float_result * (1 << 15));
+
+        /* This detects overflow */
+        OI_ASSERT(((result >= 0) && (integerized_float_result >= 0)) ||
+                  ((result <= 0) && (integerized_float_result <= 0)));
+    }
+#endif
+    return result >> (15 - scale_factor);
+}
+
+/* This version of Dequant does not incorporate the scaling factor of 1.38. It
+ * is intended for use with implementations of the filterbank which are
+ * hard-coded into a DSP. Output is Q16.4 format, so that after joint stereo
+ * processing (which leaves the most significant bit equal to the sign bit if
+ * the encoder is conformant) the result will fit a 24 bit fixed point signed
+ * value.*/
+
+INLINE OI_INT32 OI_SBC_Dequant_Unscaled(OI_UINT32 raw, OI_UINT scale_factor, OI_UINT bits)
+{
+    OI_UINT32 d;
+    OI_INT32 result;
+
+    OI_ASSERT(scale_factor <= 15);
+    OI_ASSERT(bits <= 16);
+
+
+    if (bits <= 1) {
+        return 0;
+    }
+    if (bits == 16) {
+        result = (raw << 16) + raw - 0x7fff7fff;
+        return SCALE(result, 24 - scale_factor);
+    }
+
+
+    d = (raw * 2) + 1;
+    d *= dequant_long_unscaled[bits];
+    result = d - 0x80000000;
+
+    return SCALE(result, 24 - scale_factor);
+}
+
+/**
+@}
+*/

+ 54 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/framing-sbc.c

@@ -0,0 +1,54 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+/** @file
+@ingroup codec_internal
+*/
+
+/**@addgroup codec_internal*/
+/**@{*/
+
+#include "oi_codec_sbc_private.h"
+
+const OI_CHAR* const OI_CODEC_SBC_FreqText[] =     { "SBC_FREQ_16000", "SBC_FREQ_32000", "SBC_FREQ_44100", "SBC_FREQ_48000" };
+const OI_CHAR* const OI_CODEC_SBC_ModeText[] =     { "SBC_MONO", "SBC_DUAL_CHANNEL", "SBC_STEREO", "SBC_JOINT_STEREO" };
+const OI_CHAR* const OI_CODEC_SBC_SubbandsText[] = { "SBC_SUBBANDS_4", "SBC_SUBBANDS_8" };
+const OI_CHAR* const OI_CODEC_SBC_BlocksText[] =   { "SBC_BLOCKS_4", "SBC_BLOCKS_8", "SBC_BLOCKS_12", "SBC_BLOCKS_16" };
+const OI_CHAR* const OI_CODEC_SBC_AllocText[] =    { "SBC_LOUDNESS", "SBC_SNR" };
+
+#ifdef OI_DEBUG
+void OI_CODEC_SBC_DumpConfig(OI_CODEC_SBC_FRAME_INFO *frameInfo)
+{
+    printf("SBC configuration\n");
+    printf("  enhanced:  %s\n", frameInfo->enhanced ? "TRUE" : "FALSE");
+    printf("  frequency: %d\n", frameInfo->frequency);
+    printf("  subbands:  %d\n", frameInfo->nrof_subbands);
+    printf("  blocks:    %d\n", frameInfo->nrof_blocks);
+    printf("  channels:  %d\n", frameInfo->nrof_channels);
+    printf("  mode:      %s\n", OI_CODEC_SBC_ModeText[frameInfo->mode]);
+    printf("  alloc:     %s\n", OI_CODEC_SBC_AllocText[frameInfo->alloc]);
+    printf("  bitpool:   %d\n", frameInfo->bitpool);
+}
+#endif /* OI_DEBUG */
+
+/**@}*/

+ 249 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/framing.c

@@ -0,0 +1,249 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+/**
+@file
+Checksum and header-related functions.
+
+@ingroup codec_internal
+*/
+
+/**
+@addtogroup codec_internal
+@{
+*/
+
+#include "oi_codec_sbc_private.h"
+#include "oi_assert.h"
+
+
+/* asdasd */
+
+#define USE_NIBBLEWISE_CRC
+
+/* #define PRINT_SAMPLES */
+/* #define PRINT_SCALEFACTORS */
+/* #define DEBUG_CRC */
+
+/*
+ * CRC-8 table for X^8 + X^4 + X^3 + X^2 + 1; byte-wise lookup
+ */
+#ifdef USE_WIDE_CRC
+/* Save space if a char is 16 bits, such as on the C54x */
+const OI_BYTE crc8_wide[128] = {
+    0x001d, 0x3a27, 0x7469, 0x4e53, 0xe8f5, 0xd2cf, 0x9c81, 0xa6bb, 0xcdd0, 0xf7ea, 0xb9a4, 0x839e, 0x2538, 0x1f02, 0x514c, 0x6b76, 0x879a, 0xbda0, 0xf3ee, 0xc9d4, 0x6f72, 0x5548, 0x1b06, 0x213c, 0x4a57, 0x706d, 0x3e23, 0x0419, 0xa2bf, 0x9885, 0xd6cb, 0xecf1, 0x130e, 0x2934, 0x677a, 0x5d40, 0xfbe6, 0xc1dc, 0x8f92, 0xb5a8, 0xdec3, 0xe4f9, 0xaab7, 0x908d, 0x362b, 0x0c11, 0x425f, 0x7865, 0x9489, 0xaeb3, 0xe0fd, 0xdac7, 0x7c61, 0x465b, 0x0815, 0x322f, 0x5944, 0x637e, 0x2d30, 0x170a, 0xb1ac, 0x8b96, 0xc5d8, 0xffe2, 0x263b, 0x1c01, 0x524f, 0x6875, 0xced3, 0xf4e9, 0xbaa7, 0x809d, 0xebf6, 0xd1cc, 0x9f82, 0xa5b8, 0x031e, 0x3924, 0x776a, 0x4d50, 0xa1bc, 0x9b86, 0xd5c8, 0xeff2, 0x4954, 0x736e, 0x3d20, 0x071a, 0x6c71, 0x564b, 0x1805, 0x223f, 0x8499, 0xbea3, 0xf0ed, 0xcad7, 0x3528, 0x0f12, 0x415c, 0x7b66, 0xddc0, 0xe7fa, 0xa9b4, 0x938e, 0xf8e5, 0xc2df, 0x8c91, 0xb6ab, 0x100d, 0x2a37, 0x6479, 0x5e43, 0xb2af, 0x8895, 0xc6db, 0xfce1, 0x5a47, 0x607d, 0x2e33, 0x1409, 0x7f62, 0x4558, 0x0b16, 0x312c, 0x978a, 0xadb0, 0xe3fe, 0xd9c4,
+};
+#elif defined(USE_NIBBLEWISE_CRC)
+const OI_BYTE crc8_narrow[16] = {
+    0x00, 0x1d, 0x3a, 0x27, 0x74, 0x69, 0x4e, 0x53, 0xe8, 0xf5, 0xd2, 0xcf, 0x9c, 0x81, 0xa6, 0xbb
+};
+#else
+const OI_BYTE crc8_narrow[256] = {
+    0x00, 0x1d, 0x3a, 0x27, 0x74, 0x69, 0x4e, 0x53, 0xe8, 0xf5, 0xd2, 0xcf, 0x9c, 0x81, 0xa6, 0xbb, 0xcd, 0xd0, 0xf7, 0xea, 0xb9, 0xa4, 0x83, 0x9e, 0x25, 0x38, 0x1f, 0x02, 0x51, 0x4c, 0x6b, 0x76, 0x87, 0x9a, 0xbd, 0xa0, 0xf3, 0xee, 0xc9, 0xd4, 0x6f, 0x72, 0x55, 0x48, 0x1b, 0x06, 0x21, 0x3c, 0x4a, 0x57, 0x70, 0x6d, 0x3e, 0x23, 0x04, 0x19, 0xa2, 0xbf, 0x98, 0x85, 0xd6, 0xcb, 0xec, 0xf1, 0x13, 0x0e, 0x29, 0x34, 0x67, 0x7a, 0x5d, 0x40, 0xfb, 0xe6, 0xc1, 0xdc, 0x8f, 0x92, 0xb5, 0xa8, 0xde, 0xc3, 0xe4, 0xf9, 0xaa, 0xb7, 0x90, 0x8d, 0x36, 0x2b, 0x0c, 0x11, 0x42, 0x5f, 0x78, 0x65, 0x94, 0x89, 0xae, 0xb3, 0xe0, 0xfd, 0xda, 0xc7, 0x7c, 0x61, 0x46, 0x5b, 0x08, 0x15, 0x32, 0x2f, 0x59, 0x44, 0x63, 0x7e, 0x2d, 0x30, 0x17, 0x0a, 0xb1, 0xac, 0x8b, 0x96, 0xc5, 0xd8, 0xff, 0xe2, 0x26, 0x3b, 0x1c, 0x01, 0x52, 0x4f, 0x68, 0x75, 0xce, 0xd3, 0xf4, 0xe9, 0xba, 0xa7, 0x80, 0x9d, 0xeb, 0xf6, 0xd1, 0xcc, 0x9f, 0x82, 0xa5, 0xb8, 0x03, 0x1e, 0x39, 0x24, 0x77, 0x6a, 0x4d, 0x50, 0xa1, 0xbc, 0x9b, 0x86, 0xd5, 0xc8, 0xef, 0xf2, 0x49, 0x54, 0x73, 0x6e, 0x3d, 0x20, 0x07, 0x1a, 0x6c, 0x71, 0x56, 0x4b, 0x18, 0x05, 0x22, 0x3f, 0x84, 0x99, 0xbe, 0xa3, 0xf0, 0xed, 0xca, 0xd7, 0x35, 0x28, 0x0f, 0x12, 0x41, 0x5c, 0x7b, 0x66, 0xdd, 0xc0, 0xe7, 0xfa, 0xa9, 0xb4, 0x93, 0x8e, 0xf8, 0xe5, 0xc2, 0xdf, 0x8c, 0x91, 0xb6, 0xab, 0x10, 0x0d, 0x2a, 0x37, 0x64, 0x79, 0x5e, 0x43, 0xb2, 0xaf, 0x88, 0x95, 0xc6, 0xdb, 0xfc, 0xe1, 0x5a, 0x47, 0x60, 0x7d, 0x2e, 0x33, 0x14, 0x09, 0x7f, 0x62, 0x45, 0x58, 0x0b, 0x16, 0x31, 0x2c, 0x97, 0x8a, 0xad, 0xb0, 0xe3, 0xfe, 0xd9, 0xc4
+};
+#endif
+const OI_UINT32 dequant_long_scaled[17] = {
+    0,
+    0,
+    0x1ee9e116,  /* bits=2  0.24151243  1/3      * (1/1.38019122262781) (0x00000008)*/
+    0x0d3fa99c,  /* bits=3  0.10350533  1/7      * (1/1.38019122262781) (0x00000013)*/
+    0x062ec69e,  /* bits=4  0.04830249  1/15     * (1/1.38019122262781) (0x00000029)*/
+    0x02fddbfa,  /* bits=5  0.02337217  1/31     * (1/1.38019122262781) (0x00000055)*/
+    0x0178d9f5,  /* bits=6  0.01150059  1/63     * (1/1.38019122262781) (0x000000ad)*/
+    0x00baf129,  /* bits=7  0.00570502  1/127    * (1/1.38019122262781) (0x0000015e)*/
+    0x005d1abe,  /* bits=8  0.00284132  1/255    * (1/1.38019122262781) (0x000002bf)*/
+    0x002e760d,  /* bits=9  0.00141788  1/511    * (1/1.38019122262781) (0x00000582)*/
+    0x00173536,  /* bits=10 0.00070825  1/1023   * (1/1.38019122262781) (0x00000b07)*/
+    0x000b9928,  /* bits=11 0.00035395  1/2047   * (1/1.38019122262781) (0x00001612)*/
+    0x0005cc37,  /* bits=12 0.00017693  1/4095   * (1/1.38019122262781) (0x00002c27)*/
+    0x0002e604,  /* bits=13 0.00008846  1/8191   * (1/1.38019122262781) (0x00005852)*/
+    0x000172fc,  /* bits=14 0.00004422  1/16383  * (1/1.38019122262781) (0x0000b0a7)*/
+    0x0000b97d,  /* bits=15 0.00002211  1/32767  * (1/1.38019122262781) (0x00016150)*/
+    0x00005cbe,  /* bits=16 0.00001106  1/65535  * (1/1.38019122262781) (0x0002c2a5)*/
+};
+
+
+const OI_UINT32 dequant_long_unscaled[17] = {
+    0,
+    0,
+    0x2aaaaaab,  /* bits=2  0.33333333  1/3      (0x00000005)*/
+    0x12492492,  /* bits=3  0.14285714  1/7      (0x0000000e)*/
+    0x08888889,  /* bits=4  0.06666667  1/15     (0x0000001d)*/
+    0x04210842,  /* bits=5  0.03225806  1/31     (0x0000003e)*/
+    0x02082082,  /* bits=6  0.01587302  1/63     (0x0000007e)*/
+    0x01020408,  /* bits=7  0.00787402  1/127    (0x000000fe)*/
+    0x00808081,  /* bits=8  0.00392157  1/255    (0x000001fd)*/
+    0x00402010,  /* bits=9  0.00195695  1/511    (0x000003fe)*/
+    0x00200802,  /* bits=10 0.00097752  1/1023   (0x000007fe)*/
+    0x00100200,  /* bits=11 0.00048852  1/2047   (0x00000ffe)*/
+    0x00080080,  /* bits=12 0.00024420  1/4095   (0x00001ffe)*/
+    0x00040020,  /* bits=13 0.00012209  1/8191   (0x00003ffe)*/
+    0x00020008,  /* bits=14 0.00006104  1/16383  (0x00007ffe)*/
+    0x00010002,  /* bits=15 0.00003052  1/32767  (0x0000fffe)*/
+    0x00008001,  /* bits=16 0.00001526  1/65535  (0x0001fffc)*/
+};
+
+#if defined(OI_DEBUG) || defined(PRINT_SAMPLES) || defined(PRINT_SCALEFACTORS)
+#include <stdio.h>
+#endif
+
+#ifdef USE_WIDE_CRC
+INLINE OI_CHAR crc_iterate(OI_UINT8 oldcrc, OI_UINT8 next)
+{
+    OI_UINT crc;
+    OI_UINT idx;
+    idx = oldcrc^next;
+    crc = crc8_wide[idx >> 1];
+    if (idx%2) {
+        crc &= 0xff;
+    } else {
+        crc >>= 8;
+    }
+
+    return crc;
+}
+
+INLINE OI_CHAR crc_iterate_top4(OI_UINT8 oldcrc, OI_UINT8 next)
+{
+    OI_UINT crc;
+    OI_UINT idx;
+    idx = (oldcrc ^ next) >> 4;
+    crc = crc8_wide[idx>>1];
+    if (idx%2) {
+        crc &= 0xff;
+    } else {
+        crc >>= 8;
+    }
+
+    return (oldcrc << 4) ^ crc;
+}
+
+#else // USE_WIDE_CRC
+
+INLINE OI_UINT8 crc_iterate_top4(OI_UINT8 oldcrc, OI_UINT8 next)
+{
+    return (oldcrc << 4) ^ crc8_narrow[(oldcrc^next) >> 4];
+}
+
+#ifdef USE_NIBBLEWISE_CRC
+INLINE OI_UINT8 crc_iterate(OI_UINT8 crc, OI_UINT8 next)
+{
+    crc = (crc << 4) ^ crc8_narrow[(crc^next) >> 4];
+    crc = (crc << 4) ^ crc8_narrow[((crc>>4)^next)&0xf];
+
+    return crc;
+}
+
+#else   // USE_NIBBLEWISE_CRC
+INLINE OI_UINT8 crc_iterate(OI_UINT8 crc, OI_UINT8 next)
+{
+  return crc8_narrow[crc^next];
+}
+
+#endif  // USE_NIBBLEWISE_CRC
+
+#endif // USE_WIDE_CRC
+
+
+PRIVATE OI_UINT8 OI_SBC_CalculateChecksum(OI_CODEC_SBC_FRAME_INFO *frame, OI_BYTE const *data)
+{
+    OI_UINT i;
+    OI_UINT8 crc = 0x0f;
+    /* Count is the number of whole bytes subject to CRC. Actually, it's one
+     * more than this number, because data[3] is the CRC field itself, which is
+     * explicitly skipped. Since crc_iterate (should be) inlined, it's cheaper
+     * spacewise to include the check in the loop. This shouldn't be much of a
+     * bottleneck routine in the first place. */
+    OI_UINT count = (frame->nrof_subbands * frame->nrof_channels / 2u) + 4;
+
+    if (frame->mode == SBC_JOINT_STEREO && frame->nrof_subbands == 8) {
+        count++;
+    }
+
+    for (i = 1; i < count; i++) {
+        if (i != 3) {
+            crc = crc_iterate(crc,data[i]);
+        }
+    }
+
+    if (frame->mode == SBC_JOINT_STEREO && frame->nrof_subbands == 4) {
+        crc = crc_iterate_top4(crc, data[i]);
+    }
+
+    return crc;
+}
+
+void OI_SBC_ExpandFrameFields(OI_CODEC_SBC_FRAME_INFO *frame)
+{
+    frame->nrof_blocks = block_values[frame->blocks];
+    frame->nrof_subbands = band_values[frame->subbands];
+
+    frame->frequency = freq_values[frame->freqIndex];
+    frame->nrof_channels = channel_values[frame->mode];
+}
+
+/**
+ * Unrolled macro to copy 4 32-bit aligned 32-bit values backward in memory
+ */
+#define COPY4WORDS_BACK(_dest, _src)            \
+    do {                                        \
+            OI_INT32 _a, _b, _c, _d;            \
+            _a = *--_src;                       \
+            _b = *--_src;                       \
+            _c = *--_src;                       \
+            _d = *--_src;                       \
+            *--_dest = _a;                      \
+            *--_dest = _b;                      \
+            *--_dest = _c;                      \
+            *--_dest = _d;                      \
+    } while (0)
+
+
+#if defined(USE_PLATFORM_MEMMOVE) || defined(USE_PLATFORM_MEMCPY)
+#include <string.h>
+#endif
+PRIVATE void shift_buffer(SBC_BUFFER_T *dest, SBC_BUFFER_T *src, OI_UINT wordCount)
+{
+#ifdef USE_PLATFORM_MEMMOVE
+    memmove(dest, src, wordCount * sizeof(SBC_BUFFER_T));
+#elif defined(USE_PLATFORM_MEMCPY)
+    OI_ASSERT(((OI_CHAR *)(dest) - (OI_CHAR *)(src)) >= wordCount*sizeof(*dest));
+    memcpy(dest, src, wordCount * sizeof(SBC_BUFFER_T));
+#else
+    OI_UINT n;
+    OI_INT32 *d;
+    OI_INT32 *s;
+    n = wordCount / 4 / (sizeof(OI_INT32)/sizeof(*dest));
+    OI_ASSERT((n * 4 * (sizeof(OI_INT32)/sizeof(*dest))) == wordCount);
+
+    d = (void*)(dest + wordCount);
+    s = (void*)(src + wordCount);
+
+    do {
+        COPY4WORDS_BACK(d, s);
+    } while (--n);
+#endif
+}
+/**
+@}
+*/

+ 57 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/oi_codec_version.c

@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2002 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**
+@file
+This file contains a single function, which returns a string indicating the
+version number of the eSBC codec
+
+@ingroup codec_internal
+*/
+
+/**
+@addtogroup codec_internal
+@{
+*/
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+#include "oi_stddefs.h"
+#include "oi_codec_sbc_private.h"
+
+/** Version string for the BLUEmagic 3.0 protocol stack and profiles */
+PRIVATE OI_CHAR * const codecVersion = "v1.5"
+#ifdef OI_SBC_EVAL
+" (Evaluation version)"
+#endif
+;
+
+/** This function returns the version string for the BLUEmagic 3.0 protocol stack
+    and profiles */
+OI_CHAR *OI_CODEC_Version(void) {
+    return codecVersion;
+}
+
+/**********************************************************************************/
+
+/**
+@}
+*/

+ 111 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/readsamplesjoint.inc

@@ -0,0 +1,111 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/*******************************************************************************
+ * @file readsamplesjoint.inc
+ *
+ * This is the body of the generic version of OI_SBC_ReadSamplesJoint().
+ * It is designed to be \#included into a function as follows:
+    \code
+    void OI_SBC_ReadSamplesJoint4(OI_CODEC_SBC_COMMON_CONTEXT *common, OI_BITSTREAM *global_bs)
+    {
+        #define NROF_SUBBANDS 4
+        #include "readsamplesjoint.inc"
+        #undef NROF_SUBBANDS
+    }
+
+    void OI_SBC_ReadSamplesJoint8(OI_CODEC_SBC_COMMON_CONTEXT *common, OI_BITSTREAM *global_bs)
+    {
+        #define NROF_SUBBANDS 8
+        #include "readsamplesjoint.inc"
+        #undef NROF_SUBBANDS
+    }
+    \endcode
+ * Or to make a generic version:
+    \code
+    void OI_SBC_ReadSamplesJoint(OI_CODEC_SBC_COMMON_CONTEXT *common, OI_BITSTREAM *global_bs)
+    {
+        OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
+
+        #define NROF_SUBBANDS nrof_subbands
+        #include "readsamplesjoint.inc"
+        #undef NROF_SUBBANDS
+    }
+    \endcode
+ * @ingroup codec_internal
+ *******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+{
+    OI_CODEC_SBC_COMMON_CONTEXT *common = &context->common;
+    OI_UINT bl = common->frameInfo.nrof_blocks;
+    OI_INT32 * RESTRICT s = common->subdata;
+    OI_UINT8 *ptr = global_bs->ptr.w;
+    OI_UINT32 value = global_bs->value;
+    OI_UINT bitPtr = global_bs->bitPtr;
+    OI_UINT8 jmask = common->frameInfo.join << (8 - NROF_SUBBANDS);
+
+    do {
+        OI_INT8 *sf_array = &common->scale_factor[0];
+        OI_UINT8 *bits_array = &common->bits.uint8[0];
+        OI_UINT8 joint = jmask;
+        OI_UINT sb;
+        /*
+         * Left channel
+         */
+        sb = NROF_SUBBANDS;
+        do {
+            OI_UINT32 raw;
+            OI_INT32 dequant;
+            OI_UINT8 bits = *bits_array++;
+            OI_INT sf = *sf_array++;
+
+            OI_BITSTREAM_READUINT(raw, bits, ptr, value, bitPtr);
+            dequant = OI_SBC_Dequant(raw, sf, bits);
+            *s++ = dequant;
+        } while (--sb);
+        /*
+         * Right channel
+         */
+        sb = NROF_SUBBANDS;
+        do {
+            OI_UINT32 raw;
+            OI_INT32 dequant;
+            OI_UINT8 bits = *bits_array++;
+            OI_INT sf = *sf_array++;
+
+            OI_BITSTREAM_READUINT(raw, bits, ptr, value, bitPtr);
+            dequant = OI_SBC_Dequant(raw, sf, bits);
+            /*
+             * Check if we need to do mid/side
+             */
+            if (joint & 0x80) {
+                OI_INT32 mid = *(s - NROF_SUBBANDS);
+                OI_INT32 side = dequant;
+                *(s - NROF_SUBBANDS) = mid + side;
+                dequant = mid - side;
+            }
+            joint <<= 1;
+            *s++ = dequant;
+        } while (--sb);
+    } while (--bl);
+}

+ 135 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/synthesis-8-generated.c

@@ -0,0 +1,135 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**
+ @file
+
+ DO NOT EDIT THIS FILE DIRECTLY
+
+ This file is automatically generated by the "synthesis-gen.pl" script.
+ Any changes to this generated file will be lost when the script is re-run.
+
+ These functions are called by functions in synthesis.c to perform the synthesis
+ filterbank computations for the SBC decoder.
+
+
+ */
+
+#include <oi_codec_sbc_private.h>
+
+#ifndef CLIP_INT16
+#define CLIP_INT16(x) do { if (x > OI_INT16_MAX) { x = OI_INT16_MAX; } else if (x < OI_INT16_MIN) { x = OI_INT16_MIN; } } while (0)
+#endif
+
+#define MUL_16S_16S(_x, _y) ((_x) * (_y))
+
+PRIVATE void SynthWindow80_generated(OI_INT16 *pcm, SBC_BUFFER_T const * RESTRICT buffer, OI_UINT strideShift)
+{
+    OI_INT32 pcm_a, pcm_b;
+    /* 1 - stage 0 */ pcm_b = 0;
+    /* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(8235, buffer[ 12]))>> 3;
+    /* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(-23167, buffer[ 20]))>> 3;
+    /* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(26479, buffer[ 28]))>> 2;
+    /* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(-17397, buffer[ 36]))<< 1;
+    /* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(9399, buffer[ 44]))<< 3;
+    /* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(17397, buffer[ 52]))<< 1;
+    /* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(26479, buffer[ 60]))>> 2;
+    /* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(23167, buffer[ 68]))>> 3;
+    /* 1 - stage 0 */ pcm_b +=(MUL_16S_16S(8235, buffer[ 76]))>> 3;
+    /* 1 - stage 0 */ pcm_b /= 32768; CLIP_INT16(pcm_b); pcm[0<<strideShift] = (OI_INT16)pcm_b;
+    /* 1 - stage 1 */ pcm_a = 0;
+    /* 1 - stage 1 */ pcm_b = 0;
+    /* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(-3263, buffer[  5]))>> 5;
+    /* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(9293, buffer[  5]))>> 3;
+    /* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(29293, buffer[ 11]))>> 5;
+    /* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(-6087, buffer[ 11]))>> 2;
+    /* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(-5229, buffer[ 21]));
+    /* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(1247, buffer[ 21]))<< 3;
+    /* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(30835, buffer[ 27]))>> 3;
+    /* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(-2893, buffer[ 27]))<< 3;
+    /* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(-27021, buffer[ 37]))<< 1;
+    /* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(23671, buffer[ 37]))<< 2;
+    /* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(31633, buffer[ 43]))<< 1;
+    /* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(18055, buffer[ 43]))<< 1;
+    /* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(17319, buffer[ 53]))<< 1;
+    /* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(11537, buffer[ 53]))>> 1;
+    /* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(26663, buffer[ 59]))>> 2;
+    /* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(1747, buffer[ 59]))<< 1;
+    /* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(4555, buffer[ 69]))>> 1;
+    /* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(685, buffer[ 69]))<< 1;
+    /* 1 - stage 1 */ pcm_a +=(MUL_16S_16S(12419, buffer[ 75]))>> 4;
+    /* 1 - stage 1 */ pcm_b +=(MUL_16S_16S(8721, buffer[ 75]))>> 7;
+    /* 1 - stage 1 */ pcm_a /= 32768; CLIP_INT16(pcm_a); pcm[1<<strideShift] = (OI_INT16)pcm_a;
+    /* 1 - stage 1 */ pcm_b /= 32768; CLIP_INT16(pcm_b); pcm[7<<strideShift] = (OI_INT16)pcm_b;
+    /* 1 - stage 2 */ pcm_a = 0;
+    /* 1 - stage 2 */ pcm_b = 0;
+    /* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(-10385, buffer[  6]))>> 6;
+    /* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(11167, buffer[  6]))>> 4;
+    /* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(24995, buffer[ 10]))>> 5;
+    /* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(-10337, buffer[ 10]))>> 4;
+    /* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(-309, buffer[ 22]))<< 4;
+    /* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(1917, buffer[ 22]))<< 2;
+    /* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(9161, buffer[ 26]))>> 3;
+    /* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(-30605, buffer[ 26]))>> 1;
+    /* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(-23063, buffer[ 38]))<< 1;
+    /* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(8317, buffer[ 38]))<< 3;
+    /* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(27561, buffer[ 42]))<< 1;
+    /* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(9553, buffer[ 42]))<< 2;
+    /* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(2309, buffer[ 54]))<< 3;
+    /* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(22117, buffer[ 54]))>> 4;
+    /* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(12705, buffer[ 58]))>> 1;
+    /* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(16383, buffer[ 58]))>> 2;
+    /* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(6239, buffer[ 70]))>> 3;
+    /* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(7543, buffer[ 70]))>> 3;
+    /* 1 - stage 2 */ pcm_a +=(MUL_16S_16S(9251, buffer[ 74]))>> 4;
+    /* 1 - stage 2 */ pcm_b +=(MUL_16S_16S(8603, buffer[ 74]))>> 6;
+    /* 1 - stage 2 */ pcm_a /= 32768; CLIP_INT16(pcm_a); pcm[2<<strideShift] = (OI_INT16)pcm_a;
+    /* 1 - stage 2 */ pcm_b /= 32768; CLIP_INT16(pcm_b); pcm[6<<strideShift] = (OI_INT16)pcm_b;
+    /* 1 - stage 3 */ pcm_a = 0;
+    /* 1 - stage 3 */ pcm_b = 0;
+    /* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(-16457, buffer[  7]))>> 6;
+    /* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(16913, buffer[  7]))>> 5;
+    /* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(19083, buffer[  9]))>> 5;
+    /* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(-8443, buffer[  9]))>> 7;
+    /* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(-23641, buffer[ 23]))>> 2;
+    /* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(3687, buffer[ 23]))<< 1;
+    /* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(-29015, buffer[ 25]))>> 4;
+    /* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(-301, buffer[ 25]))<< 5;
+    /* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(-12889, buffer[ 39]))<< 2;
+    /* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(15447, buffer[ 39]))<< 2;
+    /* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(6145, buffer[ 41]))<< 3;
+    /* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(10255, buffer[ 41]))<< 2;
+    /* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(24211, buffer[ 55]))>> 1;
+    /* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(-18233, buffer[ 55]))>> 3;
+    /* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(23469, buffer[ 57]))>> 2;
+    /* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(9405, buffer[ 57]))>> 1;
+    /* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(21223, buffer[ 71]))>> 8;
+    /* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(1499, buffer[ 71]))>> 1;
+    /* 1 - stage 3 */ pcm_a +=(MUL_16S_16S(26913, buffer[ 73]))>> 6;
+    /* 1 - stage 3 */ pcm_b +=(MUL_16S_16S(26189, buffer[ 73]))>> 7;
+    /* 1 - stage 3 */ pcm_a /= 32768; CLIP_INT16(pcm_a); pcm[3<<strideShift] = (OI_INT16)pcm_a;
+    /* 1 - stage 3 */ pcm_b /= 32768; CLIP_INT16(pcm_b); pcm[5<<strideShift] = (OI_INT16)pcm_b;
+    /* 1 - stage 4 */ pcm_a = 0;
+    /* 1 - stage 4 */ pcm_a +=(MUL_16S_16S(10445, buffer[  8]))>> 4;
+    /* 1 - stage 4 */ pcm_a +=(MUL_16S_16S(-5297, buffer[ 24]))<< 1;
+    /* 1 - stage 4 */ pcm_a +=(MUL_16S_16S(22299, buffer[ 40]))<< 2;
+    /* 1 - stage 4 */ pcm_a +=(MUL_16S_16S(10603, buffer[ 56]));
+    /* 1 - stage 4 */ pcm_a +=(MUL_16S_16S(9539, buffer[ 72]))>> 4;
+    /* 1 - stage 4 */ pcm_a /= 32768; CLIP_INT16(pcm_a); pcm[4<<strideShift] = (OI_INT16)pcm_a;
+}

+ 305 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/synthesis-dct8.c

@@ -0,0 +1,305 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+/** @file
+@ingroup codec_internal
+*/
+
+/**@addgroup codec_internal*/
+/**@{*/
+
+/*
+ * Performs an 8-point Type-II scaled DCT using the Arai-Agui-Nakajima
+ * factorization. The scaling factors are folded into the windowing
+ * constants. 29 adds and 5 16x32 multiplies per 8 samples.
+ */
+
+#include "oi_codec_sbc_private.h"
+
+#define AAN_C4_FIX (759250125)/* S1.30  759250125   0.707107*/
+
+#define AAN_C6_FIX (410903207)/* S1.30  410903207   0.382683*/
+
+#define AAN_Q0_FIX (581104888)/* S1.30  581104888   0.541196*/
+
+#define AAN_Q1_FIX (1402911301)/* S1.30 1402911301   1.306563*/
+
+/** Scales x by y bits to the right, adding a rounding factor.
+ */
+#ifndef SCALE
+#define SCALE(x, y) (((x) + (1 <<((y)-1))) >> (y))
+#endif
+
+/**
+ * Default C language implementation of a 32x32->32 multiply. This function may
+ * be replaced by a platform-specific version for speed.
+ *
+ * @param u A signed 32-bit multiplicand
+ * @param v A signed 32-bit multiplier
+
+ * @return  A signed 32-bit value corresponding to the 32 most significant bits
+ * of the 64-bit product of u and v.
+ */
+INLINE OI_INT32 default_mul_32s_32s_hi(OI_INT32 u, OI_INT32 v)
+{
+    OI_UINT32 u0, v0;
+    OI_INT32 u1, v1, w1, w2, t;
+
+    u0 = u & 0xFFFF; u1 = u >> 16;
+    v0 = v & 0xFFFF; v1 = v >> 16;
+    t = u0*v0;
+    t = u1*v0 + ((OI_UINT32)t >> 16);
+    w1 = t & 0xFFFF;
+    w2 = t >> 16;
+    w1 = u0*v1 + w1;
+    return u1*v1 + w2 + (w1 >> 16);
+}
+
+#define MUL_32S_32S_HI(_x, _y) default_mul_32s_32s_hi(_x, _y)
+
+
+#ifdef DEBUG_DCT
+PRIVATE void float_dct2_8(float * RESTRICT out, OI_INT32 const *RESTRICT in)
+{
+#define FIX(x,bits) (((int)floor(0.5f+((x)*((float)(1<<bits)))))/((float)(1<<bits)))
+#define FLOAT_BUTTERFLY(x,y) x += y; y = x - (y*2); OI_ASSERT(VALID_INT32(x)); OI_ASSERT(VALID_INT32(y));
+#define FLOAT_MULT_DCT(K, sample) (FIX(K,20) * sample)
+#define FLOAT_SCALE(x, y) (((x) / (double)(1 << (y))))
+
+    double L00,L01,L02,L03,L04,L05,L06,L07;
+    double L25;
+
+    double in0,in1,in2,in3;
+    double in4,in5,in6,in7;
+
+    in0 = FLOAT_SCALE(in[0], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in0));
+    in1 = FLOAT_SCALE(in[1], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in1));
+    in2 = FLOAT_SCALE(in[2], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in2));
+    in3 = FLOAT_SCALE(in[3], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in3));
+    in4 = FLOAT_SCALE(in[4], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in4));
+    in5 = FLOAT_SCALE(in[5], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in5));
+    in6 = FLOAT_SCALE(in[6], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in6));
+    in7 = FLOAT_SCALE(in[7], DCTII_8_SHIFT_IN); OI_ASSERT(VALID_INT32(in7));
+
+    L00 = (in0 + in7); OI_ASSERT(VALID_INT32(L00));
+    L01 = (in1 + in6); OI_ASSERT(VALID_INT32(L01));
+    L02 = (in2 + in5); OI_ASSERT(VALID_INT32(L02));
+    L03 = (in3 + in4); OI_ASSERT(VALID_INT32(L03));
+
+    L04 = (in3 - in4); OI_ASSERT(VALID_INT32(L04));
+    L05 = (in2 - in5); OI_ASSERT(VALID_INT32(L05));
+    L06 = (in1 - in6); OI_ASSERT(VALID_INT32(L06));
+    L07 = (in0 - in7); OI_ASSERT(VALID_INT32(L07));
+
+    FLOAT_BUTTERFLY(L00, L03);
+    FLOAT_BUTTERFLY(L01, L02);
+
+    L02 += L03; OI_ASSERT(VALID_INT32(L02));
+
+    L02 = FLOAT_MULT_DCT(AAN_C4_FLOAT, L02); OI_ASSERT(VALID_INT32(L02));
+
+    FLOAT_BUTTERFLY(L00, L01);
+
+    out[0] = (float)FLOAT_SCALE(L00, DCTII_8_SHIFT_0); OI_ASSERT(VALID_INT16(out[0]));
+    out[4] = (float)FLOAT_SCALE(L01, DCTII_8_SHIFT_4); OI_ASSERT(VALID_INT16(out[4]));
+
+    FLOAT_BUTTERFLY(L03, L02);
+    out[6] = (float)FLOAT_SCALE(L02, DCTII_8_SHIFT_6); OI_ASSERT(VALID_INT16(out[6]));
+    out[2] = (float)FLOAT_SCALE(L03, DCTII_8_SHIFT_2); OI_ASSERT(VALID_INT16(out[2]));
+
+    L04 += L05; OI_ASSERT(VALID_INT32(L04));
+    L05 += L06; OI_ASSERT(VALID_INT32(L05));
+    L06 += L07; OI_ASSERT(VALID_INT32(L06));
+
+    L04/=2;
+    L05/=2;
+    L06/=2;
+    L07/=2;
+
+    L05 = FLOAT_MULT_DCT(AAN_C4_FLOAT, L05); OI_ASSERT(VALID_INT32(L05));
+
+    L25 = L06 - L04; OI_ASSERT(VALID_INT32(L25));
+    L25 = FLOAT_MULT_DCT(AAN_C6_FLOAT, L25); OI_ASSERT(VALID_INT32(L25));
+
+    L04 = FLOAT_MULT_DCT(AAN_Q0_FLOAT, L04); OI_ASSERT(VALID_INT32(L04));
+    L04 -= L25; OI_ASSERT(VALID_INT32(L04));
+
+    L06 = FLOAT_MULT_DCT(AAN_Q1_FLOAT, L06); OI_ASSERT(VALID_INT32(L06));
+    L06 -= L25; OI_ASSERT(VALID_INT32(L25));
+
+    FLOAT_BUTTERFLY(L07, L05);
+
+    FLOAT_BUTTERFLY(L05, L04);
+    out[3] = (float)(FLOAT_SCALE(L04, DCTII_8_SHIFT_3-1)); OI_ASSERT(VALID_INT16(out[3]));
+    out[5] = (float)(FLOAT_SCALE(L05, DCTII_8_SHIFT_5-1)); OI_ASSERT(VALID_INT16(out[5]));
+
+    FLOAT_BUTTERFLY(L07, L06);
+    out[7] = (float)(FLOAT_SCALE(L06, DCTII_8_SHIFT_7-1)); OI_ASSERT(VALID_INT16(out[7]));
+    out[1] = (float)(FLOAT_SCALE(L07, DCTII_8_SHIFT_1-1)); OI_ASSERT(VALID_INT16(out[1]));
+}
+#undef BUTTERFLY
+#endif
+
+
+/*
+ * This function calculates the AAN DCT. Its inputs are in S16.15 format, as
+ * returned by OI_SBC_Dequant. In practice, abs(in[x]) < 52429.0 / 1.38
+ * (1244918057 integer). The function it computes is an approximation to the array defined
+ * by:
+ *
+ * diag(aan_s) * AAN= C2
+ *
+ *   or
+ *
+ * AAN = diag(1/aan_s) * C2
+ *
+ * where C2 is as it is defined in the comment at the head of this file, and
+ *
+ * aan_s[i] = aan_s = 1/(2*cos(i*pi/16)) with i = 1..7, aan_s[0] = 1;
+ *
+ * aan_s[i] = [ 1.000  0.510  0.541  0.601  0.707  0.900  1.307  2.563 ]
+ *
+ * The output ranges are shown as follows:
+ *
+ * Let Y[0..7] = AAN * X[0..7]
+ *
+ * Without loss of generality, assume the input vector X consists of elements
+ * between -1 and 1. The maximum possible value of a given output element occurs
+ * with some particular combination of input vector elements each of which is -1
+ * or 1. Consider the computation of Y[i]. Y[i] = sum t=0..7 of AAN[t,i]*X[i]. Y is
+ * maximized if the sign of X[i] matches the sign of AAN[t,i], ensuring a
+ * positive contribution to the sum. Equivalently, one may simply sum
+ * abs(AAN)[t,i] over t to get the maximum possible value of Y[i].
+ *
+ * This yields approximately [8.00  10.05   9.66   8.52   8.00   5.70   4.00   2.00]
+ *
+ * Given the maximum magnitude sensible input value of +/-37992, this yields the
+ * following vector of maximum output magnitudes:
+ *
+ * [ 303936  381820  367003  323692  303936  216555  151968   75984 ]
+ *
+ * Ultimately, these values must fit into 16 bit signed integers, so they must
+ * be scaled. A non-uniform scaling helps maximize the kept precision. The
+ * relative number of extra bits of precision maintainable with respect to the
+ * largest value is given here:
+ *
+ * [ 0  0  0  0  0  0  1  2 ]
+ *
+ */
+PRIVATE void dct2_8(SBC_BUFFER_T * RESTRICT out, OI_INT32 const *RESTRICT in)
+{
+#define BUTTERFLY(x,y) x += y; y = x - (y<<1);
+#define FIX_MULT_DCT(K, x) (MUL_32S_32S_HI(K,x)<<2)
+
+    OI_INT32 L00,L01,L02,L03,L04,L05,L06,L07;
+    OI_INT32 L25;
+
+    OI_INT32 in0,in1,in2,in3;
+    OI_INT32 in4,in5,in6,in7;
+
+#if DCTII_8_SHIFT_IN != 0
+    in0 = SCALE(in[0], DCTII_8_SHIFT_IN);
+    in1 = SCALE(in[1], DCTII_8_SHIFT_IN);
+    in2 = SCALE(in[2], DCTII_8_SHIFT_IN);
+    in3 = SCALE(in[3], DCTII_8_SHIFT_IN);
+    in4 = SCALE(in[4], DCTII_8_SHIFT_IN);
+    in5 = SCALE(in[5], DCTII_8_SHIFT_IN);
+    in6 = SCALE(in[6], DCTII_8_SHIFT_IN);
+    in7 = SCALE(in[7], DCTII_8_SHIFT_IN);
+#else
+    in0 = in[0];
+    in1 = in[1];
+    in2 = in[2];
+    in3 = in[3];
+    in4 = in[4];
+    in5 = in[5];
+    in6 = in[6];
+    in7 = in[7];
+#endif
+
+    L00 = in0 + in7;
+    L01 = in1 + in6;
+    L02 = in2 + in5;
+    L03 = in3 + in4;
+
+    L04 = in3 - in4;
+    L05 = in2 - in5;
+    L06 = in1 - in6;
+    L07 = in0 - in7;
+
+    BUTTERFLY(L00, L03);
+    BUTTERFLY(L01, L02);
+
+    L02 += L03;
+
+    L02 = FIX_MULT_DCT(AAN_C4_FIX, L02);
+
+    BUTTERFLY(L00, L01);
+
+    out[0] = (OI_INT16)SCALE(L00, DCTII_8_SHIFT_0);
+    out[4] = (OI_INT16)SCALE(L01, DCTII_8_SHIFT_4);
+
+    BUTTERFLY(L03, L02);
+    out[6] = (OI_INT16)SCALE(L02, DCTII_8_SHIFT_6);
+    out[2] = (OI_INT16)SCALE(L03, DCTII_8_SHIFT_2);
+
+    L04 += L05;
+    L05 += L06;
+    L06 += L07;
+
+    L04/=2;
+    L05/=2;
+    L06/=2;
+    L07/=2;
+
+    L05 = FIX_MULT_DCT(AAN_C4_FIX, L05);
+
+    L25 = L06 - L04;
+    L25 = FIX_MULT_DCT(AAN_C6_FIX, L25);
+
+    L04 = FIX_MULT_DCT(AAN_Q0_FIX, L04);
+    L04 -= L25;
+
+    L06 = FIX_MULT_DCT(AAN_Q1_FIX, L06);
+    L06 -= L25;
+
+    BUTTERFLY(L07, L05);
+
+    BUTTERFLY(L05, L04);
+    out[3] = (OI_INT16)SCALE(L04, DCTII_8_SHIFT_3-1);
+    out[5] = (OI_INT16)SCALE(L05, DCTII_8_SHIFT_5-1);
+
+    BUTTERFLY(L07, L06);
+    out[7] = (OI_INT16)SCALE(L06, DCTII_8_SHIFT_7-1);
+    out[1] = (OI_INT16)SCALE(L07, DCTII_8_SHIFT_1-1);
+#undef BUTTERFLY
+
+#ifdef DEBUG_DCT
+    {
+        float float_out[8];
+        float_dct2_8(float_out, in);
+    }
+#endif
+}
+
+/**@}*/

+ 510 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/decoder/srce/synthesis-sbc.c

@@ -0,0 +1,510 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2014 The Android Open Source Project
+ *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/**********************************************************************************
+  $Revision: #1 $
+***********************************************************************************/
+
+/** @file
+
+This file, along with synthesis-generated.c, contains the synthesis
+filterbank routines. The operations performed correspond to the
+operations described in A2DP Appendix B, Figure 12.3. Several
+mathematical optimizations are performed, particularly for the
+8-subband case.
+
+One important optimization is to note that the "matrixing" operation
+can be decomposed into the product of a type II discrete cosine kernel
+and another, sparse matrix.
+
+According to Fig 12.3, in the 8-subband case,
+@code
+    N[k][i] = cos((i+0.5)*(k+4)*pi/8), k = 0..15 and i = 0..7
+@endcode
+
+N can be factored as R * C2, where C2 is an 8-point type II discrete
+cosine kernel given by
+@code
+    C2[k][i] = cos((i+0.5)*k*pi/8)), k = 0..7 and i = 0..7
+@endcode
+
+R turns out to be a sparse 16x8 matrix with the following non-zero
+entries:
+@code
+    R[k][k+4]        =  1,   k = 0..3
+    R[k][abs(12-k)]  = -1,   k = 5..15
+@endcode
+
+The spec describes computing V[0..15] as N * R.
+@code
+    V[0..15] = N * R = (R * C2) * R = R * (C2 * R)
+@endcode
+
+C2 * R corresponds to computing the discrete cosine transform of R, so
+V[0..15] can be computed by taking the DCT of R followed by assignment
+and selective negation of the DCT result into V.
+
+        Although this was derived empirically using GNU Octave, it is
+        formally demonstrated in, e.g., Liu, Chi-Min and Lee,
+        Wen-Chieh. "A Unified Fast Algorithm for Cosine Modulated
+        Filter Banks in Current Audio Coding Standards." Journal of
+        the AES 47 (December 1999): 1061.
+
+Given the shift operation performed prior to computing V[0..15], it is
+clear that V[0..159] represents a rolling history of the 10 most
+recent groups of blocks input to the synthesis operation. Interpreting
+the matrix N in light of its factorization into C2 and R, R's
+sparseness has implications for interpreting the values in V. In
+particular, there is considerable redundancy in the values stored in
+V. Furthermore, since R[4][0..7] are all zeros, one out of every 16
+values in V will be zero regardless of the input data. Within each
+block of 16 values in V, fully half of them are redundant or
+irrelevant:
+
+@code
+    V[ 0] =  DCT[4]
+    V[ 1] =  DCT[5]
+    V[ 2] =  DCT[6]
+    V[ 3] =  DCT[7]
+    V[ 4] = 0
+    V[ 5] = -DCT[7] = -V[3] (redundant)
+    V[ 6] = -DCT[6] = -V[2] (redundant)
+    V[ 7] = -DCT[5] = -V[1] (redundant)
+    V[ 8] = -DCT[4] = -V[0] (redundant)
+    V[ 9] = -DCT[3]
+    V[10] = -DCT[2]
+    V[11] = -DCT[1]
+    V[12] = -DCT[0]
+    V[13] = -DCT[1] = V[11] (redundant)
+    V[14] = -DCT[2] = V[10] (redundant)
+    V[15] = -DCT[3] = V[ 9] (redundant)
+@endcode
+
+Since the elements of V beyond 15 were originally computed the same
+way during a previous run, what holds true for V[x] also holds true
+for V[x+16]. Thus, so long as care is taken to maintain the mapping,
+we need only actually store the unique values, which correspond to the
+output of the DCT, in some cases inverted. In fact, instead of storing
+V[0..159], we could store DCT[0..79] which would contain a history of
+DCT results. More on this in a bit.
+
+Going back to figure 12.3 in the spec, it should be clear that the
+vector U need not actually be explicitly constructed, but that with
+suitable indexing into V during the window operation, the same end can
+be accomplished. In the same spirit of the pseudocode shown in the
+figure, the following is the construction of W without using U:
+
+@code
+    for i=0 to 79 do
+        W[i] = D[i]*VSIGN(i)*V[remap_V(i)] where remap_V(i) = 32*(int(i/16)) + (i % 16) + (i % 16 >= 8 ? 16 : 0)
+                                             and VSIGN(i) maps i%16 into {1, 1, 1, 1, 0, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1 }
+                                             These values correspond to the
+                                             signs of the redundant values as
+                                             shown in the explanation three
+                                             paragraphs above.
+@endcode
+
+We saw above how V[4..8,13..15] (and by extension
+V[(4..8,13..15)+16*n]) can be defined in terms of other elements
+within the subblock of V. V[0..3,9..12] correspond to DCT elements.
+
+@code
+    for i=0 to 79 do
+        W[i] = D[i]*DSIGN(i)*DCT[remap_DCT(i)]
+@endcode
+
+The DCT is calculated using the Arai-Agui-Nakajima factorization,
+which saves some computation by producing output that needs to be
+multiplied by scaling factors before being used.
+
+@code
+    for i=0 to 79 do
+        W[i] = D[i]*SCALE[i%8]*AAN_DCT[remap_DCT(i)]
+@endcode
+
+D can be premultiplied with the DCT scaling factors to yield
+
+@code
+    for i=0 to 79 do
+        W[i] = DSCALED[i]*AAN_DCT[remap_DCT(i)] where DSCALED[i] = D[i]*SCALE[i%8]
+@endcode
+
+The output samples X[0..7] are defined as sums of W:
+
+@code
+        X[j] = sum{i=0..9}(W[j+8*i])
+@endcode
+
+@ingroup codec_internal
+*/
+
+/**
+@addtogroup codec_internal
+@{
+*/
+
+#include "oi_codec_sbc_private.h"
+
+const OI_INT32 dec_window_4[21] = {
+           0,        /* +0.00000000E+00 */
+          97,        /* +5.36548976E-04 */
+         270,        /* +1.49188357E-03 */
+         495,        /* +2.73370904E-03 */
+         694,        /* +3.83720193E-03 */
+         704,        /* +3.89205149E-03 */
+         338,        /* +1.86581691E-03 */
+        -554,        /* -3.06012286E-03 */
+        1974,        /* +1.09137620E-02 */
+        3697,        /* +2.04385087E-02 */
+        5224,        /* +2.88757392E-02 */
+        5824,        /* +3.21939290E-02 */
+        4681,        /* +2.58767811E-02 */
+        1109,        /* +6.13245186E-03 */
+       -5214,        /* -2.88217274E-02 */
+      -14047,        /* -7.76463494E-02 */
+       24529,        /* +1.35593274E-01 */
+       35274,        /* +1.94987841E-01 */
+       44618,        /* +2.46636662E-01 */
+       50984,        /* +2.81828203E-01 */
+       53243,        /* +2.94315332E-01 */
+};
+
+#define DCTII_4_K06_FIX ( 11585)/* S1.14      11585   0.707107*/
+
+#define DCTII_4_K08_FIX ( 21407)/* S1.14      21407   1.306563*/
+
+#define DCTII_4_K09_FIX (-15137)/* S1.14     -15137  -0.923880*/
+
+#define DCTII_4_K10_FIX ( -8867)/* S1.14      -8867  -0.541196*/
+
+/** Scales x by y bits to the right, adding a rounding factor.
+ */
+#ifndef SCALE
+#define SCALE(x, y) (((x) + (1 <<((y)-1))) >> (y))
+#endif
+
+#ifndef CLIP_INT16
+#define CLIP_INT16(x) do { if (x > OI_INT16_MAX) { x = OI_INT16_MAX; } else if (x < OI_INT16_MIN) { x = OI_INT16_MIN; } } while (0)
+#endif
+
+/**
+ * Default C language implementation of a 16x32->32 multiply. This function may
+ * be replaced by a platform-specific version for speed.
+ *
+ * @param u A signed 16-bit multiplicand
+ * @param v A signed 32-bit multiplier
+
+ * @return  A signed 32-bit value corresponding to the 32 most significant bits
+ * of the 48-bit product of u and v.
+ */
+INLINE OI_INT32 default_mul_16s_32s_hi(OI_INT16 u, OI_INT32 v)
+{
+    OI_UINT16 v0;
+    OI_INT16 v1;
+
+    OI_INT32 w,x;
+
+    v0 = (OI_UINT16)(v & 0xffff);
+    v1 = (OI_INT16) (v >> 16);
+
+    w = v1 * u;
+    x = u * v0;
+
+    return w + (x >> 16);
+}
+
+#define MUL_16S_32S_HI(_x, _y) default_mul_16s_32s_hi(_x, _y)
+
+#define LONG_MULT_DCT(K, sample) (MUL_16S_32S_HI(K, sample)<<2)
+
+PRIVATE void SynthWindow80_generated(OI_INT16 *pcm, SBC_BUFFER_T const * RESTRICT buffer, OI_UINT strideShift);
+PRIVATE void SynthWindow112_generated(OI_INT16 *pcm, SBC_BUFFER_T const * RESTRICT buffer, OI_UINT strideShift);
+PRIVATE void dct2_8(SBC_BUFFER_T * RESTRICT out, OI_INT32 const * RESTRICT x);
+
+typedef void (*SYNTH_FRAME)(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount);
+
+#ifndef COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS
+#define COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(dest, src) do { shift_buffer(dest, src, 72); } while (0)
+#endif
+
+#ifndef DCT2_8
+#define DCT2_8(dst, src) dct2_8(dst, src)
+#endif
+
+#ifndef SYNTH80
+#define SYNTH80 SynthWindow80_generated
+#endif
+
+#ifndef SYNTH112
+#define SYNTH112 SynthWindow112_generated
+#endif
+
+PRIVATE void OI_SBC_SynthFrame_80(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount)
+{
+    OI_UINT blk;
+    OI_UINT ch;
+    OI_UINT nrof_channels = context->common.frameInfo.nrof_channels;
+    OI_UINT pcmStrideShift = context->common.pcmStride == 1 ? 0 : 1;
+    OI_UINT offset = context->common.filterBufferOffset;
+    OI_INT32 *s = context->common.subdata + 8 * nrof_channels * blkstart;
+    OI_UINT blkstop = blkstart + blkcount;
+
+    for (blk = blkstart; blk < blkstop; blk++) {
+        if (offset == 0) {
+            COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(context->common.filterBuffer[0] + context->common.filterBufferLen - 72, context->common.filterBuffer[0]);
+            if (nrof_channels == 2) {
+                COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(context->common.filterBuffer[1] + context->common.filterBufferLen - 72, context->common.filterBuffer[1]);
+            }
+            offset = context->common.filterBufferLen - 80;
+        } else {
+            offset -= 1*8;
+        }
+
+        for (ch = 0; ch < nrof_channels; ch++) {
+            DCT2_8(context->common.filterBuffer[ch] + offset, s);
+            SYNTH80(pcm + ch, context->common.filterBuffer[ch] + offset, pcmStrideShift);
+            s += 8;
+        }
+        pcm += (8 << pcmStrideShift);
+    }
+    context->common.filterBufferOffset = offset;
+}
+
+PRIVATE void OI_SBC_SynthFrame_4SB(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount)
+{
+    OI_UINT blk;
+    OI_UINT ch;
+    OI_UINT nrof_channels = context->common.frameInfo.nrof_channels;
+    OI_UINT pcmStrideShift = context->common.pcmStride == 1 ? 0 : 1;
+    OI_UINT offset = context->common.filterBufferOffset;
+    OI_INT32 *s = context->common.subdata + 8 * nrof_channels * blkstart;
+    OI_UINT blkstop = blkstart + blkcount;
+
+    for (blk = blkstart; blk < blkstop; blk++) {
+        if (offset == 0) {
+            COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(context->common.filterBuffer[0] + context->common.filterBufferLen - 72,context->common.filterBuffer[0]);
+            if (nrof_channels == 2) {
+                COPY_BACKWARD_32BIT_ALIGNED_72_HALFWORDS(context->common.filterBuffer[1] + context->common.filterBufferLen - 72,context->common.filterBuffer[1]);
+            }
+            offset =context->common.filterBufferLen - 80;
+        } else {
+            offset -= 8;
+        }
+        for (ch = 0; ch < nrof_channels; ch++) {
+            cosineModulateSynth4(context->common.filterBuffer[ch] + offset, s);
+            SynthWindow40_int32_int32_symmetry_with_sum(pcm + ch,
+                                                        context->common.filterBuffer[ch] + offset,
+                                                        pcmStrideShift);
+            s += 4;
+        }
+        pcm += (4 << pcmStrideShift);
+    }
+    context->common.filterBufferOffset = offset;
+}
+
+#ifdef SBC_ENHANCED
+
+PRIVATE void OI_SBC_SynthFrame_Enhanced(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT blkstart, OI_UINT blkcount)
+{
+    OI_UINT blk;
+    OI_UINT ch;
+    OI_UINT nrof_channels = context->common.frameInfo.nrof_channels;
+    OI_UINT pcmStrideShift = context->common.pcmStride == 1 ? 0 : 1;
+    OI_UINT offset = context->common.filterBufferOffset;
+    OI_INT32 *s = context->common.subdata + 8 * nrof_channels * blkstart;
+    OI_UINT blkstop = blkstart + blkcount;
+
+    for (blk = blkstart; blk < blkstop; blk++) {
+        if (offset == 0) {
+            COPY_BACKWARD_32BIT_ALIGNED_104_HALFWORDS(context->common.filterBuffer[0] +context->common.filterBufferLen - 104, context->common.filterBuffer[0]);
+            if (nrof_channels == 2) {
+                COPY_BACKWARD_32BIT_ALIGNED_104_HALFWORDS(context->common.filterBuffer[1] + context->common.filterBufferLen - 104, context->common.filterBuffer[1]);
+            }
+            offset = context->common.filterBufferLen - 112;
+        } else {
+            offset -= 8;
+        }
+        for (ch = 0; ch < nrof_channels; ++ch) {
+            DCT2_8(context->common.filterBuffer[ch] + offset, s);
+            SYNTH112(pcm + ch, context->common.filterBuffer[ch] + offset, pcmStrideShift);
+            s += 8;
+        }
+        pcm += (8 << pcmStrideShift);
+    }
+    context->common.filterBufferOffset = offset;
+}
+
+static const SYNTH_FRAME SynthFrameEnhanced[] = {
+    NULL,                       /* invalid */
+    OI_SBC_SynthFrame_Enhanced, /* mono */
+    OI_SBC_SynthFrame_Enhanced  /* stereo */
+};
+
+#endif
+
+static const SYNTH_FRAME SynthFrame8SB[] = {
+    NULL,             /* invalid */
+    OI_SBC_SynthFrame_80, /* mono */
+    OI_SBC_SynthFrame_80  /* stereo */
+};
+
+
+static const SYNTH_FRAME SynthFrame4SB[] = {
+    NULL,                  /* invalid */
+    OI_SBC_SynthFrame_4SB, /* mono */
+    OI_SBC_SynthFrame_4SB  /* stereo */
+};
+
+PRIVATE void OI_SBC_SynthFrame(OI_CODEC_SBC_DECODER_CONTEXT *context, OI_INT16 *pcm, OI_UINT start_block, OI_UINT nrof_blocks)
+{
+    OI_UINT nrof_subbands = context->common.frameInfo.nrof_subbands;
+    OI_UINT nrof_channels = context->common.frameInfo.nrof_channels;
+
+    OI_ASSERT(nrof_subbands == 4 || nrof_subbands == 8);
+    if (nrof_subbands == 4) {
+        SynthFrame4SB[nrof_channels](context, pcm, start_block, nrof_blocks);
+#ifdef SBC_ENHANCED
+    } else if (context->common.frameInfo.enhanced) {
+        SynthFrameEnhanced[nrof_channels](context, pcm, start_block, nrof_blocks);
+#endif /* SBC_ENHANCED */
+        } else {
+        SynthFrame8SB[nrof_channels](context, pcm, start_block, nrof_blocks);
+    }
+}
+
+
+void SynthWindow40_int32_int32_symmetry_with_sum(OI_INT16 *pcm, SBC_BUFFER_T buffer[80], OI_UINT strideShift)
+{
+    OI_INT32 pa;
+    OI_INT32 pb;
+
+    /* These values should be zero, since out[2] of the 4-band cosine modulation
+     * is always zero. */
+    OI_ASSERT(buffer[ 2] == 0);
+    OI_ASSERT(buffer[10] == 0);
+    OI_ASSERT(buffer[18] == 0);
+    OI_ASSERT(buffer[26] == 0);
+    OI_ASSERT(buffer[34] == 0);
+    OI_ASSERT(buffer[42] == 0);
+    OI_ASSERT(buffer[50] == 0);
+    OI_ASSERT(buffer[58] == 0);
+    OI_ASSERT(buffer[66] == 0);
+    OI_ASSERT(buffer[74] == 0);
+
+
+    pa  = dec_window_4[ 4] * (buffer[12] + buffer[76]);
+    pa += dec_window_4[ 8] * (buffer[16] - buffer[64]);
+    pa += dec_window_4[12] * (buffer[28] + buffer[60]);
+    pa += dec_window_4[16] * (buffer[32] - buffer[48]);
+    pa += dec_window_4[20] *  buffer[44];
+    pa = SCALE(-pa, 15);
+    CLIP_INT16(pa);
+    pcm[0 << strideShift] = (OI_INT16)pa;
+
+
+    pa  = dec_window_4[ 1] * buffer[ 1]; pb  = dec_window_4[ 1] * buffer[79];
+    pb += dec_window_4[ 3] * buffer[ 3]; pa += dec_window_4[ 3] * buffer[77];
+    pa += dec_window_4[ 5] * buffer[13]; pb += dec_window_4[ 5] * buffer[67];
+    pb += dec_window_4[ 7] * buffer[15]; pa += dec_window_4[ 7] * buffer[65];
+    pa += dec_window_4[ 9] * buffer[17]; pb += dec_window_4[ 9] * buffer[63];
+    pb += dec_window_4[11] * buffer[19]; pa += dec_window_4[11] * buffer[61];
+    pa += dec_window_4[13] * buffer[29]; pb += dec_window_4[13] * buffer[51];
+    pb += dec_window_4[15] * buffer[31]; pa += dec_window_4[15] * buffer[49];
+    pa += dec_window_4[17] * buffer[33]; pb += dec_window_4[17] * buffer[47];
+    pb += dec_window_4[19] * buffer[35]; pa += dec_window_4[19] * buffer[45];
+    pa = SCALE(-pa, 15);
+    CLIP_INT16(pa);
+    pcm[1 << strideShift] = (OI_INT16)(pa);
+    pb = SCALE(-pb, 15);
+    CLIP_INT16(pb);
+    pcm[3 << strideShift] = (OI_INT16)(pb);
+
+
+    pa  = dec_window_4[2] * (/*buffer[ 2] + */ buffer[78]);  /* buffer[ 2] is always zero */
+    pa += dec_window_4[6] * (buffer[14] /* + buffer[66]*/);  /* buffer[66] is always zero */
+    pa += dec_window_4[10] * (/*buffer[18] + */ buffer[62]);  /* buffer[18] is always zero */
+    pa += dec_window_4[14] * (buffer[30] /* + buffer[50]*/);  /* buffer[50] is always zero */
+    pa += dec_window_4[18] * (/*buffer[34] + */ buffer[46]);  /* buffer[34] is always zero */
+    pa = SCALE(-pa, 15);
+    CLIP_INT16(pa);
+    pcm[2 << strideShift] = (OI_INT16)(pa);
+}
+
+
+/**
+  This routine implements the cosine modulation matrix for 4-subband
+  synthesis. This is called "matrixing" in the SBC specification. This
+  matrix, M4,  can be factored into an 8-point Type II Discrete Cosine
+  Transform, DCTII_4 and a matrix S4, given here:
+
+  @code
+        __               __
+       |   0   0   1   0   |
+       |   0   0   0   1   |
+       |   0   0   0   0   |
+       |   0   0   0  -1   |
+  S4 = |   0   0  -1   0   |
+       |   0  -1   0   0   |
+       |  -1   0   0   0   |
+       |__ 0  -1   0   0 __|
+
+  M4 * in = S4 * (DCTII_4 * in)
+  @endcode
+
+  (DCTII_4 * in) is computed using a Fast Cosine Transform. The algorithm
+  here is based on an implementation computed by the SPIRAL computer
+  algebra system, manually converted to fixed-point arithmetic. S4 can be
+  implemented using only assignment and negation.
+  */
+PRIVATE void cosineModulateSynth4(SBC_BUFFER_T * RESTRICT out, OI_INT32 const * RESTRICT in)
+{
+    OI_INT32 f0, f1, f2, f3, f4, f7, f8, f9, f10;
+    OI_INT32 y0, y1, y2, y3;
+
+    f0 = (in[0] - in[3]);
+    f1 = (in[0] + in[3]);
+    f2 = (in[1] - in[2]);
+    f3 = (in[1] + in[2]);
+
+    f4 = f1 - f3;
+
+    y0 = -SCALE(f1 + f3, DCT_SHIFT);
+    y2 = -SCALE(LONG_MULT_DCT(DCTII_4_K06_FIX, f4), DCT_SHIFT);
+    f7 = f0 + f2;
+    f8 = LONG_MULT_DCT(DCTII_4_K08_FIX, f0);
+    f9 = LONG_MULT_DCT(DCTII_4_K09_FIX, f7);
+    f10 = LONG_MULT_DCT(DCTII_4_K10_FIX, f2);
+    y3 = -SCALE(f8 + f9, DCT_SHIFT);
+    y1 = -SCALE(f10 - f9, DCT_SHIFT);
+
+    out[0] = (OI_INT16)-y2;
+    out[1] = (OI_INT16)-y3;
+    out[2] = (OI_INT16)0;
+    out[3] = (OI_INT16)y3;
+    out[4] = (OI_INT16)y2;
+    out[5] = (OI_INT16)y1;
+    out[6] = (OI_INT16)y0;
+    out[7] = (OI_INT16)y1;
+}
+
+
+
+/**
+@}
+*/

+ 91 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/include/sbc_dct.h

@@ -0,0 +1,91 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Definitions for the fast DCT.
+ *
+ ******************************************************************************/
+
+#ifndef SBC_DCT_H
+#define SBC_DCT_H
+
+#if (SBC_ARM_ASM_OPT==TRUE)
+#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1, s32OutLow)					\
+{																			    \
+    __asm																		\
+{																				\
+    MUL s32OutLow,(SINT32)s16In2, (s32In1>>15)        \
+}																				\
+}
+#else
+#if (SBC_DSP_OPT==TRUE)
+#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) s32OutLow = SBC_Multiply_32_16_Simplified((SINT32)s16In2,s32In1);
+#else
+#if (SBC_IPAQ_OPT==TRUE)
+/*#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) s32OutLow=(SINT32)((SINT32)(s16In2)*(SINT32)(s32In1>>15)); */
+#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow) s32OutLow=(SINT32)(((SINT64)s16In2*(SINT64)s32In1)>>15);
+#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
+#define SBC_MULT_32_32(s32In2, s32In1, s32OutLow)                           \
+{                                                                           \
+    s64Temp = ((SINT64) s32In2) * ((SINT64) s32In1)>>31;            \
+    s32OutLow = (SINT32) s64Temp;                                                    \
+}
+#endif
+#else
+#define SBC_MULT_32_16_SIMPLIFIED(s16In2, s32In1 , s32OutLow)                   \
+{                                                                               \
+    s32In1Temp = s32In1;                                                        \
+    s32In2Temp = (SINT32)s16In2;                                                \
+                                                                                \
+    /* Multiply one +ve and the other -ve number */                             \
+    if (s32In1Temp < 0)                                                         \
+    {                                                                           \
+        s32In1Temp ^= 0xFFFFFFFF;                                               \
+        s32In1Temp++;                                                           \
+        s32OutLow  = (s32In2Temp * (s32In1Temp >> 16));                         \
+        s32OutLow += (( s32In2Temp * (s32In1Temp & 0xFFFF)) >> 16);             \
+        s32OutLow ^= 0xFFFFFFFF;                                                \
+        s32OutLow++;                                                            \
+    }                                                                           \
+    else                                                                        \
+    {                                                                           \
+        s32OutLow  = (s32In2Temp * (s32In1Temp >> 16));                         \
+        s32OutLow += (( s32In2Temp * (s32In1Temp & 0xFFFF)) >> 16);             \
+    }                                                                           \
+    s32OutLow <<= 1;                                                            \
+}
+#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
+#define SBC_MULT_64(s32In1, s32In2, s32OutLow, s32OutHi)  \
+{\
+        s32OutLow=(SINT32)(((SINT64)s32In1*(SINT64)s32In2)& 0x00000000FFFFFFFF);\
+        s32OutHi=(SINT32)(((SINT64)s32In1*(SINT64)s32In2)>>32);\
+}
+#define SBC_MULT_32_32(s32In2, s32In1, s32OutLow)                           \
+{                                                                           \
+    s32HiTemp = 0;                                                          \
+    SBC_MULT_64(s32In2,s32In1 , s32OutLow, s32HiTemp);                      \
+    s32OutLow   = (((s32OutLow>>15)&0x1FFFF) | (s32HiTemp << 17));          \
+}
+#endif
+
+#endif
+#endif
+#endif
+
+#endif

+ 57 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/include/sbc_enc_func_declare.h

@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Function declarations.
+ *
+ ******************************************************************************/
+
+#ifndef SBC_FUNCDECLARE_H
+#define SBC_FUNCDECLARE_H
+
+/*#include "sbc_encoder.h"*/
+/* Global data */
+#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == FALSE)
+extern const SINT16 gas32CoeffFor4SBs[];
+extern const SINT16 gas32CoeffFor8SBs[];
+#else
+extern const SINT32 gas32CoeffFor4SBs[];
+extern const SINT32 gas32CoeffFor8SBs[];
+#endif
+
+/* Global functions*/
+
+extern void sbc_enc_bit_alloc_mono(SBC_ENC_PARAMS *CodecParams);
+extern void sbc_enc_bit_alloc_ste(SBC_ENC_PARAMS *CodecParams);
+
+extern void SbcAnalysisInit (void);
+
+extern void SbcAnalysisFilter4(SBC_ENC_PARAMS *strEncParams);
+extern void SbcAnalysisFilter8(SBC_ENC_PARAMS *strEncParams);
+
+extern void SBC_FastIDCT8 (SINT32 *pInVect, SINT32 *pOutVect);
+extern void SBC_FastIDCT4 (SINT32 *x0, SINT32 *pOutVect);
+
+extern void EncPacking(SBC_ENC_PARAMS *strEncParams);
+extern void EncQuantizer(SBC_ENC_PARAMS *);
+#if (SBC_DSP_OPT==TRUE)
+    SINT32 SBC_Multiply_32_16_Simplified(SINT32 s32In2Temp,SINT32 s32In1Temp);
+#endif
+#endif
+

+ 202 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/include/sbc_encoder.h

@@ -0,0 +1,202 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains constants and structures used by Encoder.
+ *
+ ******************************************************************************/
+
+#ifndef SBC_ENCODER_H
+#define SBC_ENCODER_H
+
+#define ENCODER_VERSION "0025"
+
+#ifdef BUILDCFG
+    #include "bt_target.h"
+#endif
+
+/*DEFINES*/
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+#define SBC_MAX_NUM_OF_SUBBANDS 8
+#define SBC_MAX_NUM_OF_CHANNELS 2
+#define SBC_MAX_NUM_OF_BLOCKS   16
+
+#define SBC_LOUDNESS    0
+#define SBC_SNR 1
+
+#define SUB_BANDS_8 8
+#define SUB_BANDS_4 4
+
+#define SBC_sf16000 0
+#define SBC_sf32000 1
+#define SBC_sf44100 2
+#define SBC_sf48000 3
+
+#define SBC_MONO    0
+#define SBC_DUAL    1
+#define SBC_STEREO  2
+#define SBC_JOINT_STEREO    3
+
+#define SBC_BLOCK_0 4
+#define SBC_BLOCK_1 8
+#define SBC_BLOCK_2 12
+#define SBC_BLOCK_3 16
+
+#define SBC_NULL    0
+
+#ifndef SBC_MAX_NUM_FRAME
+#define SBC_MAX_NUM_FRAME 1
+#endif
+
+#ifndef SBC_DSP_OPT
+#define SBC_DSP_OPT FALSE
+#endif
+
+/* Set SBC_USE_ARM_PRAGMA to TRUE to use "#pragma arm section zidata" */
+#ifndef SBC_USE_ARM_PRAGMA
+#define SBC_USE_ARM_PRAGMA FALSE
+#endif
+
+/* Set SBC_ARM_ASM_OPT to TRUE in case the target is an ARM */
+/* this will replace all the 32 and 64 bit mult by in line assembly code */
+#ifndef SBC_ARM_ASM_OPT
+#define SBC_ARM_ASM_OPT FALSE
+#endif
+
+/* green hill compiler option -> Used to distinguish the syntax for inline assembly code*/
+#ifndef SBC_GHS_COMPILER
+#define SBC_GHS_COMPILER FALSE
+#endif
+
+/* ARM compiler option -> Used to distinguish the syntax for inline assembly code */
+#ifndef SBC_ARM_COMPILER
+#define SBC_ARM_COMPILER TRUE
+#endif
+
+/* Set SBC_IPAQ_OPT to TRUE in case the target is an ARM */
+/* 32 and 64 bit mult will be performed using SINT64 ( usualy __int64 ) cast that usualy give optimal performance if supported */
+#ifndef SBC_IPAQ_OPT
+#define SBC_IPAQ_OPT TRUE
+#endif
+
+/* Debug only: set SBC_IS_64_MULT_IN_WINDOW_ACCU to TRUE to use 64 bit multiplication in the windowing */
+/* -> not recomended, more MIPS for the same restitution.  */
+#ifndef SBC_IS_64_MULT_IN_WINDOW_ACCU
+#define SBC_IS_64_MULT_IN_WINDOW_ACCU  FALSE
+#endif /*SBC_IS_64_MULT_IN_WINDOW_ACCU */
+
+/* Set SBC_IS_64_MULT_IN_IDCT to TRUE to use 64 bits multiplication in the DCT of Matrixing */
+/* -> more MIPS required for a better audio quality. comparasion with the SIG utilities shows a division by 10 of the RMS */
+/* CAUTION: It only apply in the if SBC_FAST_DCT is set to TRUE */
+#ifndef SBC_IS_64_MULT_IN_IDCT
+#define SBC_IS_64_MULT_IN_IDCT  FALSE
+#endif /*SBC_IS_64_MULT_IN_IDCT */
+
+/* set SBC_IS_64_MULT_IN_QUANTIZER to TRUE to use 64 bits multiplication in the quantizer */
+/* setting this flag to FALSE add whistling noise at 5.5 and 11 KHz usualy not perceptible by human's hears. */
+#ifndef SBC_IS_64_MULT_IN_QUANTIZER
+#define SBC_IS_64_MULT_IN_QUANTIZER  TRUE
+#endif /*SBC_IS_64_MULT_IN_IDCT */
+
+/* Debug only: set this flag to FALSE to disable fast DCT algorithm */
+#ifndef SBC_FAST_DCT
+#define SBC_FAST_DCT  TRUE
+#endif /*SBC_FAST_DCT */
+
+/* In case we do not use joint stereo mode the flag save some RAM and ROM in case it is set to FALSE */
+#ifndef SBC_JOINT_STE_INCLUDED
+#define SBC_JOINT_STE_INCLUDED TRUE
+#endif
+
+/* TRUE -> application should provide PCM buffer, FALSE PCM buffer reside in SBC_ENC_PARAMS */
+#ifndef SBC_NO_PCM_CPY_OPTION
+#define SBC_NO_PCM_CPY_OPTION FALSE
+#endif
+
+#define MINIMUM_ENC_VX_BUFFER_SIZE (8*10*2)
+#ifndef ENC_VX_BUFFER_SIZE
+#define ENC_VX_BUFFER_SIZE (MINIMUM_ENC_VX_BUFFER_SIZE + 64)
+/*#define ENC_VX_BUFFER_SIZE MINIMUM_ENC_VX_BUFFER_SIZE + 1024*/
+#endif
+
+#ifndef SBC_FOR_EMBEDDED_LINUX
+#define SBC_FOR_EMBEDDED_LINUX FALSE
+#endif
+
+/*constants used for index calculation*/
+#define SBC_BLK (SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS)
+
+#include "sbc_types.h"
+
+typedef struct SBC_ENC_PARAMS_TAG
+{
+    SINT16 s16SamplingFreq;                         /* 16k, 32k, 44.1k or 48k*/
+    SINT16 s16ChannelMode;                          /* mono, dual, streo or joint streo*/
+    SINT16 s16NumOfSubBands;                        /* 4 or 8 */
+    SINT16 s16NumOfChannels;
+    SINT16 s16NumOfBlocks;                          /* 4, 8, 12 or 16*/
+    SINT16 s16AllocationMethod;                     /* loudness or SNR*/
+    SINT16 s16BitPool;                              /* 16*numOfSb for mono & dual;
+                                                       32*numOfSb for stereo & joint stereo */
+    UINT16 u16BitRate;
+    UINT8   u8NumPacketToEncode;                    /* number of sbc frame to encode. Default is 1 */
+#if (SBC_JOINT_STE_INCLUDED == TRUE)
+    SINT16 as16Join[SBC_MAX_NUM_OF_SUBBANDS];       /*1 if JS, 0 otherwise*/
+#endif
+
+    SINT16 s16MaxBitNeed;
+    SINT16 as16ScaleFactor[SBC_MAX_NUM_OF_CHANNELS*SBC_MAX_NUM_OF_SUBBANDS];
+
+    SINT16 *ps16NextPcmBuffer;
+#if (SBC_NO_PCM_CPY_OPTION == TRUE)
+    SINT16 *ps16PcmBuffer;
+#else
+    SINT16 as16PcmBuffer[SBC_MAX_NUM_FRAME*SBC_MAX_NUM_OF_BLOCKS * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS];
+#endif
+
+    SINT16  s16ScartchMemForBitAlloc[16];
+
+    SINT32  s32SbBuffer[SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * SBC_MAX_NUM_OF_BLOCKS];
+
+    SINT16 as16Bits[SBC_MAX_NUM_OF_CHANNELS*SBC_MAX_NUM_OF_SUBBANDS];
+
+    UINT8  *pu8Packet;
+    UINT8  *pu8NextPacket;
+    UINT16 FrameHeader;
+    UINT16 u16PacketLength;
+
+}SBC_ENC_PARAMS;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+extern void SBC_Encoder(SBC_ENC_PARAMS *strEncParams);
+extern void SBC_Encoder_Init(SBC_ENC_PARAMS *strEncParams);
+#ifdef __cplusplus
+}
+#endif
+#endif

+ 47 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/include/sbc_if.h

@@ -0,0 +1,47 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+#ifndef _SBC_IF_H
+#define _SBC_IF_H
+
+#define PCM_BUFFER_SIZE 512
+
+/*
+ SBC_Init - called once for each track played
+
+ pcm_sample_freq - 4000 to 48000
+ channels - 1 mono 2 stereo
+ bits_per_sample - 8 or 16
+ return - 0 sucess
+*/
+
+int SBC_init(int pcm_sample_freq, int channels, int bits_per_sample);
+
+/*
+ SBC_write - called repeatedly with pcm_in pointer
+	increasing by length until track is finished.
+
+ pcm_in - pointer to PCM buffer
+ length - any
+ sbc_out - pointer to SBC output buffer
+ return - number of bytes written to sbc_out
+*/
+
+int SBC_write(unsigned char *pcm_in, int length, unsigned char *sbc_out);
+
+#endif

+ 59 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/include/sbc_types.h

@@ -0,0 +1,59 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  Data type declarations.
+ *
+ ******************************************************************************/
+
+#ifndef SBC_TYPES_H
+#define SBC_TYPES_H
+
+#include <stdint.h>
+
+#ifdef BUILDCFG
+#include "bt_target.h"
+#endif
+
+#include "bt_types.h"
+
+typedef short SINT16;
+typedef long SINT32;
+
+#if (SBC_IPAQ_OPT == TRUE)
+
+#if (SBC_FOR_EMBEDDED_LINUX == TRUE)
+typedef long long SINT64;
+#else
+typedef int64_t SINT64;
+#endif
+
+#elif (SBC_IS_64_MULT_IN_WINDOW_ACCU == TRUE) || (SBC_IS_64_MULT_IN_IDCT == TRUE)
+
+#if (SBC_FOR_EMBEDDED_LINUX == TRUE)
+typedef long long SINT64;
+#else
+typedef int64_t SINT64;
+#endif
+
+#endif
+
+#define abs32(x) ( (x >= 0) ? x : (-x) )
+
+#endif

+ 1107 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_analysis.c

@@ -0,0 +1,1107 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the code that performs Analysis of the input audio
+ *  stream.
+ *
+ ******************************************************************************/
+#include <string.h>
+#include "sbc_encoder.h"
+#include "sbc_enc_func_declare.h"
+/*#include <math.h>*/
+
+#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == TRUE)
+#define WIND_4_SUBBANDS_0_1 (SINT32)0x01659F45  /* gas32CoeffFor4SBs[8] = -gas32CoeffFor4SBs[32] = 0x01659F45 */
+#define WIND_4_SUBBANDS_0_2 (SINT32)0x115B1ED2  /* gas32CoeffFor4SBs[16] = -gas32CoeffFor4SBs[24] = 0x115B1ED2 */
+#define WIND_4_SUBBANDS_1_0 (SINT32)0x001194E6  /* gas32CoeffFor4SBs[1 et 39] = 0x001194E6 */
+#define WIND_4_SUBBANDS_1_1 (SINT32)0x029DBAA3  /* gas32CoeffFor4SBs[9 et 31] = 0x029DBAA3 */
+#define WIND_4_SUBBANDS_1_2 (SINT32)0x18F55C90  /* gas32CoeffFor4SBs[17 et 23] = 0x18F55C90 */
+#define WIND_4_SUBBANDS_1_3 (SINT32)0xF60FAF37  /* gas32CoeffFor4SBs[15 et 25] = 0xF60FAF37 */
+#define WIND_4_SUBBANDS_1_4 (SINT32)0xFF9BB9D5  /* gas32CoeffFor4SBs[7 et 33] = 0xFF9BB9D5 */
+#define WIND_4_SUBBANDS_2_0 (SINT32)0x0030E2D3  /* gas32CoeffFor4SBs[2 et 38] = 0x0030E2D3 */
+#define WIND_4_SUBBANDS_2_1 (SINT32)0x03B23341  /* gas32CoeffFor4SBs[10 et 30] = 0x03B23341 */
+#define WIND_4_SUBBANDS_2_2 (SINT32)0x1F91CA46  /* gas32CoeffFor4SBs[18 et 22] = 0x1F91CA46 */
+#define WIND_4_SUBBANDS_2_3 (SINT32)0xFC4F91D4  /* gas32CoeffFor4SBs[14 et 26] = 0xFC4F91D4 */
+#define WIND_4_SUBBANDS_2_4 (SINT32)0x003D239B  /* gas32CoeffFor4SBs[6 et 34] = 0x003D239B */
+#define WIND_4_SUBBANDS_3_0 (SINT32)0x00599403  /* gas32CoeffFor4SBs[3 et 37] = 0x00599403 */
+#define WIND_4_SUBBANDS_3_1 (SINT32)0x041EEE40  /* gas32CoeffFor4SBs[11 et 29] = 0x041EEE40 */
+#define WIND_4_SUBBANDS_3_2 (SINT32)0x2412F251  /* gas32CoeffFor4SBs[19 et 21] = 0x2412F251 */
+#define WIND_4_SUBBANDS_3_3 (SINT32)0x00C8F2BC  /* gas32CoeffFor4SBs[13 et 27] = 0x00C8F2BC */
+#define WIND_4_SUBBANDS_3_4 (SINT32)0x007F88E4  /* gas32CoeffFor4SBs[5 et 35] = 0x007F88E4 */
+#define WIND_4_SUBBANDS_4_0 (SINT32)0x007DBCC8  /* gas32CoeffFor4SBs[4 et 36] = 0x007DBCC8 */
+#define WIND_4_SUBBANDS_4_1 (SINT32)0x034FEE2C  /* gas32CoeffFor4SBs[12 et 28] = 0x034FEE2C */
+#define WIND_4_SUBBANDS_4_2 (SINT32)0x25AC1FF2  /* gas32CoeffFor4SBs[20] = 0x25AC1FF2 */
+
+#define WIND_8_SUBBANDS_0_1 (SINT32)0x00B97348  /* 16 0x00B97348 */
+#define WIND_8_SUBBANDS_0_2 (SINT32)0x08B4307A  /* 32 0x08B4307A */
+#define WIND_8_SUBBANDS_1_0 (SINT32)0x00052173  /* 1 et 79 = 0x00052173 */
+#define WIND_8_SUBBANDS_1_1 (SINT32)0x01071B96  /* 17 et 63 = 0x01071B96 */
+#define WIND_8_SUBBANDS_1_2 (SINT32)0x0A9F3E9A  /* 33 et 47 = 0x0A9F3E9A*/
+#define WIND_8_SUBBANDS_1_3 (SINT32)0xF9312891  /* 31 et 49 = 0xF9312891 */
+#define WIND_8_SUBBANDS_1_4 (SINT32)0xFF8D6793  /* 15 et 65 = 0xFF8D6793 */
+#define WIND_8_SUBBANDS_2_0 (SINT32)0x000B3F71  /* 2 et 78 = 0x000B3F71 */
+#define WIND_8_SUBBANDS_2_1 (SINT32)0x0156B3CA  /* 18 et 62 = 0x0156B3CA */
+#define WIND_8_SUBBANDS_2_2 (SINT32)0x0C7D59B6  /* 34 et 46 = 0x0C7D59B6 */
+#define WIND_8_SUBBANDS_2_3 (SINT32)0xFAFF95FC  /* 30 et 50 = 0xFAFF95FC */
+#define WIND_8_SUBBANDS_2_4 (SINT32)0xFFC9F10E  /* 14 et 66 = 0xFFC9F10E */
+#define WIND_8_SUBBANDS_3_0 (SINT32)0x00122C7D  /* 3 et 77 = 0x00122C7D*/
+#define WIND_8_SUBBANDS_3_1 (SINT32)0x01A1B38B  /* 19 et 61 = 0x01A1B38B */
+#define WIND_8_SUBBANDS_3_2 (SINT32)0x0E3BB16F  /* 35 et 45 = 0x0E3BB16F */
+#define WIND_8_SUBBANDS_3_3 (SINT32)0xFCA86E7E  /* 29 et 51 = 0xFCA86E7E */
+#define WIND_8_SUBBANDS_3_4 (SINT32)0xFFFA2413  /* 13 et 67 = 0xFFFA2413 */
+#define WIND_8_SUBBANDS_4_0 (SINT32)0x001AFF89  /* 4 et 66 = 0x001AFF89 */
+#define WIND_8_SUBBANDS_4_1 (SINT32)0x01E0224C  /* 20 et 60 = 0x01E0224C */
+#define WIND_8_SUBBANDS_4_2 (SINT32)0x0FC721F9  /* 36 et 44 = 0x0FC721F9 */
+#define WIND_8_SUBBANDS_4_3 (SINT32)0xFE20435D  /* 28 et 52 = 0xFE20435D */
+#define WIND_8_SUBBANDS_4_4 (SINT32)0x001D8FD2  /* 12 et 68 = 0x001D8FD2 */
+#define WIND_8_SUBBANDS_5_0 (SINT32)0x00255A62  /* 5 et 75 = 0x00255A62 */
+#define WIND_8_SUBBANDS_5_1 (SINT32)0x0209291F  /* 21 et 59 = 0x0209291F */
+#define WIND_8_SUBBANDS_5_2 (SINT32)0x110ECEF0  /* 37 et 43 = 0x110ECEF0 */
+#define WIND_8_SUBBANDS_5_3 (SINT32)0xFF5EEB73  /* 27 et  53 = 0xFF5EEB73 */
+#define WIND_8_SUBBANDS_5_4 (SINT32)0x0034F8B6  /* 11 et 69 = 0x0034F8B6 */
+#define WIND_8_SUBBANDS_6_0 (SINT32)0x003060F4  /* 6 et 74 = 0x003060F4 */
+#define WIND_8_SUBBANDS_6_1 (SINT32)0x02138653  /* 22 et 58 = 0x02138653 */
+#define WIND_8_SUBBANDS_6_2 (SINT32)0x120435FA  /* 38 et 42 = 0x120435FA */
+#define WIND_8_SUBBANDS_6_3 (SINT32)0x005FD0FF  /* 26 et 54 = 0x005FD0FF */
+#define WIND_8_SUBBANDS_6_4 (SINT32)0x00415B75  /* 10 et 70 = 0x00415B75 */
+#define WIND_8_SUBBANDS_7_0 (SINT32)0x003A72E7  /* 7 et 73 = 0x003A72E7 */
+#define WIND_8_SUBBANDS_7_1 (SINT32)0x01F5F424  /* 23 et 57 = 0x01F5F424 */
+#define WIND_8_SUBBANDS_7_2 (SINT32)0x129C226F  /* 39 et 41 = 0x129C226F */
+#define WIND_8_SUBBANDS_7_3 (SINT32)0x01223EBA  /* 25 et 55 = 0x01223EBA */
+#define WIND_8_SUBBANDS_7_4 (SINT32)0x0044EF48  /* 9 et 71 = 0x0044EF48 */
+#define WIND_8_SUBBANDS_8_0 (SINT32)0x0041EC6A  /* 8 et 72 = 0x0041EC6A */
+#define WIND_8_SUBBANDS_8_1 (SINT32)0x01A7ECEF  /* 24 et 56 = 0x01A7ECEF */
+#define WIND_8_SUBBANDS_8_2 (SINT32)0x12CF6C75  /* 40 = 0x12CF6C75 */
+#else
+#define WIND_4_SUBBANDS_0_1 (SINT16)0x0166  /* gas32CoeffFor4SBs[8] = -gas32CoeffFor4SBs[32] = 0x01659F45 */
+#define WIND_4_SUBBANDS_0_2 (SINT16)0x115B  /* gas32CoeffFor4SBs[16] = -gas32CoeffFor4SBs[24] = 0x115B1ED2 */
+#define WIND_4_SUBBANDS_1_0 (SINT16)0x0012  /* gas32CoeffFor4SBs[1 et 39] = 0x001194E6 */
+#define WIND_4_SUBBANDS_1_1 (SINT16)0x029E  /* gas32CoeffFor4SBs[9 et 31] = 0x029DBAA3 */
+#define WIND_4_SUBBANDS_1_2 (SINT16)0x18F5  /* gas32CoeffFor4SBs[17 et 23] = 0x18F55C90 */
+#define WIND_4_SUBBANDS_1_3 (SINT16)0xF610  /* gas32CoeffFor4SBs[15 et 25] = 0xF60FAF37 */
+#define WIND_4_SUBBANDS_1_4 (SINT16)0xFF9C  /* gas32CoeffFor4SBs[7 et 33] = 0xFF9BB9D5 */
+#define WIND_4_SUBBANDS_2_0 (SINT16)0x0031  /* gas32CoeffFor4SBs[2 et 38] = 0x0030E2D3 */
+#define WIND_4_SUBBANDS_2_1 (SINT16)0x03B2  /* gas32CoeffFor4SBs[10 et 30] = 0x03B23341 */
+#define WIND_4_SUBBANDS_2_2 (SINT16)0x1F91  /* gas32CoeffFor4SBs[18 et 22] = 0x1F91CA46 */
+#define WIND_4_SUBBANDS_2_3 (SINT16)0xFC50  /* gas32CoeffFor4SBs[14 et 26] = 0xFC4F91D4 */
+#define WIND_4_SUBBANDS_2_4 (SINT16)0x003D  /* gas32CoeffFor4SBs[6 et 34] = 0x003D239B */
+#define WIND_4_SUBBANDS_3_0 (SINT16)0x005A  /* gas32CoeffFor4SBs[3 et 37] = 0x00599403 */
+#define WIND_4_SUBBANDS_3_1 (SINT16)0x041F  /* gas32CoeffFor4SBs[11 et 29] = 0x041EEE40 */
+#define WIND_4_SUBBANDS_3_2 (SINT16)0x2413  /* gas32CoeffFor4SBs[19 et 21] = 0x2412F251 */
+#define WIND_4_SUBBANDS_3_3 (SINT16)0x00C9  /* gas32CoeffFor4SBs[13 et 27] = 0x00C8F2BC */
+#define WIND_4_SUBBANDS_3_4 (SINT16)0x0080  /* gas32CoeffFor4SBs[5 et 35] = 0x007F88E4 */
+#define WIND_4_SUBBANDS_4_0 (SINT16)0x007E  /* gas32CoeffFor4SBs[4 et 36] = 0x007DBCC8 */
+#define WIND_4_SUBBANDS_4_1 (SINT16)0x0350  /* gas32CoeffFor4SBs[12 et 28] = 0x034FEE2C */
+#define WIND_4_SUBBANDS_4_2 (SINT16)0x25AC  /* gas32CoeffFor4SBs[20] = 25AC1FF2 */
+
+#define WIND_8_SUBBANDS_0_1 (SINT16)0x00B9  /* 16 0x12CF6C75 */
+#define WIND_8_SUBBANDS_0_2 (SINT16)0x08B4  /* 32 0x08B4307A */
+#define WIND_8_SUBBANDS_1_0 (SINT16)0x0005  /* 1 et 79 = 0x00052173 */
+#define WIND_8_SUBBANDS_1_1 (SINT16)0x0107  /* 17 et 63 = 0x01071B96 */
+#define WIND_8_SUBBANDS_1_2 (SINT16)0x0A9F  /* 33 et 47 = 0x0A9F3E9A*/
+#define WIND_8_SUBBANDS_1_3 (SINT16)0xF931  /* 31 et 49 = 0xF9312891 */
+#define WIND_8_SUBBANDS_1_4 (SINT16)0xFF8D  /* 15 et 65 = 0xFF8D6793 */
+#define WIND_8_SUBBANDS_2_0 (SINT16)0x000B  /* 2 et 78 = 0x000B3F71 */
+#define WIND_8_SUBBANDS_2_1 (SINT16)0x0157  /* 18 et 62 = 0x0156B3CA */
+#define WIND_8_SUBBANDS_2_2 (SINT16)0x0C7D  /* 34 et 46 = 0x0C7D59B6 */
+#define WIND_8_SUBBANDS_2_3 (SINT16)0xFB00  /* 30 et 50 = 0xFAFF95FC */
+#define WIND_8_SUBBANDS_2_4 (SINT16)0xFFCA  /* 14 et 66 = 0xFFC9F10E */
+#define WIND_8_SUBBANDS_3_0 (SINT16)0x0012  /* 3 et 77 = 0x00122C7D*/
+#define WIND_8_SUBBANDS_3_1 (SINT16)0x01A2  /* 19 et 61 = 0x01A1B38B */
+#define WIND_8_SUBBANDS_3_2 (SINT16)0x0E3C  /* 35 et 45 = 0x0E3BB16F */
+#define WIND_8_SUBBANDS_3_3 (SINT16)0xFCA8  /* 29 et 51 = 0xFCA86E7E */
+#define WIND_8_SUBBANDS_3_4 (SINT16)0xFFFA  /* 13 et 67 = 0xFFFA2413 */
+#define WIND_8_SUBBANDS_4_0 (SINT16)0x001B  /* 4 et 66 = 0x001AFF89 */
+#define WIND_8_SUBBANDS_4_1 (SINT16)0x01E0  /* 20 et 60 = 0x01E0224C */
+#define WIND_8_SUBBANDS_4_2 (SINT16)0x0FC7  /* 36 et 44 = 0x0FC721F9 */
+#define WIND_8_SUBBANDS_4_3 (SINT16)0xFE20  /* 28 et 52 = 0xFE20435D */
+#define WIND_8_SUBBANDS_4_4 (SINT16)0x001E  /* 12 et 68 = 0x001D8FD2 */
+#define WIND_8_SUBBANDS_5_0 (SINT16)0x0025  /* 5 et 75 = 0x00255A62 */
+#define WIND_8_SUBBANDS_5_1 (SINT16)0x0209  /* 21 et 59 = 0x0209291F */
+#define WIND_8_SUBBANDS_5_2 (SINT16)0x110F  /* 37 et 43 = 0x110ECEF0 */
+#define WIND_8_SUBBANDS_5_3 (SINT16)0xFF5F  /* 27 et  53 = 0xFF5EEB73 */
+#define WIND_8_SUBBANDS_5_4 (SINT16)0x0035  /* 11 et 69 = 0x0034F8B6 */
+#define WIND_8_SUBBANDS_6_0 (SINT16)0x0030  /* 6 et 74 = 0x003060F4 */
+#define WIND_8_SUBBANDS_6_1 (SINT16)0x0214  /* 22 et 58 = 0x02138653 */
+#define WIND_8_SUBBANDS_6_2 (SINT16)0x1204  /* 38 et 42 = 0x120435FA */
+#define WIND_8_SUBBANDS_6_3 (SINT16)0x0060  /* 26 et 54 = 0x005FD0FF */
+#define WIND_8_SUBBANDS_6_4 (SINT16)0x0041  /* 10 et 70 = 0x00415B75 */
+#define WIND_8_SUBBANDS_7_0 (SINT16)0x003A  /* 7 et 73 = 0x003A72E7 */
+#define WIND_8_SUBBANDS_7_1 (SINT16)0x01F6  /* 23 et 57 = 0x01F5F424 */
+#define WIND_8_SUBBANDS_7_2 (SINT16)0x129C  /* 39 et 41 = 0x129C226F */
+#define WIND_8_SUBBANDS_7_3 (SINT16)0x0122  /* 25 et 55 = 0x01223EBA */
+#define WIND_8_SUBBANDS_7_4 (SINT16)0x0045  /* 9 et 71 = 0x0044EF48 */
+#define WIND_8_SUBBANDS_8_0 (SINT16)0x0042  /* 8 et 72 = 0x0041EC6A */
+#define WIND_8_SUBBANDS_8_1 (SINT16)0x01A8  /* 24 et 56 = 0x01A7ECEF */
+#define WIND_8_SUBBANDS_8_2 (SINT16)0x12CF  /* 40 = 0x12CF6C75 */
+#endif
+
+#if (SBC_USE_ARM_PRAGMA==TRUE)
+#pragma arm section zidata = "sbc_s32_analysis_section"
+#endif
+static SINT32   s32DCTY[16]  = {0};
+static SINT32   s32X[ENC_VX_BUFFER_SIZE/2];
+static SINT16   *s16X=(SINT16*) s32X;      /* s16X must be 32 bits aligned cf  SHIFTUP_X8_2*/
+#if (SBC_USE_ARM_PRAGMA==TRUE)
+#pragma arm section zidata
+#endif
+
+/* This macro is for 4 subbands */
+#define SHIFTUP_X4                                                               \
+{                                                                                   \
+    ps32X=(SINT32 *)(s16X+EncMaxShiftCounter+38);                                 \
+    for (i=0;i<9;i++)                                                               \
+    {                                                                               \
+        *ps32X=*(ps32X-2-(ShiftCounter>>1));  ps32X--;                                 \
+        *ps32X=*(ps32X-2-(ShiftCounter>>1));  ps32X--;                                 \
+    }                                                                               \
+}
+#define SHIFTUP_X4_2                                                              \
+{                                                                                   \
+    ps32X=(SINT32 *)(s16X+EncMaxShiftCounter+38);                                   \
+    ps32X2=(SINT32 *)(s16X+(EncMaxShiftCounter<<1)+78);                             \
+    for (i=0;i<9;i++)                                                               \
+    {                                                                               \
+        *ps32X=*(ps32X-2-(ShiftCounter>>1));  *(ps32X2)=*(ps32X2-2-(ShiftCounter>>1)); ps32X--;  ps32X2--;                     \
+        *ps32X=*(ps32X-2-(ShiftCounter>>1));  *(ps32X2)=*(ps32X2-2-(ShiftCounter>>1)); ps32X--;  ps32X2--;                     \
+    }                                                                               \
+}
+
+/* This macro is for 8 subbands */
+#define SHIFTUP_X8                                                               \
+{                                                                                   \
+    ps32X=(SINT32 *)(s16X+EncMaxShiftCounter+78);                                 \
+    for (i=0;i<9;i++)                                                               \
+    {                                                                               \
+        *ps32X=*(ps32X-4-(ShiftCounter>>1));  ps32X--;                                 \
+        *ps32X=*(ps32X-4-(ShiftCounter>>1));  ps32X--;                                 \
+        *ps32X=*(ps32X-4-(ShiftCounter>>1));  ps32X--;                                 \
+        *ps32X=*(ps32X-4-(ShiftCounter>>1));  ps32X--;                                 \
+    }                                                                               \
+}
+#define SHIFTUP_X8_2                                                               \
+{                                                                                   \
+    ps32X=(SINT32 *)(s16X+EncMaxShiftCounter+78);                                   \
+    ps32X2=(SINT32 *)(s16X+(EncMaxShiftCounter<<1)+158);                             \
+    for (i=0;i<9;i++)                                                               \
+    {                                                                               \
+        *ps32X=*(ps32X-4-(ShiftCounter>>1));  *(ps32X2)=*(ps32X2-4-(ShiftCounter>>1)); ps32X--;  ps32X2--;                     \
+        *ps32X=*(ps32X-4-(ShiftCounter>>1));  *(ps32X2)=*(ps32X2-4-(ShiftCounter>>1)); ps32X--;  ps32X2--;                     \
+        *ps32X=*(ps32X-4-(ShiftCounter>>1));  *(ps32X2)=*(ps32X2-4-(ShiftCounter>>1)); ps32X--;  ps32X2--;                     \
+        *ps32X=*(ps32X-4-(ShiftCounter>>1));  *(ps32X2)=*(ps32X2-4-(ShiftCounter>>1)); ps32X--;  ps32X2--;                     \
+    }                                                                               \
+}
+
+#if (SBC_ARM_ASM_OPT==TRUE)
+#define WINDOW_ACCU_8_0 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_8_SUBBANDS_0_1,(s16X[ChOffset+16]-s16X[ChOffset+64]);\
+        MLA s32Hi,WIND_8_SUBBANDS_0_2,(s16X[ChOffset+32]-s16X[ChOffset+48]),s32Hi;\
+        MOV s32DCTY[0],s32Hi;\
+    }\
+}
+#define WINDOW_ACCU_8_1_15 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_8_SUBBANDS_1_0,s16X[ChOffset+1];\
+        MUL s32Hi2,WIND_8_SUBBANDS_1_0,s16X[ChOffset+64+15];\
+        MLA s32Hi,WIND_8_SUBBANDS_1_1,s16X[ChOffset+16+1],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_1_1,s16X[ChOffset+48+15],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_1_2,s16X[ChOffset+32+1],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_1_2,s16X[ChOffset+32+15],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_1_3,s16X[ChOffset+48+1],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_1_3,s16X[ChOffset+16+15],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_1_4,s16X[ChOffset+64+1],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_1_4,s16X[ChOffset+15],s32Hi2;\
+        MOV s32DCTY[1],s32Hi;\
+        MOV s32DCTY[15],s32Hi2;\
+    }\
+}
+#define WINDOW_ACCU_8_2_14 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_8_SUBBANDS_2_0,s16X[ChOffset+2];\
+        MUL s32Hi2,WIND_8_SUBBANDS_2_0,s16X[ChOffset+64+14];\
+        MLA s32Hi,WIND_8_SUBBANDS_2_1,s16X[ChOffset+16+2],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_2_1,s16X[ChOffset+48+14],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_2_2,s16X[ChOffset+32+2],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_2_2,s16X[ChOffset+32+14],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_2_3,s16X[ChOffset+48+2],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_2_3,s16X[ChOffset+16+14],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_2_4,s16X[ChOffset+64+2],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_2_4,s16X[ChOffset+14],s32Hi2;\
+        MOV s32DCTY[2],s32Hi;\
+        MOV s32DCTY[14],s32Hi2;\
+    }\
+}
+#define WINDOW_ACCU_8_3_13 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_8_SUBBANDS_3_0,s16X[ChOffset+3];\
+        MUL s32Hi2,WIND_8_SUBBANDS_3_0,s16X[ChOffset+64+13];\
+        MLA s32Hi,WIND_8_SUBBANDS_3_1,s16X[ChOffset+16+3],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_3_1,s16X[ChOffset+48+13],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_3_2,s16X[ChOffset+32+3],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_3_2,s16X[ChOffset+32+13],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_3_3,s16X[ChOffset+48+3],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_3_3,s16X[ChOffset+16+13],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_3_4,s16X[ChOffset+64+3],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_3_4,s16X[ChOffset+13],s32Hi2;\
+        MOV s32DCTY[3],s32Hi;\
+        MOV s32DCTY[13],s32Hi2;\
+    }\
+}
+#define WINDOW_ACCU_8_4_12 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_8_SUBBANDS_4_0,s16X[ChOffset+4];\
+        MUL s32Hi2,WIND_8_SUBBANDS_4_0,s16X[ChOffset+64+12];\
+        MLA s32Hi,WIND_8_SUBBANDS_4_1,s16X[ChOffset+16+4],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_4_1,s16X[ChOffset+48+12],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_4_2,s16X[ChOffset+32+4],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_4_2,s16X[ChOffset+32+12],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_4_3,s16X[ChOffset+48+4],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_4_3,s16X[ChOffset+16+12],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_4_4,s16X[ChOffset+64+4],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_4_4,s16X[ChOffset+12],s32Hi2;\
+        MOV s32DCTY[4],s32Hi;\
+        MOV s32DCTY[12],s32Hi2;\
+    }\
+}
+#define WINDOW_ACCU_8_5_11 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_8_SUBBANDS_5_0,s16X[ChOffset+5];\
+        MUL s32Hi2,WIND_8_SUBBANDS_5_0,s16X[ChOffset+64+11];\
+        MLA s32Hi,WIND_8_SUBBANDS_5_1,s16X[ChOffset+16+5],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_5_1,s16X[ChOffset+48+11],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_5_2,s16X[ChOffset+32+5],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_5_2,s16X[ChOffset+32+11],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_5_3,s16X[ChOffset+48+5],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_5_3,s16X[ChOffset+16+11],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_5_4,s16X[ChOffset+64+5],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_5_4,s16X[ChOffset+11],s32Hi2;\
+        MOV s32DCTY[5],s32Hi;\
+        MOV s32DCTY[11],s32Hi2;\
+    }\
+}
+#define WINDOW_ACCU_8_6_10 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_8_SUBBANDS_6_0,s16X[ChOffset+6];\
+        MUL s32Hi2,WIND_8_SUBBANDS_6_0,s16X[ChOffset+64+10];\
+        MLA s32Hi,WIND_8_SUBBANDS_6_1,s16X[ChOffset+16+6],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_6_1,s16X[ChOffset+48+10],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_6_2,s16X[ChOffset+32+6],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_6_2,s16X[ChOffset+32+10],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_6_3,s16X[ChOffset+48+6],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_6_3,s16X[ChOffset+16+10],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_6_4,s16X[ChOffset+64+6],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_6_4,s16X[ChOffset+10],s32Hi2;\
+        MOV s32DCTY[6],s32Hi;\
+        MOV s32DCTY[10],s32Hi2;\
+    }\
+}
+#define WINDOW_ACCU_8_7_9 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_8_SUBBANDS_7_0,s16X[ChOffset+7];\
+        MUL s32Hi2,WIND_8_SUBBANDS_7_0,s16X[ChOffset+64+9];\
+        MLA s32Hi,WIND_8_SUBBANDS_7_1,s16X[ChOffset+16+7],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_7_1,s16X[ChOffset+48+9],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_7_2,s16X[ChOffset+32+7],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_7_2,s16X[ChOffset+32+9],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_7_3,s16X[ChOffset+48+7],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_7_3,s16X[ChOffset+16+9],s32Hi2;\
+        MLA s32Hi,WIND_8_SUBBANDS_7_4,s16X[ChOffset+64+7],s32Hi;\
+        MLA s32Hi2,WIND_8_SUBBANDS_7_4,s16X[ChOffset+9],s32Hi2;\
+        MOV s32DCTY[7],s32Hi;\
+        MOV s32DCTY[9],s32Hi2;\
+    }\
+}
+#define WINDOW_ACCU_8_8 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_8_SUBBANDS_8_0,(s16X[ChOffset+8]+s16X[ChOffset+8+64]);\
+        MLA s32Hi,WIND_8_SUBBANDS_8_1,(s16X[ChOffset+8+16]+s16X[ChOffset+8+64]),s32Hi;\
+        MLA s32Hi,WIND_8_SUBBANDS_8_2,s16X[ChOffset+8+32],s32Hi;\
+        MOV s32DCTY[8],s32Hi;\
+    }\
+}
+#define WINDOW_ACCU_4_0 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_4_SUBBANDS_0_1,(s16X[ChOffset+8]-s16X[ChOffset+32]);\
+        MLA s32Hi,WIND_4_SUBBANDS_0_2,(s16X[ChOffset+16]-s16X[ChOffset+24]),s32Hi;\
+        MOV s32DCTY[0],s32Hi;\
+    }\
+}
+#define WINDOW_ACCU_4_1_7 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_4_SUBBANDS_1_0,s16X[ChOffset+1];\
+        MUL s32Hi2,WIND_4_SUBBANDS_1_0,s16X[ChOffset+32+7];\
+        MLA s32Hi,WIND_4_SUBBANDS_1_1,s16X[ChOffset+8+1],s32Hi;\
+        MLA s32Hi2,WIND_4_SUBBANDS_1_1,s16X[ChOffset+24+7],s32Hi2;\
+        MLA s32Hi,WIND_4_SUBBANDS_1_2,s16X[ChOffset+16+1],s32Hi;\
+        MLA s32Hi2,WIND_4_SUBBANDS_1_2,s16X[ChOffset+16+7],s32Hi2;\
+        MLA s32Hi,WIND_4_SUBBANDS_1_3,s16X[ChOffset+24+1],s32Hi;\
+        MLA s32Hi2,WIND_4_SUBBANDS_1_3,s16X[ChOffset+8+7],s32Hi2;\
+        MLA s32Hi,WIND_4_SUBBANDS_1_4,s16X[ChOffset+32+1],s32Hi;\
+        MLA s32Hi2,WIND_4_SUBBANDS_1_4,s16X[ChOffset+7],s32Hi2;\
+        MOV s32DCTY[1],s32Hi;\
+        MOV s32DCTY[7],s32Hi2;\
+    }\
+}
+#define WINDOW_ACCU_4_2_6 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_4_SUBBANDS_2_0,s16X[ChOffset+2];\
+        MUL s32Hi2,WIND_4_SUBBANDS_2_0,s16X[ChOffset+32+6];\
+        MLA s32Hi,WIND_4_SUBBANDS_2_1,s16X[ChOffset+8+2],s32Hi;\
+        MLA s32Hi2,WIND_4_SUBBANDS_2_1,s16X[ChOffset+24+6],s32Hi2;\
+        MLA s32Hi,WIND_4_SUBBANDS_2_2,s16X[ChOffset+16+2],s32Hi;\
+        MLA s32Hi2,WIND_4_SUBBANDS_2_2,s16X[ChOffset+16+6],s32Hi2;\
+        MLA s32Hi,WIND_4_SUBBANDS_2_3,s16X[ChOffset+24+2],s32Hi;\
+        MLA s32Hi2,WIND_4_SUBBANDS_2_3,s16X[ChOffset+8+6],s32Hi2;\
+        MLA s32Hi,WIND_4_SUBBANDS_2_4,s16X[ChOffset+32+2],s32Hi;\
+        MLA s32Hi2,WIND_4_SUBBANDS_2_4,s16X[ChOffset+6],s32Hi2;\
+        MOV s32DCTY[2],s32Hi;\
+        MOV s32DCTY[6],s32Hi2;\
+    }\
+}
+#define WINDOW_ACCU_4_3_5 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_4_SUBBANDS_3_0,s16X[ChOffset+3];\
+        MUL s32Hi2,WIND_4_SUBBANDS_3_0,s16X[ChOffset+32+5];\
+        MLA s32Hi,WIND_4_SUBBANDS_3_1,s16X[ChOffset+8+3],s32Hi;\
+        MLA s32Hi2,WIND_4_SUBBANDS_3_1,s16X[ChOffset+24+5],s32Hi2;\
+        MLA s32Hi,WIND_4_SUBBANDS_3_2,s16X[ChOffset+16+3],s32Hi;\
+        MLA s32Hi2,WIND_4_SUBBANDS_3_2,s16X[ChOffset+16+5],s32Hi2;\
+        MLA s32Hi,WIND_4_SUBBANDS_3_3,s16X[ChOffset+24+3],s32Hi;\
+        MLA s32Hi2,WIND_4_SUBBANDS_3_3,s16X[ChOffset+8+5],s32Hi2;\
+        MLA s32Hi,WIND_4_SUBBANDS_3_4,s16X[ChOffset+32+3],s32Hi;\
+        MLA s32Hi2,WIND_4_SUBBANDS_3_4,s16X[ChOffset+5],s32Hi2;\
+        MOV s32DCTY[3],s32Hi;\
+        MOV s32DCTY[5],s32Hi2;\
+    }\
+}
+#define WINDOW_ACCU_4_4 \
+{\
+    __asm\
+    {\
+        MUL s32Hi,WIND_4_SUBBANDS_4_0,(s16X[ChOffset+4]+s16X[ChOffset+4+32]);\
+        MLA s32Hi,WIND_4_SUBBANDS_4_1,(s16X[ChOffset+4+8]+s16X[ChOffset+4+24]),s32Hi;\
+        MLA s32Hi,WIND_4_SUBBANDS_4_2,s16X[ChOffset+4+16],s32Hi;\
+        MOV s32DCTY[4],s32Hi;\
+    }\
+}
+
+#define WINDOW_PARTIAL_4 \
+{\
+    WINDOW_ACCU_4_0;     WINDOW_ACCU_4_1_7;\
+    WINDOW_ACCU_4_2_6;   WINDOW_ACCU_4_3_5;\
+    WINDOW_ACCU_4_4;\
+}
+
+#define WINDOW_PARTIAL_8 \
+{\
+    WINDOW_ACCU_8_0;     WINDOW_ACCU_8_1_15;\
+    WINDOW_ACCU_8_2_14;  WINDOW_ACCU_8_3_13;\
+    WINDOW_ACCU_8_4_12;  WINDOW_ACCU_8_5_11;\
+    WINDOW_ACCU_8_6_10;  WINDOW_ACCU_8_7_9;\
+    WINDOW_ACCU_8_8;\
+}
+
+#else
+#if (SBC_IPAQ_OPT==TRUE)
+
+#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == TRUE)
+#define WINDOW_ACCU_8_0 \
+{\
+    s64Temp=(SINT64)WIND_8_SUBBANDS_0_1*(SINT64)(s16X[ChOffset+16]-s16X[ChOffset+64]);\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_0_2*(SINT64)(s16X[ChOffset+32]-s16X[ChOffset+48]);\
+    s32DCTY[0]=(SINT32)(s64Temp>>16);\
+}
+#define WINDOW_ACCU_8_1_15 \
+{\
+    s64Temp=(SINT64)WIND_8_SUBBANDS_1_0*(SINT64)s16X[ChOffset+1];\
+    s64Temp2=(SINT64)WIND_8_SUBBANDS_1_0*(SINT64)s16X[ChOffset+64+15];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_1_1*(SINT64)s16X[ChOffset+16+1];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_1_1*(SINT64)s16X[ChOffset+48+15];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_1_2*(SINT64)s16X[ChOffset+32+1];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_1_2*(SINT64)s16X[ChOffset+32+15];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_1_3*(SINT64)s16X[ChOffset+48+1];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_1_3*(SINT64)s16X[ChOffset+16+15];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_1_4*(SINT64)s16X[ChOffset+64+1];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_1_4*(SINT64)s16X[ChOffset+15];\
+    s32DCTY[1]=(SINT32)(s64Temp>>16);\
+    s32DCTY[15]=(SINT32)(s64Temp2>>16);\
+}
+#define WINDOW_ACCU_8_2_14 \
+{\
+    s64Temp=(SINT64)WIND_8_SUBBANDS_2_0*(SINT64)s16X[ChOffset+2];\
+    s64Temp2=(SINT64)WIND_8_SUBBANDS_2_0*(SINT64)s16X[ChOffset+64+14];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_2_1*(SINT64)s16X[ChOffset+16+2];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_2_1*(SINT64)s16X[ChOffset+48+14];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_2_2*(SINT64)s16X[ChOffset+32+2];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_2_2*(SINT64)s16X[ChOffset+32+14];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_2_3*(SINT64)s16X[ChOffset+48+2];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_2_3*(SINT64)s16X[ChOffset+16+14];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_2_4*(SINT64)s16X[ChOffset+64+2];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_2_4*(SINT64)s16X[ChOffset+14];\
+    s32DCTY[2]=(SINT32)(s64Temp>>16);\
+    s32DCTY[14]=(SINT32)(s64Temp2>>16);\
+}
+#define WINDOW_ACCU_8_3_13 \
+{\
+    s64Temp=(SINT64)WIND_8_SUBBANDS_3_0*(SINT64)s16X[ChOffset+3];\
+    s64Temp2=(SINT64)WIND_8_SUBBANDS_3_0*(SINT64)s16X[ChOffset+64+13];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_3_1*(SINT64)s16X[ChOffset+16+3];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_3_1*(SINT64)s16X[ChOffset+48+13];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_3_2*(SINT64)s16X[ChOffset+32+3];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_3_2*(SINT64)s16X[ChOffset+32+13];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_3_3*(SINT64)s16X[ChOffset+48+3];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_3_3*(SINT64)s16X[ChOffset+16+13];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_3_4*(SINT64)s16X[ChOffset+64+3];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_3_4*(SINT64)s16X[ChOffset+13];\
+    s32DCTY[3]=(SINT32)(s64Temp>>16);\
+    s32DCTY[13]=(SINT32)(s64Temp2>>16);\
+}
+#define WINDOW_ACCU_8_4_12 \
+{\
+    s64Temp=(SINT64)WIND_8_SUBBANDS_4_0*(SINT64)s16X[ChOffset+4];\
+    s64Temp2=(SINT64)WIND_8_SUBBANDS_4_0*(SINT64)s16X[ChOffset+64+12];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_4_1*(SINT64)s16X[ChOffset+16+4];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_4_1*(SINT64)s16X[ChOffset+48+12];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_4_2*(SINT64)s16X[ChOffset+32+4];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_4_2*(SINT64)s16X[ChOffset+32+12];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_4_3*(SINT64)s16X[ChOffset+48+4];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_4_3*(SINT64)s16X[ChOffset+16+12];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_4_4*(SINT64)s16X[ChOffset+64+4];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_4_4*(SINT64)s16X[ChOffset+12];\
+    s32DCTY[4]=(SINT32)(s64Temp>>16);\
+    s32DCTY[12]=(SINT32)(s64Temp2>>16);\
+}
+#define WINDOW_ACCU_8_5_11 \
+{\
+    s64Temp=(SINT64)WIND_8_SUBBANDS_5_0*(SINT64)s16X[ChOffset+5];\
+    s64Temp2=(SINT64)WIND_8_SUBBANDS_5_0*(SINT64)s16X[ChOffset+64+11];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_5_1*(SINT64)s16X[ChOffset+16+5];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_5_1*(SINT64)s16X[ChOffset+48+11];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_5_2*(SINT64)s16X[ChOffset+32+5];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_5_2*(SINT64)s16X[ChOffset+32+11];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_5_3*(SINT64)s16X[ChOffset+48+5];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_5_3*(SINT64)s16X[ChOffset+16+11];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_5_4*(SINT64)s16X[ChOffset+64+5];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_5_4*(SINT64)s16X[ChOffset+11];\
+    s32DCTY[5]=(SINT32)(s64Temp>>16);\
+    s32DCTY[11]=(SINT32)(s64Temp2>>16);\
+}
+#define WINDOW_ACCU_8_6_10 \
+{\
+    s64Temp=(SINT64)WIND_8_SUBBANDS_6_0*(SINT64)s16X[ChOffset+6];\
+    s64Temp2=(SINT64)WIND_8_SUBBANDS_6_0*(SINT64)s16X[ChOffset+64+10];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_6_1*(SINT64)s16X[ChOffset+16+6];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_6_1*(SINT64)s16X[ChOffset+48+10];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_6_2*(SINT64)s16X[ChOffset+32+6];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_6_2*(SINT64)s16X[ChOffset+32+10];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_6_3*(SINT64)s16X[ChOffset+48+6];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_6_3*(SINT64)s16X[ChOffset+16+10];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_6_4*(SINT64)s16X[ChOffset+64+6];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_6_4*(SINT64)s16X[ChOffset+10];\
+    s32DCTY[6]=(SINT32)(s64Temp>>16);\
+    s32DCTY[10]=(SINT32)(s64Temp2>>16);\
+}
+#define WINDOW_ACCU_8_7_9 \
+{\
+    s64Temp=(SINT64)WIND_8_SUBBANDS_7_0*(SINT64)s16X[ChOffset+7];\
+    s64Temp2=(SINT64)WIND_8_SUBBANDS_7_0*(SINT64)s16X[ChOffset+64+9];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_7_1*(SINT64)s16X[ChOffset+16+7];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_7_1*(SINT64)s16X[ChOffset+48+9];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_7_2*(SINT64)s16X[ChOffset+32+7];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_7_2*(SINT64)s16X[ChOffset+32+9];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_7_3*(SINT64)s16X[ChOffset+48+7];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_7_3*(SINT64)s16X[ChOffset+16+9];\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_7_4*(SINT64)s16X[ChOffset+64+7];\
+    s64Temp2+=(SINT64)WIND_8_SUBBANDS_7_4*(SINT64)s16X[ChOffset+9];\
+    s32DCTY[7]=(SINT32)(s64Temp>>16);\
+    s32DCTY[9]=(SINT32)(s64Temp2>>16);\
+}
+#define WINDOW_ACCU_8_8 \
+{\
+    s64Temp=(SINT64)WIND_8_SUBBANDS_8_0*(SINT64)(s16X[ChOffset+8]+s16X[ChOffset+64+8]);\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_8_1*(SINT64)(s16X[ChOffset+16+8]+s16X[ChOffset+48+8]);\
+    s64Temp+=(SINT64)WIND_8_SUBBANDS_8_2*(SINT64)s16X[ChOffset+32+8];\
+    s32DCTY[8]=(SINT32)(s64Temp>>16);\
+}
+#define WINDOW_ACCU_4_0 \
+{\
+    s64Temp=(SINT64)WIND_4_SUBBANDS_0_1*(SINT64)(s16X[ChOffset+8]-s16X[ChOffset+32]);\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_0_2*(SINT64)(s16X[ChOffset+16]-s16X[ChOffset+24]);\
+    s32DCTY[0]=(SINT32)(s64Temp>>16);\
+}
+#define WINDOW_ACCU_4_1_7 \
+{\
+    s64Temp=(SINT64)WIND_4_SUBBANDS_1_0*(SINT64)s16X[ChOffset+1];\
+    s64Temp2=(SINT64)WIND_4_SUBBANDS_1_0*(SINT64)s16X[ChOffset+32+7];\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_1_1*(SINT64)s16X[ChOffset+8+1];\
+    s64Temp2+=(SINT64)WIND_4_SUBBANDS_1_1*(SINT64)s16X[ChOffset+24+7];\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_1_2*(SINT64)s16X[ChOffset+16+1];\
+    s64Temp2+=(SINT64)WIND_4_SUBBANDS_1_2*(SINT64)s16X[ChOffset+16+7];\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_1_3*(SINT64)s16X[ChOffset+24+1];\
+    s64Temp2+=(SINT64)WIND_4_SUBBANDS_1_3*(SINT64)s16X[ChOffset+8+7];\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_1_4*(SINT64)s16X[ChOffset+32+1];\
+    s64Temp2+=(SINT64)WIND_4_SUBBANDS_1_4*(SINT64)s16X[ChOffset+7];\
+    s32DCTY[1]=(SINT32)(s64Temp>>16);\
+    s32DCTY[7]=(SINT32)(s64Temp2>>16);\
+}
+#define WINDOW_ACCU_4_2_6 \
+{\
+    s64Temp=(SINT64)WIND_4_SUBBANDS_2_0*(SINT64)s16X[ChOffset+2];\
+    s64Temp2=(SINT64)WIND_4_SUBBANDS_2_0*(SINT64)s16X[ChOffset+32+6];\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_2_1*(SINT64)s16X[ChOffset+8+2];\
+    s64Temp2+=(SINT64)WIND_4_SUBBANDS_2_1*(SINT64)s16X[ChOffset+24+6];\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_2_2*(SINT64)s16X[ChOffset+16+2];\
+    s64Temp2+=(SINT64)WIND_4_SUBBANDS_2_2*(SINT64)s16X[ChOffset+16+6];\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_2_3*(SINT64)s16X[ChOffset+24+2];\
+    s64Temp2+=(SINT64)WIND_4_SUBBANDS_2_3*(SINT64)s16X[ChOffset+8+6];\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_2_4*(SINT64)s16X[ChOffset+32+2];\
+    s64Temp2+=(SINT64)WIND_4_SUBBANDS_2_4*(SINT64)s16X[ChOffset+6];\
+    s32DCTY[2]=(SINT32)(s64Temp>>16);\
+    s32DCTY[6]=(SINT32)(s64Temp2>>16);\
+}
+#define WINDOW_ACCU_4_3_5 \
+{\
+    s64Temp=(SINT64)WIND_4_SUBBANDS_3_0*(SINT64)s16X[ChOffset+3];\
+    s64Temp2=(SINT64)WIND_4_SUBBANDS_3_0*(SINT64)s16X[ChOffset+32+5];\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_3_1*(SINT64)s16X[ChOffset+8+3];\
+    s64Temp2+=(SINT64)WIND_4_SUBBANDS_3_1*(SINT64)s16X[ChOffset+24+5];\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_3_2*(SINT64)s16X[ChOffset+16+3];\
+    s64Temp2+=(SINT64)WIND_4_SUBBANDS_3_2*(SINT64)s16X[ChOffset+16+5];\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_3_3*(SINT64)s16X[ChOffset+24+3];\
+    s64Temp2+=(SINT64)WIND_4_SUBBANDS_3_3*(SINT64)s16X[ChOffset+8+5];\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_3_4*(SINT64)s16X[ChOffset+32+3];\
+    s64Temp2+=(SINT64)WIND_4_SUBBANDS_3_4*(SINT64)s16X[ChOffset+5];\
+    s32DCTY[3]=(SINT32)(s64Temp>>16);\
+    s32DCTY[5]=(SINT32)(s64Temp2>>16);\
+}
+
+#define WINDOW_ACCU_4_4 \
+{\
+    s64Temp=(SINT64)WIND_4_SUBBANDS_4_0*(SINT64)(s16X[ChOffset+4]+s16X[ChOffset+4+32]);\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_4_1*(SINT64)(s16X[ChOffset+4+8]+s16X[ChOffset+4+24]);\
+    s64Temp+=(SINT64)WIND_4_SUBBANDS_4_2*(SINT64)s16X[ChOffset+4+16];\
+    s32DCTY[4]=(SINT32)(s64Temp>>16);\
+}
+#else /* SBC_IS_64_MULT_IN_WINDOW_ACCU == FALSE */
+#define WINDOW_ACCU_8_0 \
+{\
+    s32Temp=(SINT32)WIND_8_SUBBANDS_0_1*(SINT32)(s16X[ChOffset+16]-s16X[ChOffset+64]);\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_0_2*(SINT32)(s16X[ChOffset+32]-s16X[ChOffset+48]);\
+    s32DCTY[0]=(SINT32)s32Temp;\
+}
+#define WINDOW_ACCU_8_1_15 \
+{\
+    s32Temp=(SINT32)WIND_8_SUBBANDS_1_0*(SINT32)s16X[ChOffset+1];\
+    s32Temp2=(SINT32)WIND_8_SUBBANDS_1_0*(SINT32)s16X[ChOffset+64+15];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_1_1*(SINT32)s16X[ChOffset+16+1];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_1_1*(SINT32)s16X[ChOffset+48+15];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_1_2*(SINT32)s16X[ChOffset+32+1];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_1_2*(SINT32)s16X[ChOffset+32+15];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_1_3*(SINT32)s16X[ChOffset+48+1];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_1_3*(SINT32)s16X[ChOffset+16+15];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_1_4*(SINT32)s16X[ChOffset+64+1];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_1_4*(SINT32)s16X[ChOffset+15];\
+    s32DCTY[1]=(SINT32)s32Temp;\
+    s32DCTY[15]=(SINT32)s32Temp2;\
+}
+#define WINDOW_ACCU_8_2_14 \
+{\
+    s32Temp=(SINT32)WIND_8_SUBBANDS_2_0*(SINT32)s16X[ChOffset+2];\
+    s32Temp2=(SINT32)WIND_8_SUBBANDS_2_0*(SINT32)s16X[ChOffset+64+14];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_2_1*(SINT32)s16X[ChOffset+16+2];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_2_1*(SINT32)s16X[ChOffset+48+14];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_2_2*(SINT32)s16X[ChOffset+32+2];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_2_2*(SINT32)s16X[ChOffset+32+14];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_2_3*(SINT32)s16X[ChOffset+48+2];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_2_3*(SINT32)s16X[ChOffset+16+14];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_2_4*(SINT32)s16X[ChOffset+64+2];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_2_4*(SINT32)s16X[ChOffset+14];\
+    s32DCTY[2]=(SINT32)s32Temp;\
+    s32DCTY[14]=(SINT32)s32Temp2;\
+}
+#define WINDOW_ACCU_8_3_13 \
+{\
+    s32Temp=(SINT32)WIND_8_SUBBANDS_3_0*(SINT32)s16X[ChOffset+3];\
+    s32Temp2=(SINT32)WIND_8_SUBBANDS_3_0*(SINT32)s16X[ChOffset+64+13];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_3_1*(SINT32)s16X[ChOffset+16+3];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_3_1*(SINT32)s16X[ChOffset+48+13];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_3_2*(SINT32)s16X[ChOffset+32+3];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_3_2*(SINT32)s16X[ChOffset+32+13];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_3_3*(SINT32)s16X[ChOffset+48+3];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_3_3*(SINT32)s16X[ChOffset+16+13];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_3_4*(SINT32)s16X[ChOffset+64+3];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_3_4*(SINT32)s16X[ChOffset+13];\
+    s32DCTY[3]=(SINT32)s32Temp;\
+    s32DCTY[13]=(SINT32)s32Temp2;\
+}
+#define WINDOW_ACCU_8_4_12 \
+{\
+    s32Temp=(SINT32)WIND_8_SUBBANDS_4_0*(SINT32)s16X[ChOffset+4];\
+    s32Temp2=(SINT32)WIND_8_SUBBANDS_4_0*(SINT32)s16X[ChOffset+64+12];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_4_1*(SINT32)s16X[ChOffset+16+4];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_4_1*(SINT32)s16X[ChOffset+48+12];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_4_2*(SINT32)s16X[ChOffset+32+4];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_4_2*(SINT32)s16X[ChOffset+32+12];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_4_3*(SINT32)s16X[ChOffset+48+4];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_4_3*(SINT32)s16X[ChOffset+16+12];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_4_4*(SINT32)s16X[ChOffset+64+4];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_4_4*(SINT32)s16X[ChOffset+12];\
+    s32DCTY[4]=(SINT32)s32Temp;\
+    s32DCTY[12]=(SINT32)s32Temp2;\
+}
+#define WINDOW_ACCU_8_5_11 \
+{\
+    s32Temp=(SINT32)WIND_8_SUBBANDS_5_0*(SINT32)s16X[ChOffset+5];\
+    s32Temp2=(SINT32)WIND_8_SUBBANDS_5_0*(SINT32)s16X[ChOffset+64+11];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_5_1*(SINT32)s16X[ChOffset+16+5];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_5_1*(SINT32)s16X[ChOffset+48+11];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_5_2*(SINT32)s16X[ChOffset+32+5];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_5_2*(SINT32)s16X[ChOffset+32+11];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_5_3*(SINT32)s16X[ChOffset+48+5];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_5_3*(SINT32)s16X[ChOffset+16+11];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_5_4*(SINT32)s16X[ChOffset+64+5];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_5_4*(SINT32)s16X[ChOffset+11];\
+    s32DCTY[5]=(SINT32)s32Temp;\
+    s32DCTY[11]=(SINT32)s32Temp2;\
+}
+#define WINDOW_ACCU_8_6_10 \
+{\
+    s32Temp=(SINT32)WIND_8_SUBBANDS_6_0*(SINT32)s16X[ChOffset+6];\
+    s32Temp2=(SINT32)WIND_8_SUBBANDS_6_0*(SINT32)s16X[ChOffset+64+10];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_6_1*(SINT32)s16X[ChOffset+16+6];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_6_1*(SINT32)s16X[ChOffset+48+10];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_6_2*(SINT32)s16X[ChOffset+32+6];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_6_2*(SINT32)s16X[ChOffset+32+10];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_6_3*(SINT32)s16X[ChOffset+48+6];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_6_3*(SINT32)s16X[ChOffset+16+10];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_6_4*(SINT32)s16X[ChOffset+64+6];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_6_4*(SINT32)s16X[ChOffset+10];\
+    s32DCTY[6]=(SINT32)s32Temp;\
+    s32DCTY[10]=(SINT32)s32Temp2;\
+}
+#define WINDOW_ACCU_8_7_9 \
+{\
+    s32Temp=(SINT32)WIND_8_SUBBANDS_7_0*(SINT32)s16X[ChOffset+7];\
+    s32Temp2=(SINT32)WIND_8_SUBBANDS_7_0*(SINT32)s16X[ChOffset+64+9];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_7_1*(SINT32)s16X[ChOffset+16+7];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_7_1*(SINT32)s16X[ChOffset+48+9];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_7_2*(SINT32)s16X[ChOffset+32+7];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_7_2*(SINT32)s16X[ChOffset+32+9];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_7_3*(SINT32)s16X[ChOffset+48+7];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_7_3*(SINT32)s16X[ChOffset+16+9];\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_7_4*(SINT32)s16X[ChOffset+64+7];\
+    s32Temp2+=(SINT32)WIND_8_SUBBANDS_7_4*(SINT32)s16X[ChOffset+9];\
+    s32DCTY[7]=(SINT32)s32Temp;\
+    s32DCTY[9]=(SINT32)s32Temp2;\
+}
+#define WINDOW_ACCU_8_8 \
+{\
+    s32Temp=(SINT32)WIND_8_SUBBANDS_8_0*(SINT32)(s16X[ChOffset+8]+s16X[ChOffset+64+8]);\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_8_1*(SINT32)(s16X[ChOffset+16+8]+s16X[ChOffset+48+8]);\
+    s32Temp+=(SINT32)WIND_8_SUBBANDS_8_2*(SINT32)s16X[ChOffset+32+8];\
+    s32DCTY[8]=(SINT32)s32Temp;\
+}
+#define WINDOW_ACCU_4_0 \
+{\
+    s32Temp=(SINT32)WIND_4_SUBBANDS_0_1*(SINT32)(s16X[ChOffset+8]-s16X[ChOffset+32]);\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_0_2*(SINT32)(s16X[ChOffset+16]-s16X[ChOffset+24]);\
+    s32DCTY[0]=(SINT32)(s32Temp);\
+}
+#define WINDOW_ACCU_4_1_7 \
+{\
+    s32Temp=(SINT32)WIND_4_SUBBANDS_1_0*(SINT32)s16X[ChOffset+1];\
+    s32Temp2=(SINT32)WIND_4_SUBBANDS_1_0*(SINT32)s16X[ChOffset+32+7];\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_1_1*(SINT32)s16X[ChOffset+8+1];\
+    s32Temp2+=(SINT32)WIND_4_SUBBANDS_1_1*(SINT32)s16X[ChOffset+24+7];\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_1_2*(SINT32)s16X[ChOffset+16+1];\
+    s32Temp2+=(SINT32)WIND_4_SUBBANDS_1_2*(SINT32)s16X[ChOffset+16+7];\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_1_3*(SINT32)s16X[ChOffset+24+1];\
+    s32Temp2+=(SINT32)WIND_4_SUBBANDS_1_3*(SINT32)s16X[ChOffset+8+7];\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_1_4*(SINT32)s16X[ChOffset+32+1];\
+    s32Temp2+=(SINT32)WIND_4_SUBBANDS_1_4*(SINT32)s16X[ChOffset+7];\
+    s32DCTY[1]=(SINT32)(s32Temp);\
+    s32DCTY[7]=(SINT32)(s32Temp2);\
+}
+#define WINDOW_ACCU_4_2_6 \
+{\
+    s32Temp=(SINT32)WIND_4_SUBBANDS_2_0*(SINT32)s16X[ChOffset+2];\
+    s32Temp2=(SINT32)WIND_4_SUBBANDS_2_0*(SINT32)s16X[ChOffset+32+6];\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_2_1*(SINT32)s16X[ChOffset+8+2];\
+    s32Temp2+=(SINT32)WIND_4_SUBBANDS_2_1*(SINT32)s16X[ChOffset+24+6];\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_2_2*(SINT32)s16X[ChOffset+16+2];\
+    s32Temp2+=(SINT32)WIND_4_SUBBANDS_2_2*(SINT32)s16X[ChOffset+16+6];\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_2_3*(SINT32)s16X[ChOffset+24+2];\
+    s32Temp2+=(SINT32)WIND_4_SUBBANDS_2_3*(SINT32)s16X[ChOffset+8+6];\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_2_4*(SINT32)s16X[ChOffset+32+2];\
+    s32Temp2+=(SINT32)WIND_4_SUBBANDS_2_4*(SINT32)s16X[ChOffset+6];\
+    s32DCTY[2]=(SINT32)(s32Temp);\
+    s32DCTY[6]=(SINT32)(s32Temp2);\
+}
+#define WINDOW_ACCU_4_3_5 \
+{\
+    s32Temp=(SINT32)WIND_4_SUBBANDS_3_0*(SINT32)s16X[ChOffset+3];\
+    s32Temp2=(SINT32)WIND_4_SUBBANDS_3_0*(SINT32)s16X[ChOffset+32+5];\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_3_1*(SINT32)s16X[ChOffset+8+3];\
+    s32Temp2+=(SINT32)WIND_4_SUBBANDS_3_1*(SINT32)s16X[ChOffset+24+5];\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_3_2*(SINT32)s16X[ChOffset+16+3];\
+    s32Temp2+=(SINT32)WIND_4_SUBBANDS_3_2*(SINT32)s16X[ChOffset+16+5];\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_3_3*(SINT32)s16X[ChOffset+24+3];\
+    s32Temp2+=(SINT32)WIND_4_SUBBANDS_3_3*(SINT32)s16X[ChOffset+8+5];\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_3_4*(SINT32)s16X[ChOffset+32+3];\
+    s32Temp2+=(SINT32)WIND_4_SUBBANDS_3_4*(SINT32)s16X[ChOffset+5];\
+    s32DCTY[3]=(SINT32)(s32Temp);\
+    s32DCTY[5]=(SINT32)(s32Temp2);\
+}
+
+#define WINDOW_ACCU_4_4 \
+{\
+    s32Temp=(SINT32)WIND_4_SUBBANDS_4_0*(SINT32)(s16X[ChOffset+4]+s16X[ChOffset+4+32]);\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_4_1*(SINT32)(s16X[ChOffset+4+8]+s16X[ChOffset+4+24]);\
+    s32Temp+=(SINT32)WIND_4_SUBBANDS_4_2*(SINT32)s16X[ChOffset+4+16];\
+    s32DCTY[4]=(SINT32)(s32Temp);\
+}
+#endif
+#define WINDOW_PARTIAL_4 \
+{\
+    WINDOW_ACCU_4_0;     WINDOW_ACCU_4_1_7;\
+    WINDOW_ACCU_4_2_6;   WINDOW_ACCU_4_3_5;\
+    WINDOW_ACCU_4_4;\
+}
+
+#define WINDOW_PARTIAL_8 \
+{\
+    WINDOW_ACCU_8_0;         WINDOW_ACCU_8_1_15;\
+    WINDOW_ACCU_8_2_14;      WINDOW_ACCU_8_3_13;\
+    WINDOW_ACCU_8_4_12;      WINDOW_ACCU_8_5_11;\
+    WINDOW_ACCU_8_6_10;      WINDOW_ACCU_8_7_9;\
+    WINDOW_ACCU_8_8;\
+}
+#else
+#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == TRUE)
+#define WINDOW_ACCU_4(i) \
+{\
+    s64Temp=((SINT64)gas32CoeffFor4SBs[i] * (SINT64)s16X[ChOffset+i]);                                    \
+    s64Temp+=((SINT64)gas32CoeffFor4SBs[(i+8)] * (SINT64)s16X[ChOffset+i+8]);                                    \
+    s64Temp+=((SINT64)gas32CoeffFor4SBs[(i+16)] * (SINT64)s16X[ChOffset+i+16]);                                    \
+    s64Temp+=((SINT64)gas32CoeffFor4SBs[(i+24)] * (SINT64)s16X[ChOffset+i+24]);                                    \
+    s64Temp+=((SINT64)gas32CoeffFor4SBs[(i+32)] * (SINT64)s16X[ChOffset+i+32]);                                    \
+    s32DCTY[i]=(SINT32)(s64Temp>>16);\
+	/*printf("s32DCTY4: 0x%x \n", s32DCTY[i]);*/\
+}
+#else
+#define WINDOW_ACCU_4(i) \
+{\
+    s32DCTY[i]=(gas32CoeffFor4SBs[i * 2] * s16X[ChOffset+i])                                    \
+            +  (((SINT32)(UINT16)(gas32CoeffFor4SBs[(i * 2) + 1]) * s16X[ChOffset+i]) >> 16);   \
+    s32DCTY[i]+=(gas32CoeffFor4SBs[(i+8) * 2] * s16X[ChOffset+i+8])                                    \
+            +  (((SINT32)(UINT16)(gas32CoeffFor4SBs[((i+8) * 2) + 1]) * s16X[ChOffset+i+8]) >> 16);   \
+    s32DCTY[i]+=(gas32CoeffFor4SBs[(i+16) * 2] * s16X[ChOffset+i+16])                                    \
+            +  (((SINT32)(UINT16)(gas32CoeffFor4SBs[((i+16) * 2) + 1]) * s16X[ChOffset+i+16]) >> 16);   \
+    s32DCTY[i]+=(gas32CoeffFor4SBs[(i+24) * 2] * s16X[ChOffset+i+24])                                    \
+            +  (((SINT32)(UINT16)(gas32CoeffFor4SBs[((i+24) * 2) + 1]) * s16X[ChOffset+i+24]) >> 16);   \
+    s32DCTY[i]+=(gas32CoeffFor4SBs[(i+32) * 2] * s16X[ChOffset+i+32])                                    \
+            +  (((SINT32)(UINT16)(gas32CoeffFor4SBs[((i+32) * 2) + 1]) * s16X[ChOffset+i+32]) >> 16);   \
+}
+#endif
+#define WINDOW_PARTIAL_4 \
+{\
+    WINDOW_ACCU_4(0);      WINDOW_ACCU_4(1);\
+    WINDOW_ACCU_4(2);      WINDOW_ACCU_4(3);\
+    WINDOW_ACCU_4(4);      WINDOW_ACCU_4(5);\
+    WINDOW_ACCU_4(6);      WINDOW_ACCU_4(7);\
+}
+
+#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == TRUE)
+#define WINDOW_ACCU_8(i) \
+{\
+    s64Temp = ((((SINT64)gas32CoeffFor8SBs[i]      * (SINT64)s16X[ChOffset+i]   )));                 \
+    s64Temp+= ((((SINT64)gas32CoeffFor8SBs[(i+16)] * (SINT64)s16X[ChOffset+i+16])));                 \
+    s64Temp+= ((((SINT64)gas32CoeffFor8SBs[(i+32)] * (SINT64)s16X[ChOffset+i+32])));                 \
+    s64Temp+= ((((SINT64)gas32CoeffFor8SBs[(i+48)] * (SINT64)s16X[ChOffset+i+48])));                 \
+    s64Temp+= ((((SINT64)gas32CoeffFor8SBs[(i+64)] * (SINT64)s16X[ChOffset+i+64])));                 \
+	/*printf("s32DCTY8: %d= 0x%x * %d\n", s32DCTY[i], gas32CoeffFor8SBs[i], s16X[ChOffset+i]);*/     \
+    s32DCTY[i]=(SINT32)(s64Temp>>16);\
+}
+#else
+#define WINDOW_ACCU_8(i) \
+{\
+    s32DCTY[i]=(gas32CoeffFor8SBs[i * 2] * s16X[ChOffset+i])                                    \
+            +  (((SINT32)(UINT16)(gas32CoeffFor8SBs[(i * 2) + 1]) * s16X[ChOffset+i]) >> 16);   \
+    s32DCTY[i]+=(gas32CoeffFor8SBs[(i+16) * 2] * s16X[ChOffset+i+16])                                    \
+            +  (((SINT32)(UINT16)(gas32CoeffFor8SBs[((i+16) * 2) + 1]) * s16X[ChOffset+i+16]) >> 16);   \
+    s32DCTY[i]+=(gas32CoeffFor8SBs[(i+32) * 2] * s16X[ChOffset+i+32])                                    \
+            +  (((SINT32)(UINT16)(gas32CoeffFor8SBs[((i+32) * 2) + 1]) * s16X[ChOffset+i+32]) >> 16);   \
+    s32DCTY[i]+=(gas32CoeffFor8SBs[(i+48) * 2] * s16X[ChOffset+i+48])                                    \
+            +  (((SINT32)(UINT16)(gas32CoeffFor8SBs[((i+48) * 2) + 1]) * s16X[ChOffset+i+48]) >> 16);   \
+    s32DCTY[i]+=(gas32CoeffFor8SBs[(i+64) * 2] * s16X[ChOffset+i+64])                                    \
+            +  (((SINT32)(UINT16)(gas32CoeffFor8SBs[((i+64) * 2) + 1]) * s16X[ChOffset+i+64]) >> 16);   \
+	/*printf("s32DCTY8: %d = 0x%4x%4x * %d\n", s32DCTY[i], gas32CoeffFor8SBs[i * 2], (gas32CoeffFor8SBs[(i * 2) + 1]), s16X[ChOffset+i]);*/\
+    /*s32DCTY[i]=(SINT32)(s64Temp>>16);*/\
+}
+#endif
+#define WINDOW_PARTIAL_8 \
+{\
+    WINDOW_ACCU_8(0);      WINDOW_ACCU_8(1);\
+    WINDOW_ACCU_8(2);      WINDOW_ACCU_8(3);\
+    WINDOW_ACCU_8(4);      WINDOW_ACCU_8(5);\
+    WINDOW_ACCU_8(6);      WINDOW_ACCU_8(7);\
+    WINDOW_ACCU_8(8);      WINDOW_ACCU_8(9);\
+    WINDOW_ACCU_8(10);     WINDOW_ACCU_8(11);\
+    WINDOW_ACCU_8(12);     WINDOW_ACCU_8(13);\
+    WINDOW_ACCU_8(14);     WINDOW_ACCU_8(15);\
+}
+#endif
+#endif
+
+static SINT16 ShiftCounter=0;
+extern SINT16 EncMaxShiftCounter;
+/****************************************************************************
+* SbcAnalysisFilter - performs Analysis of the input audio stream
+*
+* RETURNS : N/A
+*/
+void SbcAnalysisFilter4(SBC_ENC_PARAMS *pstrEncParams)
+{
+    SINT16 *ps16PcmBuf;
+    SINT32 *ps32SbBuf;
+    SINT32  s32Blk,s32Ch;
+    SINT32  s32NumOfChannels, s32NumOfBlocks;
+    SINT32 i,*ps32X,*ps32X2;
+    SINT32 Offset,Offset2,ChOffset;
+#if (SBC_ARM_ASM_OPT==TRUE)
+    register SINT32 s32Hi,s32Hi2;
+#else
+#if (SBC_IPAQ_OPT==TRUE)
+#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == TRUE)
+    register SINT64 s64Temp,s64Temp2;
+#else
+	register SINT32 s32Temp,s32Temp2;
+#endif
+#else
+
+#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == TRUE)
+    SINT64 s64Temp;
+#endif
+
+#endif
+#endif
+
+    s32NumOfChannels = pstrEncParams->s16NumOfChannels;
+    s32NumOfBlocks   = pstrEncParams->s16NumOfBlocks;
+
+    ps16PcmBuf = pstrEncParams->ps16NextPcmBuffer;
+
+    ps32SbBuf  = pstrEncParams->s32SbBuffer;
+    Offset2=(SINT32)(EncMaxShiftCounter+40);
+    for (s32Blk=0; s32Blk <s32NumOfBlocks; s32Blk++)
+    {
+        Offset=(SINT32)(EncMaxShiftCounter-ShiftCounter);
+        /* Store new samples */
+        if (s32NumOfChannels==1)
+        {
+            s16X[3+Offset] = *ps16PcmBuf;   ps16PcmBuf++;
+            s16X[2+Offset] = *ps16PcmBuf;   ps16PcmBuf++;
+            s16X[1+Offset] = *ps16PcmBuf;   ps16PcmBuf++;
+            s16X[0+Offset] = *ps16PcmBuf;   ps16PcmBuf++;
+        }
+        else
+        {
+            s16X[3+Offset] = *ps16PcmBuf;        ps16PcmBuf++;
+            s16X[Offset2+3+Offset] = *ps16PcmBuf;     ps16PcmBuf++;
+            s16X[2+Offset] = *ps16PcmBuf;        ps16PcmBuf++;
+            s16X[Offset2+2+Offset] = *ps16PcmBuf;     ps16PcmBuf++;
+            s16X[1+Offset] = *ps16PcmBuf;        ps16PcmBuf++;
+            s16X[Offset2+1+Offset] = *ps16PcmBuf;     ps16PcmBuf++;
+            s16X[0+Offset] = *ps16PcmBuf;        ps16PcmBuf++;
+            s16X[Offset2+0+Offset] = *ps16PcmBuf;     ps16PcmBuf++;
+        }
+        for (s32Ch=0;s32Ch<s32NumOfChannels;s32Ch++)
+        {
+            ChOffset=s32Ch*Offset2+Offset;
+
+            WINDOW_PARTIAL_4
+
+            SBC_FastIDCT4(s32DCTY, ps32SbBuf);
+
+            ps32SbBuf +=SUB_BANDS_4;
+        }
+        if (s32NumOfChannels==1)
+        {
+            if (ShiftCounter>=EncMaxShiftCounter)
+            {
+                SHIFTUP_X4;
+                ShiftCounter=0;
+            }
+            else
+            {
+                ShiftCounter+=SUB_BANDS_4;
+            }
+        }
+        else
+        {
+            if (ShiftCounter>=EncMaxShiftCounter)
+            {
+                SHIFTUP_X4_2;
+                ShiftCounter=0;
+            }
+            else
+            {
+                ShiftCounter+=SUB_BANDS_4;
+            }
+        }
+    }
+}
+
+/* //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */
+void SbcAnalysisFilter8 (SBC_ENC_PARAMS *pstrEncParams)
+{
+    SINT16 *ps16PcmBuf;
+    SINT32 *ps32SbBuf;
+    SINT32  s32Blk,s32Ch;                                     /* counter for block*/
+    SINT32 Offset,Offset2;
+    SINT32  s32NumOfChannels, s32NumOfBlocks;
+    SINT32 i,*ps32X,*ps32X2;
+    SINT32 ChOffset;
+#if (SBC_ARM_ASM_OPT==TRUE)
+    register SINT32 s32Hi,s32Hi2;
+#else
+#if (SBC_IPAQ_OPT==TRUE)
+#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == TRUE)
+    register SINT64 s64Temp,s64Temp2;
+#else
+	register SINT32 s32Temp,s32Temp2;
+#endif
+#else
+#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == TRUE)
+    SINT64 s64Temp;
+#endif
+#endif
+#endif
+
+    s32NumOfChannels = pstrEncParams->s16NumOfChannels;
+    s32NumOfBlocks   = pstrEncParams->s16NumOfBlocks;
+
+    ps16PcmBuf = pstrEncParams->ps16NextPcmBuffer;
+
+    ps32SbBuf  = pstrEncParams->s32SbBuffer;
+    Offset2=(SINT32)(EncMaxShiftCounter+80);
+    for (s32Blk=0; s32Blk <s32NumOfBlocks; s32Blk++)
+    {
+        Offset=(SINT32)(EncMaxShiftCounter-ShiftCounter);
+        /* Store new samples */
+        if (s32NumOfChannels==1)
+        {
+            s16X[7+Offset] = *ps16PcmBuf;   ps16PcmBuf++;
+            s16X[6+Offset] = *ps16PcmBuf;   ps16PcmBuf++;
+            s16X[5+Offset] = *ps16PcmBuf;   ps16PcmBuf++;
+            s16X[4+Offset] = *ps16PcmBuf;   ps16PcmBuf++;
+            s16X[3+Offset] = *ps16PcmBuf;   ps16PcmBuf++;
+            s16X[2+Offset] = *ps16PcmBuf;   ps16PcmBuf++;
+            s16X[1+Offset] = *ps16PcmBuf;   ps16PcmBuf++;
+            s16X[0+Offset] = *ps16PcmBuf;   ps16PcmBuf++;
+        }
+        else
+        {
+            s16X[7+Offset] = *ps16PcmBuf;        ps16PcmBuf++;
+            s16X[Offset2+7+Offset] = *ps16PcmBuf;     ps16PcmBuf++;
+            s16X[6+Offset] = *ps16PcmBuf;        ps16PcmBuf++;
+            s16X[Offset2+6+Offset] = *ps16PcmBuf;     ps16PcmBuf++;
+            s16X[5+Offset] = *ps16PcmBuf;        ps16PcmBuf++;
+            s16X[Offset2+5+Offset] = *ps16PcmBuf;     ps16PcmBuf++;
+            s16X[4+Offset] = *ps16PcmBuf;        ps16PcmBuf++;
+            s16X[Offset2+4+Offset] = *ps16PcmBuf;     ps16PcmBuf++;
+            s16X[3+Offset] = *ps16PcmBuf;        ps16PcmBuf++;
+            s16X[Offset2+3+Offset] = *ps16PcmBuf;     ps16PcmBuf++;
+            s16X[2+Offset] = *ps16PcmBuf;        ps16PcmBuf++;
+            s16X[Offset2+2+Offset] = *ps16PcmBuf;     ps16PcmBuf++;
+            s16X[1+Offset] = *ps16PcmBuf;        ps16PcmBuf++;
+            s16X[Offset2+1+Offset] = *ps16PcmBuf;     ps16PcmBuf++;
+            s16X[0+Offset] = *ps16PcmBuf;        ps16PcmBuf++;
+            s16X[Offset2+0+Offset] = *ps16PcmBuf;     ps16PcmBuf++;
+        }
+        for (s32Ch=0;s32Ch<s32NumOfChannels;s32Ch++)
+        {
+            ChOffset=s32Ch*Offset2+Offset;
+
+            WINDOW_PARTIAL_8
+
+            SBC_FastIDCT8 (s32DCTY, ps32SbBuf);
+
+            ps32SbBuf +=SUB_BANDS_8;
+        }
+        if (s32NumOfChannels==1)
+        {
+            if (ShiftCounter>=EncMaxShiftCounter)
+            {
+                SHIFTUP_X8;
+                ShiftCounter=0;
+            }
+            else
+            {
+                ShiftCounter+=SUB_BANDS_8;
+            }
+        }
+        else
+        {
+            if (ShiftCounter>=EncMaxShiftCounter)
+            {
+                SHIFTUP_X8_2;
+                ShiftCounter=0;
+            }
+            else
+            {
+                ShiftCounter+=SUB_BANDS_8;
+            }
+        }
+    }
+}
+
+void SbcAnalysisInit (void)
+{
+    memset(s16X,0,ENC_VX_BUFFER_SIZE*sizeof(SINT16));
+    ShiftCounter=0;
+}

+ 245 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_dct.c

@@ -0,0 +1,245 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  source file for fast dct operations
+ *
+ ******************************************************************************/
+
+#include "sbc_encoder.h"
+#include "sbc_enc_func_declare.h"
+#include "sbc_dct.h"
+
+
+
+/*******************************************************************************
+**
+** Function         SBC_FastIDCT8
+**
+** Description      implementation of fast DCT algorithm by Feig and Winograd
+**
+**
+** Returns          y = dct(pInVect)
+**
+**
+*******************************************************************************/
+
+#if (SBC_IS_64_MULT_IN_IDCT == FALSE)
+#define SBC_COS_PI_SUR_4            (0x00005a82)  /* ((0x8000) * 0.7071)     = cos(pi/4) */
+#define SBC_COS_PI_SUR_8            (0x00007641)  /* ((0x8000) * 0.9239)     = (cos(pi/8)) */
+#define SBC_COS_3PI_SUR_8           (0x000030fb)  /* ((0x8000) * 0.3827)     = (cos(3*pi/8)) */
+#define SBC_COS_PI_SUR_16           (0x00007d8a)  /* ((0x8000) * 0.9808))     = (cos(pi/16)) */
+#define SBC_COS_3PI_SUR_16          (0x00006a6d)  /* ((0x8000) * 0.8315))     = (cos(3*pi/16)) */
+#define SBC_COS_5PI_SUR_16          (0x0000471c)  /* ((0x8000) * 0.5556))     = (cos(5*pi/16)) */
+#define SBC_COS_7PI_SUR_16          (0x000018f8)  /* ((0x8000) * 0.1951))     = (cos(7*pi/16)) */
+#define SBC_IDCT_MULT(a,b,c) SBC_MULT_32_16_SIMPLIFIED(a,b,c)
+#else
+#define SBC_COS_PI_SUR_4            (0x5A827999)  /* ((0x80000000) * 0.707106781)      = (cos(pi/4)   ) */
+#define SBC_COS_PI_SUR_8            (0x7641AF3C)  /* ((0x80000000) * 0.923879533)      = (cos(pi/8)   ) */
+#define SBC_COS_3PI_SUR_8           (0x30FBC54D)  /* ((0x80000000) * 0.382683432)      = (cos(3*pi/8) ) */
+#define SBC_COS_PI_SUR_16           (0x7D8A5F3F)  /* ((0x80000000) * 0.98078528 ))     = (cos(pi/16)  ) */
+#define SBC_COS_3PI_SUR_16          (0x6A6D98A4)  /* ((0x80000000) * 0.831469612))     = (cos(3*pi/16)) */
+#define SBC_COS_5PI_SUR_16          (0x471CECE6)  /* ((0x80000000) * 0.555570233))     = (cos(5*pi/16)) */
+#define SBC_COS_7PI_SUR_16          (0x18F8B83C)  /* ((0x80000000) * 0.195090322))     = (cos(7*pi/16)) */
+#define SBC_IDCT_MULT(a,b,c) SBC_MULT_32_32(a,b,c)
+#endif /* SBC_IS_64_MULT_IN_IDCT */
+
+#if (SBC_FAST_DCT == FALSE)
+extern const SINT16 gas16AnalDCTcoeff8[];
+extern const SINT16 gas16AnalDCTcoeff4[];
+#endif
+
+void SBC_FastIDCT8(SINT32 *pInVect, SINT32 *pOutVect)
+{
+#if (SBC_FAST_DCT == TRUE)
+#if (SBC_ARM_ASM_OPT==TRUE)
+#else
+#if (SBC_IPAQ_OPT==TRUE)
+#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
+    SINT64 s64Temp;
+#endif
+#else
+#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
+    SINT32 s32HiTemp;
+#else
+    SINT32 s32In2Temp;
+    register SINT32 s32In1Temp;
+#endif
+#endif
+#endif
+
+    register SINT32 x0, x1, x2, x3, x4, x5, x6, x7,temp;
+    SINT32 res_even[4], res_odd[4];
+    /*x0= (pInVect[4])/2 ;*/
+    SBC_IDCT_MULT(SBC_COS_PI_SUR_4,pInVect[4], x0);
+    /*printf("x0 0x%x = %d = %d * %d\n", x0, x0, SBC_COS_PI_SUR_4, pInVect[4]);*/
+
+    x1 = (pInVect[3] + pInVect[5])  >>1;
+    x2 = (pInVect[2] + pInVect[6])  >>1;
+    x3 = (pInVect[1] + pInVect[7])  >>1;
+    x4 = (pInVect[0] + pInVect[8])  >>1;
+    x5 = (pInVect[9] - pInVect[15]) >>1;
+    x6 = (pInVect[10] - pInVect[14])>>1;
+    x7 = (pInVect[11] - pInVect[13])>>1;
+
+    /* 2-point IDCT of x0 and x4 as in (11) */
+    temp = x0 ;
+    SBC_IDCT_MULT(SBC_COS_PI_SUR_4, ( x0 + x4 ), x0);          /*x0 = ( x0 + x4 ) * cos(1*pi/4) ; */
+    SBC_IDCT_MULT(SBC_COS_PI_SUR_4, ( temp - x4 ), x4);        /*x4 = ( temp - x4 ) * cos(1*pi/4) ; */
+
+    /* rearrangement of x2 and x6 as in (15) */
+    x2 -=x6;
+    x6 <<= 1 ;
+
+    /* 2-point IDCT of x2 and x6 and post-multiplication as in (15) */
+    SBC_IDCT_MULT(SBC_COS_PI_SUR_4,x6, x6); /*x6 = x6 * cos(1*pi/4) ; */
+    temp = x2 ;
+    SBC_IDCT_MULT(SBC_COS_PI_SUR_8,( x2 + x6 ), x2); /*x2 = ( x2 + x6 ) * cos(1*pi/8) ; */
+    SBC_IDCT_MULT(SBC_COS_3PI_SUR_8,( temp - x6 ), x6); /*x6 = ( temp - x6 ) * cos(3*pi/8) ;*/
+
+    /* 4-point IDCT of x0,x2,x4 and x6 as in (11) */
+    res_even[ 0 ] = x0 + x2 ;
+    res_even[ 1 ] = x4 + x6 ;
+    res_even[ 2 ] = x4 - x6 ;
+    res_even[ 3 ] = x0 - x2 ;
+
+
+    /* rearrangement of x1,x3,x5,x7 as in (15) */
+    x7 <<= 1 ;
+    x5 = ( x5 <<1 ) - x7 ;
+    x3 = ( x3 <<1 ) - x5 ;
+    x1 -= x3 >>1 ;
+
+    /* two-dimensional IDCT of x1 and x5 */
+    SBC_IDCT_MULT(SBC_COS_PI_SUR_4, x5, x5);          /*x5 = x5 * cos(1*pi/4) ; */
+    temp = x1 ;
+    x1 = x1 + x5 ;
+    x5 = temp - x5 ;
+
+    /* rearrangement of x3 and x7 as in (15) */
+    x3 -= x7;
+    x7 <<= 1 ;
+    SBC_IDCT_MULT(SBC_COS_PI_SUR_4, x7, x7);          /*x7 = x7 * cos(1*pi/4) ; */
+
+    /* 2-point IDCT of x3 and x7 and post-multiplication as in (15) */
+    temp = x3 ;
+    SBC_IDCT_MULT( SBC_COS_PI_SUR_8,( x3 + x7 ), x3);          /*x3 = ( x3 + x7 ) * cos(1*pi/8)  ; */
+    SBC_IDCT_MULT( SBC_COS_3PI_SUR_8,( temp - x7 ), x7);          /*x7 = ( temp - x7 ) * cos(3*pi/8) ;*/
+
+    /* 4-point IDCT of x1,x3,x5 and x7 and post multiplication by diagonal matrix as in (14) */
+    SBC_IDCT_MULT((SBC_COS_PI_SUR_16),   ( x1 + x3 ) ,   res_odd[0]); /*res_odd[ 0 ] = ( x1 + x3 ) * cos(1*pi/16) ; */
+    SBC_IDCT_MULT((SBC_COS_3PI_SUR_16),  ( x5 + x7 ) ,   res_odd[1]); /*res_odd[ 1 ] = ( x5 + x7 ) * cos(3*pi/16) ; */
+    SBC_IDCT_MULT((SBC_COS_5PI_SUR_16),  ( x5 - x7 ) ,   res_odd[2]); /*res_odd[ 2 ] = ( x5 - x7 ) * cos(5*pi/16) ; */
+    SBC_IDCT_MULT((SBC_COS_7PI_SUR_16),  ( x1 - x3 ) ,  res_odd[3]); /*res_odd[ 3 ] = ( x1 - x3 ) * cos(7*pi/16) ; */
+
+    /* additions and subtractions as in (9) */
+    pOutVect[0] = (res_even[ 0 ] + res_odd[ 0 ])  ;
+    pOutVect[1] = (res_even[ 1 ] + res_odd[ 1 ])  ;
+    pOutVect[2] = (res_even[ 2 ] + res_odd[ 2 ])  ;
+    pOutVect[3] = (res_even[ 3 ] + res_odd[ 3 ])  ;
+    pOutVect[7] = (res_even[ 0 ] - res_odd[ 0 ])  ;
+    pOutVect[6] = (res_even[ 1 ] - res_odd[ 1 ])  ;
+    pOutVect[5] = (res_even[ 2 ] - res_odd[ 2 ])  ;
+    pOutVect[4] = (res_even[ 3 ] - res_odd[ 3 ])  ;
+#else
+    UINT8 Index, k;
+    SINT32 temp;
+	/*Calculate 4 subband samples by matrixing*/
+    for(Index=0; Index<8; Index++)
+    {
+        temp = 0;
+        for(k=0; k<16; k++)
+        {
+            /*temp += (SINT32)(((SINT64)M[(Index*strEncParams->numOfSubBands*2)+k] * Y[k]) >> 16 );*/
+            temp += (gas16AnalDCTcoeff8[(Index*8*2)+k] * (pInVect[k] >> 16));
+            temp += ((gas16AnalDCTcoeff8[(Index*8*2)+k] * (pInVect[k] & 0xFFFF)) >> 16);
+        }
+        pOutVect[Index] = temp;
+    }
+#endif
+/*    printf("pOutVect: 0x%x;0x%x;0x%x;0x%x;0x%x;0x%x;0x%x;0x%x\n",\
+        pOutVect[0],pOutVect[1],pOutVect[2],pOutVect[3],pOutVect[4],pOutVect[5],pOutVect[6],pOutVect[7]);*/
+}
+
+/*******************************************************************************
+**
+** Function         SBC_FastIDCT4
+**
+** Description      implementation of fast DCT algorithm by Feig and Winograd
+**
+**
+** Returns          y = dct(x0)
+**
+**
+*******************************************************************************/
+void SBC_FastIDCT4(SINT32 *pInVect, SINT32 *pOutVect)
+{
+#if (SBC_FAST_DCT == TRUE)
+#if (SBC_ARM_ASM_OPT==TRUE)
+#else
+#if (SBC_IPAQ_OPT==TRUE)
+#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
+    SINT64 s64Temp;
+#endif
+#else
+#if (SBC_IS_64_MULT_IN_IDCT == TRUE)
+    SINT32 s32HiTemp;
+#else
+    UINT16 s32In2Temp;
+    SINT32 s32In1Temp;
+#endif
+#endif
+#endif
+    SINT32 temp,x2;
+    SINT32 tmp[8];
+
+    x2=pInVect[2]>>1;
+    temp=(pInVect[0]+pInVect[4]);
+    SBC_IDCT_MULT((SBC_COS_PI_SUR_4>>1), temp , tmp[0]);
+    tmp[1]=x2-tmp[0];
+    tmp[0]+=x2;
+    temp=(pInVect[1]+pInVect[3]);
+    SBC_IDCT_MULT((SBC_COS_3PI_SUR_8>>1), temp , tmp[3]);
+    SBC_IDCT_MULT((SBC_COS_PI_SUR_8>>1), temp , tmp[2]);
+    temp=(pInVect[5]-pInVect[7]);
+    SBC_IDCT_MULT((SBC_COS_3PI_SUR_8>>1), temp , tmp[5]);
+    SBC_IDCT_MULT((SBC_COS_PI_SUR_8>>1), temp , tmp[4]);
+    tmp[6]=tmp[2]+tmp[5];
+    tmp[7]=tmp[3]-tmp[4];
+    pOutVect[0] = (tmp[0]+tmp[6]);
+    pOutVect[1] = (tmp[1]+tmp[7]);
+    pOutVect[2] = (tmp[1]-tmp[7]);
+    pOutVect[3] = (tmp[0]-tmp[6]);
+#else
+    UINT8 Index, k;
+    SINT32 temp;
+	/*Calculate 4 subband samples by matrixing*/
+    for(Index=0; Index<4; Index++)
+    {
+        temp = 0;
+        for(k=0; k<8; k++)
+        {
+            /*temp += (SINT32)(((SINT64)M[(Index*strEncParams->numOfSubBands*2)+k] * Y[k]) >> 16 ); */
+            temp += (gas16AnalDCTcoeff4[(Index*4*2)+k] * (pInVect[k] >> 16));
+            temp += ((gas16AnalDCTcoeff4[(Index*4*2)+k] * (pInVect[k] & 0xFFFF)) >> 16);
+        }
+        pOutVect[Index] = temp;
+    }
+#endif
+}

+ 200 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_dct_coeffs.c

@@ -0,0 +1,200 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the coefficient table used for DCT computation in
+ *  analysis.
+ *
+ ******************************************************************************/
+
+#include "sbc_encoder.h"
+/*DCT coeff for 4 sub-band case.*/
+#if (SBC_FAST_DCT == FALSE)
+const SINT16 gas16AnalDCTcoeff4[] =
+{
+	(SINT16)(0.7071*32768),
+	(SINT16)(0.9239*32768),
+	(SINT16)(1.0000*32767),
+	(SINT16)(0.9239*32768),
+	(SINT16)(0.7071*32768),
+	(SINT16)(0.3827*32768),
+	(SINT16)(0.0000*32768),
+	(SINT16)(-0.3827*32768),
+
+	(SINT16)(-0.7071*32768),
+	(SINT16)(0.3827*32768),
+	(SINT16)(1.0000*32767),
+	(SINT16)(0.3827*32768),
+	(SINT16)(-0.7071*32768),
+	(SINT16)(-0.9239*32768),
+	(SINT16)(-0.0000*32768),
+	(SINT16)(0.9239*32768),
+
+	(SINT16)(-0.7071*32768),
+	(SINT16)(-0.3827*32768),
+	(SINT16)(1.0000*32767),
+	(SINT16)(-0.3827*32768),
+	(SINT16)(-0.7071*32768),
+	(SINT16)(0.9239*32768),
+	(SINT16)(0.0000*32768),
+	(SINT16)(-0.9239*32768),
+
+	(SINT16)(0.7071*32768),
+	(SINT16)(-0.9239*32768),
+	(SINT16)(1.0000*32767),
+	(SINT16)(-0.9239*32768),
+	(SINT16)(0.7071*32768),
+	(SINT16)(-0.3827*32768),
+	(SINT16)(-0.0000*32768),
+	(SINT16)(0.3827*32768)
+};
+
+/*DCT coeff for 8 sub-band case.*/
+const SINT16 gas16AnalDCTcoeff8[] =
+{
+	(SINT16)(0.7071*32768),
+	(SINT16)(0.8315*32768),
+	(SINT16)(0.9239*32768),
+	(SINT16)(0.9808*32768),
+	(SINT16)(1.0000*32767),
+	(SINT16)(0.9808*32768),
+	(SINT16)(0.9239*32768),
+	(SINT16)(0.8315*32768),
+	(SINT16)(0.7071*32768),
+	(SINT16)(0.5556*32768),
+	(SINT16)(0.3827*32768),
+	(SINT16)(0.1951*32768),
+	(SINT16)(0.0000*32768),
+	(SINT16)(-0.1951*32768),
+	(SINT16)(-0.3827*32768),
+	(SINT16)(-0.5556*32768),
+	(SINT16)(-0.7071*32768),
+	(SINT16)(-0.1951*32768),
+	(SINT16)(0.3827*32768),
+	(SINT16)(0.8315*32768),
+	(SINT16)(1.0000*32767),
+	(SINT16)(0.8315*32768),
+	(SINT16)(0.3827*32768),
+	(SINT16)(-0.1951*32768),
+	(SINT16)(-0.7071*32768),
+	(SINT16)(-0.9808*32768),
+	(SINT16)(-0.9239*32768),
+	(SINT16)(-0.5556*32768),
+	(SINT16)(-0.0000*32768),
+	(SINT16)(0.5556*32768),
+	(SINT16)(0.9239*32768),
+	(SINT16)(0.9808*32768),
+	(SINT16)(-0.7071*32768),
+	(SINT16)(-0.9808*32768),
+	(SINT16)(-0.3827*32768),
+	(SINT16)(0.5556*32768),
+	(SINT16)(1.0000*32767),
+	(SINT16)(0.5556*32768),
+	(SINT16)(-0.3827*32768),
+	(SINT16)(-0.9808*32768),
+	(SINT16)(-0.7071*32768),
+	(SINT16)(0.1951*32768),
+	(SINT16)(0.9239*32768),
+	(SINT16)(0.8315*32768),
+	(SINT16)(0.0000*32768),
+	(SINT16)(-0.8315*32768),
+	(SINT16)(-0.9239*32768),
+	(SINT16)(-0.1951*32768),
+	(SINT16)(0.7071*32768),
+	(SINT16)(-0.5556*32768),
+	(SINT16)(-0.9239*32768),
+	(SINT16)(0.1951*32768),
+	(SINT16)(1.0000*32767),
+	(SINT16)(0.1951*32768),
+	(SINT16)(-0.9239*32768),
+	(SINT16)(-0.5556*32768),
+	(SINT16)(0.7071*32768),
+	(SINT16)(0.8315*32768),
+	(SINT16)(-0.3827*32768),
+	(SINT16)(-0.9808*32768),
+	(SINT16)(-0.0000*32768),
+	(SINT16)(0.9808*32768),
+	(SINT16)(0.3827*32768),
+	(SINT16)(-0.8315*32768),
+	(SINT16)(0.7071*32768),
+	(SINT16)(0.5556*32768),
+	(SINT16)(-0.9239*32768),
+	(SINT16)(-0.1951*32768),
+	(SINT16)(1.0000*32767),
+	(SINT16)(-0.1951*32768),
+	(SINT16)(-0.9239*32768),
+	(SINT16)(0.5556*32768),
+	(SINT16)(0.7071*32768),
+	(SINT16)(-0.8315*32768),
+	(SINT16)(-0.3827*32768),
+	(SINT16)(0.9808*32768),
+	(SINT16)(0.0000*32768),
+	(SINT16)(-0.9808*32768),
+	(SINT16)(0.3827*32768),
+	(SINT16)(0.8315*32768),
+	(SINT16)(-0.7071*32768),
+	(SINT16)(0.9808*32768),
+	(SINT16)(-0.3827*32768),
+	(SINT16)(-0.5556*32768),
+	(SINT16)(1.0000*32767),
+	(SINT16)(-0.5556*32768),
+	(SINT16)(-0.3827*32768),
+	(SINT16)(0.9808*32768),
+	(SINT16)(-0.7071*32768),
+	(SINT16)(-0.1951*32768),
+	(SINT16)(0.9239*32768),
+	(SINT16)(-0.8315*32768),
+	(SINT16)(-0.0000*32768),
+	(SINT16)(0.8315*32768),
+	(SINT16)(-0.9239*32768),
+	(SINT16)(0.1951*32768),
+	(SINT16)(-0.7071*32768),
+	(SINT16)(0.1951*32768),
+	(SINT16)(0.3827*32768),
+	(SINT16)(-0.8315*32768),
+	(SINT16)(1.0000*32767),
+	(SINT16)(-0.8315*32768),
+	(SINT16)(0.3827*32768),
+	(SINT16)(0.1951*32768),
+	(SINT16)(-0.7071*32768),
+	(SINT16)(0.9808*32768),
+	(SINT16)(-0.9239*32768),
+	(SINT16)(0.5556*32768),
+	(SINT16)(-0.0000*32768),
+	(SINT16)(-0.5556*32768),
+	(SINT16)(0.9239*32768),
+	(SINT16)(-0.9808*32768),
+	(SINT16)(0.7071*32768),
+	(SINT16)(-0.8315*32768),
+	(SINT16)(0.9239*32768),
+	(SINT16)(-0.9808*32768),
+	(SINT16)(1.0000*32767),
+	(SINT16)(-0.9808*32768),
+	(SINT16)(0.9239*32768),
+	(SINT16)(-0.8315*32768),
+	(SINT16)(0.7071*32768),
+	(SINT16)(-0.5556*32768),
+	(SINT16)(0.3827*32768),
+	(SINT16)(-0.1951*32768),
+	(SINT16)(-0.0000*32768),
+	(SINT16)(0.1951*32768),
+	(SINT16)(-0.3827*32768),
+	(SINT16)(0.5556*32768)
+};
+#endif

+ 199 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_enc_bit_alloc_mono.c

@@ -0,0 +1,199 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the code for bit allocation algorithm. It calculates
+ *  the number of bits required for the encoded stream of data.
+ *
+ ******************************************************************************/
+
+/*Includes*/
+#include "sbc_encoder.h"
+#include "sbc_enc_func_declare.h"
+
+/*global arrays*/
+const SINT16 sbc_enc_as16Offset4[4][4] = {  {-1, 0, 0, 0}, {-2, 0, 0, 1},
+                                    {-2, 0, 0, 1}, {-2, 0, 0, 1} };
+const SINT16 sbc_enc_as16Offset8[4][8] = {  {-2, 0, 0, 0, 0, 0, 0, 1},
+                                    {-3, 0, 0, 0, 0, 0, 1, 2},
+                                    {-4, 0, 0, 0, 0, 0, 1, 2},
+                                    {-4, 0, 0, 0, 0, 0, 1, 2} };
+
+/****************************************************************************
+* BitAlloc - Calculates the required number of bits for the given scale factor
+* and the number of subbands.
+*
+* RETURNS : N/A
+*/
+
+void sbc_enc_bit_alloc_mono(SBC_ENC_PARAMS *pstrCodecParams)
+{
+    SINT32 s32MaxBitNeed;   /*to store the max bits needed per sb*/
+    SINT32 s32BitCount;     /*the used number of bits*/
+    SINT32 s32SliceCount;   /*to store hwo many slices can be put in bitpool*/
+    SINT32 s32BitSlice;     /*number of bitslices in bitpool*/
+    SINT32 s32Sb;           /*counter for sub-band*/
+    SINT32 s32Ch;           /*counter for channel*/
+    SINT16 *ps16BitNeed;    /*temp memory to store required number of bits*/
+    SINT32 s32Loudness;     /*used in Loudness calculation*/
+    SINT16 *ps16GenBufPtr;
+    SINT16 *ps16GenArrPtr;
+    SINT16 *ps16GenTabPtr;
+    SINT32  s32NumOfSubBands = pstrCodecParams->s16NumOfSubBands;
+
+    ps16BitNeed = pstrCodecParams->s16ScartchMemForBitAlloc;
+
+    for (s32Ch = 0; s32Ch < pstrCodecParams->s16NumOfChannels; s32Ch++)
+    {
+        ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands;
+        ps16GenArrPtr = pstrCodecParams->as16Bits+s32Ch*SBC_MAX_NUM_OF_SUBBANDS;
+
+        /* bitneed values are derived from scale factor */
+        if (pstrCodecParams->s16AllocationMethod == SBC_SNR)
+        {
+            ps16BitNeed = pstrCodecParams->as16ScaleFactor;
+            ps16GenBufPtr = ps16BitNeed + s32Ch * s32NumOfSubBands;
+        }
+        else
+        {
+            ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands;
+            if(s32NumOfSubBands == 4)
+            {
+                ps16GenTabPtr = (SINT16 *)
+                    sbc_enc_as16Offset4[pstrCodecParams->s16SamplingFreq];
+            }
+            else
+            {
+                ps16GenTabPtr = (SINT16 *)
+                    sbc_enc_as16Offset8[pstrCodecParams->s16SamplingFreq];
+            }
+            for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++)
+            {
+                if(pstrCodecParams->as16ScaleFactor[s32Ch*s32NumOfSubBands+s32Sb] == 0)
+                    *(ps16GenBufPtr) = -5;
+                else
+                {
+                    s32Loudness =
+                        (SINT32)(pstrCodecParams->as16ScaleFactor[s32Ch*s32NumOfSubBands+s32Sb]
+                                                            - *ps16GenTabPtr);
+                    if(s32Loudness > 0)
+                        *(ps16GenBufPtr) = (SINT16)(s32Loudness >>1);
+                    else
+                        *(ps16GenBufPtr) = (SINT16)s32Loudness;
+                }
+                ps16GenBufPtr++;
+                ps16GenTabPtr++;
+            }
+
+        }
+
+        /* max bitneed index is searched*/
+        s32MaxBitNeed = 0;
+        ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands;
+        for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++)
+        {
+            if( *(ps16GenBufPtr) > s32MaxBitNeed)
+                s32MaxBitNeed = *(ps16GenBufPtr);
+
+            ps16GenBufPtr++;
+        }
+        ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands;
+        /*iterative process to find hwo many bitslices fit into the bitpool*/
+        s32BitSlice = s32MaxBitNeed + 1;
+        s32BitCount = pstrCodecParams->s16BitPool;
+        s32SliceCount = 0;
+        do
+        {
+            s32BitSlice --;
+            s32BitCount -= s32SliceCount;
+            s32SliceCount = 0;
+
+            for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++)
+            {
+                if( (((*ps16GenBufPtr-s32BitSlice)< 16) && (*ps16GenBufPtr-s32BitSlice) >= 1))
+                {
+                    if((*ps16GenBufPtr-s32BitSlice) == 1)
+                        s32SliceCount+=2;
+                    else
+                        s32SliceCount++;
+                }
+                ps16GenBufPtr++;
+
+            }/*end of for*/
+            ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands;
+        }while(s32BitCount-s32SliceCount>0);
+
+        if(s32BitCount == 0)
+        {
+            s32BitCount -= s32SliceCount;
+            s32BitSlice --;
+        }
+
+        /*Bits are distributed until the last bitslice is reached*/
+        ps16GenArrPtr = pstrCodecParams->as16Bits+s32Ch*s32NumOfSubBands;
+        ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands;
+        for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++)
+        {
+            if(*(ps16GenBufPtr) < s32BitSlice+2)
+                *(ps16GenArrPtr) = 0;
+            else
+                *(ps16GenArrPtr) = ((*(ps16GenBufPtr)-s32BitSlice)<16) ?
+                    (SINT16)(*(ps16GenBufPtr)-s32BitSlice) : 16;
+
+            ps16GenBufPtr++;
+            ps16GenArrPtr++;
+        }
+        ps16GenArrPtr = pstrCodecParams->as16Bits+s32Ch*s32NumOfSubBands;
+        ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands;
+        /*the remaining bits are allocated starting at subband 0*/
+        s32Sb=0;
+        while( (s32BitCount > 0) && (s32Sb < s32NumOfSubBands) )
+        {
+            if( (*(ps16GenArrPtr) >= 2) && (*(ps16GenArrPtr) < 16) )
+            {
+                (*(ps16GenArrPtr))++;
+                s32BitCount--;
+            }
+            else if( (*(ps16GenBufPtr) == s32BitSlice+1) &&
+                (s32BitCount > 1) )
+            {
+                *(ps16GenArrPtr) = 2;
+                s32BitCount -= 2;
+            }
+            s32Sb++;
+            ps16GenArrPtr++;
+            ps16GenBufPtr++;
+        }
+        ps16GenArrPtr = pstrCodecParams->as16Bits+s32Ch*s32NumOfSubBands;
+
+
+        s32Sb=0;
+        while( (s32BitCount > 0) && (s32Sb < s32NumOfSubBands) )
+        {
+            if( *(ps16GenArrPtr) < 16)
+            {
+                (*(ps16GenArrPtr))++;
+                s32BitCount--;
+            }
+            s32Sb++;
+            ps16GenArrPtr++;
+        }
+    }
+}
+/*End of BitAlloc() function*/

+ 212 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c

@@ -0,0 +1,212 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the code for bit allocation algorithm. It calculates
+ *  the number of bits required for the encoded stream of data.
+ *
+ ******************************************************************************/
+
+/*Includes*/
+#include "sbc_encoder.h"
+#include "sbc_enc_func_declare.h"
+
+/*global arrays*/
+extern const SINT16 sbc_enc_as16Offset4[4][4];
+extern const SINT16 sbc_enc_as16Offset8[4][8];
+
+/****************************************************************************
+* BitAlloc - Calculates the required number of bits for the given scale factor
+* and the number of subbands.
+*
+* RETURNS : N/A
+*/
+
+void sbc_enc_bit_alloc_ste(SBC_ENC_PARAMS *pstrCodecParams)
+{
+	/* CAUTIOM -> mips optim for arm 32 require to use SINT32 instead of SINT16 */
+	/* Do not change variable type or name */
+    SINT32 s32MaxBitNeed;   /*to store the max bits needed per sb*/
+    SINT32 s32BitCount;     /*the used number of bits*/
+    SINT32 s32SliceCount;   /*to store hwo many slices can be put in bitpool*/
+    SINT32 s32BitSlice;     /*number of bitslices in bitpool*/
+    SINT32 s32Sb;           /*counter for sub-band*/
+    SINT32 s32Ch;           /*counter for channel*/
+    SINT16 *ps16BitNeed;    /*temp memory to store required number of bits*/
+    SINT32 s32Loudness;     /*used in Loudness calculation*/
+    SINT16 *ps16GenBufPtr,*pas16ScaleFactor;
+    SINT16 *ps16GenArrPtr;
+    SINT16 *ps16GenTabPtr;
+    SINT32  s32NumOfSubBands = pstrCodecParams->s16NumOfSubBands;
+    SINT32  s32BitPool       = pstrCodecParams->s16BitPool;
+
+    /* bitneed values are derived from scale factor */
+    if (pstrCodecParams->s16AllocationMethod == SBC_SNR)
+    {
+        ps16BitNeed   = pstrCodecParams->as16ScaleFactor;
+        s32MaxBitNeed = pstrCodecParams->s16MaxBitNeed;
+    }
+    else
+    {
+        ps16BitNeed   = pstrCodecParams->s16ScartchMemForBitAlloc;
+        pas16ScaleFactor=pstrCodecParams->as16ScaleFactor;
+        s32MaxBitNeed = 0;
+        ps16GenBufPtr = ps16BitNeed;
+        for (s32Ch = 0; s32Ch < 2; s32Ch++)
+        {
+            if (s32NumOfSubBands == 4)
+            {
+                ps16GenTabPtr = (SINT16 *)sbc_enc_as16Offset4[pstrCodecParams->s16SamplingFreq];
+            }
+            else
+            {
+                ps16GenTabPtr = (SINT16 *)sbc_enc_as16Offset8[pstrCodecParams->s16SamplingFreq];
+            }
+
+            for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++)
+            {
+                if (*pas16ScaleFactor == 0)
+                    *ps16GenBufPtr = -5;
+                else
+                {
+                    s32Loudness = (SINT32)(*pas16ScaleFactor - *ps16GenTabPtr);
+
+                    if (s32Loudness > 0)
+                        *ps16GenBufPtr = (SINT16)(s32Loudness >> 1);
+                    else
+                        *ps16GenBufPtr = (SINT16)s32Loudness;
+                }
+
+                if (*ps16GenBufPtr > s32MaxBitNeed)
+                    s32MaxBitNeed = *ps16GenBufPtr;
+                pas16ScaleFactor++;
+                ps16GenBufPtr++;
+                ps16GenTabPtr++;
+            }
+        }
+    }
+
+    /* iterative process to find out hwo many bitslices fit into the bitpool */
+    s32BitSlice = s32MaxBitNeed + 1;
+    s32BitCount = s32BitPool;
+    s32SliceCount = 0;
+    do
+    {
+        s32BitSlice --;
+        s32BitCount -= s32SliceCount;
+        s32SliceCount = 0;
+        ps16GenBufPtr = ps16BitNeed;
+
+        for (s32Sb = 0; s32Sb < 2*s32NumOfSubBands; s32Sb++)
+        {
+            if ( (*ps16GenBufPtr >= s32BitSlice + 1) && (*ps16GenBufPtr < s32BitSlice + 16) )
+            {
+                if (*(ps16GenBufPtr) == s32BitSlice+1)
+                    s32SliceCount += 2;
+                else
+                    s32SliceCount++;
+            }
+            ps16GenBufPtr++;
+        }
+    } while (s32BitCount-s32SliceCount>0);
+
+    if (s32BitCount-s32SliceCount == 0)
+    {
+        s32BitCount -= s32SliceCount;
+        s32BitSlice --;
+    }
+
+    /* Bits are distributed until the last bitslice is reached */
+    ps16GenBufPtr = ps16BitNeed;
+    ps16GenArrPtr = pstrCodecParams->as16Bits;
+    for (s32Ch = 0; s32Ch < 2; s32Ch++)
+    {
+        for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++)
+        {
+            if (*ps16GenBufPtr < s32BitSlice+2)
+                *ps16GenArrPtr = 0;
+            else
+                *ps16GenArrPtr = ((*(ps16GenBufPtr)-s32BitSlice) < 16) ?
+                                        (SINT16)(*(ps16GenBufPtr)-s32BitSlice):16;
+            ps16GenBufPtr++;
+            ps16GenArrPtr++;
+        }
+    }
+
+    /* the remaining bits are allocated starting at subband 0 */
+    s32Ch=0;
+    s32Sb=0;
+    ps16GenBufPtr = ps16BitNeed;
+    ps16GenArrPtr -= 2*s32NumOfSubBands;
+
+    while ( (s32BitCount > 0) && (s32Sb < s32NumOfSubBands) )
+    {
+        if ( (*(ps16GenArrPtr) >= 2) && (*(ps16GenArrPtr) < 16) )
+        {
+            (*(ps16GenArrPtr))++;
+            s32BitCount--;
+        }
+        else if ((*ps16GenBufPtr == s32BitSlice+1) && (s32BitCount > 1))
+        {
+            *(ps16GenArrPtr) = 2;
+            s32BitCount -= 2;
+        }
+        if(s32Ch == 1)
+        {
+            s32Ch = 0;
+            s32Sb++;
+            ps16GenBufPtr = ps16BitNeed+s32Sb;
+            ps16GenArrPtr = pstrCodecParams->as16Bits+s32Sb;
+
+        }
+        else
+        {
+            s32Ch =1;
+            ps16GenBufPtr = ps16BitNeed+s32NumOfSubBands+s32Sb;
+            ps16GenArrPtr = pstrCodecParams->as16Bits+s32NumOfSubBands+s32Sb;
+        }
+    }
+
+    s32Ch=0;
+    s32Sb=0;
+    ps16GenArrPtr = pstrCodecParams->as16Bits;
+
+    while ((s32BitCount >0) && (s32Sb < s32NumOfSubBands))
+    {
+        if(*(ps16GenArrPtr) < 16)
+        {
+            (*(ps16GenArrPtr))++;
+            s32BitCount--;
+        }
+        if (s32Ch == 1)
+        {
+            s32Ch = 0;
+            s32Sb++;
+            ps16GenArrPtr = pstrCodecParams->as16Bits+s32Sb;
+        }
+        else
+        {
+            s32Ch = 1;
+            ps16GenArrPtr = pstrCodecParams->as16Bits+s32NumOfSubBands+s32Sb;
+        }
+    }
+}
+
+/*End of BitAlloc() function*/
+

+ 319 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_enc_coeffs.c

@@ -0,0 +1,319 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains the Windowing coeffs for synthesis filter
+ *
+ ******************************************************************************/
+
+#include "sbc_encoder.h"
+
+#if (SBC_ARM_ASM_OPT==FALSE && SBC_IPAQ_OPT==FALSE)
+#if (SBC_IS_64_MULT_IN_WINDOW_ACCU ==  FALSE)
+/*Window coeff for 4 sub band case*/
+const SINT16 gas32CoeffFor4SBs[] =
+{
+    (SINT16)((SINT32)0x00000000 >> 16),	(SINT16)0x00000000,
+	(SINT16)((SINT32)0x001194E6 >> 16),	(SINT16)0x001194E6,
+	(SINT16)((SINT32)0x0030E2D3 >> 16),	(SINT16)0x0030E2D3,
+	(SINT16)((SINT32)0x00599403 >> 16),	(SINT16)0x00599403,
+	(SINT16)((SINT32)0x007DBCC8 >> 16),	(SINT16)0x007DBCC8,
+	(SINT16)((SINT32)0x007F88E4 >> 16),	(SINT16)0x007F88E4,
+	(SINT16)((SINT32)0x003D239B >> 16),	(SINT16)0x003D239B,
+	(SINT16)((SINT32)0xFF9BB9D5 >> 16),	(SINT16)0xFF9BB9D5,
+
+	(SINT16)((SINT32)0x01659F45 >> 16),	(SINT16)0x01659F45,
+	(SINT16)((SINT32)0x029DBAA3 >> 16),	(SINT16)0x029DBAA3,
+	(SINT16)((SINT32)0x03B23341 >> 16),	(SINT16)0x03B23341,
+	(SINT16)((SINT32)0x041EEE40 >> 16),	(SINT16)0x041EEE40,
+	(SINT16)((SINT32)0x034FEE2C >> 16),	(SINT16)0x034FEE2C,
+	(SINT16)((SINT32)0x00C8F2BC >> 16),	(SINT16)0x00C8F2BC,
+	(SINT16)((SINT32)0xFC4F91D4 >> 16),	(SINT16)0xFC4F91D4,
+	(SINT16)((SINT32)0xF60FAF37 >> 16),	(SINT16)0xF60FAF37,
+
+	(SINT16)((SINT32)0x115B1ED2 >> 16),	(SINT16)0x115B1ED2,
+	(SINT16)((SINT32)0x18F55C90 >> 16),	(SINT16)0x18F55C90,
+	(SINT16)((SINT32)0x1F91CA46 >> 16),	(SINT16)0x1F91CA46,
+	(SINT16)((SINT32)0x2412F251 >> 16),	(SINT16)0x2412F251,
+	(SINT16)((SINT32)0x25AC1FF2 >> 16),	(SINT16)0x25AC1FF2,
+	(SINT16)((SINT32)0x2412F251 >> 16),	(SINT16)0x2412F251,
+	(SINT16)((SINT32)0x1F91CA46 >> 16),	(SINT16)0x1F91CA46,
+	(SINT16)((SINT32)0x18F55C90 >> 16),	(SINT16)0x18F55C90,
+
+	(SINT16)((SINT32)0xEEA4E12E >> 16),	(SINT16)0xEEA4E12E,
+	(SINT16)((SINT32)0xF60FAF37 >> 16),	(SINT16)0xF60FAF37,
+	(SINT16)((SINT32)0xFC4F91D4 >> 16),	(SINT16)0xFC4F91D4,
+	(SINT16)((SINT32)0x00C8F2BC >> 16),	(SINT16)0x00C8F2BC,
+	(SINT16)((SINT32)0x034FEE2C >> 16),	(SINT16)0x034FEE2C,
+	(SINT16)((SINT32)0x041EEE40 >> 16),	(SINT16)0x041EEE40,
+	(SINT16)((SINT32)0x03B23341 >> 16),	(SINT16)0x03B23341,
+	(SINT16)((SINT32)0x029DBAA3 >> 16),	(SINT16)0x029DBAA3,
+
+	(SINT16)((SINT32)0xFE9A60BB >> 16),	(SINT16)0xFE9A60BB,
+	(SINT16)((SINT32)0xFF9BB9D5 >> 16),	(SINT16)0xFF9BB9D5,
+	(SINT16)((SINT32)0x003D239B >> 16),	(SINT16)0x003D239B,
+	(SINT16)((SINT32)0x007F88E4 >> 16),	(SINT16)0x007F88E4,
+	(SINT16)((SINT32)0x007DBCC8 >> 16),	(SINT16)0x007DBCC8,
+	(SINT16)((SINT32)0x00599403 >> 16),	(SINT16)0x00599403,
+	(SINT16)((SINT32)0x0030E2D3 >> 16),	(SINT16)0x0030E2D3,
+	(SINT16)((SINT32)0x001194E6 >> 16),	(SINT16)0x001194E6
+};
+
+/*Window coeff for 8 sub band case*/
+const SINT16 gas32CoeffFor8SBs[] =
+{
+    (SINT16)((SINT32)0x00000000 >>16),	(SINT16)0x00000000,
+	(SINT16)((SINT32)0x00052173 >>16),	(SINT16)0x00052173,
+	(SINT16)((SINT32)0x000B3F71 >>16),	(SINT16)0x000B3F71,
+	(SINT16)((SINT32)0x00122C7D >>16),	(SINT16)0x00122C7D,
+	(SINT16)((SINT32)0x001AFF89 >>16),	(SINT16)0x001AFF89,
+	(SINT16)((SINT32)0x00255A62 >>16),	(SINT16)0x00255A62,
+	(SINT16)((SINT32)0x003060F4 >>16),	(SINT16)0x003060F4,
+	(SINT16)((SINT32)0x003A72E7 >>16),	(SINT16)0x003A72E7,
+
+	(SINT16)((SINT32)0x0041EC6A >>16),	(SINT16)0x0041EC6A,  /* 8 */
+	(SINT16)((SINT32)0x0044EF48 >>16),	(SINT16)0x0044EF48,
+	(SINT16)((SINT32)0x00415B75 >>16),	(SINT16)0x00415B75,
+	(SINT16)((SINT32)0x0034F8B6 >>16),	(SINT16)0x0034F8B6,
+	(SINT16)((SINT32)0x001D8FD2 >>16),	(SINT16)0x001D8FD2,
+	(SINT16)((SINT32)0xFFFA2413 >>16),	(SINT16)0xFFFA2413,
+	(SINT16)((SINT32)0xFFC9F10E >>16),	(SINT16)0xFFC9F10E,
+	(SINT16)((SINT32)0xFF8D6793 >>16),	(SINT16)0xFF8D6793,
+
+	(SINT16)((SINT32)0x00B97348 >>16),	(SINT16)0x00B97348,  /* 16 */
+	(SINT16)((SINT32)0x01071B96 >>16),	(SINT16)0x01071B96,
+	(SINT16)((SINT32)0x0156B3CA >>16),	(SINT16)0x0156B3CA,
+	(SINT16)((SINT32)0x01A1B38B >>16),	(SINT16)0x01A1B38B,
+	(SINT16)((SINT32)0x01E0224C >>16),	(SINT16)0x01E0224C,
+	(SINT16)((SINT32)0x0209291F >>16),	(SINT16)0x0209291F,
+	(SINT16)((SINT32)0x02138653 >>16),	(SINT16)0x02138653,
+	(SINT16)((SINT32)0x01F5F424 >>16),	(SINT16)0x01F5F424,
+
+	(SINT16)((SINT32)0x01A7ECEF >>16),	(SINT16)0x01A7ECEF, /* 24 */
+	(SINT16)((SINT32)0x01223EBA >>16),	(SINT16)0x01223EBA,
+	(SINT16)((SINT32)0x005FD0FF >>16),	(SINT16)0x005FD0FF,
+	(SINT16)((SINT32)0xFF5EEB73 >>16),	(SINT16)0xFF5EEB73,
+	(SINT16)((SINT32)0xFE20435D >>16),	(SINT16)0xFE20435D,
+	(SINT16)((SINT32)0xFCA86E7E >>16),	(SINT16)0xFCA86E7E,
+	(SINT16)((SINT32)0xFAFF95FC >>16),	(SINT16)0xFAFF95FC,
+	(SINT16)((SINT32)0xF9312891 >>16),	(SINT16)0xF9312891,
+
+	(SINT16)((SINT32)0x08B4307A >>16),	(SINT16)0x08B4307A, /* 32 */
+	(SINT16)((SINT32)0x0A9F3E9A >>16),	(SINT16)0x0A9F3E9A,
+	(SINT16)((SINT32)0x0C7D59B6 >>16),	(SINT16)0x0C7D59B6,
+	(SINT16)((SINT32)0x0E3BB16F >>16),	(SINT16)0x0E3BB16F,
+	(SINT16)((SINT32)0x0FC721F9 >>16),	(SINT16)0x0FC721F9,
+	(SINT16)((SINT32)0x110ECEF0 >>16),	(SINT16)0x110ECEF0,
+	(SINT16)((SINT32)0x120435FA >>16),	(SINT16)0x120435FA,
+	(SINT16)((SINT32)0x129C226F >>16),	(SINT16)0x129C226F,
+
+	(SINT16)((SINT32)0x12CF6C75 >>16),	(SINT16)0x12CF6C75, /* 40 */
+	(SINT16)((SINT32)0x129C226F >>16),	(SINT16)0x129C226F,
+	(SINT16)((SINT32)0x120435FA >>16),	(SINT16)0x120435FA,
+	(SINT16)((SINT32)0x110ECEF0 >>16),	(SINT16)0x110ECEF0,
+	(SINT16)((SINT32)0x0FC721F9 >>16),	(SINT16)0x0FC721F9,
+	(SINT16)((SINT32)0x0E3BB16F >>16),	(SINT16)0x0E3BB16F,
+	(SINT16)((SINT32)0x0C7D59B6 >>16),	(SINT16)0x0C7D59B6,
+	(SINT16)((SINT32)0x0A9F3E9A >>16),	(SINT16)0x0A9F3E9A,
+
+	(SINT16)((SINT32)0xF74BCF86 >>16),	(SINT16)0xF74BCF86, /* 48 */
+	(SINT16)((SINT32)0xF9312891 >>16),	(SINT16)0xF9312891,
+	(SINT16)((SINT32)0xFAFF95FC >>16),	(SINT16)0xFAFF95FC,
+	(SINT16)((SINT32)0xFCA86E7E >>16),	(SINT16)0xFCA86E7E,
+	(SINT16)((SINT32)0xFE20435D >>16),	(SINT16)0xFE20435D,
+	(SINT16)((SINT32)0xFF5EEB73 >>16),	(SINT16)0xFF5EEB73,
+	(SINT16)((SINT32)0x005FD0FF >>16),	(SINT16)0x005FD0FF,
+	(SINT16)((SINT32)0x01223EBA >>16),	(SINT16)0x01223EBA,
+
+	(SINT16)((SINT32)0x01A7ECEF >>16),	(SINT16)0x01A7ECEF, /* 56 */
+	(SINT16)((SINT32)0x01F5F424 >>16),	(SINT16)0x01F5F424,
+	(SINT16)((SINT32)0x02138653 >>16),	(SINT16)0x02138653,
+	(SINT16)((SINT32)0x0209291F >>16),	(SINT16)0x0209291F,
+	(SINT16)((SINT32)0x01E0224C >>16),	(SINT16)0x01E0224C,
+	(SINT16)((SINT32)0x01A1B38B >>16),	(SINT16)0x01A1B38B,
+	(SINT16)((SINT32)0x0156B3CA >>16),	(SINT16)0x0156B3CA,
+	(SINT16)((SINT32)0x01071B96 >>16),	(SINT16)0x01071B96,
+
+	(SINT16)((SINT32)0xFF468CB8 >>16),	(SINT16)0xFF468CB8, /* 64 */
+	(SINT16)((SINT32)0xFF8D6793 >>16),	(SINT16)0xFF8D6793,
+	(SINT16)((SINT32)0xFFC9F10E >>16),	(SINT16)0xFFC9F10E,
+	(SINT16)((SINT32)0xFFFA2413 >>16),	(SINT16)0xFFFA2413,
+	(SINT16)((SINT32)0x001D8FD2 >>16),	(SINT16)0x001D8FD2,
+	(SINT16)((SINT32)0x0034F8B6 >>16),	(SINT16)0x0034F8B6,
+	(SINT16)((SINT32)0x00415B75 >>16),	(SINT16)0x00415B75,
+	(SINT16)((SINT32)0x0044EF48 >>16),	(SINT16)0x0044EF48,
+
+	(SINT16)((SINT32)0x0041EC6A >>16),	(SINT16)0x0041EC6A, /* 72 */
+	(SINT16)((SINT32)0x003A72E7 >>16),	(SINT16)0x003A72E7,
+	(SINT16)((SINT32)0x003060F4 >>16),	(SINT16)0x003060F4,
+	(SINT16)((SINT32)0x00255A62 >>16),	(SINT16)0x00255A62,
+	(SINT16)((SINT32)0x001AFF89 >>16),	(SINT16)0x001AFF89,
+	(SINT16)((SINT32)0x00122C7D >>16),	(SINT16)0x00122C7D,
+	(SINT16)((SINT32)0x000B3F71 >>16),	(SINT16)0x000B3F71,
+	(SINT16)((SINT32)0x00052173 >>16),	(SINT16)0x00052173
+};
+
+#else
+
+/*Window coeff for 4 sub band case*/
+const SINT32 gas32CoeffFor4SBs[] =
+{
+    (SINT32)0x00000000,
+	(SINT32)0x001194E6,
+	(SINT32)0x0030E2D3,
+	(SINT32)0x00599403,
+	(SINT32)0x007DBCC8,
+	(SINT32)0x007F88E4,
+	(SINT32)0x003D239B,
+	(SINT32)0xFF9BB9D5,
+
+	(SINT32)0x01659F45,
+	(SINT32)0x029DBAA3,
+	(SINT32)0x03B23341,
+	(SINT32)0x041EEE40,
+	(SINT32)0x034FEE2C,
+	(SINT32)0x00C8F2BC,
+	(SINT32)0xFC4F91D4,
+	(SINT32)0xF60FAF37,
+
+	(SINT32)0x115B1ED2,
+	(SINT32)0x18F55C90,
+	(SINT32)0x1F91CA46,
+	(SINT32)0x2412F251,
+	(SINT32)0x25AC1FF2,
+	(SINT32)0x2412F251,
+	(SINT32)0x1F91CA46,
+	(SINT32)0x18F55C90,
+
+	(SINT32)0xEEA4E12E,
+	(SINT32)0xF60FAF37,
+	(SINT32)0xFC4F91D4,
+	(SINT32)0x00C8F2BC,
+	(SINT32)0x034FEE2C,
+	(SINT32)0x041EEE40,
+	(SINT32)0x03B23341,
+	(SINT32)0x029DBAA3,
+
+	(SINT32)0xFE9A60BB,
+	(SINT32)0xFF9BB9D5,
+	(SINT32)0x003D239B,
+	(SINT32)0x007F88E4,
+	(SINT32)0x007DBCC8,
+	(SINT32)0x00599403,
+	(SINT32)0x0030E2D3,
+	(SINT32)0x001194E6
+};
+
+/*Window coeff for 8 sub band case*/
+const SINT32 gas32CoeffFor8SBs[] =
+{
+    (SINT32)0x00000000,
+	(SINT32)0x00052173,
+	(SINT32)0x000B3F71,
+	(SINT32)0x00122C7D,
+	(SINT32)0x001AFF89,
+	(SINT32)0x00255A62,
+	(SINT32)0x003060F4,
+	(SINT32)0x003A72E7,
+
+	(SINT32)0x0041EC6A,  /* 8 */
+	(SINT32)0x0044EF48,
+	(SINT32)0x00415B75,
+	(SINT32)0x0034F8B6,
+	(SINT32)0x001D8FD2,
+	(SINT32)0xFFFA2413,
+	(SINT32)0xFFC9F10E,
+	(SINT32)0xFF8D6793,
+
+	(SINT32)0x00B97348,  /* 16 */
+	(SINT32)0x01071B96,
+	(SINT32)0x0156B3CA,
+	(SINT32)0x01A1B38B,
+	(SINT32)0x01E0224C,
+	(SINT32)0x0209291F,
+	(SINT32)0x02138653,
+	(SINT32)0x01F5F424,
+
+	(SINT32)0x01A7ECEF, /* 24 */
+	(SINT32)0x01223EBA,
+	(SINT32)0x005FD0FF,
+	(SINT32)0xFF5EEB73,
+	(SINT32)0xFE20435D,
+	(SINT32)0xFCA86E7E,
+	(SINT32)0xFAFF95FC,
+	(SINT32)0xF9312891,
+
+	(SINT32)0x08B4307A, /* 32 */
+	(SINT32)0x0A9F3E9A,
+	(SINT32)0x0C7D59B6,
+	(SINT32)0x0E3BB16F,
+	(SINT32)0x0FC721F9,
+	(SINT32)0x110ECEF0,
+	(SINT32)0x120435FA,
+	(SINT32)0x129C226F,
+
+	(SINT32)0x12CF6C75, /* 40 */
+	(SINT32)0x129C226F,
+	(SINT32)0x120435FA,
+	(SINT32)0x110ECEF0,
+	(SINT32)0x0FC721F9,
+	(SINT32)0x0E3BB16F,
+	(SINT32)0x0C7D59B6,
+	(SINT32)0x0A9F3E9A,
+
+	(SINT32)0xF74BCF86, /* 48 */
+	(SINT32)0xF9312891,
+	(SINT32)0xFAFF95FC,
+	(SINT32)0xFCA86E7E,
+	(SINT32)0xFE20435D,
+	(SINT32)0xFF5EEB73,
+	(SINT32)0x005FD0FF,
+	(SINT32)0x01223EBA,
+
+	(SINT32)0x01A7ECEF, /* 56 */
+	(SINT32)0x01F5F424,
+	(SINT32)0x02138653,
+	(SINT32)0x0209291F,
+	(SINT32)0x01E0224C,
+	(SINT32)0x01A1B38B,
+	(SINT32)0x0156B3CA,
+	(SINT32)0x01071B96,
+
+	(SINT32)0xFF468CB8, /* 64 */
+	(SINT32)0xFF8D6793,
+	(SINT32)0xFFC9F10E,
+	(SINT32)0xFFFA2413,
+	(SINT32)0x001D8FD2,
+	(SINT32)0x0034F8B6,
+	(SINT32)0x00415B75,
+	(SINT32)0x0044EF48,
+
+	(SINT32)0x0041EC6A, /* 72 */
+	(SINT32)0x003A72E7,
+	(SINT32)0x003060F4,
+	(SINT32)0x00255A62,
+	(SINT32)0x001AFF89,
+	(SINT32)0x00122C7D,
+	(SINT32)0x000B3F71,
+	(SINT32)0x00052173
+};
+
+#endif
+#endif
+

+ 402 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_encoder.c

@@ -0,0 +1,402 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  contains code for encoder flow and initalization of encoder
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "bt_target.h"
+#include "sbc_encoder.h"
+#include "sbc_enc_func_declare.h"
+
+SINT16 EncMaxShiftCounter;
+
+/*************************************************************************************************
+ * SBC encoder scramble code
+ * Purpose: to tie the SBC code with BTE/mobile stack code,
+ *          especially for the case when the SBC is ported into a third-party Multimedia chip
+ *
+ * Algorithm:
+ *  init process: all counters reset to 0,
+ *                calculate base_index: (6 + s16NumOfChannels*s16NumOfSubBands/2)
+ *    scramble side:    the init process happens every time SBC_Encoder_Init() is called.
+ *    descramble side:  it would be nice to know if he "init" process has happened.
+ *                      alter the SBC SYNC word 0x9C (1001 1100) to 0x8C (1000 1100).
+ *
+ *  scramble process:
+ *    The CRC byte:
+ *    Every SBC frame has a frame header.
+ *    The 1st byte is the sync word and the following 2 bytes are about the stream format.
+ *    They are supposed to be "constant" within a "song"
+ *    The 4th byte is the CRC byte. The CRC byte is bound to be random.
+ *    Derive 2 items from the CRC byte; one is the "use" bit, the other is the "index".
+ *
+ *    SBC keeps 2 sets of "use" & "index"; derived the current and the previous frame.
+ *
+ *    The "use" bit is any bit in SBC_PRTC_USE_MASK is set.
+ *    If set, SBC uses the "index" from the current frame.
+ *    If not set, SBC uses the "index" from the previous frame or 0.
+ *
+ *    index = (CRC & 0x3) + ((CRC & 0x30) >> 2) // 8 is the max index
+ *
+ *    if(index > 0)
+ *    {
+ *        p = &u8frame[base_index];
+ *        if((index&1)&&(u16PacketLength > (base_index+index*2)))
+ *        {
+ *            // odd index: swap 2 bytes
+ *            tmp = p[index];
+ *            p[index] = p[index*2];
+ *            p[index*2] = tmp;
+ *        }
+ *        else
+ *        {
+ *            // even index: shift by 3
+ *            tmp = (p[index] >> 5) + (p[index] << 3);
+ *            p[index] = tmp;
+ *        }
+ *    }
+ *    //else index is 0. The frame stays unaltered
+ *
+ */
+
+#define SBC_PRTC_CRC_IDX        3
+#define SBC_PRTC_USE_MASK       0x64
+#define SBC_PRTC_SYNC_MASK      0x10
+#define SBC_PRTC_CIDX           0
+#define SBC_PRTC_LIDX           1
+typedef struct
+{
+    UINT8   use;
+    UINT8   idx;
+} tSBC_FR_CB;
+
+typedef struct
+{
+    tSBC_FR_CB      fr[2];
+    UINT8           init;
+    UINT8           index;
+    UINT8           base;
+} tSBC_PRTC_CB;
+tSBC_PRTC_CB sbc_prtc_cb;
+
+#define SBC_PRTC_IDX(sc) (((sc) & 0x3) + (((sc) & 0x30) >> 2))
+#define SBC_PRTC_CHK_INIT(ar) {if(sbc_prtc_cb.init == 0){sbc_prtc_cb.init=1; ar[0] &= ~SBC_PRTC_SYNC_MASK;}}
+#define SBC_PRTC_C2L() {p_last=&sbc_prtc_cb.fr[SBC_PRTC_LIDX]; p_cur=&sbc_prtc_cb.fr[SBC_PRTC_CIDX]; \
+                        p_last->idx = p_cur->idx; p_last->use = p_cur->use;}
+#define SBC_PRTC_GETC(ar) {p_cur->use = ar[SBC_PRTC_CRC_IDX] & SBC_PRTC_USE_MASK; \
+                           p_cur->idx = SBC_PRTC_IDX(ar[SBC_PRTC_CRC_IDX]);}
+#define SBC_PRTC_CHK_CRC(ar) {SBC_PRTC_C2L();SBC_PRTC_GETC(ar);sbc_prtc_cb.index = (p_cur->use)?SBC_PRTC_CIDX:SBC_PRTC_LIDX;}
+#define SBC_PRTC_SCRMB(ar) {idx = sbc_prtc_cb.fr[sbc_prtc_cb.index].idx; \
+    if(idx > 0){if((idx&1)&&(pstrEncParams->u16PacketLength > (sbc_prtc_cb.base+(idx<<1)))) {tmp2=idx<<1; tmp=ar[idx];ar[idx]=ar[tmp2];ar[tmp2]=tmp;} \
+                else{tmp2=ar[idx]; tmp=(tmp2>>5)+(tmp2<<3);ar[idx]=(UINT8)tmp;}}}
+
+#if (SBC_JOINT_STE_INCLUDED == TRUE)
+SINT32   s32LRDiff[SBC_MAX_NUM_OF_BLOCKS]    = {0};
+SINT32   s32LRSum[SBC_MAX_NUM_OF_BLOCKS]     = {0};
+#endif
+
+void SBC_Encoder(SBC_ENC_PARAMS *pstrEncParams)
+{
+    SINT32 s32Ch;                               /* counter for ch*/
+    SINT32 s32Sb;                               /* counter for sub-band*/
+    UINT32 u32Count, maxBit = 0;                          /* loop count*/
+    SINT32 s32MaxValue;                         /* temp variable to store max value */
+
+    SINT16 *ps16ScfL;
+    SINT32 *SbBuffer;
+    SINT32 s32Blk;                              /* counter for block*/
+    SINT32  s32NumOfBlocks   = pstrEncParams->s16NumOfBlocks;
+#if (SBC_JOINT_STE_INCLUDED == TRUE)
+    SINT32 s32MaxValue2;
+    UINT32 u32CountSum,u32CountDiff;
+    SINT32 *pSum, *pDiff;
+#endif
+    UINT8  *pu8;
+    tSBC_FR_CB  *p_cur, *p_last;
+    UINT32       idx, tmp, tmp2;
+    register SINT32  s32NumOfSubBands = pstrEncParams->s16NumOfSubBands;
+
+    pstrEncParams->pu8NextPacket = pstrEncParams->pu8Packet;
+
+#if (SBC_NO_PCM_CPY_OPTION == TRUE)
+    pstrEncParams->ps16NextPcmBuffer = pstrEncParams->ps16PcmBuffer;
+#else
+    pstrEncParams->ps16NextPcmBuffer  = pstrEncParams->as16PcmBuffer;
+#endif
+    do
+    {
+        /* SBC ananlysis filter*/
+        if (s32NumOfSubBands == 4)
+            SbcAnalysisFilter4(pstrEncParams);
+        else
+            SbcAnalysisFilter8(pstrEncParams);
+
+        /* compute the scale factor, and save the max */
+        ps16ScfL = pstrEncParams->as16ScaleFactor;
+        s32Ch=pstrEncParams->s16NumOfChannels*s32NumOfSubBands;
+
+            pstrEncParams->ps16NextPcmBuffer+=s32Ch*s32NumOfBlocks; /* in case of multible sbc frame to encode update the pcm pointer */
+
+        for (s32Sb=0; s32Sb<s32Ch; s32Sb++)
+        {
+            SbBuffer=pstrEncParams->s32SbBuffer+s32Sb;
+            s32MaxValue=0;
+            for (s32Blk=s32NumOfBlocks;s32Blk>0;s32Blk--)
+            {
+                if (s32MaxValue<abs32(*SbBuffer))
+                    s32MaxValue=abs32(*SbBuffer);
+                SbBuffer+=s32Ch;
+            }
+
+            u32Count = (s32MaxValue > 0x800000) ? 9 : 0;
+
+            for ( ; u32Count < 15; u32Count++)
+            {
+                if (s32MaxValue <= (SINT32)(0x8000 << u32Count))
+                    break;
+            }
+            *ps16ScfL++ = (SINT16)u32Count;
+
+            if (u32Count > maxBit)
+                maxBit = u32Count;
+        }
+        /* In case of JS processing,check whether to use JS */
+#if (SBC_JOINT_STE_INCLUDED == TRUE)
+        if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
+        {
+            /* Calculate sum and differance  scale factors for making JS decision   */
+            ps16ScfL = pstrEncParams->as16ScaleFactor ;
+            /* calculate the scale factor of Joint stereo max sum and diff */
+            for (s32Sb = 0; s32Sb < s32NumOfSubBands-1; s32Sb++)
+            {
+                SbBuffer=pstrEncParams->s32SbBuffer+s32Sb;
+                s32MaxValue2=0;
+                s32MaxValue=0;
+                pSum       = s32LRSum;
+                pDiff      = s32LRDiff;
+                for (s32Blk=0;s32Blk<s32NumOfBlocks;s32Blk++)
+                {
+                    *pSum=(*SbBuffer+*(SbBuffer+s32NumOfSubBands))>>1;
+                    if (abs32(*pSum)>s32MaxValue)
+                        s32MaxValue=abs32(*pSum);
+                    pSum++;
+                    *pDiff=(*SbBuffer-*(SbBuffer+s32NumOfSubBands))>>1;
+                    if (abs32(*pDiff)>s32MaxValue2)
+                        s32MaxValue2=abs32(*pDiff);
+                    pDiff++;
+                    SbBuffer+=s32Ch;
+                }
+                u32Count = (s32MaxValue > 0x800000) ? 9 : 0;
+                for ( ; u32Count < 15; u32Count++)
+                {
+                    if (s32MaxValue <= (SINT32)(0x8000 << u32Count))
+                        break;
+                }
+                u32CountSum=u32Count;
+                u32Count = (s32MaxValue2 > 0x800000) ? 9 : 0;
+                for ( ; u32Count < 15; u32Count++)
+                {
+                    if (s32MaxValue2 <= (SINT32)(0x8000 << u32Count))
+                        break;
+                }
+                u32CountDiff=u32Count;
+                if ( (*ps16ScfL + *(ps16ScfL+s32NumOfSubBands)) > (SINT16)(u32CountSum + u32CountDiff) )
+                {
+
+                    if (u32CountSum > maxBit)
+                        maxBit = u32CountSum;
+
+                    if (u32CountDiff > maxBit)
+                        maxBit = u32CountDiff;
+
+                    *ps16ScfL = (SINT16)u32CountSum;
+                    *(ps16ScfL+s32NumOfSubBands) = (SINT16)u32CountDiff;
+
+                    SbBuffer=pstrEncParams->s32SbBuffer+s32Sb;
+                    pSum       = s32LRSum;
+                    pDiff      = s32LRDiff;
+
+                    for (s32Blk = 0; s32Blk < s32NumOfBlocks; s32Blk++)
+                    {
+                        *SbBuffer = *pSum;
+                        *(SbBuffer+s32NumOfSubBands) = *pDiff;
+
+                        SbBuffer += s32NumOfSubBands<<1;
+                        pSum++;
+                        pDiff++;
+                    }
+
+                    pstrEncParams->as16Join[s32Sb] = 1;
+                }
+                else
+                {
+                    pstrEncParams->as16Join[s32Sb] = 0;
+                }
+                ps16ScfL++;
+            }
+            pstrEncParams->as16Join[s32Sb] = 0;
+        }
+#endif
+
+        pstrEncParams->s16MaxBitNeed = (SINT16)maxBit;
+
+        /* bit allocation */
+        if ((pstrEncParams->s16ChannelMode == SBC_STEREO) || (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO))
+            sbc_enc_bit_alloc_ste(pstrEncParams);
+        else
+            sbc_enc_bit_alloc_mono(pstrEncParams);
+
+        /* save the beginning of the frame. pu8NextPacket is modified in EncPacking() */
+        pu8 = pstrEncParams->pu8NextPacket;
+        /* Quantize the encoded audio */
+        EncPacking(pstrEncParams);
+
+        /* scramble the code */
+        SBC_PRTC_CHK_INIT(pu8);
+        SBC_PRTC_CHK_CRC(pu8);
+#if 0
+        if(pstrEncParams->u16PacketLength > ((sbc_prtc_cb.fr[sbc_prtc_cb.index].idx * 2) + sbc_prtc_cb.base))
+            printf("len: %d, idx: %d\n", pstrEncParams->u16PacketLength, sbc_prtc_cb.fr[sbc_prtc_cb.index].idx);
+        else
+            printf("len: %d, idx: %d!!!!\n", pstrEncParams->u16PacketLength, sbc_prtc_cb.fr[sbc_prtc_cb.index].idx);
+#endif
+        SBC_PRTC_SCRMB((&pu8[sbc_prtc_cb.base]));
+    }
+    while(--(pstrEncParams->u8NumPacketToEncode));
+
+    pstrEncParams->u8NumPacketToEncode = 1; /* default is one for retrocompatibility purpose */
+
+}
+
+/****************************************************************************
+* InitSbcAnalysisFilt - Initalizes the input data to 0
+*
+* RETURNS : N/A
+*/
+void SBC_Encoder_Init(SBC_ENC_PARAMS *pstrEncParams)
+{
+    UINT16 s16SamplingFreq; /*temp variable to store smpling freq*/
+    SINT16 s16Bitpool;      /*to store bit pool value*/
+    SINT16 s16BitRate;      /*to store bitrate*/
+    SINT16 s16FrameLen;     /*to store frame length*/
+    UINT16 HeaderParams;
+
+    pstrEncParams->u8NumPacketToEncode = 1; /* default is one for retrocompatibility purpose */
+
+    /* Required number of channels */
+    if (pstrEncParams->s16ChannelMode == SBC_MONO)
+        pstrEncParams->s16NumOfChannels = 1;
+    else
+        pstrEncParams->s16NumOfChannels = 2;
+
+    /* Bit pool calculation */
+    if (pstrEncParams->s16SamplingFreq == SBC_sf16000)
+        s16SamplingFreq = 16000;
+    else if (pstrEncParams->s16SamplingFreq == SBC_sf32000)
+        s16SamplingFreq = 32000;
+    else if (pstrEncParams->s16SamplingFreq == SBC_sf44100)
+        s16SamplingFreq = 44100;
+    else
+        s16SamplingFreq = 48000;
+
+    if ( (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
+        ||  (pstrEncParams->s16ChannelMode == SBC_STEREO) )
+    {
+        s16Bitpool = (SINT16)( (pstrEncParams->u16BitRate *
+            pstrEncParams->s16NumOfSubBands * 1000 / s16SamplingFreq)
+            -( (32 + (4 * pstrEncParams->s16NumOfSubBands *
+            pstrEncParams->s16NumOfChannels)
+            + ( (pstrEncParams->s16ChannelMode - 2) *
+            pstrEncParams->s16NumOfSubBands )   )
+            / pstrEncParams->s16NumOfBlocks) );
+
+        s16FrameLen = 4 + (4*pstrEncParams->s16NumOfSubBands*
+            pstrEncParams->s16NumOfChannels)/8
+            + ( ((pstrEncParams->s16ChannelMode - 2) *
+            pstrEncParams->s16NumOfSubBands)
+            + (pstrEncParams->s16NumOfBlocks * s16Bitpool) ) / 8;
+
+        s16BitRate = (8 * s16FrameLen * s16SamplingFreq)
+            / (pstrEncParams->s16NumOfSubBands *
+            pstrEncParams->s16NumOfBlocks * 1000);
+
+        if (s16BitRate > pstrEncParams->u16BitRate)
+            s16Bitpool--;
+
+        if(pstrEncParams->s16NumOfSubBands == 8)
+            pstrEncParams->s16BitPool = (s16Bitpool > 255) ? 255 : s16Bitpool;
+        else
+            pstrEncParams->s16BitPool = (s16Bitpool > 128) ? 128 : s16Bitpool;
+    }
+    else
+    {
+        s16Bitpool = (SINT16)( ((pstrEncParams->s16NumOfSubBands *
+            pstrEncParams->u16BitRate * 1000)
+            / (s16SamplingFreq * pstrEncParams->s16NumOfChannels))
+            -( ( (32 / pstrEncParams->s16NumOfChannels) +
+            (4 * pstrEncParams->s16NumOfSubBands) )
+            /   pstrEncParams->s16NumOfBlocks ) );
+
+        pstrEncParams->s16BitPool = (s16Bitpool >
+            (16 * pstrEncParams->s16NumOfSubBands))
+            ? (16*pstrEncParams->s16NumOfSubBands) : s16Bitpool;
+    }
+
+    if (pstrEncParams->s16BitPool < 0)
+        pstrEncParams->s16BitPool = 0;
+    /* sampling freq */
+    HeaderParams = ((pstrEncParams->s16SamplingFreq & 3)<< 6);
+
+    /* number of blocks*/
+    HeaderParams |= (((pstrEncParams->s16NumOfBlocks -4) & 12) << 2);
+
+    /* channel mode: mono, dual...*/
+    HeaderParams |= ((pstrEncParams->s16ChannelMode & 3)<< 2);
+
+    /* Loudness or SNR */
+    HeaderParams |= ((pstrEncParams->s16AllocationMethod & 1)<< 1);
+    HeaderParams |= ((pstrEncParams->s16NumOfSubBands >> 3) & 1);  /*4 or 8*/
+    pstrEncParams->FrameHeader=HeaderParams;
+
+    if (pstrEncParams->s16NumOfSubBands==4)
+    {
+        if (pstrEncParams->s16NumOfChannels==1)
+            EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-4*10)>>2)<<2;
+        else
+            EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-4*10*2)>>3)<<2;
+    }
+    else
+    {
+        if (pstrEncParams->s16NumOfChannels==1)
+            EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-8*10)>>3)<<3;
+        else
+            EncMaxShiftCounter=((ENC_VX_BUFFER_SIZE-8*10*2)>>4)<<3;
+    }
+
+    APPL_TRACE_EVENT("SBC_Encoder_Init : bitrate %d, bitpool %d",
+            pstrEncParams->u16BitRate, pstrEncParams->s16BitPool);
+
+    SbcAnalysisInit();
+
+    memset(&sbc_prtc_cb, 0, sizeof(tSBC_PRTC_CB));
+    sbc_prtc_cb.base = 6 + pstrEncParams->s16NumOfChannels*pstrEncParams->s16NumOfSubBands/2;
+}

+ 274 - 0
examples/09_a2dp/components/bluedroid_demos/embdrv/sbc/encoder/srce/sbc_packing.c

@@ -0,0 +1,274 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 1999-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ *  This file contains code for packing the Encoded data into bit streams.
+ *
+ ******************************************************************************/
+
+#include "sbc_encoder.h"
+#include "sbc_enc_func_declare.h"
+
+#if (SBC_ARM_ASM_OPT==TRUE)
+#define Mult32(s32In1,s32In2,s32OutLow)                                                 \
+{                                                                                       \
+   __asm                                                                                \
+   {                                                                                    \
+        MUL s32OutLow,s32In1,s32In2;                                                    \
+    }                                                                                   \
+}
+#define Mult64(s32In1, s32In2, s32OutLow, s32OutHi)                                     \
+{                                                                                       \
+    __asm													        					\
+    {														    						\
+        SMULL s32OutLow,s32OutHi,s32In1,s32In2          	    						\
+    }														    						\
+}
+#else
+#define Mult32(s32In1,s32In2,s32OutLow) s32OutLow=(SINT32)s32In1*(SINT32)s32In2;
+#define Mult64(s32In1, s32In2, s32OutLow, s32OutHi)                                     \
+{                                                                                       \
+	s32OutLow   = ((SINT32)(UINT16)s32In1  * (UINT16)s32In2);                           \
+	s32TempVal2 = (SINT32)((s32In1 >> 16) * (UINT16)s32In2);                            \
+	s32Carry    = ( (((UINT32)(s32OutLow)>>16)&0xFFFF) +                                \
+										+ (s32TempVal2 & 0xFFFF) ) >> 16;               \
+	s32OutLow   += (s32TempVal2 << 16);                                                 \
+	s32OutHi     = (s32TempVal2 >> 16) + s32Carry;                                      \
+}
+#endif
+
+void EncPacking(SBC_ENC_PARAMS *pstrEncParams)
+{
+    UINT8       *pu8PacketPtr;                      /* packet ptr*/
+    UINT8 Temp;
+    SINT32      s32Blk;                             /* counter for block*/
+    SINT32      s32Ch;                              /* counter for channel*/
+    SINT32      s32Sb;                              /* counter for sub-band*/
+    SINT32 s32PresentBit;                      /* represents bit to be stored*/
+    /*SINT32 s32LoopCountI;                       loop counter*/
+    SINT32 s32LoopCountJ;                      /* loop counter*/
+    UINT32 u32QuantizedSbValue,u32QuantizedSbValue0; /* temp variable to store quantized sb val*/
+    SINT32 s32LoopCount;                       /* loop counter*/
+    UINT8 u8XoredVal;                         /* to store XORed value in CRC calculation*/
+    UINT8 u8CRC;                              /* to store CRC value*/
+    SINT16 *ps16GenPtr;
+    SINT32 s32NumOfBlocks;
+    SINT32 s32NumOfSubBands = pstrEncParams->s16NumOfSubBands;
+    SINT32 s32NumOfChannels = pstrEncParams->s16NumOfChannels;
+	UINT32 u32SfRaisedToPow2;	/*scale factor raised to power 2*/
+    SINT16 *ps16ScfPtr;
+    SINT32 *ps32SbPtr;
+	UINT16 u16Levels;	/*to store levels*/
+	SINT32 s32Temp1;	/*used in 64-bit multiplication*/
+	SINT32 s32Low;	/*used in 64-bit multiplication*/
+#if (SBC_IS_64_MULT_IN_QUANTIZER==TRUE)
+	SINT32 s32Hi1,s32Low1,s32Carry,s32TempVal2,s32Hi, s32Temp2;
+#endif
+
+    pu8PacketPtr    = pstrEncParams->pu8NextPacket;    /*Initialize the ptr*/
+    *pu8PacketPtr++ = (UINT8)0x9C;  /*Sync word*/
+    *pu8PacketPtr++=(UINT8)(pstrEncParams->FrameHeader);
+
+    *pu8PacketPtr = (UINT8)(pstrEncParams->s16BitPool & 0x00FF);
+    pu8PacketPtr += 2;  /*skip for CRC*/
+
+    /*here it indicate if it is byte boundary or nibble boundary*/
+    s32PresentBit = 8;
+    Temp=0;
+#if (SBC_JOINT_STE_INCLUDED == TRUE)
+    if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
+    {
+        /* pack join stero parameters */
+        for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++)
+        {
+            Temp <<= 1;
+            Temp |= pstrEncParams->as16Join[s32Sb];
+        }
+
+        /* pack RFA */
+        if (s32NumOfSubBands == SUB_BANDS_4)
+        {
+            s32PresentBit = 4;
+        }
+        else
+        {
+            *(pu8PacketPtr++)=Temp;
+            Temp = 0;
+        }
+    }
+#endif
+
+    /* Pack Scale factor */
+    ps16GenPtr = pstrEncParams->as16ScaleFactor;
+    s32Sb=s32NumOfChannels*s32NumOfSubBands;
+    /*Temp=*pu8PacketPtr;*/
+    for (s32Ch = s32Sb; s32Ch >0; s32Ch--)
+    {
+        Temp<<= 4;
+        Temp |= *ps16GenPtr++;
+
+        if(s32PresentBit == 4)
+        {
+            s32PresentBit = 8;
+            *(pu8PacketPtr++)=Temp;
+            Temp = 0;
+        }
+        else
+        {
+            s32PresentBit = 4;
+        }
+    }
+
+    /* Pack samples */
+    ps32SbPtr   = pstrEncParams->s32SbBuffer;
+    /*Temp=*pu8PacketPtr;*/
+    s32NumOfBlocks= pstrEncParams->s16NumOfBlocks;
+    for (s32Blk = s32NumOfBlocks-1; s32Blk >=0; s32Blk--)
+    {
+        ps16GenPtr  = pstrEncParams->as16Bits;
+        ps16ScfPtr  = pstrEncParams->as16ScaleFactor;
+        for (s32Ch = s32Sb-1; s32Ch >= 0; s32Ch--)
+        {
+            s32LoopCount = *ps16GenPtr++;
+            if (s32LoopCount != 0)
+            {
+#if (SBC_IS_64_MULT_IN_QUANTIZER==TRUE)
+                /* finding level from reconstruction part of decoder */
+                u32SfRaisedToPow2 = ((UINT32)1 << ((*ps16ScfPtr)+1));
+                u16Levels = (UINT16)(((UINT32)1 << s32LoopCount) - 1);
+
+                /* quantizer */
+                s32Temp1 = (*ps32SbPtr >> 2) + (u32SfRaisedToPow2 << 12);
+                s32Temp2 = u16Levels;
+
+                Mult64 (s32Temp1, s32Temp2, s32Low, s32Hi);
+
+                s32Low1   = s32Low >> ((*ps16ScfPtr)+2);
+                s32Low1  &= ((UINT32)1 << (32 - ((*ps16ScfPtr)+2))) - 1;
+                s32Hi1    = s32Hi << (32 - ((*ps16ScfPtr) +2));
+
+                u32QuantizedSbValue0 = (UINT16)((s32Low1 | s32Hi1) >> 12);
+#else
+                /* finding level from reconstruction part of decoder */
+                u32SfRaisedToPow2 = ((UINT32)1 << *ps16ScfPtr);
+                u16Levels = (UINT16)(((UINT32)1 << s32LoopCount)-1);
+
+                /* quantizer */
+                s32Temp1 = (*ps32SbPtr >> 15) + u32SfRaisedToPow2;
+                Mult32(s32Temp1,u16Levels,s32Low);
+                s32Low>>= (*ps16ScfPtr+1);
+                u32QuantizedSbValue0 = (UINT16)s32Low;
+#endif
+                /*store the number of bits required and the quantized s32Sb
+                sample to ease the coding*/
+                u32QuantizedSbValue = u32QuantizedSbValue0;
+
+                if(s32PresentBit >= s32LoopCount)
+                {
+                    Temp <<= s32LoopCount;
+                    Temp |= u32QuantizedSbValue;
+                    s32PresentBit -= s32LoopCount;
+                }
+                else
+                {
+                    while (s32PresentBit < s32LoopCount)
+                    {
+                        s32LoopCount -= s32PresentBit;
+                        u32QuantizedSbValue >>= s32LoopCount;
+
+                        /*remove the unwanted msbs*/
+                        /*u32QuantizedSbValue <<= 16 - s32PresentBit;
+                        u32QuantizedSbValue >>= 16 - s32PresentBit;*/
+
+                        Temp <<= s32PresentBit;
+
+                        Temp |= u32QuantizedSbValue ;
+                        /*restore the original*/
+                        u32QuantizedSbValue=u32QuantizedSbValue0;
+
+                        *(pu8PacketPtr++)=Temp;
+                        Temp = 0;
+                        s32PresentBit = 8;
+                    }
+                    Temp <<= s32LoopCount;
+
+                    /* remove the unwanted msbs */
+                    /*u32QuantizedSbValue <<= 16 - s32LoopCount;
+                    u32QuantizedSbValue >>= 16 - s32LoopCount;*/
+
+                    Temp |= u32QuantizedSbValue;
+
+                    s32PresentBit -= s32LoopCount;
+                }
+            }
+            ps16ScfPtr++;
+            ps32SbPtr++;
+        }
+    }
+
+    Temp <<= s32PresentBit;
+    *pu8PacketPtr=Temp;
+    pstrEncParams->u16PacketLength=pu8PacketPtr-pstrEncParams->pu8NextPacket+1;
+    /*find CRC*/
+    pu8PacketPtr = pstrEncParams->pu8NextPacket+1;    /*Initialize the ptr*/
+    u8CRC = 0x0F;
+    s32LoopCount = s32Sb >> 1;
+
+    /*
+    The loops is run from the start of the packet till the scale factor
+    parameters. In case of JS, 'join' parameter is included in the packet
+    so that many more bytes are included in CRC calculation.
+    */
+    Temp=*pu8PacketPtr;
+    for (s32Ch=1; s32Ch < (s32LoopCount+4); s32Ch++)
+    {
+        /* skip sync word and CRC bytes */
+        if (s32Ch != 3)
+        {
+            for (s32LoopCountJ=7; s32LoopCountJ>=0; s32LoopCountJ--)
+            {
+                u8XoredVal = ((u8CRC >> 7) & 0x01) ^((Temp >> s32LoopCountJ) & 0x01);
+                u8CRC <<= 1;
+                u8CRC ^= (u8XoredVal * 0x1D);
+                u8CRC &= 0xFF;
+            }
+        }
+        Temp=*(++pu8PacketPtr);
+    }
+
+    if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
+    {
+        for (s32LoopCountJ = 7; s32LoopCountJ >= (8 - s32NumOfSubBands); s32LoopCountJ--)
+        {
+            u8XoredVal = ((u8CRC >> 7) & 0x01) ^((Temp >> s32LoopCountJ) & 0x01);
+            u8CRC <<= 1;
+            u8CRC ^= (u8XoredVal * 0x1D);
+            u8CRC &= 0xFF;
+        }
+    }
+
+    /* CRC calculation ends here */
+
+    /* store CRC in packet */
+    pu8PacketPtr = pstrEncParams->pu8NextPacket;    /*Initialize the ptr*/
+    pu8PacketPtr += 3;
+    *pu8PacketPtr = u8CRC;
+    pstrEncParams->pu8NextPacket+=pstrEncParams->u16PacketLength;  /* move the pointer to the end in case there is more than one frame to encode */
+}
+

+ 30 - 0
examples/09_a2dp/components/bluedroid_demos/include/bt_app_common.h

@@ -0,0 +1,30 @@
+#ifndef __BT_APP_COMMON_H__
+#define __BT_APP_COMMON_H__
+
+#include <stdint.h>
+#include "osi.h"
+#include "bt_common_types.h"
+#include "bt_defs.h"
+    
+/* BT APP Events */
+#define BT_EVT_APP                     (0xB000)
+#define BT_EVT_APP_CONTEXT_SWITCH      (0x0001 | BT_EVT_APP)
+
+typedef void (tBTAPP_CBACK) (uint16_t event, char *p_param);
+typedef void (tBTAPP_COPY_CBACK) (uint16_t event, char *p_dest, char *p_src);
+
+typedef struct
+{
+    BT_HDR               hdr;
+    tBTAPP_CBACK*       p_cb;    /* context switch callback */
+
+    /* parameters passed to callback */
+    UINT16               event;   /* message event id */
+    char                 p_param[0]; /* parameter area needs to be last */
+} tBTAPP_CONTEXT_SWITCH_CBACK;
+
+bt_status_t bt_app_transfer_context (tBTAPP_CBACK *p_cback, UINT16 event, char* p_params, int param_len, tBTAPP_COPY_CBACK *p_copy_cback);
+
+void bt_app_task_start_up(void);
+
+#endif /* __BT_APP_COMMON_H__ */

+ 103 - 0
examples/09_a2dp/components/bluedroid_demos/include/bt_av.h

@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_INCLUDE_BT_AV_H
+#define ANDROID_INCLUDE_BT_AV_H
+
+__BEGIN_DECLS
+
+/* Bluetooth AV connection states */
+typedef enum {
+    BTAV_CONNECTION_STATE_DISCONNECTED = 0,
+    BTAV_CONNECTION_STATE_CONNECTING,
+    BTAV_CONNECTION_STATE_CONNECTED,
+    BTAV_CONNECTION_STATE_DISCONNECTING
+} btav_connection_state_t;
+
+/* Bluetooth AV datapath states */
+typedef enum {
+    BTAV_AUDIO_STATE_REMOTE_SUSPEND = 0,
+    BTAV_AUDIO_STATE_STOPPED,
+    BTAV_AUDIO_STATE_STARTED,
+} btav_audio_state_t;
+
+
+/** Callback for connection state change.
+ *  state will have one of the values from btav_connection_state_t
+ */
+typedef void (* btav_connection_state_callback)(btav_connection_state_t state, 
+                                                    bt_bdaddr_t *bd_addr);
+
+/** Callback for audiopath state change.
+ *  state will have one of the values from btav_audio_state_t
+ */
+typedef void (* btav_audio_state_callback)(btav_audio_state_t state, 
+                                               bt_bdaddr_t *bd_addr);
+
+/** Callback for audio configuration change.
+ *  Used only for the A2DP sink interface.
+ *  state will have one of the values from btav_audio_state_t
+ *  sample_rate: sample rate in Hz
+ *  channel_count: number of channels (1 for mono, 2 for stereo)
+ */
+typedef void (* btav_audio_config_callback)(bt_bdaddr_t *bd_addr,
+                                                uint32_t sample_rate,
+                                                uint8_t channel_count);
+
+/** BT-AV callback structure. */
+typedef struct {
+    /** set to sizeof(btav_callbacks_t) */
+    size_t      size;
+    btav_connection_state_callback  connection_state_cb;
+    btav_audio_state_callback audio_state_cb;
+    btav_audio_config_callback audio_config_cb;
+} btav_callbacks_t;
+
+/** 
+ * NOTE:
+ *
+ * 1. AVRCP 1.0 shall be supported initially. AVRCP passthrough commands
+ *    shall be handled internally via uinput 
+ *
+ * 2. A2DP data path shall be handled via a socket pipe between the AudioFlinger
+ *    android_audio_hw library and the Bluetooth stack.
+ * 
+ */
+/** Represents the standard BT-AV interface.
+ *  Used for both the A2DP source and sink interfaces.
+ */
+typedef struct {
+
+    /** set to sizeof(btav_interface_t) */
+    size_t          size;
+    /**
+     * Register the BtAv callbacks
+     */
+    bt_status_t (*init)( btav_callbacks_t* callbacks );
+
+    /** connect to headset */
+    bt_status_t (*connect)( bt_bdaddr_t *bd_addr );
+
+    /** dis-connect from headset */
+    bt_status_t (*disconnect)( bt_bdaddr_t *bd_addr );
+
+    /** Closes the interface. */
+    void  (*cleanup)( void );
+} btav_interface_t;
+
+__END_DECLS
+
+#endif /* ANDROID_INCLUDE_BT_AV_H */

+ 133 - 0
examples/09_a2dp/components/bluedroid_demos/udrv/include/uipc.h

@@ -0,0 +1,133 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2007-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+#ifndef UIPC_H
+#define UIPC_H
+
+#include "bt_types.h"
+
+#define UIPC_CH_ID_AV_CTRL  0
+#define UIPC_CH_ID_AV_AUDIO 1
+#define UIPC_CH_NUM         2
+
+#define UIPC_CH_ID_ALL      3   /* used to address all the ch id at once */
+
+#define DEFAULT_READ_POLL_TMO_MS 100
+
+typedef UINT8 tUIPC_CH_ID;
+
+/* Events generated */
+typedef enum {
+    UIPC_OPEN_EVT           = 0x0001,
+    UIPC_CLOSE_EVT          = 0x0002,
+    UIPC_RX_DATA_EVT        = 0x0004,
+    UIPC_RX_DATA_READY_EVT  = 0x0008,
+    UIPC_TX_DATA_READY_EVT  = 0x0010
+} tUIPC_EVENT;
+
+/*
+ * UIPC IOCTL Requests
+ */
+
+#define UIPC_REQ_RX_FLUSH               1
+#define UIPC_REG_CBACK                  2
+#define UIPC_REG_REMOVE_ACTIVE_READSET  3
+#define UIPC_SET_READ_POLL_TMO          4
+
+typedef void (tUIPC_RCV_CBACK)(tUIPC_CH_ID ch_id, tUIPC_EVENT event); /* points to BT_HDR which describes event type and length of data; len contains the number of bytes of entire message (sizeof(BT_HDR) + offset + size of data) */
+
+const char* dump_uipc_event(tUIPC_EVENT event);
+
+/*******************************************************************************
+**
+** Function         UIPC_Init
+**
+** Description      Initialize UIPC module
+**
+** Returns          void
+**
+*******************************************************************************/
+void UIPC_Init(void *);
+
+/*******************************************************************************
+**
+** Function         UIPC_Open
+**
+** Description      Open UIPC interface
+**
+** Returns          void
+**
+*******************************************************************************/
+BOOLEAN UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK *p_cback);
+
+/*******************************************************************************
+**
+** Function         UIPC_Close
+**
+** Description      Close UIPC interface
+**
+** Returns          void
+**
+*******************************************************************************/
+void UIPC_Close(tUIPC_CH_ID ch_id);
+
+/*******************************************************************************
+**
+** Function         UIPC_SendBuf
+**
+** Description      Called to transmit a message over UIPC.
+**                  Message buffer will be freed by UIPC_SendBuf.
+**
+** Returns          void
+**
+*******************************************************************************/
+BOOLEAN UIPC_SendBuf(tUIPC_CH_ID ch_id, BT_HDR *p_msg);
+
+/*******************************************************************************
+**
+** Function         UIPC_Send
+**
+** Description      Called to transmit a message over UIPC.
+**
+** Returns          void
+**
+*******************************************************************************/
+BOOLEAN UIPC_Send(tUIPC_CH_ID ch_id, UINT16 msg_evt, UINT8 *p_buf, UINT16 msglen);
+
+/*******************************************************************************
+**
+** Function         UIPC_Read
+**
+** Description      Called to read a message from UIPC.
+**
+** Returns          void
+**
+*******************************************************************************/
+UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UINT32 len);
+
+/*******************************************************************************
+**
+** Function         UIPC_Ioctl
+**
+** Description      Called to control UIPC.
+**
+** Returns          void
+**
+*******************************************************************************/
+BOOLEAN UIPC_Ioctl(tUIPC_CH_ID ch_id, UINT32 request, void *param);
+
+#endif  /* UIPC_H */

+ 139 - 0
examples/09_a2dp/components/bluedroid_demos/udrv/ulinux/uipc.c

@@ -0,0 +1,139 @@
+/******************************************************************************
+ *
+ *  Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at:
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ ******************************************************************************/
+
+/*****************************************************************************
+ *
+ *  Filename:      uipc.c
+ *
+ *  Description:   UIPC implementation for bluedroid
+ *
+ *****************************************************************************/
+#include <stddef.h>
+#include "uipc.h"
+
+/*****************************************************************************
+**  Constants & Macros
+******************************************************************************/
+
+
+
+const char* dump_uipc_event(tUIPC_EVENT event)
+{
+    return NULL;
+}
+
+/*******************************************************************************
+**
+** Function         UIPC_Init
+**
+** Description      Initialize UIPC module
+**
+** Returns          void
+**
+*******************************************************************************/
+void UIPC_Init(void *dummy)
+{
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         UIPC_Open
+**
+** Description      Open UIPC interface
+**
+** Returns          void
+**
+*******************************************************************************/
+BOOLEAN UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK *p_cback)
+{
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         UIPC_Close
+**
+** Description      Close UIPC interface
+**
+** Returns          void
+**
+*******************************************************************************/
+void UIPC_Close(tUIPC_CH_ID ch_id)
+{
+    return;
+}
+
+/*******************************************************************************
+**
+** Function         UIPC_SendBuf
+**
+** Description      Called to transmit a message over UIPC.
+**                  Message buffer will be freed by UIPC_SendBuf.
+**
+** Returns          void
+**
+*******************************************************************************/
+BOOLEAN UIPC_SendBuf(tUIPC_CH_ID ch_id, BT_HDR *p_msg)
+{
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         UIPC_Send
+**
+** Description      Called to transmit a message over UIPC.
+**
+** Returns          void
+**
+*******************************************************************************/
+BOOLEAN UIPC_Send(tUIPC_CH_ID ch_id, UINT16 msg_evt, UINT8 *p_buf, UINT16 msglen)
+{
+    return TRUE;
+}
+
+/*******************************************************************************
+**
+** Function         UIPC_Read
+**
+** Description      Called to read a message from UIPC.
+**
+** Returns          void
+**
+*******************************************************************************/
+UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UINT32 len)
+{
+    return 0;
+}
+
+
+/*******************************************************************************
+**
+** Function         UIPC_Ioctl
+**
+** Description      Called to control UIPC.
+**
+** Returns          void
+**
+*******************************************************************************/
+BOOLEAN UIPC_Ioctl(tUIPC_CH_ID ch_id, UINT32 request, void *param)
+{
+    return TRUE;
+}
+

+ 10 - 0
examples/09_a2dp/main/component.mk

@@ -0,0 +1,10 @@
+#
+# Main Makefile. This is basically the same as a component makefile.
+#
+# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, 
+# this will take the sources in the src/ directory, compile them and link them into 
+# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
+# please read the ESP-IDF documents if you need to do this.
+#
+
+include $(IDF_PATH)/make/component_common.mk

+ 28 - 0
examples/09_a2dp/main/demo_main.c

@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "bt.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "string.h"
+
+
+extern void bte_main_boot_entry(void *);
+extern void bt_app_task_start_up(void);
+extern void bt_app_core_start(void);
+
+void pingTask(void *pvParameters)
+{
+    while (1) {
+        vTaskDelay(1000 / portTICK_PERIOD_MS);
+        printf("ping\n");
+    }
+}
+
+void app_main()
+{
+    bt_controller_init();
+    xTaskCreatePinnedToCore(&pingTask, "pingTask", 2048, NULL, 5, NULL, 0);
+    bt_app_task_start_up();
+    // bte_main_boot_entry(bt_app_core_start);
+}