git describe --tags to find it):xtensa-esp32-elf-gcc --version to find it):ESP32 receives audio data over WiFi and pushes it to a ringbuffer. The audio is then read from the ringbuffer in bt_app_a2d_data_cb. It all worked well before we upgraded to release/v4.0. The callback function stops working after this event:
_a2dp media start successfully._
Then the callback function stops being called. I am not sure what is the cause or if it is just coincidence that it happens on same time.
When i dont use the ringbuffers and just generate some random noise it works.
I made example application where the callback function stops working after it works properly for a few seconds.
_Callback function in example is same as we use on device with udp._
Should connect to the tested device and then send random noise to the a2dp sink device.
On succesfull connect sound is transfered but stops after about 5 seconds.
Run the code below. Only thing to change in code is the name of device you want to connect. It is at same place as in example.
See the commit.
@KollarRichard Thanks for reporting, we will look into. Thanks.
@KollarRichard
bt_app_a2d_data_cb, when you call xRingbufferReceive, What is the last parameter you used? Suggesting to use 0.@blueMoodBHD
xRingbufferGetCurFreeSize it works for a while. Stops anyway but later. xRingbufferReceiveUpTo and which parameter you mean? There are more of them. DocumentationxTicksToWait as the last parameter. I noticed it just now. It seems like that there is something error about ringbuffer. Here are some considerations:
bt_app_a2d_data_cb, so xTicksToWait should be 0. And there should not be any other delays.xRingbufferReceiveUpTo, A call to vRingbufferReturnItem is required after this to free up the date retrieved. even if the data you received is less than xMaxSize.0 but stopped working anyway. vRingbufferReturnItem is called.Here is my code for callback function:
static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len)
{
if (len < 0 || data == NULL)
{
return 0;
}
size_t item_size;
// size_t free_size = xRingbufferGetCurFreeSize(a2dp_input_buffer);
// ESP_LOGE(BT_AV_TAG, "Waiting for bluetooth data, buffer free size: %d", free_size);
char *item = (char *)xRingbufferReceiveUpTo(a2dp_input_buffer, &item_size, 0, len / 2);
if (item != NULL)
{
if (item_size < (len / 2))
{
ESP_LOGI(BT_AV_TAG, "!!!!!Less items in buffer (%d) than required (%d)", item_size, len / 2);
}
// ESP_LOGI(BT_AV_TAG, "Received data for bluetooth: %d", item_size);
for (int i = 0; i < item_size / 2; i++)
{
char v1 = item[2 * i];
char v2 = item[2 * i + 1];
data[4 * i] = v1;
data[4 * i + 1] = v2;
data[4 * i + 2] = v1;
data[4 * i + 3] = v2;
}
vRingbufferReturnItem(a2dp_input_buffer, (void *)item);
return len;
}
else
{
ESP_LOGE(BT_AV_TAG, "Received no data for bluetooth");
return len;
}
}
@KollarRichard I'm also using a ring buffer to pass audio to a BT headset. I've used your example above and modified it to make it work with both current master and release/v4.0. Please, take a look and let me know if it helps.
See the diff with master
Hi @KollarRichard
I have done some fix in your a2dp source example. And it runs well connected with another ESP32-WROVER-B board runs official a2dp_sink example.
The main fix is in the app_main(), I change the sequence of tasks.
In my opinion, AVRC and A2DP service should start up completely first, then other tasks based on these two function should be started up.
I attached the example, please take a look if the problem still exists. And pin me anytime if you have questions about the fix.
@KollarRichard Feel free to reopen if the issue still happens. Thanks.
Most helpful comment
@KollarRichard I'm also using a ring buffer to pass audio to a BT headset. I've used your example above and modified it to make it work with both current
masterandrelease/v4.0. Please, take a look and let me know if it helps.See the diff with master