Fix the audio crash bugs

Fix voice recognition bugs

Fix audio memory leak bug.
This commit is contained in:
weitianhua 2019-11-04 16:39:53 +08:00 committed by bot
parent a47c07d319
commit 0c6e1f7ef8
10 changed files with 107 additions and 93 deletions

View file

@ -49,7 +49,7 @@ typedef enum
{
ESP_HF_CONNECTION_STATE_EVT = 0, /*!< Connection state changed event */
ESP_HF_AUDIO_STATE_EVT, /*!< Audio connection state change event */
ESP_HF_BVRA_EVT, /*!< Voice recognition state change event */
ESP_HF_BVRA_RESPONSE_EVT, /*!< Voice recognition state change event */
ESP_HF_VOLUME_CONTROL_EVT, /*!< Audio volume control command from HF Client, provided by +VGM or +VGS message */
ESP_HF_UNAT_RESPONSE_EVT, /*!< Unknown AT cmd Response*/
@ -89,7 +89,7 @@ typedef union
} audio_stat; /*!< AG callback param of ESP_AG_AUDIO_STATE_EVT */
/**
* @brief ESP_HF_BVRA_EVT
* @brief ESP_HF_BVRA_RESPONSE_EVT
*/
struct hf_bvra_param {
esp_bd_addr_t remote_addr;

View file

@ -262,8 +262,6 @@ void BTA_AgResult(UINT16 handle, tBTA_AG_RES result, tBTA_AG_RES_DATA *p_data)
{
tBTA_AG_API_RESULT *p_buf;
// printf("BTA_AgReslut: %d\n",result);
if ((p_buf = (tBTA_AG_API_RESULT *) osi_malloc(sizeof(tBTA_AG_API_RESULT))) != NULL) {
p_buf->hdr.event = BTA_AG_API_RESULT_EVT;
p_buf->hdr.layer_specific = handle;

View file

@ -991,6 +991,8 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
if (!(p_scb->features & BTA_AG_FEAT_VREC)) {
event = 0;
bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
} else {
bta_ag_send_ok(p_scb);
}
break;
@ -1536,6 +1538,12 @@ void bta_ag_hfp_result(tBTA_AG_SCB *p_scb, tBTA_AG_API_RESULT *p_result)
case BTA_AG_BVRA_RES:
bta_ag_send_result(p_scb, code, NULL, p_result->data.state);
if (p_result->data.ok_flag!= BTA_AG_OK_ERROR)
{
bta_ag_send_ok(p_scb);
} else {
bta_ag_send_error(p_scb, p_result->data.errcode);
}
break;
case BTA_AG_BTRH_RES: // Not supported yet

View file

@ -272,7 +272,7 @@ const tBTA_AG_ST_TBL bta_ag_st_tbl[] =
/*****************************************************************************
** Global data
*****************************************************************************/
const char *bta_ag_version = "1.5"; //"1.6"
const char *bta_ag_version = "1.6";
/* AG control block */
#if BTA_DYNAMIC_MEMORY == FALSE
tBTA_AG_CB bta_ag_cb;

View file

@ -1301,7 +1301,12 @@ void btc_hf_cb_handler(btc_msg_t *msg)
do {
memset(&param, 0, sizeof(esp_hf_cb_param_t));
param.vra_rep.value = p_data->val.num;
btc_hf_cb_to_app(ESP_HF_BVRA_EVT, &param);
btc_hf_cb_to_app(ESP_HF_BVRA_RESPONSE_EVT, &param);
if (p_data->val.num) {
btc_hf_connect_audio(&hf_local_param[idx].btc_hf_cb.connected_bda);
} else {
btc_hf_disconnect_audio(&hf_local_param[idx].btc_hf_cb.connected_bda);
}
} while (0);
break;
}
@ -1422,6 +1427,14 @@ void btc_hf_cb_handler(btc_msg_t *msg)
break;
}
case BTA_AG_AT_BCS_EVT:
{
BTC_TRACE_DEBUG("AG Bitmap of peer-codecs %d", p_data->val.num);
memset(&param, 0, sizeof(esp_hf_cb_param_t));
param.codec.mode = p_data->val.num;
btc_hf_cb_to_app(ESP_HF_BCS_RESPONSE_EVT, &param);
break;
}
#if (BTM_WBS_INCLUDED == TRUE )
case BTA_AG_WBS_EVT:
{
@ -1453,11 +1466,6 @@ void btc_hf_cb_handler(btc_msg_t *msg)
}
#endif
break;
case BTA_AG_AT_BCS_EVT:
BTC_TRACE_DEBUG("AG final seleded codec is %d 1=CVSD 2=MSBC", p_data->val.num);
/* no ESP_HF_WBS_NONE case, becuase HF 1.6 supported device can send BCS */
btc_hf_cb_to_app(ESP_HF_BCS_RESPONSE_EVT, &param);
break;
default:
BTC_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event);
break;

View file

@ -339,7 +339,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
pkt_size = BT_HDR_SIZE + len;
pkt = (BT_HDR *) osi_calloc(pkt_size);
//pkt = (BT_HDR *)hci_hal_env.allocator->alloc(pkt_size);
if (!pkt) {
HCI_TRACE_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__);
return -1;

View file

@ -1,6 +1,6 @@
# Hands-Free Audio Gateway
This example is to show how to use the APIs of Hands-Free (HF) Audio Gateway (AG) Component and the effects of them with the help of user commands. You can use this example to communicate with a Hands-Free Unit (e.g. a headphone set). This example uses UART as a transportation of user commands and uses GPIO for PCM audio data stream.
This example is to show how to use the APIs of Hands-Free (HF) Audio Gateway (AG) Component and the effects of them by providing a set of commands. You can use this example to communicate with a Hands-Free Unit (e.g. a headphone set). This example uses UART for user commands and uses GPIO for PCM audio data stream.
## How to use example
@ -8,16 +8,19 @@ This example is to show how to use the APIs of Hands-Free (HF) Audio Gateway (AG
If possible, example should be able to run on any commonly available ESP32 development board and is supposed to connect to _Hands Free Unit example (hfp_hf)_ in ESP-IDF.
### Audio Data Path
ESP32 supports two types of audio data path: PCM and HCI.
- PCM : When using PCM, audio data stream is mapped to GPIO pins and you should link these GPIO pins to a speaker via I2S port.
- HCI : When using HCI, audio data stream will be transport to HF unit app via HCI.
### Configure the project
```
idf.py menuconfig
```
- Enable `Classic Bluetooth`, `Hands Free/Handset` and `Aduio Gateway` under `Component config ---> Bluetooth ---> Bluedroid Options`.
- When using PCM as the data path and this example configures PCM audio data to GPIO pins. You can link the GPIO pins to a speaker via I2S port. PCM data path does not support mSBC codec but CVSD codec.
- When using HCI data path, ESP32 support both CVSD and mSBC codec.
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
@ -34,7 +37,7 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
## Example Output
When you run this example the command table will prints like:
When you run this example the commands help table prints like:
```
########################################################################
@ -59,12 +62,12 @@ hf ind <call> <ntk> <callsetup> <sig>; -- unsolicited notify device notifi
hf ate <rep> <err>; -- send extended at error code
rep: response code from 0 to 7
err: error code from 0 to 32
hf iron; -- inband ring tone provided
hf iroff; -- inband ring tone not provided
hf iron; -- in-band ring tone provided
hf iroff; -- in-band ring tone not provided
hf ac; -- Answer Incoming Call from AG
hf rc; -- Reject Incoming Call from AG
hf d <num>; -- Dial Number by AG, e.g. hf d 11223344
hf end; -- End up a call by AG
hf end; -- End a call by AG
hf h; -- to see the command for HFP AG
########################################################################
```
@ -76,25 +79,27 @@ The commands help table will print out in monitor whenever you type `hf h;` or i
You can type `hf con;` to establish a service level connection with HF Unit device and log prints like:
```
E (100147) CNSL: Command [hf dis;]
disconnect
W (100427) BT_RFCOMM: port_rfc_closed RFCOMM connection in state 3 closed: Closed (res: 19)
W (100427) BT_APPL: BTA_HF_CLIENT_SCO_SHUTDOWN_ST: Ignoring event 3
E (100427) BT_HF: APP HFP event: CONNECTION_STATE_EVT
E (100437) BT_HF: --connection state disconnected, peer feats 0x0, chld_feats 0x0
W (2211) BT_APPL: new conn_srvc id:5, app_id:0
I (2221) BT_APP_HF: APP HFP event: CONNECTION_STATE_EVT
I (2221) BT_APP_HF: --connection state CONNECTED, peer feats 0x0, chld_feats 0x0
I (2291) BT_APP_HF: APP HFP event: CIND_RESPONSE_EVT
I (2291) BT_APP_HF: --CIND Start.
I (2331) BT_APP_HF: APP HFP event: CONNECTION_STATE_EVT
I (2331) BT_APP_HF: --connection state SLC_CONNECTED, peer feats 0xff, chld_feats 0x4010
```
**Note: Only after HF service is initialized and a service level connection exists between the HF Unit and AG could other commands be available.**
**Note: Only after HFP service is initialized and a service level connection exists between an HF Unit and an AG device, could other commands be available.**
You can type `hf dis;` to disconnect with the connected HF Unit device, and log prints like:
```
E (100147) CNSL: Command [hf dis;]
disconnect
W (100427) BT_RFCOMM: port_rfc_closed RFCOMM connection in state 3 closed: Closed (res: 19)
W (100427) BT_APPL: BTA_HF_CLIENT_SCO_SHUTDOWN_ST: Ignoring event 3
E (100427) BT_HF: APP HFP event: CONNECTION_STATE_EVT
E (100437) BT_HF: --connection state disconnected, peer feats 0x0, chld_feats 0x0
W (77321) BT_RFCOMM: port_rfc_closed RFCOMM connection in state 2 closed: Closed (res: 19)
I (77321) BT_APP_HF: APP HFP event: CONNECTION_STATE_EVT
I (77321) BT_APP_HF: --connection state DISCONNECTED, peer feats 0x0, chld_feats 0x0
W (77381) BT_RFCOMM: rfc_find_lcid_mcb LCID reused LCID:0x41 current:0x0
W (77381) BT_RFCOMM: RFCOMM_DisconnectInd LCID:0x41
```
### Audio Connection and Disconnection
@ -114,10 +119,8 @@ You can type `hf cona;` to establish the audio connection between HF Unit and AG
#### Audio Data path
ESP32 supports two types of audio data path: PCM and HCI.
- PCM : When using PCM, audio data stream is mapped to GPIO pins and you should link these GPIO pins to a speaker via I2S port.
- HCI : When using HCI, audio data stream acts in "loopback" mode. For example, you can hear your own voice when you place a call to a phone connected with a ESP32 development borad.
- When using PCM as the data path and this example configures PCM audio data to GPIO pins. You can link the GPIO pins to a speaker via I2S port. PCM data path does not support mSBC codec but CVSD codec.
- When using HCI data path, ESP32 support both CVSD and mSBC codec.
#### Codec
@ -157,15 +160,17 @@ I (1067240) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT
I (1067240) BT_APP_HF: --Audio State disconnected
```
#### End Up a Call
#### End a Call
You can type `hf end;` to end up the current ongoing call and log prints like:
You can type `hf end;` to end the current ongoing call and log prints like:
```
E (40390) CNSL: Command [hf end;]
E (157741) CNSL: Command [hf end;]
End Call from AG.
I (1067240) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT
I (1067240) BT_APP_HF: --Audio State disconnected
W (157741) BT_APPL: BTA_AG_SCO_CLOSING_ST: Ignoring event 3
I (159311) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT
I (159311) BT_APP_HF: --Audio State disconnected
I (159311) BT_APP_HF: --ESP AG Audio Connection Disconnected.
```
### Dial Number
@ -173,58 +178,55 @@ I (1067240) BT_APP_HF: --Audio State disconnected
You can type `hf d <num>;` to dial `<num>` from AG and log prints like:
```
E (105600) CNSL: Command [hf d 18629485549;]
E (207351) CNSL: Command [hf d 18629485549;]
Dial number 18629485549
I (105610) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT
I (105610) BT_APP_HF: --Audio State connecting
I (106120) BT_APP_HF: APP HFP event: BCS_EVT
I (106130) BT_APP_HF: --AG choose codec mode: CVSD Only
E (106160) BT_BTM: btm_sco_connected, handle 180
I (106160) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT
I (106160) BT_APP_HF: --Audio State connected
I (207361) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT
I (207361) BT_APP_HF: --Audio State connecting
W (207361) BT_APPL: BTA_AG_SCO_OPENING_ST: Ignoring event 1
W (207371) BT_APPL: BTA_AG_SCO_OPENING_ST: Ignoring event 1
E (208801) BT_BTM: btm_sco_connected, handle 181
I (208811) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT
I (208811) BT_APP_HF: --Audio State connected
```
### Volume Control
You can type `hf vu <tgt> <vol>;` to sync volume gain of headset or microphone. The parameter set:
You can type `hf vu <tgt> <vol>;` to update volume gain of headset or microphone. The parameter set:
- `<tgt>` : 0 - headset, 1 - microphone.
- `<vol>` : Integer among 0 - 15.
For example, `hf vu 0 9;` sync the volume of headset and log on AG side prints `volume update`, on HF Unit side log prints like:
For example, `hf vu 0 9;` update the volume of headset and log on AG side prints `Volume Update`, on HF Unit side log prints like:
```
E (17087) BT_HF: APP HFP event: VOLUME_CONTROL_EVT
E (17087) BT_HF: --volume_target: SPEAKER, volume 9
```
And also, `hf vu 1 9;` sync the volume gain of microphone and log on HF Unit side prints like:
And also, `hf vu 1 9;` update the volume gain of microphone and log on HF Unit side prints like:
```
E (32087) BT_HF: APP HFP event: VOLUME_CONTROL_EVT
E (32087) BT_HF: --volume_target: MICROPHONE, volume 9
```
#### Voice Recognition
You can type `hf vron;` to start the voice recognition of AG and type `hf vroff;` to end the voice recognition. Both command will notify the HF Unit the status of voice recognition. For example, type `hf vron;` and log prints like:
You can type `hf vron;` to start the voice recognition of AG and type `hf vroff;` to terminate the voice recognition. Both command will notify the HF Unit the status of voice recognition. For example, type `hf vron;` and log prints like:
```
E (203128) CNSL: Command [hf vron;]
E (244131) CNSL: Command [hf vron;]
Start Voice Recognition.
I (203138) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT
I (203138) BT_APP_HF: --Audio State connecting
I (203148) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT
I (1014138) BT_APP_HF: --Audio State connected
I (244141) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT
I (244141) BT_APP_HF: --Audio State connecting
E (245301) BT_BTM: btm_sco_connected, handle 181
I (245311) BT_APP_HF: APP HFP event: AUDIO_STATE_EVT
I (245311) BT_APP_HF: --Audio State connected
```
#### Notify Device Notification
You can type `hf ind <call> <ntk> <callsetup> <sig>` to send device status of AG to HF Unit. Log on AG will printout like: `Device Indicator Changed!` and on HF Unit side will prints like:
You can type `hf ind <call> <ntk> <callsetup> <sig>` to send device status of AG to HF Unit. Log on AG prints like: `Device Indicator Changed!` and on HF Unit side prints like:
```
E (293641) BT_HF: APP HFP event: CALL_IND_EVT
@ -233,14 +235,13 @@ E (293641) BT_HF: APP HFP event: CALL_SETUP_IND_EVT
E (293651) BT_HF: --Call setup indicator INCOMING
E (293651) BT_HF: APP HFP event: SIGNAL_STRENGTH_IND_EVT
E (293661) BT_HF: -- signal strength: 5
```
**Note: AG only sends changed status to HF Unit.**
#### Send Extended AT Error Code
You can type `hf ate <rep> <err>` to send extended AT error coed to HF Unit. Parameter set:
You can type `hf ate <rep> <err>` to send extended AT error code to HF Unit. Parameter set:
- `<rep>` : integer among 0 - 7.
- `<err>` : integer among 0 - 32.
@ -253,30 +254,31 @@ E (448146) BT_HF: --AT response event, code 7, cme 7
```
#### Inband Ring Tone Enable and Disable
#### In-Band Ring Tone Setting
You can type `hf iron;` to enable inband ring tone and type `hf iroff;` to disable inband ring tone. Log on AG side prints like `Device Indicator Changed!` and on HF Unit side prints like:
You can type `hf iron;` to enable in-band ring tone and type `hf iroff;` to disable in-band ring tone. Log on AG side prints like `Device Indicator Changed!` and on HF Unit side prints like:
```
E (19546) BT_HF: APP HFP event: INBAND_RING_TONE_EVT
E (19556) BT_HF: --inband ring state Provided
E (19546) BT_HF: APP HFP event: IN-BAND_RING_TONE_EVT
E (19556) BT_HF: --in-band ring state Provided
```
## Troubleshooting
- You should type the command in the terminal according to the format described in the command help table.
If you encounter any problems, please check if the following rules are followed:
- You should type the command in the terminal according to the format described in the commands help table.
- Not all commands in the table are supported by HF Unit.
- If you want to use AG to establish a service level connection with HF Unit, you should add the MAC address of HF Unit in `hfp_hf/main/bt_app.c`, for example: `esp_bd_addr_t peer_addr = {0xb4, 0xe6, 0x2d, 0xeb, 0x09, 0x93};`
- If you want to `hf con;` to establish a service level connection with specific HF Unit, you should add the MAC address of HF Unit in `app_hf_msg_set.c`, for example: `esp_bd_addr_t peer_addr = {0xb4, 0xe6, 0x2d, 0xeb, 0x09, 0x93};`
- Use `esp_hf_client_register_callback()` and `esp_hf_client_init();` before establishing a service level connection.
## Example Breakdown
This example has relatively more source files than other bluetooth examples because _Hands Free Profile_ is somehow complex. But we want to show the functions of _Hands Free Profile_ in a simple way, so we use the _Commands and Effects_ scheme to show the usage of APIs of HFP in ESP-IDF.
Due to the complexity of Hands Free Profile, this example has more source files than other bluetooth examples. To show functions of Hands Free Profile in a simple way, we use the Commands and Effects scheme to illustrate APIs of HFP in ESP-IDF.
- The example will respond to user command through UART console. Please go to `hfp_hf/main/console_uart.c` for the configuration details.
- For voice interface, ESP32 has provided PCM input/output signals which can be mapped to GPIO pins, please go to `hfp_hf/main/gpio_pcm_config.c` for the configuration details.
- If you want to fix the command table, please refer to `hfp_hf/main/app_hf_msg_set.c`.
- If you want to fix the command parse rules, please refer to `hfp_hf/main/app_hf_msg_prs.c`.
- If you want to fix the responses of AG or want to fix the log, please refer to `hfp_hf/main/bt_app_hf.c`.
- Task configuration part is in `hfp_hf/main/bt_app_core.c`.
- The example will respond to user command through UART console. Please go to `console_uart.c` for the configuration details.
- For voice interface, ESP32 has provided PCM input/output signals which can be mapped to GPIO pins, please go to `gpio_pcm_config.c` for the configuration details.
- If you want to update the command table, please refer to `app_hf_msg_set.c`.
- If you want to update the command parse rules, please refer to `app_hf_msg_prs.c`.
- If you want to update the responses of AG or want to update the log, please refer to `bt_app_hf.c`.
- Task configuration part is in `bt_app_core.c`.

View file

@ -12,6 +12,9 @@
#include "app_hf_msg_set.h"
#include "bt_app_hf.h"
// if you want to connect a specific device, add it's bda here
// esp_bd_addr_t hf_peer_addr = {0x70,0x26,0x05,0xca,0xeb,0x21};
void hf_msg_show_usage(void)
{
printf("########################################################################\n");
@ -35,8 +38,8 @@ void hf_msg_show_usage(void)
printf("hf ate <rep> <err>; -- send extended at error code\n");
printf(" rep: response code from 0 to 7\n");
printf(" err: error code from 0 to 32\n");
printf("hf iron; -- inband ring tone provided\n");
printf("hf iroff; -- inband ring tone not provided\n");
printf("hf iron; -- in-band ring tone provided\n");
printf("hf iroff; -- in-band ring tone not provided\n");
printf("hf ac; -- Answer Incoming Call from AG\n");
printf("hf rc; -- Reject Incoming Call from AG\n");
printf("hf d <num>; -- Dial Number by AG, e.g. hf d 11223344\n");

View file

@ -154,11 +154,6 @@ void bt_app_hf_cb(esp_hf_cb_event_t event, esp_hf_cb_param_t *param)
param->conn_stat.peer_feat,
param->conn_stat.chld_feat);
memcpy(hf_peer_addr, param->conn_stat.remote_bda, ESP_BD_ADDR_LEN);
if (param->conn_stat.state == ESP_HF_CONNECTION_STATE_CONNECTING) {
esp_bt_hf_connect(hf_peer_addr);
} else if (param->conn_stat.state == ESP_HF_CONNECTION_STATE_DISCONNECTING) {
esp_bt_hf_disconnect(hf_peer_addr);
}
break;
}
@ -176,7 +171,7 @@ void bt_app_hf_cb(esp_hf_cb_event_t event, esp_hf_cb_param_t *param)
break;
}
case ESP_HF_BVRA_EVT:
case ESP_HF_BVRA_RESPONSE_EVT:
{
ESP_LOGI(BT_HF_TAG, "--Voice Recognition is %s", c_vr_state_str[param->vra_rep.value]);
break;
@ -283,7 +278,7 @@ void bt_app_hf_cb(esp_hf_cb_event_t event, esp_hf_cb_param_t *param)
break;
}
// case ESP_HF_BAC_RESPONSE_EVT:
case ESP_HF_BAC_RESPONSE_EVT:
case ESP_HF_BCS_RESPONSE_EVT:
{
ESP_LOGI(BT_HF_TAG, "--AG choose codec mode: %s",c_codec_mode_str[param->codec.mode]);

View file

@ -62,23 +62,23 @@ static void console_uart_task(void *pvParameters)
}
//Event of HW FIFO overflow detected
case UART_FIFO_OVF:
ESP_LOGI(TAG_CNSL, "hw fifo overflow\n");
ESP_LOGI(TAG_CNSL, "hw fifo overflow");
break;
//Event of UART ring buffer full
case UART_BUFFER_FULL:
ESP_LOGI(TAG_CNSL, "ring buffer full\n");
ESP_LOGI(TAG_CNSL, "ring buffer full");
break;
//Event of UART RX break detected
case UART_BREAK:
ESP_LOGI(TAG_CNSL, "uart rx break\n");
ESP_LOGI(TAG_CNSL, "uart rx break");
break;
//Event of UART parity check error
case UART_PARITY_ERR:
ESP_LOGI(TAG_CNSL, "uart parity error\n");
ESP_LOGI(TAG_CNSL, "uart parity error");
break;
//Event of UART frame error
case UART_FRAME_ERR:
ESP_LOGI(TAG_CNSL, "uart frame error\n");
ESP_LOGI(TAG_CNSL, "uart frame error");
break;
//Others
default: