Page 1 of 1

AVRCP Volume Control

Posted: Tue Nov 12, 2019 1:53 pm
by besterm
I'm working on a BT speaker that will have local control buttons for such things as play, stop, fwd, rev, volume up and volume down. I can successfully have the phone play and stop with the following type of command:
esp_avrc_ct_send_passthrough_cmd(0, ESP_AVRC_PT_CMD_PLAY, ESP_AVRC_PT_CMD_STATE_PRESSED);

I am having no luck with using this same function call to control volume up and down:
esp_avrc_ct_send_passthrough_cmd(0, ESP_AVRC_PT_CMD_VOL_DOWN, ESP_AVRC_PT_CMD_STATE_PRESSED);
err = esp_avrc_ct_send_passthrough_cmd(0, ESP_AVRC_PT_CMD_VOL_UP, ESP_AVRC_PT_CMD_STATE_PRESSED);

The return value from these calls is 0 (ESP_OK) but the phone isn't adjusting it's volume when these commands are sent.

I have also tried to use the esp_avrc_ct_send_set_absolute_volume_cmd() command without success either.

When I press the volume up or down button on my device, I want the phone's volume slider to adjust up or down 1 increment with each button press.

Any ideas would be appreciated.

Thanks.

Re: AVRCP Volume Control

Posted: Mon Nov 18, 2019 5:22 pm
by ESP_sushant
Hello,
bluetooth/bluedroid/classic_bt/a2dp_sink example in ESP-IDF, which simulates the volume change and sends notification to the remote device, works fine with most of the mobile handsets. If you haven't already, please take a look at this example and make sure you are following all the steps correctly.
As mobile handset is working as AVRCP CT device and BT speaker as AVRCP TG device, the mobile handset needs to register volume change notification (please check bluetooth/bluedroid/classic_bt/a2dp_source example) to receive the notify events from the speaker when volume is changed.
If volume change notifications are not being sent after following the procedure correctly on BT speaker side, there are two possibilities:
Case 1: Mobile handset is not registering the Volume change notification
> To verify this please check if the given mobile handset receives volume change notify events from any BT speaker

Case 2: Mobile handset is not able to recognise the Volume change notify event sent by the BT speaker because of some interpretability issue
> In this case, please share the mobile handset details (Software version/ manufacturer) and possible BT snoop logs, if possible.

Thanks.

Re: AVRCP Volume Control

Posted: Mon Nov 18, 2019 6:44 pm
by besterm
Thanks for the reply. I figured out the following last week while working on this problem:

1. Volume up and down pass-thru commands are not accepted by Android or Iphone devices (play, stop, prev, next work good).
2. In order to sync the phone volume control with the target device, "absolute volume" commands must be used.
3. Absolute volume commands where introduced in AVRCP V1.4.
4. IDF V3 doesn't support absolute volume commands. IDF V4 introduced this support.
5. I updated my project to IDF 4.
6. The volume synchronization works fine between the phone and my target board (volume reading always correspond with each other).
7. The actual scaling of the I2S audio data doesn't work correctly.
8. The volume jumps up at 0%, 4%, 8%, 12%, and 16% settings. Any volume setting above 16% stays the same (assuming this is max volume).
9. The volume jumps occur exactly the same whether the volume command is from the controller (phone) or from the target device (local control).
10. I have tested another vendor's bluetooth module and verified that it's I2S audio scaling works correctly from 0% volume setting up to 100% volume setting without any issues using absolute volume control.
11. I was going to try to test the ADF pipeline sink example, but discovered that ADF is only supported with IDF V3, which doesn't support the absolute volume command.
12. I noticed that the ADF example code changes the LYRAT VOL+ and VOL- button commands to PREV and NEXT commands. I suspect this is because ADF doesn't support the absolute volume command. Maybe when they designed the LYRAT board, they were counting on the volume command to be supported.
13. I tried to look through the bluedroid stack to see if I could intercept the location that is actually scaling the audio based on the volume setting, but couldn't find where this math actually happens. Based on remark #8 from above, I suspect that the volume scaling math that is implemented on the incoming audio data is incorrect. If I could figure out how to fix the math or bypass the math and adjust the volume with my amplifier instead, that would be sufficient. I don't have the option to remove the absolute volume support from my project, as the volume synchronization between the controller and the target is a hard requirement.

I need to make a decision within the next week with regards to which bluetooth module that we are going to use in our product. The ESP32 appears to have potential, but I must be able to resolve this issue.

I would be grateful for any advice to resolve this volume command issue.

FYI - I did testing on the example a2dp sink project:
https://github.com/espressif/esp-idf/tr ... /a2dp_sink

I did this to rule out any potential issues that may be caused by additional code.

Thanks.

Mike

Re: AVRCP Volume Control

Posted: Tue Nov 19, 2019 5:35 am
by ESP_Vikram
The volume synchronization works fine between the phone and my target board (volume reading always correspond with each other).
Volume negotiated via `ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT` event of tg_cb is always in the range of [0, 127].
You must scale this to range your device maintains/supports volume to! So, if volume range your device supports is [0, 100], you must do

Code: Select all

actual_volume = (received_volume * 100) / 127;
and set your device to this volume.

Also, while telling mobile device change of volume using `esp_avrc_tg_send_rn_rsp` command, you must scale your device volume in [0, 127] range.

I hope you are doing this already. `a2dp-sink` example in IDF4 already do this!

Also, if you are interested in using adf, ADF already considers volume range in [0, 100]: https://github.com/espressif/esp-adf/bl ... udio_hal.h

As far as using ADF with latest IDF is concerned, this is under development. For now, you should be able to update IDF and use it with fixing some minor issues for now.
The volume jumps up at 0%, 4%, 8%, 12%, and 16% settings. Any volume setting above 16% stays the same (assuming this is max volume).
If you've set volume range from [0, 16]. You should scale received volume [0, 127]-->[0, 16]. So, max received 127 is mapped to 16. While reporting to phone do the reverse.

Re: AVRCP Volume Control

Posted: Tue Nov 19, 2019 12:39 pm
by besterm
OK. From the last comment it sounds like when the phone sends an absolute volume control command to the ESP32, the I2S data that is being sent from the ESP32 to my codec/amplifier shouldn't be affected and that I should be able to just control my target volume by adjusting my amplifier IC (which is I2C controlled)? If that is the case, then my problem is that the I2S data is being modified somewhere in the IDF4 code, because the I2S data magnitude is being automatically adjusted at the 0%-16% steps that I described previously. I measured the I2S data with a logic analyzer while playing a 440Hz square wave sound from my phone in order to easily read max + and min - excursion values. If I modify my firmware to not support the absolute volume control method, I can see the I2S data magnitude scale from 0% - 100% volume using the full phone volume slider range. I can also verify audibly that the sound goes from mute to very loud as well. This works without changing any settings on my codec/amplifier IC. If I can turn off the scaling of the I2S, I could easily just control the amplifier output with it's registers via the I2C interface.

Is it correct to say that the IDF4 libraries shouldn't be modifying the I2S data based on AVRCP absolute volume control received messages? and that I should be able to fully control my audio volume with my own firmware that controls my amplifier IC?

Re: AVRCP Volume Control

Posted: Tue Nov 19, 2019 3:35 pm
by besterm
OK. Made a discovery. The weird I2C volume changes only occur on my Pixel 3A device. If I use a Pixel 2 or IPhone, the I2S remains volume doesn't change. This is exactly what I wanted. Makes me wonder if I could see if the Pixel 3A is modifying the SBC audio data that is sent by the phone.

Re: AVRCP Volume Control

Posted: Thu Nov 21, 2019 7:56 am
by ESP_Vikram
besterm wrote:
Tue Nov 19, 2019 3:35 pm
OK. Made a discovery. The weird I2C volume changes only occur on my Pixel 3A device. If I use a Pixel 2 or IPhone, the I2S remains volume doesn't change. This is exactly what I wanted. Makes me wonder if I could see if the Pixel 3A is modifying the SBC audio data that is sent by the phone.
Yes, some Android devices do that. They do not support volume registration and instead do scaling of samples on their side to change volume.

In those cases, both a mobile device and speaker maintain different level of volume.

Re: AVRCP Volume Control

Posted: Fri Apr 24, 2020 1:20 pm
by benjavita
Hello,

I'm having the same issue, esp_avrc_ct_send_passthrough_cmd works with play/stop commands, e.g:

Code: Select all

esp_avrc_ct_send_passthrough_cmd(1, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED);
but not for the volume:

Code: Select all

esp_avrc_ct_send_passthrough_cmd(1, ESP_AVRC_PT_CMD_VOL_UP, ESP_AVRC_PT_CMD_STATE_PRESSED);
I updated my project to IDF v4 (was on 3.3), but same result.

Also tried esp_avrc_ct_send_set_absolute_volume_cmd but it doesn't seem to work either....

Any ideas?

Thanks!

Re: AVRCP Volume Control

Posted: Tue May 19, 2020 12:08 am
by Will_ISM
Hello Benjavita, if you doesn't fix your code, try this option: https://www.youtube.com/watch?v=4a10Tl5eR30&t=1s.
It runs perfectly to me, to fix the same problem.

Good luck!