ESP32-A2DP is an open-source library based on the ESP32 microcontroller, providing a simple and easy-to-use API that allows the ESP32 to easily receive and send Bluetooth audio data, building your own Bluetooth music world. This article will detail the features, usage methods, and some application scenarios of ESP32-A2DP, helping you quickly get started and develop interesting Bluetooth music projects.
1. Introduction to ESP32-A2DP
The ESP32-A2DP library is based on the A2DP Bluetooth protocol of the ESP32, supporting the receiving and sending of audio data. It provides a concise API for users to develop in the Arduino IDE.
1.1 Supported Bluetooth Protocols
ESP32-A2DP primarily supports the A2DP (Advanced Audio Distribution Profile) Bluetooth protocol, which is used for wireless transmission of audio data. Additionally, it supports the AVRCP (Audio/Video Remote Control Profile) protocol for controlling audio playback.
1.2 I2S API and Dependencies
The ESP32-A2DP library relies on the I2S API of the ESP32 for audio data output. To ensure code compatibility, it is recommended to use the AudioTools library, which provides a unified I2S output API compatible with different versions of the ESP32.
2. A2DP Sink (Music Receiver)
ESP32-A2DP can act as an A2DP Sink, receiving audio data from Bluetooth devices. For example, you can use it to build a Bluetooth speaker.
2.1 Simple I2S Example
Below is a simple example demonstrating how to output Bluetooth audio data to the I2S interface:
#include "AudioTools.h"
#include "BluetoothA2DPSink.h"
I2SStream i2s;
BluetoothA2DPSink a2dp_sink(i2s);
void setup() {
a2dp_sink.start("MyMusic");
}
void loop() {
}
This example creates a Bluetooth device named “MyMusic” and outputs audio data to the default I2S pins (bck_io_num = 14, ws_io_num = 15, data_out_num = 22). You need to connect these pins to an external DAC to convert the digital audio signal to an analog audio signal.
2.2 Custom Pins
You can customize the I2S pins by configuring them in the setup()
function:
#include "AudioTools.h"
#include "BluetoothA2DPSink.h"
I2SStream i2s;
BluetoothA2DPSink a2dp_sink(i2s);
void setup() {
auto cfg = i2s.defaultConfig();
cfg.pin_bck = 14;
cfg.pin_ws = 15;
cfg.pin_data = 22;
i2s.begin(cfg);
a2dp_sink.start("MyMusic");
}
void loop() {
}
2.3 Using ESP32 I2S API
You can also use the ESP32 I2S API without installing additional libraries:
#include "I2S.h"
#include "BluetoothA2DPSink.h"
BluetoothA2DPSink a2dp_sink(I2S);
void setup() {
I2S.setSckPin(14);
I2S.setFsPin(15);
I2S.setDataPin(22);
if (!I2S.begin(I2S_PHILIPS_MODE, 44100, 16)) {
Serial.println("Failed to initialize I2S!");
while (1); // do nothing
}
a2dp_sink.start("MyMusic");
}
void loop() {
}
2.4 Output to Internal DAC
You can directly output audio data to the internal DAC of the ESP32 using the AnalogAudioStream
class from the AudioTools library:
#include "AudioTools.h"
#include "BluetoothA2DPSink.h"
AnalogAudioStream out;
BluetoothA2DPSink a2dp_sink(out);
void setup() {
a2dp_sink.start("MyMusic");
}
void loop() {
}
Audio data will be output to DAC pins GPIO25 (channel 1) and GPIO26 (channel 2).
2.5 Using Callback Functions to Access Data Streams
You can use callback functions to receive audio data packets. Audio data is typically encoded in a 44.1kHz sampling rate, dual-channel 16-bit sample format.
// Set callback function in setup function
a2dp_sink.set_on_data_received(data_received_callback);
// Callback function
void data_received_callback() {
Serial.println("Data packet received");
}
Alternatively, you can directly access the data packets:
// Set data stream reading function in setup function
a2dp_sink.set_stream_reader(read_data_stream);
// Data stream reading function
void read_data_stream(const uint8_t *data, uint32_t length)
{
int16_t *samples = (int16_t*) data;
uint32_t sample_count = length/2;
// Process audio data
}
2.6 Metadata Support
ESP32-A2DP supports receiving AVRCP metadata, such as song title, playtime, etc. You can register a callback function to handle metadata:
void avrc_metadata_callback(uint8_t data1, const uint8_t *data2) {
Serial.printf("AVRC metadata rsp: attribute id 0x%x, %s\n", data1, data2);
}
a2dp_sink.set_avrc_metadata_callback(avrc_metadata_callback);
a2dp_sink.start("BT");
2.7 Notification Support
ESP32-A2DP supports receiving AVRCP notifications, such as play status, playback position, track changes, etc. You can register callback functions to handle these notifications.
3. A2DP Source (Music Sender)
ESP32-A2DP can act as an A2DP Source, sending audio data to Bluetooth devices. For example, you can use it to build a Bluetooth audio transmitter.
3.1 Using Callback Functions to Send Data
You can use callback functions to generate audio data and send it to Bluetooth devices. ESP32-A2DP supports the SBC audio codec, and audio data is typically encoded in a 44.1kHz sampling rate, dual-channel 16-bit sample format.
#include "BluetoothA2DPSource.h"
BluetoothA2DPSource a2dp_source;
// Callback function
int32_t get_sound_data(Frame *data, int32_t frameCount) {
// Generate audio data
// Return length of generated audio data (in frames)
return frameCount;
}
void setup() {
a2dp_source.start("MyMusic", get_sound_data);
}
void loop() {
}
3.2 Sending Data Using Pre-recorded Data
You can also use pre-recorded data to send audio data.
#include "BluetoothA2DPSource.h"
extern const uint8_t StarWars10_raw[];
extern const unsigned int StarWars10_raw_len;
BluetoothA2DPSource a2dp_source;
SoundData *music = new OneChannelSoundData((int16_t*)StarWars30_raw, StarWars30_raw_len/2);
void setup() {
a2dp_source.start("RadioPlayer");
a2dp_source.write_data(music);
}
void loop() {
}
4. Application Scenarios
ESP32-A2DP can be applied in various Bluetooth music projects, such as:
-
• Bluetooth Speaker: Receives audio data from mobile phones or other Bluetooth devices and outputs it to speakers.
-
• Bluetooth Audio Transmitter: Sends audio data to Bluetooth headphones or speakers.
-
• Bluetooth Music Player: Reads audio data from SD cards or other storage devices and sends it to Bluetooth devices.
-
• Bluetooth Audio Processing: Uses the audio processing capabilities of the ESP32 to process audio data, such as adding effects, filtering, etc.
5. Conclusion
ESP32-A2DP is a powerful and easy-to-use Bluetooth audio library that can help you easily build various Bluetooth music projects. Whether you want to create a Bluetooth speaker, Bluetooth audio transmitter, or perform audio processing, ESP32-A2DP can meet your needs. I hope this article helps you quickly understand and use the ESP32-A2DP library to create more interesting Bluetooth music projects.
References
-
• ESP32-A2DP Library: https://github.com/pschatzmann/ESP32-A2DP
-
• ESP32 Documentation: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_gap_ble_api.html
-
• AudioTools Library: https://github.com/pschatzmann/audio-tools