esp-idf: A2DP Source stream audio to two Sink device (IDFGH-253)
Hello all, @blueMoodBHD @mywang-espressif @igrr @FayeY
I want to add new functionality to the A2DP source capability of the esp-idf. Especially I want to stream audio from ESP32 to two bluetooth speaker.
I want to reach this funtionality with the design guidelines of the bluetooth.org from the study called “WHITE PAPER ON USAGE OF MULTIPLE HEADPHONES”: (https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=110679)
In this study there are use cases how should a source device act if the user wants to connect two sink audio device.
One of the scenario follows the next steps:
- AVDTP & AVCTP Connection establish with Sink device 1
- A2DP SEP Disc/Selec with Sink device 1
- SET_CONFIG for Sink device 1
- OPEN connection with Sink device 1
- START meadia Sink device 1 (ESP_A2D_MEDIA_CTRL_START)
- STREAM Media to Sink device 1 ---- new device connection----
- GAP/ACL Connect to Sink device 2
- AVDTP Establish, SEP Disc/Select with Sink device 2
- Suspend media to Sink device 1 (ESP_A2D_MEDIA_CTRL_SUSPEND)
- SET_CONFIG to Sink device 2
- OPEN connection with Sink device 2
- START Media on Sink device 2 (ESP_A2D_MEDIA_CTRL_START)
- STREAM Media to Sink device 1
- STREAM Media to Sink device 2
- HAPPY USERs
Would somebody give some idea how to start for the 7-8, and 10th steps? The base application would be the A2DP_source example code.
The study states we need to have two (or more) Stream End Point, SEPs on the SRC device that support the SBC codec.
I have already figured out the SEPs are initialized with the bta_av_api_register() function in the bt/bluedroid/bta/av/bta_av_main.c file. The SEPs are handled in a tBTA_AV_SCB struct with the following code:
tBTA_AV_SEP seps[BTA_AV_MAX_SEPS];
Here it can be seen the BlueDroid stack is already prepared somehow to handle more connection.
As I go through the code in the current esp-idf there are two streams are handled. One seperated stream for the source device and one seperated stream for sink device. And that is why the BTA_AV_MAX_SEPS equals two. I guess…
In the bt/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c file, the btc_a2dp_source_send_aa_frame() function prepares the audio data/frame what we want to send to the sink device. And it would be good if the created frame would be sended to both of the connected devices in a queue. In that manner all SNK devices will be receiving identical A2DP media packets. But I have no idea where to start in this manner. Maybe the btc_a2dp_source_task_handler() function needs some rework too.
The study mentioned the following:
When the SRC connects to another SNK device the configuration of the SBC codec should be the same as the configuration of the SBC codec in the existing SNK device.
In the code hwo can I attach the same SBC configuration for both of the device?
Anyway, these are very small slices of the “game” and I know this is not a small rewrite. I just really need some help and advice which functions shall be rewrited.
Any advice are welcomed!
Rob
UPDATE 2018.06.22
I modified the btc_av.c , btc_avrc.c and the main API state handler to handle the multiple connections.
Basically I modified two main things:
In the btc_av.c the following:
typedef struct {
int service_id[BT_NUM_OF_DEVICES];
tBTA_AV_HNDL bta_handle[BT_NUM_OF_DEVICES];
uint8_t peer_bda[BT_NUM_OF_DEVICES][BD_ADDR_LEN];
btc_sm_handle_t sm_handle[BT_NUM_OF_DEVICES];
UINT8 flags[BT_NUM_OF_DEVICES];
tBTA_AV_EDR edr[BT_NUM_OF_DEVICES];
UINT8 peer_sep[BT_NUM_OF_DEVICES]; /* sep type of peer device */
UINT8 connected_dev_num; //< count how much device connected
UINT8 active_dev_idx; //< index number of the activated device
UINT8 conn_slot; //< how much device is already connected
UINT8 media_ctrl_pending; //< flag for indication of the media control is pending
} btc_av_cb_t;
And in the btc_avrc.c:
typedef struct {
BOOLEAN rc_connected[BT_NUM_OF_DEVICES];
UINT8 rc_handle[BT_NUM_OF_DEVICES];
tBTA_AV_FEAT rc_features[BT_NUM_OF_DEVICES];
uint8_t rc_addr[BT_NUM_OF_DEVICES][BD_ADDR_LEN];
UINT16 rc_pending_play[BT_NUM_OF_DEVICES];
btc_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN]; //todo: this is not prepared fow two sink
btc_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS]; //todo: this is not prepared fow two sink
unsigned int rc_volume[BT_NUM_OF_DEVICES];
uint8_t rc_vol_label[BT_NUM_OF_DEVICES];
uint8_t active_dev_idx; //< index number of the activated device
uint8_t conn_slot; //< index number of the activated device
} btc_rc_cb_t;
And I modified all of the functions whose are using these variables. But I run into an error when the second device tries to connec: av scb not available for avdt connection
This came from the bta_av_sig_chg() function in the bt/bluedroid/bta/av/bta_av_act.c file:
/* check if we found something */
if (xx == BTA_AV_NUM_LINKS) {
/* We do not have scb for this avdt connection. */
/* Silently close the connection. */
APPL_TRACE_ERROR("av scb not available for avdt connection");
AVDT_DisconnectReq (p_data->str_msg.bd_addr, NULL);
return;
}
Any advice what can be the problem?
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 5
- Comments: 16
Sorry, the BLE audio chip is not ready, still in R&D stage.