A couple of months ago, I described how you can use my Arduino A2DP library to receive music with an ESP32 via Bluetooth e.g. from a mobile phone.

I have extended the library and implemented the BluetoothA2DPSource class that you can use to to the opposite and send sound data from an ESP32 to a Bluetooth Receiver:

#include "BluetoothA2DPSource.h"
#include <math.h> 

BluetoothA2DPSource a2dp_source;

void setup() {
  a2dp_source.start("MyMusic", get_sound_data);  
}

void loop() {
}

That’s pretty easy to use: In the start you just indicate the Bluetooth Device name that you want to connect to and indicate a call back function. So the only challenge is to provide an implementation for the get_sound_data callback method. The supported audio codec in ESP32 A2DP is SBC: SBC audio stream is encoded from PCM data normally formatted as 44.1kHz sampling rate with two-channel 16-bit sample data.

Here is an simple implementation that just generates some sound with the help of the sin() function:

#define c3_frequency  130.81
#define c4_frequency  261.63 

// The supported audio codec in ESP32 A2DP is SBC. SBC audio stream is encoded
// from PCM data normally formatted as 44.1kHz sampling rate, two-channel 16-bit sample data
int32_t get_data(uint8_t *data, int32_t len) {
    if (len < 0 || data == NULL) {
        return 0;
    }
    Channels* ch_data = (Channels*) data;
    static double m_time = 0.0;
    double m_amplitude = 10000;  // max -32,768 to 32,767
    double m_deltaTime = 1.0 / 44100;
    double m_phase = 0.0;
    double double_Pi = PI * 2.0;
    for (int sample = 0; sample < len/4; ++sample) {
        ch_data[sample].channel1 = m_amplitude * sin(double_Pi * c3_frequency * m_time + m_phase);
        ch_data[sample].channel2 = m_amplitude * sin(double_Pi * c4_frequency * m_time + m_phase);
        m_time += m_deltaTime;
    }
    return len;
}

The new version 1.1 of the library is available new on Github.

Categories: Arduino

36 Comments

Sergio83100 · 7. August 2024 at 12:24

Hello Phil, I would like to stream mp3 from SD to BT speaker via A2DP, not very difficult. I have many BT speaker with the same name in my home. My question is how to pair ESP32 source with one BT speaker and memorize this pairing. In this way I could have several couples of ESP32/BT speaker.
Thanks in advance for yur help.

    pschatzmann · 7. August 2024 at 15:03

    Just have a look at the ssid callback example: You can accept a connection by ssid, address and rssi:
    https://github.com/pschatzmann/ESP32-A2DP/blob/main/examples/bt_music_sender_ssid_callback/bt_music_sender_ssid_callback.ino

      Sergio83100 · 17. August 2024 at 13:51

      hello Phil, sorry for responding so late.
      I did what you suggested by compiling and executing the sketch in question as is and I did not obtain any results on the serial connection. However, I have devices with Bluetooth activated nearby. Probably I’m missunderstood something. Also I don’t understand the comment above the call back SSID declaration in this example: true, false why and how … By the way where are defined structure of parameters of callback, “esp_bd_adr_t” for example.

        pschatzmann · 18. August 2024 at 9:21

        please use a github discussion!

Suneeth · 19. April 2024 at 20:56

Could you please give me a little extra insight about writing a callback function if at all I have to send a custom audio rather than a sin() wave please?

Anonymous · 16. October 2023 at 16:09

Pin definition are not straight forward to change pins of controller ,i2s_pin_config_t pin_config no where found in all your work

    pschatzmann · 16. October 2023 at 16:15

    That’s nonsense: Just read the Readme of the Project!
    The documentation is quite complete!

Sagi · 31. July 2023 at 10:20

Hey there!
first of all thank you for all your work, it helped me a lot!
Now I’ve been trying to use connect from my esp32 to a portable speaker and for some reason Im only able to connect to a specific one from an unknown company, and when Im trying to connect to a JBL flip or to my EarPods I’m not able to.
Do you have a way to solve this?

thanks a lot in advance and Ill appreciate any response.
Sagi

    pschatzmann · 3. August 2023 at 3:05

    This is not the right place for this: I suggest to check and use the Issues and Discussions on Github

Andrew Banchieri · 6. February 2023 at 23:08

Thank you for your efforts. I have a Bluetooth speaker system that uses a pairing code. I’d like to use the ESP32 to send an audio signal to this speaker system. Is there a method to have the ESP32 send a pairing code?

    pschatzmann · 7. February 2023 at 8:31

    Did you have a look at the class documentation ? There you should find the following entry:
    /// Defines the pin code. If nothing is defined we use “1234”
    virtual void set_pin_code(const char* pin_code, esp_bt_pin_type_t pin_type=ESP_BT_PIN_TYPE_VARIABLE);

Michael · 9. October 2022 at 9:41

Hi, is it possible to connect a esp32 to an audio source and stream this audio over ble to a hearing aid? Like the asha gatt protocol that android use.
Cheers

    pschatzmann · 9. October 2022 at 9:49

    No, the ESP32 still does not provide any audio functionality with BLE…

Joel Leon · 6. October 2022 at 23:06

All your work is quite exceptional and greatly appreciated. Thank you.
My project uses an Esp32 to create a varying tone in response to a sensor. To date I play the tone on a hard wired speaker. I would like to send the tone to a Smartphone over BLE. Can you point me in the right direction to continue my project.
Thanks,
Joel

    pschatzmann · 7. October 2022 at 18:42

    Nop, the ESP32 currently does not provide any audio functionality with BLE…

saadistan · 23. July 2022 at 10:46

can you stream audio from PDM MIC to a mobile device and simultaneously use Bluetooth serial communication as well for two-way serial data transfer?

    pschatzmann · 25. July 2022 at 21:02

    No you can have only one Bluetooth connection at any time!
    Please note that when you use Bluetooth you also can’t use WIFI

Paul · 20. July 2022 at 21:00

Thanks again for all your hard working creating this A2DP Source library. Much appreciated! Regarding the function write_data(), how do we assess the state of the queue before calling write_data()? I’ve looked at the library’s source code, but am not able to figure this out (yet). Thanks!

Paul · 7. November 2021 at 1:02

What you have done is great. Many thanks and Kudos!! Question: Is it possible for the ESP32 to connect to a two-way bluetooth device (e.g. headset microphone), by name, and then be both a sink and a source at the same time?
My interest is in operating a two-way radio with the ESP32 and instead of hard wiring a microphone and speaker/earphone I would like to be able to do both audio exchanges using an off the shelf BT headset. And if it’s important… the radio is “half-duplex” so the streams of audio in the two directions wouldn’t have to be simultaneous so long as the change in direction was without significant delay.
As you likely know the limitations of the ESP32 BT interface well, I thought that you may be able to answer this with some certainty.
Thanks again.

Holger · 4. November 2021 at 23:57

Hi, is it possible to send audio to ANY audio device without specifying its name?

Thanks

Holger

Nish · 28. October 2021 at 0:27

How to pair my bluetooth speaker with name “XYZ” to the ESP32 and send a tone.
Is your “MyMusic” the identifier of the speaker?

    pschatzmann · 28. October 2021 at 0:58

    yes it is.

yann keller · 24. September 2021 at 21:13

hello,
i want stream a mp3 playlist to a bluetoothspeaker, part of an installaltion, a weird three axis rotaing thing with the bt speaker inside in the center. the future plan is to start the “machine” with one button, movement and audio and best would be if the audio comes also via the controller. is it somehow possible to do that with this esp32 lib? access a sdcard or such somehow (good audio quality) and play the audio?…or is it something that might become possible in the future?

    pschatzmann · 25. September 2021 at 15:21

    This should be possible: I suggest that you have a look at https://github.com/pschatzmann/arduino-audio-tools as well.

    I am currently extending this library with an audio player which would make your described scenario a little bit easier to implement.

      yann keller · 26. September 2021 at 13:07

      great…looking forward to try it. more questions: would it be possibly to connect multiple receiving speakers to the esp32?

        pschatzmann · 27. September 2021 at 11:17

        At one point of time you can send the output only to one Bluetooth Sink

      yann keller · 28. September 2021 at 15:21

      can i follow the devellopment somewhere?

        pschatzmann · 29. September 2021 at 15:19

        You could watch the project or follow me on Github…

      yann keller · 28. September 2021 at 16:29

      what would i use to store and play the audio files from? i had ordered dfplayer mini tf card u disk before. i guess that could do it?

    yann · 21. November 2021 at 0:09

    i am now again on this project, have a sdcard directly connected via spi, communication with the card is working . i want to try the payler-sd-s2dp but get lots of errors. i have installed sdfat lib and libhelix..it does compile the sdtest.ino. tests ok. am i missing another library? it complains f. e. about multiple wifi.h. too long to post here i guess. errors mostly about arduino-audio-tools
    greets

sekpona kokou · 14. June 2021 at 3:09

good evening sir. This is an interesting project. But could I play text to speech on the bluetooth speaker with your library?

    pschatzmann · 14. June 2021 at 15:10

    This project can only send a PCM signal to a bluetooth sink (eg bluetooth speaker).
    You could try to use a ‘text to speach webservice’ e.g. from Amazon or Google to generate the PCM Audio and then use this project to send it to the bluetooth sink.

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *