Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ before you start the A2DP sink. Note that data2 is actually a char* string, so e

### Support for Notifications

Similarly to the `avrc_metadata_callback`, ESP IDF v4+ supports selected `esp_avrc_rn_param_t` callbacks like `set_avrc_rn_playstatus_callback` and `set_avrc_rn_play_pos_callback` which can be used to obtain `esp_avrc_playback_stat_t playback` playback status and `uint32_t play_pos` playback position respectively. See the playing_status_callbacks example for more.
Similarly to the `avrc_metadata_callback`, ESP IDF v4+ supports selected `esp_avrc_rn_param_t` callbacks like `set_avrc_rn_playstatus_callback`, `set_avrc_rn_play_pos_callback` and `set_avrc_rn_track_change_callback` which can be used to obtain `esp_avrc_playback_stat_t playback` playback status,`uint32_t play_pos` playback position and `uint8_t elm_id` track change flag respectively. See the playing_status_callbacks example for more details.

### Support for AVRC Commands

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "BluetoothA2DPSink.h"

I2SStream out;
BluetoothA2DPSink a2dp_sink(i2s);
BluetoothA2DPSink a2dp_sink(out);

void avrc_rn_play_pos_callback(uint32_t play_pos) {
Serial.printf("Play position is %d (%d seconds)\n", play_pos, (int)round(play_pos/1000.0));
Expand Down Expand Up @@ -48,10 +48,22 @@ void avrc_rn_playstatus_callback(esp_avrc_playback_stat_t playback) {
}
}

void avrc_rn_track_change_callback(uint8_t *id) {
Serial.println("Track Change bits:");
for (uint8_t i = 0; i < 8; i++)
{
Serial.printf("\tByte %d : 0x%x \n",i,id[i]);
}
//An example of how to project the pointer value directly as a uint8_t
uint8_t track_change_flag = *id;
Serial.printf("\tFlag value: %d\n",track_change_flag);
}

void setup() {
Serial.begin(115200);
a2dp_sink.set_avrc_rn_playstatus_callback(avrc_rn_playstatus_callback);
a2dp_sink.set_avrc_rn_play_pos_callback(avrc_rn_play_pos_callback);
a2dp_sink.set_avrc_rn_play_pos_callback(avrc_rn_play_pos_callback,5); //Update the playing position every 5 seconds when Playing
a2dp_sink.set_avrc_rn_track_change_callback(avrc_rn_track_change_callback);
a2dp_sink.start("MyMusic");
}

Expand Down
14 changes: 10 additions & 4 deletions src/BluetoothA2DPSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,8 +741,8 @@ void BluetoothA2DPSink::av_new_track() {
if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST,
&s_avrc_peer_rn_cap,
ESP_AVRC_RN_TRACK_CHANGE)) {
esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_TRACK_CHANGE,
ESP_AVRC_RN_TRACK_CHANGE, 0);
esp_avrc_ct_send_register_notification_cmd(
APP_RC_CT_TL_RN_TRACK_CHANGE, ESP_AVRC_RN_TRACK_CHANGE, 0);
}
#endif
}
Expand All @@ -766,7 +766,7 @@ void BluetoothA2DPSink::av_play_pos_changed(void) {
&s_avrc_peer_rn_cap,
ESP_AVRC_RN_PLAY_POS_CHANGED)) {
esp_avrc_ct_send_register_notification_cmd(
APP_RC_CT_TL_RN_PLAY_POS_CHANGE, ESP_AVRC_RN_PLAY_POS_CHANGED, 10);
APP_RC_CT_TL_RN_PLAY_POS_CHANGE, ESP_AVRC_RN_PLAY_POS_CHANGED, notif_interval_s);
}
#endif
}
Expand All @@ -783,7 +783,13 @@ void BluetoothA2DPSink::av_notify_evt_handler(uint8_t event_id,
switch (event_id) {
case ESP_AVRC_RN_TRACK_CHANGE:
ESP_LOGD(BT_AV_TAG, "%s ESP_AVRC_RN_TRACK_CHANGE %d", __func__, event_id);
av_new_track();
av_new_track();
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
// call avrc track change notification callback if available
if (avrc_rn_track_change_callback != nullptr) {
avrc_rn_track_change_callback(event_parameter->elm_id);
}
#endif
break;
case ESP_AVRC_RN_PLAY_STATUS_CHANGE:
ESP_LOGD(BT_AV_TAG, "%s ESP_AVRC_RN_PLAY_STATUS_CHANGE %d, to %d",
Expand Down
13 changes: 11 additions & 2 deletions src/BluetoothA2DPSink.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,18 @@ class BluetoothA2DPSink : public BluetoothA2DPCommon {
void (*callback)(esp_avrc_playback_stat_t playback)) {
this->avrc_rn_playstatus_callback = callback;
}
/// Define a callback method which provides esp_avrc_rn_param_t play position notifications
/// Define a callback method which provides esp_avrc_rn_param_t play position notifications, at a modifiable interval over 1s
virtual void set_avrc_rn_play_pos_callback(
void (*callback)(uint32_t play_pos)) {
void (*callback)(uint32_t play_pos),uint32_t notif_interval) {
this->avrc_rn_play_pos_callback = callback;
this->notif_interval_s = max(notif_interval,(uint32_t)1);
}
/// Define a callback method which provides an 8bit array for track change notifications
/// Typically the last bit is 1 when there is a track change (so can be cast to a uint8_t)
virtual void set_avrc_rn_track_change_callback(
void (*callback)(uint8_t *id)) {
this->avrc_rn_track_change_callback = callback;
}
#endif

/// Defines the method which will be called with the sample rate is updated
Expand Down Expand Up @@ -419,7 +426,9 @@ class BluetoothA2DPSink : public BluetoothA2DPCommon {
void (*avrc_metadata_callback)(uint8_t, const uint8_t *) = nullptr;
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)
void (*avrc_rn_playstatus_callback)(esp_avrc_playback_stat_t) = nullptr;
void (*avrc_rn_track_change_callback)(uint8_t *) = nullptr;
void (*avrc_rn_play_pos_callback)(uint32_t) = nullptr;
uint32_t notif_interval_s = 10;
#endif
void (*avrc_rn_volchg_complete_callback)(int) = nullptr;
bool (*address_validator)(esp_bd_addr_t remote_bda) = nullptr;
Expand Down