Page 2 of 2

Re: A2dp sink volume control?

Posted: Wed Aug 26, 2020 9:45 pm
by sdourmashkin
Thanks so much for sharing! You were right, the issue had to do with the fact that the volume data is 8 MSB (instead of 16). Your fix worked, although we also have to change the code to only parse through one byte at a time (numBytesShifted = 1). Here's the volume change function with that fix:

Code: Select all

//the following code changes the volume
uint8_t *volume_control_changeVolume(uint8_t *data, uint8_t *outputData, size_t size, uint8_t volume) {
    const int numBytesShifted = 1;
    int16_t pcmData;
    bool isNegative;
    memcpy(outputData, data, size);
    size_t h = 0;
    for (h = 0; h < size; h += numBytesShifted) {
        pcmData = data[h];
        isNegative = pcmData & 0x80;
        if (isNegative) 
            pcmData = (~pcmData) + 0x1;
        pcmData = pcmData >> (8 - volume);
        if (isNegative) 
            pcmData = (~pcmData) + 0x1;
        outputData[h] = pcmData;
    }
    return outputData;
}
There's a big jump from master_volume = 8 --> 7. I'm assuming that has to do with the data only being 8-bit though.

Setting .communication_format = I2S_COMM_FORMAT_I2S_MSB didn't seem to make a difference. Let me know if you think otherwise.

Thanks again!

- Steven

Re: A2dp sink volume control?

Posted: Thu Aug 27, 2020 1:22 pm
by mooalot
Whoops, I must've forgot to change numBytesShifted = 1 in my fix!

Now that I think about it, I dont think setting the format to MSB does anything because its only 8 bits.

You're right about the volume change as well, 8 bits doesn't allow for much change using log base 2. Im sure there are other ways to change the volume, but this was the way I used.

Glad to help.

Goodluck!

Re: A2dp sink volume control?

Posted: Tue Oct 01, 2024 8:40 pm
by spierepf
I ran into the same problem, but I came up with what I think is a simpler solution:

Code: Select all

void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len)
{
    for(int i = 0; i < len/2; ++i) {
        int32_t value = ((int16_t*)data)[i] * s_volume >> 7;
        ((int16_t*)data)[i] = value;
    }
    write_ringbuf(data, len);

    /* log the number every 100 packets */
    // if (++s_pkt_cnt % 100 == 0) {
    //     ESP_LOGI(BT_AV_TAG, "Audio packet count: %"PRIu32, s_pkt_cnt);
    // }
}

Re: A2dp sink volume control?

Posted: Tue Oct 29, 2024 6:38 am
by eiffelpeter
I can control volume on iphone or android.
By remove below lines in a2dp sink example.

Code: Select all

//esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_SET, &evt_set, ESP_AVRC_RN_VOLUME_CHANGE);
//assert(esp_avrc_tg_set_rn_evt_cap(&evt_set) == ESP_OK);
But I found the analog output will distortion when play 0dB 1kHz tone and set volume more 80%.
https://github.com/espressif/esp-idf/issues/14795