mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-20 16:46:14 +00:00
refactor(bt/bluedroid): Refactor hfp audio data path
- Refactor audio APIs, optimize audio data path, reduce memory copy operations - Support using external codec in application layer
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -528,6 +528,8 @@ esp_err_t esp_hf_ag_out_call(esp_bd_addr_t remote_addr, int num_active, int num_
|
||||
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||
|
||||
esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
@@ -548,7 +550,73 @@ esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_h
|
||||
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||
esp_err_t esp_hf_ag_register_audio_data_callback(esp_hf_ag_audio_data_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF;
|
||||
msg.act = BTC_HF_REGISTER_AUDIO_DATA_CALLBACK_EVT;
|
||||
|
||||
btc_hf_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_args_t));
|
||||
arg.reg_audio_data_cb.callback = callback;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL);
|
||||
return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_hf_audio_buff_t *esp_hf_ag_audio_buff_alloc(uint16_t size)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t *p_buf = NULL, *p_data;
|
||||
BTA_AgAudioBuffAlloc(size, &p_buf, &p_data);
|
||||
if (p_buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_hf_audio_buff_t *audio_buf = (esp_hf_audio_buff_t *)p_buf;
|
||||
audio_buf->buff_size = size;
|
||||
audio_buf->data_len = 0;
|
||||
audio_buf->data = p_data;
|
||||
return audio_buf;
|
||||
}
|
||||
|
||||
void esp_hf_ag_audio_buff_free(esp_hf_audio_buff_t *audio_buf)
|
||||
{
|
||||
if (audio_buf == NULL) {
|
||||
return;
|
||||
}
|
||||
BTA_AgAudioBuffFree((UINT8 *)audio_buf);
|
||||
}
|
||||
|
||||
esp_err_t esp_hf_ag_audio_data_send(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf_audio_buff_t *audio_buf)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (audio_buf == NULL || audio_buf->data_len == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (btc_hf_ag_audio_data_send(sync_conn_hdl, (uint8_t *)audio_buf, audio_buf->data, audio_buf->data_len)) {
|
||||
return ESP_OK;
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_hf_ag_pkt_stat_nums_get(uint16_t sync_conn_handle)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -541,6 +541,71 @@ void esp_hf_client_outgoing_data_ready(void)
|
||||
BTA_HfClientCiData();
|
||||
}
|
||||
|
||||
esp_err_t esp_hf_client_register_audio_data_callback(esp_hf_client_audio_data_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_HF_CLIENT;
|
||||
msg.act = BTC_HF_CLIENT_REGISTER_AUDIO_DATA_CALLBACK_EVT;
|
||||
|
||||
btc_hf_client_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_hf_client_args_t));
|
||||
arg.reg_audio_data_cb.callback = callback;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_hf_audio_buff_t *esp_hf_client_audio_buff_alloc(uint16_t size)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t *p_buf = NULL, *p_data;
|
||||
BTA_HfClientAudioBuffAlloc(size, &p_buf, &p_data);
|
||||
if (p_buf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_hf_audio_buff_t *audio_buf = (esp_hf_audio_buff_t *)p_buf;
|
||||
audio_buf->buff_size = size;
|
||||
audio_buf->data_len = 0;
|
||||
audio_buf->data = p_data;
|
||||
return audio_buf;
|
||||
}
|
||||
|
||||
void esp_hf_client_audio_buff_free(esp_hf_audio_buff_t *audio_buf)
|
||||
{
|
||||
if (audio_buf == NULL) {
|
||||
return;
|
||||
}
|
||||
BTA_HfClientAudioBuffFree((UINT8 *)audio_buf);
|
||||
}
|
||||
|
||||
esp_err_t esp_hf_client_audio_data_send(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf_audio_buff_t *audio_buf)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (audio_buf == NULL || audio_buf->data_len == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
BTA_HfClientAudioDataSend(sync_conn_hdl, (uint8_t *)audio_buf, audio_buf->data, audio_buf->data_len);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_hf_client_pcm_resample_init(uint32_t src_sps, uint32_t bits, uint32_t channels)
|
||||
{
|
||||
BTA_DmPcmInitSamples(src_sps, bits, channels);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_hf_defs.h"
|
||||
#include "esp_hf_ag_legacy_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -93,7 +94,8 @@ typedef union
|
||||
struct hf_audio_stat_param {
|
||||
esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */
|
||||
esp_hf_audio_state_t state; /*!< Audio connection state */
|
||||
uint16_t sync_conn_handle; /*!< (e)SCO connection handle */
|
||||
esp_hf_sync_conn_hdl_t sync_conn_handle; /*!< (e)SCO connection handle */
|
||||
uint16_t preferred_frame_size; /*!< Valid only when Voice Over HCI is enabled, recommended frame size to send */
|
||||
} audio_stat; /*!< AG callback param of ESP_HF_AUDIO_STATE_EVT */
|
||||
|
||||
/**
|
||||
@@ -233,35 +235,6 @@ typedef union
|
||||
|
||||
} esp_hf_cb_param_t; /*!< HFP AG callback param compound*/
|
||||
|
||||
/**
|
||||
* @brief AG incoming data callback function, the callback is useful in case of
|
||||
* Voice Over HCI.
|
||||
*
|
||||
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
|
||||
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||
* invoke of the callback is finished.
|
||||
*
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
*/
|
||||
typedef void (* esp_hf_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief AG outgoing data callback function, the callback is useful in case of
|
||||
* Voice Over HCI. Once audio connection is set up and the application layer has
|
||||
* prepared data to send, the lower layer will call this function to read data
|
||||
* and then send. This callback is supposed to be implemented as non-blocking,
|
||||
* and if data is not enough, return value 0 is supposed.
|
||||
*
|
||||
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
|
||||
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||
* invoke of the callback is finished.
|
||||
*
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
*
|
||||
* @return length of data successfully read
|
||||
*/
|
||||
typedef uint32_t (* esp_hf_outgoing_data_cb_t) (uint8_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief HF AG callback function type
|
||||
*
|
||||
@@ -271,6 +244,20 @@ typedef uint32_t (* esp_hf_outgoing_data_cb_t) (uint8_t *buf, uint32_t len);
|
||||
*/
|
||||
typedef void (* esp_hf_cb_t) (esp_hf_cb_event_t event, esp_hf_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief HFP AG incoming audio data callback function, user should copy audio_buf struct
|
||||
* to other place before return. This callback is used in case of Voice Over HCI.
|
||||
*
|
||||
* @param[in] sync_conn_hdl: (e)SCO connection handle
|
||||
*
|
||||
* @param[in] audio_buf: pointer to incoming data(payload of HCI synchronous data packet), user
|
||||
* should free audio buffer by calling esp_hf_ag_audio_buff_free
|
||||
*
|
||||
* @param[in] is_bad_frame: whether this packet is marked as bad frame by baseband
|
||||
*
|
||||
*/
|
||||
typedef void (* esp_hf_ag_audio_data_cb_t)(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf_audio_buff_t *audio_buf, bool is_bad_frame);
|
||||
|
||||
/************************************************************************************
|
||||
** ESP HF API
|
||||
************************************************************************************/
|
||||
@@ -678,19 +665,58 @@ esp_err_t esp_hf_ag_end_call(esp_bd_addr_t remote_addr, int num_active, int num_
|
||||
char *number, esp_hf_call_addr_type_t call_addr_type);
|
||||
|
||||
/**
|
||||
* @brief Register AG data output function.
|
||||
* The callback is only used in the case that Voice Over HCI is enabled.
|
||||
* @brief Register HFP AG audio data output function; the callback is only used in
|
||||
* the case that Voice Over HCI is enabled.
|
||||
*
|
||||
* @param[in] recv: HFP client incoming data callback function
|
||||
* @param[in] send: HFP client outgoing data callback function
|
||||
* @param[in] callback: HFP AG incoming audio data callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: if callback is a NULL function pointer
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send);
|
||||
esp_err_t esp_hf_ag_register_audio_data_callback(esp_hf_ag_audio_data_cb_t callback);
|
||||
|
||||
/**
|
||||
* @brief Allocate a audio buffer to store and send audio data. This function is only
|
||||
* used in the case that Voice Over HCI is enabled.
|
||||
*
|
||||
* @param[in] size: buffer size to allocate
|
||||
*
|
||||
* @return allocated audio buffer, if Bluedroid is not enabled, no memory, or size is
|
||||
* zeros, will return NULL
|
||||
*
|
||||
*/
|
||||
esp_hf_audio_buff_t *esp_hf_ag_audio_buff_alloc(uint16_t size);
|
||||
|
||||
/**
|
||||
* @brief Free a audio buffer allocated by esp_hf_ag_audio_buff_alloc. This function
|
||||
* is only used in the case that Voice Over HCI is enabled.
|
||||
*
|
||||
* @param[in] audio_buf: audio buffer to free
|
||||
*
|
||||
*/
|
||||
void esp_hf_ag_audio_buff_free(esp_hf_audio_buff_t *audio_buf);
|
||||
|
||||
/**
|
||||
* @brief Send audio data, the audio buffer should by allocated by esp_hf_ag_audio_buff_alloc.
|
||||
* If the length of the audio data is equal to preferred_frame_size indicated by
|
||||
* ESP_HF_AUDIO_STATE_EVT, then we can reduce one memory copy inside the Bluedroid stack.
|
||||
* This function is only used in the case that Voice Over HCI is enabled.
|
||||
*
|
||||
* @param[in] sync_conn_hdl: (e)SCO connection handle
|
||||
*
|
||||
* @param[in] audio_buf: audio buffer that audio data stored
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_ERR_INVALID_ARG: invalid parameter
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_hf_ag_audio_data_send(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf_audio_buff_t *audio_buf);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -709,16 +735,6 @@ esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_h
|
||||
*/
|
||||
esp_err_t esp_hf_ag_pkt_stat_nums_get(uint16_t sync_conn_handle);
|
||||
|
||||
/**
|
||||
* @brief Trigger the lower-layer to fetch and send audio data.
|
||||
*
|
||||
* This function is only used in the case that Voice Over HCI is enabled.
|
||||
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
|
||||
* After this function is called, lower layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data
|
||||
*
|
||||
*/
|
||||
void esp_hf_ag_outgoing_data_ready(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Some legacy APIs of HFP AG, will be removed in the future
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_hf_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief AG incoming data callback function, the callback is useful in case of
|
||||
* Voice Over HCI.
|
||||
*
|
||||
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
|
||||
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||
* invoke of the callback is finished.
|
||||
*
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
*/
|
||||
typedef void (* esp_hf_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief AG outgoing data callback function, the callback is useful in case of
|
||||
* Voice Over HCI. Once audio connection is set up and the application layer has
|
||||
* prepared data to send, the lower layer will call this function to read data
|
||||
* and then send. This callback is supposed to be implemented as non-blocking,
|
||||
* and if data is not enough, return value 0 is supposed.
|
||||
*
|
||||
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
|
||||
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||
* invoke of the callback is finished.
|
||||
*
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
*
|
||||
* @return length of data successfully read
|
||||
*/
|
||||
typedef uint32_t (* esp_hf_outgoing_data_cb_t) (uint8_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Register AG data output function.
|
||||
* The callback is only used in the case that Voice Over HCI is enabled.
|
||||
*
|
||||
* @param[in] recv: HFP client incoming data callback function
|
||||
* @param[in] send: HFP client outgoing data callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: if callback is a NULL function pointer
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send);
|
||||
|
||||
/**
|
||||
* @brief Trigger the lower-layer to fetch and send audio data.
|
||||
*
|
||||
* This function is only used in the case that Voice Over HCI is enabled.
|
||||
* As a precondition to use this API, Service Level Connection shall exist with HFP client.
|
||||
* After this function is called, lower layer will invoke esp_hf_ag_outgoing_data_cb_t to fetch data
|
||||
*
|
||||
*/
|
||||
void esp_hf_ag_outgoing_data_ready(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_hf_defs.h"
|
||||
#include "esp_hf_client_legacy_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -118,7 +119,8 @@ typedef union {
|
||||
struct hf_client_audio_stat_param {
|
||||
esp_hf_client_audio_state_t state; /*!< audio connection state */
|
||||
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
|
||||
uint16_t sync_conn_handle; /*!< (e)SCO connection handle */
|
||||
esp_hf_sync_conn_hdl_t sync_conn_handle; /*!< (e)SCO connection handle */
|
||||
uint16_t preferred_frame_size; /*!< valid only when Voice Over HCI is enabled, recommended frame size to send */
|
||||
} audio_stat; /*!< HF callback param of ESP_HF_CLIENT_AUDIO_STATE_EVT */
|
||||
|
||||
/**
|
||||
@@ -277,32 +279,18 @@ typedef union {
|
||||
} esp_hf_client_cb_param_t; /*!< HFP client callback parameters */
|
||||
|
||||
/**
|
||||
* @brief HFP client incoming data callback function, the callback is useful in case of
|
||||
* Voice Over HCI.
|
||||
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
|
||||
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||
* invoke of the callback is finished.
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
*/
|
||||
typedef void (* esp_hf_client_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief HFP client outgoing data callback function, the callback is useful in case of
|
||||
* Voice Over HCI. Once audio connection is set up and the application layer has
|
||||
* prepared data to send, the lower layer will call this function to read data
|
||||
* and then send. This callback is supposed to be implemented as non-blocking,
|
||||
* and if data is not enough, return value 0 is supposed.
|
||||
* @brief HFP client incoming audio data callback function, user should copy audio_buf struct
|
||||
* to other place before return. This callback is used in case of Voice Over HCI.
|
||||
*
|
||||
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
|
||||
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||
* invoke of the callback is finished.
|
||||
* @param[in] sync_conn_hdl: (e)SCO connection handle
|
||||
*
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
* @param[in] audio_buf: pointer to incoming data(payload of HCI synchronous data packet), user
|
||||
* should free audio buffer by calling esp_hf_client_audio_buff_free
|
||||
*
|
||||
* @return length of data successfully read
|
||||
* @param[in] is_bad_frame: whether this packet is marked as bad frame by baseband
|
||||
*
|
||||
*/
|
||||
typedef uint32_t (* esp_hf_client_outgoing_data_cb_t)(uint8_t *buf, uint32_t len);
|
||||
typedef void (* esp_hf_client_audio_data_cb_t)(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf_audio_buff_t *audio_buf, bool is_bad_frame);
|
||||
|
||||
/**
|
||||
* @brief HFP client callback function type
|
||||
@@ -662,24 +650,6 @@ esp_err_t esp_hf_client_request_last_voice_tag_number(void);
|
||||
*/
|
||||
esp_err_t esp_hf_client_send_nrec(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register HFP client data output function; the callback is only used in
|
||||
* the case that Voice Over HCI is enabled.
|
||||
*
|
||||
* @param[in] recv: HFP client incoming data callback function
|
||||
*
|
||||
* @param[in] send: HFP client outgoing data callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: if callback is a NULL function pointer
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t recv,
|
||||
esp_hf_client_outgoing_data_cb_t send);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Get the number of packets received and sent
|
||||
@@ -697,15 +667,57 @@ esp_err_t esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t
|
||||
esp_err_t esp_hf_client_pkt_stat_nums_get(uint16_t sync_conn_handle);
|
||||
|
||||
/**
|
||||
* @brief Trigger the lower-layer to fetch and send audio data.
|
||||
* This function is only only used in the case that Voice Over HCI is enabled. After this
|
||||
* function is called, lower layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data.
|
||||
* @brief Register HFP client audio data output function; the callback is only used in
|
||||
* the case that Voice Over HCI is enabled.
|
||||
*
|
||||
* As a precondition to use this API, Service Level Connection shall exist with AG.
|
||||
* @param[in] callback: HFP client incoming audio data callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
void esp_hf_client_outgoing_data_ready(void);
|
||||
esp_err_t esp_hf_client_register_audio_data_callback(esp_hf_client_audio_data_cb_t callback);
|
||||
|
||||
/**
|
||||
* @brief Allocate a audio buffer to store and send audio data. This function is only
|
||||
* used in the case that Voice Over HCI is enabled.
|
||||
*
|
||||
* @param[in] size: buffer size to allocate
|
||||
*
|
||||
* @return allocated audio buffer, if Bluedroid is not enabled, no memory, or size is
|
||||
* zeros, will return NULL
|
||||
*
|
||||
*/
|
||||
esp_hf_audio_buff_t *esp_hf_client_audio_buff_alloc(uint16_t size);
|
||||
|
||||
/**
|
||||
* @brief Free a audio buffer allocated by esp_hf_client_audio_buff_alloc. This function
|
||||
* is only used in the case that Voice Over HCI is enabled.
|
||||
*
|
||||
* @param[in] audio_buf: audio buffer to free
|
||||
*
|
||||
*/
|
||||
void esp_hf_client_audio_buff_free(esp_hf_audio_buff_t *audio_buf);
|
||||
|
||||
/**
|
||||
* @brief Send audio data, the audio buffer should by allocated by esp_hf_client_audio_buff_alloc.
|
||||
* If the length of the audio data is equal to preferred_frame_size indicated by
|
||||
* ESP_HF_CLIENT_AUDIO_STATE_EVT, then we can reduce one memory copy inside the Bluedroid stack.
|
||||
* This function is only used in the case that Voice Over HCI is enabled.
|
||||
*
|
||||
* @param[in] sync_conn_hdl: (e)SCO connection handle
|
||||
*
|
||||
* @param[in] audio_buf: audio buffer that audio data stored
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_ERR_INVALID_ARG: invalid parameter
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_hf_client_audio_data_send(esp_hf_sync_conn_hdl_t sync_conn_hdl, esp_hf_audio_buff_t *audio_buf);
|
||||
|
||||
/**
|
||||
* @brief Initialize the down sampling converter. This is a utility function that can
|
||||
|
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Some legacy APIs of HFP HF, will be removed in the future
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_hf_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief HFP client incoming data callback function, the callback is useful in case of
|
||||
* Voice Over HCI.
|
||||
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
|
||||
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||
* invoke of the callback is finished.
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
*/
|
||||
typedef void (* esp_hf_client_incoming_data_cb_t)(const uint8_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief HFP client outgoing data callback function, the callback is useful in case of
|
||||
* Voice Over HCI. Once audio connection is set up and the application layer has
|
||||
* prepared data to send, the lower layer will call this function to read data
|
||||
* and then send. This callback is supposed to be implemented as non-blocking,
|
||||
* and if data is not enough, return value 0 is supposed.
|
||||
*
|
||||
* @param[in] buf : pointer to incoming data(payload of HCI synchronous data packet), the
|
||||
* buffer is allocated inside bluetooth protocol stack and will be released after
|
||||
* invoke of the callback is finished.
|
||||
*
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
*
|
||||
* @return length of data successfully read
|
||||
*
|
||||
*/
|
||||
typedef uint32_t (* esp_hf_client_outgoing_data_cb_t)(uint8_t *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Register HFP client data output function; the callback is only used in
|
||||
* the case that Voice Over HCI is enabled.
|
||||
*
|
||||
* @param[in] recv: HFP client incoming data callback function
|
||||
*
|
||||
* @param[in] send: HFP client outgoing data callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: if callback is a NULL function pointer
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t recv,
|
||||
esp_hf_client_outgoing_data_cb_t send);
|
||||
|
||||
/**
|
||||
* @brief Trigger the lower-layer to fetch and send audio data.
|
||||
* This function is only only used in the case that Voice Over HCI is enabled. After this
|
||||
* function is called, lower layer will invoke esp_hf_client_outgoing_data_cb_t to fetch data.
|
||||
*
|
||||
* As a precondition to use this API, Service Level Connection shall exist with AG.
|
||||
*
|
||||
*/
|
||||
void esp_hf_client_outgoing_data_ready(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -13,6 +13,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef uint16_t esp_hf_sync_conn_hdl_t;
|
||||
|
||||
/// profile states
|
||||
typedef enum {
|
||||
ESP_HF_INIT_SUCCESS = 0, /*!< Indicate init successful */
|
||||
@@ -249,6 +251,25 @@ typedef enum {
|
||||
ESP_HF_CME_NETWORK_NOT_ALLOWED = 32, /*!< network not allowed --emergency calls only */
|
||||
} esp_hf_cme_err_t;
|
||||
|
||||
/* Since HFP uses a fixed set of mSBC codec parameters, define it here */
|
||||
#define ESP_HF_MSBC_CHANNEL_MODE "Mono" /*!< mSBC channel mode */
|
||||
#define ESP_HF_MSBC_SAMPLING_RATE "16 kHz" /*!< mSBC sampling rate */
|
||||
#define ESP_HF_MSBC_ALLOCATION_METHOD "Loudness" /*!< mSBC allocation method */
|
||||
#define ESP_HF_MSBC_SUBBANDS 8 /*!< mSBC subbands */
|
||||
#define ESP_HF_MSBC_BLOCK_LENGTH 15 /*!< mSBC block length */
|
||||
#define ESP_HF_MSBC_BITPOOL 26 /*!< mSBC bitpool */
|
||||
/* frame size after mSBC encoded */
|
||||
#define ESP_HF_MSBC_ENCODED_FRAME_SIZE 57 /*!< mSBC frame size */
|
||||
|
||||
/**
|
||||
* @brief HFP audio buffer
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t buff_size; /*!< buffer size */
|
||||
uint16_t data_len; /*!< audio data length, data length should not greater than buffer size */
|
||||
uint8_t *data; /*!< pointer to audio data start */
|
||||
} esp_hf_audio_buff_t; /*!< struct to store audio data */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user