espressif / esp-adf

Espressif Audio Development Framework
Other
1.52k stars 669 forks source link

No volume control in A2dP source mode (local or remote) (AUD-4852) #1066

Open 0x0fe opened 1 year ago

0x0fe commented 1 year ago

Target : ESP32D0WDR2 (infernal 2MB PSRAM)

IDF version :

framework-espidf @ 3.50002.230601 (5.0.2) tool-cmake @ 3.16.4 tool-esptoolpy @ 1.40501.0 (4.5.1) tool-idf @ 1.0.1 tool-mconf @ 1.4060000.20190628 (406.0.0) tool-mkfatfs @ 2.0.1 tool-mklittlefs @ 1.203.210628 (2.3) tool-mkspiffs @ 2.230.0 (2.30) tool-ninja @ 1.9.0 toolchain-esp32ulp @ 1.23500.220830 (2.35.0) toolchain-xtensa-esp32 @ 11.2.0+2022r1

ADF version : latest (2.6)

so, i initially tested with A2DP-source - wifi stream, and then A2DP source - sd_mmc, in both case i have no control on the volume. My test a2dP sink device has zero controls, so it is not possible to change the volume on it, volume can only be changed from the a2dp source device, and this is nott a rare case, some a2dp sink devices have no local volume conrol.

when i use this sink device from a PC or a mobile phone, the volume control is done by the source device (pc or mobile), and it works perfecly fine, however despite multiple attempts (several hours acually) i cannot find a way to do it from ADF, here are the methods i tried so far :

esp_err_t periph_bt_volume_up(esp_periph_handle_t periph)
esp_err_t periph_bt_volume_down(esp_periph_handle_t periph)

from a2dp_sream.c, but i found this must be for a2dp sink only, because i never pass the check if (s_aadp_handler.avrcp_conn_state) Leading me to assume this avrcp connection is active only in sink mode.

I also tried to call directly

bt_avrc_volume_set_by_local(20);

But it did not work either. i then tried to create a function in bluetootth_service.c a

#define APP_RC_CT_TL_RN_VOLUME_CHANGE    (1)
void set_volume(uint8_t vol){

    esp_avrc_ct_send_set_absolute_volume_cmd(APP_RC_CT_TL_RN_VOLUME_CHANGE, vol);
    if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap,
                                           ESP_AVRC_RN_VOLUME_CHANGE)) {
        esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_VOLUME_CHANGE, ESP_AVRC_RN_VOLUME_CHANGE, 0);
    }
    bt_avrc_volume_set_by_local(vol);    
}

but it did nothing. All these attemps have been done after the a2dp connection is active and audio is running

At this point i was still working on the http-stream example which has no method to control the volume of bitstream, normally normaly volume control should be a bluetooth command to the sink device, ordering it to lower its reproduction volume, but i wanted to try modifying the volume on the bitstream as a last ressort (before finding the proper way).

So i implemented sd_mmc player with a2dp source, where the player instance provides a local volume control on the bitstream (well, at least in I2S).

audio_hal_set_volume(board_handle->audio_hal, 20);

unfortunately, it doesnt work with a2dp source, the volume is still at the maximum on my sink device when i set player volume to 0.

Now I am out of option and i wonder what is the proper method, am I something? should i enable another bluetooth service in the sdkconfig? Is there a method i missed?