{"repo":"pschatzmann/ESP32-A2DP","free":true,"listed":false,"github":"https://github.com/pschatzmann/ESP32-A2DP","clone":"git clone https://github.com/pschatzmann/ESP32-A2DP.git","description":"A Simple ESP32 Bluetooth A2DP Library (to implement a Music Receiver or Sender) that supports Arduino, PlatformIO and Espressif IDF","language":"C++","stars":2711,"topics":["a2dp-sink","a2dp-source","arduino-library","audio","bluetooth","bluetooth-speaker","esp32","esp32-arduino","pcm-data"],"license":"Apache-2.0","category":"embedded_audio","readme_excerpt":"# A Simple ESP32 Bluetooth A2DP Audio Library\n\n[![Arduino Library](https://img.shields.io/badge/Arduino-Library-blue.svg)](https://www.arduino.cc/reference/en/libraries/)\n[![IDF Component](https://img.shields.io/badge/IDF-Component-blue.svg)](https://github.com/pschatzmann/ESP32-A2DP)\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0)\n\n\nThe ESP32 is a microcontroller that provides an API for Bluetooth A2DP which can be used to receive sound data e.g. from your Mobile Phone and makes it available via a callback method. The output is a PCM data stream, decoded from SBC format. The documentation can be found [here](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/i2s.html). \n\n![esp32](https://pschatzmann.github.io/ESP32-A2DP/img/esp32.jpeg)\n\nI2S is an electrical serial bus interface standard used for connecting digital audio devices together. It is used to communicate PCM audio data between integrated circuits in an electronic device.\n\nSo we can just feed the input from Bluetooth to the I2S output: An example for this from Espressif can be found on [Github](https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/bluedroid/classic_bt/a2dp_sink).\n\nUnfortunately this example did not make me happy so I decided to convert it into a simple __Arduino Library__ that is very easy to use from an Arduino Software IDE.\n\n## Supported Bluetooth Protocols\n\nAs the name of this library implies, it supports the A2DP [Bluetooth protocol](https://en.wikipedia.org/wiki/List_of_Bluetooth_profiles) which only provides audio streaming! \n\nIt also supports Audio/Video Remote Control Profile (AVRCP) together with A2DP.\n\nThe Hands-Free Profile (HFP), Headset Profile (HSP) and standalone AVRCP without A2DP are __not__ supported!\n\n## I2S API / Dependencies\n\nEspressif is retiring the legacy I2S API: So with Arduino v3.0.0 (IDF v5) [my old I2S integration](https://github.com/pschatzmann/ESP32-A2DP/wiki/Legacy-I2S-API) will not be available any more. The legacy syntax is still working as long as you don't upgrade.  \n\nIn order to support a unique output API which is version independent, it is recommended to install and use the [AudioTools](https://github.com/pschatzmann/arduino-audio-tools) library. So the documentation and all the examples have been updated to use this new approach.\n\nHowever you can also output to any other class which inherits from Arduino Print: e.g. the [Arduino ESP32 I2SClass](https://github.com/pschatzmann/ESP32-A2DP?tab=readme-ov-file#output-using-the-esp32-i2s-api) or you can use the [data callback](https://github.com/pschatzmann/ESP32-A2DP?tab=readme-ov-file#accessing-the-sink-data-stream-with-callbacks) described below. \n\n\n## A2DP Sink (Music Receiver)\n\nThis can be used e.g. to build your own Bluetooth Speaker.\n\n### A Simple I2S Example (A2DS Sink) using default Pins\nHere is the simplest example which just uses the proper default settings:\n\n```cpp\n#include \"AudioTools.h\"\n#include \"BluetoothA2DPSink.h\"\n\nI2SStream i2s;\nBluetoothA2DPSink a2dp_sink(i2s);\n\nvoid setup() {\n    Serial.begin(115200);\n    a2dp_sink.start(\"MyMusic\");\n}\n\nvoid loop() {\n}\n```\nThis creates a new Bluetooth device with the name “MyMusic” and the output will be sent to the following default I2S pins which need to be connected to an external DAC:\n\n- bck_io_num = 14\n- ws_io_num = 15\n- data_out_num = 22\n\nPlease note that these default pins have changed compared to the legacy API!\n\n### Defining Pins\n\nYou can define your own pins easily before the ```start```.\n\n```cpp\n#include \"AudioTools.h\"\n#include \"BluetoothA2DPSink.h\"\n\nI2SStream i2s;\nBluetoothA2DPSink a2dp_sink(i2s);\n\nvoid setup() {\n    Serial.begin(115200);\n    auto cfg = i2s.defaultConfig();\n    cfg.pin_bck = 14;\n    cfg.pin_ws = 15;\n    cfg.pin_data = 22;\n    i2s.begin(cfg);\n\n    a2dp_sink.start(\"MyMusic\");\n}\n\nvoid loop() {\n}\n```\n\n### Output Using the ESP32 I2S API\n\nYou can also use the Arduino ESP32 I2S API: You do not need to install any additional library for this. \n\n```cpp\n#include \"ESP_I2S.h\"\n#include \"BluetoothA2DPSink.h\"\n\nconst uint8_t I2S_SCK = 5;       /* Audio data bit clock */\nconst uint8_t I2S_WS = 25;       /* Audio data left and right clock */\nconst uint8_t I2S_SDOUT = 26;    /* ESP32 audio data output (to speakers) */\nI2SClass i2s;\n\nBluetoothA2DPSink a2dp_sink(i2s);\n\nvoid setup() {\n    Serial.begin(115200);\n\n    i2s.setPins(I2S_SCK, I2S_WS, I2S_SDOUT);\n    if (!i2s.begin(I2S_MODE_STD, 44100, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_STD_SLOT_BOTH)) {\n      Serial.println(\"Failed to initialize I2S!\");\n      while (1); // do nothing\n    }\n\n    a2dp_sink.start(\"MyMusic\");\n}\nvoid loop() {}\n```\nPlease note, that this API also depends on the installed version: The example above is for ESP32 >= 3.0.0! \n\n### Output to the Internal DAC\n\nYou can also send the output directly to the internal DAC of the ESP32 by using the AnalogAudioStream from the AudioTools:\n\n```cpp\n#include \"AudioTools.h\"\n#include \"BluetoothA2DPSink.h\"\n\nAnalogAudioStream out;\nBluetoothA2DPSink a2dp_sink(out);\n\nvoid setup() {\n    Serial.begin(115200);\n    a2dp_sink.start(\"MyMusic\");\n}\n\nvoid loop() {\n}\n```\n\nThe output goes now to the DAC pins GPIO25 (Channel 1) and GPIO26 (Channel 2).\n\n### Accessing the Sink Data Stream with Callbacks\n\nYou can be notified when a packet is received. The API is using PCM data normally formatted as 44.1kHz sampling rate, two-channel 16-bit sample data. \n\n\n```cpp\n// In the setup function:\na2dp_sink.set_on_data_received(data_received_callback);\n\n\n// Then somewhere in your sketch:\nvoid data_received_callback() {\n  Serial.println(\"Data packet received\");\n}\n```\n\nOr you can access the packet:\n\n```cpp\n// In the setup function:\na2dp_sink.set_stream_reader(read_data_stream);\n\n// Then somewhere in your sketch:\nvoid read_data_stream(const uint8_t *data, uint32_t length)\n{\n  int16_t *samples = (int16_t*) data;\n  uint32_t sample_count = length/2;\n  // Do something with the data packet\n}\n```\nIn the ```a2dp_sink.set_stream_reader()``` method you can provide an optional parameter that defines if you want the output to I2S to be active or deactive - So you can use this method to e.g. to switch off I2S just by calling ```a2dp_sink.set_stream_reader(read_data_stream, false)```\n\n### Support for Metadata\n\nYou can register a method which will be called when the system receives any AVRC metadata (`esp_avrc_md_attr_mask_t`). Here is an example\n```cpp\nvoid avrc_metadata_callback(uint8_t data1, const uint8_t *data2) {\n  Serial.printf(\"AVRC metadata rsp: attribute id 0x%x, %s\\n\", data1, data2);\n}\na2dp_sink.set_avrc_metadata_callback(avrc_metadata_callback);\na2dp_sink.start(\"BT\");\n```\nBy default you should get the most important information, however you can adjust this by calling the ```set_avrc_metadata_attribute_mask``` method e.g if you just need the title and playing time you can call:\n```cpp\nset_avrc_metadata_attribute_mask(ESP_AVRC_MD_ATTR_TITLE | ESP_AVRC_MD_ATTR_PLAYING_TIME);\n```\nbefore you start the A2DP sink. Note that data2 is actually a char* string, so even though `ESP_AVRC_MD_ATTR_PLAYING_TIME` is documented as the milliseconds of media duration you'll need to parse it before doing math on it. See the metadata example for more.\n\n### Support for Notifications\n\nSimilarly to the `avrc_metadata_callback`, ESP IDF v4+ supports selected `esp_avrc_rn_param_t` callbacks like `set_avrc_rn_playstatus_callback`, `set_avrc_rn_play_pos_callback` and `set_avrc_rn_track_change_callback` which can be used to obtain `esp_avrc_playback_stat_t playback` playback status,`uint32_t play_pos` playback position and `uint8_t elm_id` track change flag respectively. See the playing_status_callbacks example for more details.\n\n### Support for AVRC Commands\n\nI have added the following AVRC commands, that you can use to 'control' your A2DP Source:\n\n- play();\n- pause();\n- stop();\n- next();\n- previous();\n- fast_forward();\n- rewind();\n\n\n### AAC / Codec Support\n\nBy default the sink negotiates SBC. To also support AAC (or other codecs), register [audio-tools](https://pschatzmann.github.io/arduino-audio-tools) decoders via `add_decoder()`: each one gets its own stream endpoint, and its codec is decoded into PCM automatically, through the same output pipeline as SBC. `A2DPDecoderSBC`/`A2DPDecoderAAC` wrap any `audio_tools::AudioDecoder` you give them, so you can swap in another implementation (e.g. `AACDecoderFDK`) - just include its codec header yourself. See `A2DPDecoder.h` to add support for another codec, and the `bt_music_receiver_codec` example for a full sketch.\n\nNote: registering a non-SBC stream endpoint requires ESP-IDF >= 6.1 (earlier versions only support SBC there); on older IDF the source falls back to SBC, visible via the `ESP_A2D_SEP_REG_STATE_EVT` log.\n\n## A2DP Source (Music Sender)\n\nThis can be used to feed e.g. your Bluetooth Speaker with your audio data.\n\n\n### Sending Data from a A2DS Data Source with a Callback\n\nWe can also generate sound and send it e.g. to a Bluetooth Speaker.  \n\nThe supported audio codec in ESP32 A2DP is SBC: The API is using PCM data normally formatted as 44.1kHz sampling rate, two-channel 16-bit sample data. \n\nWhen you start the BluetoothA2DPSource, you need to pass the Bluetooth name that you want to connect to and a 'call back function' that provides the sound data:\n\n```cpp\n#include \"BluetoothA2DPSource.h\"\n\nBluetoothA2DPSource a2dp_source;\n\n// callback \nint32_t get_sound_data(uint8_t *data, int32_t byteCount) {\n    // generate your sound data \n    // return the effective length in bytes\n    return byteCount;\n}\n\nvoid setup() {\n  a2dp_source.set_data_callback(get_sound_data);\n  a2dp_source.start(\"MyMusic\");  \n}\n\nvoid loop() {}\n\n```\nInstead of the ```set_data_callback callback``` method you can also use ```set_data_callback_in_frames``` which uses frames instead of bytes. In Arduino you can also provide a Stream (e.g a File) as data source or a callback which provides strea","default_branch":"main","files":443,"tree":[".github/FUNDING.yml",".github/ISSUE_TEMPLATE/Issue-report.yml",".github/ISSUE_TEMPLATE/config.yml",".gitignore","CMakeLists.txt","Doxyfile","LICENSE","README.md","component.mk","docs/html/_a2_d_p_volume_control_8h_source.html","docs/html/_bluetooth_a2_d_p_8h.html","docs/html/_bluetooth_a2_d_p_8h_source.html","docs/html/_bluetooth_a2_d_p_common_8h.html","docs/html/_bluetooth_a2_d_p_common_8h_source.html","docs/html/_bluetooth_a2_d_p_output_8h_source.html","docs/html/_bluetooth_a2_d_p_sink_8h_source.html","docs/html/_bluetooth_a2_d_p_sink_queued_8h_source.html","docs/html/_bluetooth_a2_d_p_source_8h_source.html","docs/html/_bluetooth_output_8h_source.html","docs/html/_sound_data_8h_source.html","docs/html/_volume_control_8h_source.html","docs/html/annotated.html","docs/html/bc_s.png","docs/html/bc_sd.png","docs/html/bdwn.png","docs/html/class_a2_d_p_default_volume_control-members.html","docs/html/class_a2_d_p_default_volume_control.html","docs/html/class_a2_d_p_default_volume_control.png","docs/html/class_a2_d_p_linear_volume_control-members.html","docs/html/class_a2_d_p_linear_volume_control.html","docs/html/class_a2_d_p_linear_volume_control.png","docs/html/class_a2_d_p_no_volume_control-members.html","docs/html/class_a2_d_p_no_volume_control.html","docs/html/class_a2_d_p_no_volume_control.png","docs/html/class_a2_d_p_simple_exponential_volume_control-members.html","docs/html/class_a2_d_p_simple_exponential_volume_control.html","docs/html/class_a2_d_p_simple_exponential_volume_control.png","docs/html/class_a2_d_p_volume_control-members.html","docs/html/class_a2_d_p_volume_control.html","docs/html/class_a2_d_p_volume_control.png","docs/html/class_bluetooth_a2_d_p_callbacks-members.html","docs/html/class_bluetooth_a2_d_p_callbacks.html","docs/html/class_bluetooth_a2_d_p_common-members.html","docs/html/class_bluetooth_a2_d_p_common.html","docs/html/class_bluetooth_a2_d_p_common.png","docs/html/class_bluetooth_a2_d_p_output-members.html","docs/html/class_bluetooth_a2_d_p_output.html","docs/html/class_bluetooth_a2_d_p_output.png","docs/html/class_bluetooth_a2_d_p_output_audio_tools-members.html","docs/html/class_bluetooth_a2_d_p_output_audio_tools.html","docs/html/class_bluetooth_a2_d_p_output_audio_tools.png","docs/html/class_bluetooth_a2_d_p_output_default-members.html","docs/html/class_bluetooth_a2_d_p_output_default.html","docs/html/class_bluetooth_a2_d_p_output_default.png","docs/html/class_bluetooth_a2_d_p_output_legacy-members.html","docs/html/class_bluetooth_a2_d_p_output_legacy.html","docs/html/class_bluetooth_a2_d_p_output_legacy.png","docs/html/class_bluetooth_a2_d_p_output_print-members.html","docs/html/class_bluetooth_a2_d_p_output_print.html","docs/html/class_bluetooth_a2_d_p_output_print.png","docs/html/class_bluetooth_a2_d_p_sink-members.html","docs/html/class_bluetooth_a2_d_p_sink.html","docs/html/class_bluetooth_a2_d_p_sink.png","docs/html/class_bluetooth_a2_d_p_sink_callbacks-members.html","docs/html/class_bluetooth_a2_d_p_sink_callbacks.html","docs/html/class_bluetooth_a2_d_p_sink_min_r_a_m-members.html","docs/html/class_bluetooth_a2_d_p_sink_min_r_a_m.html","docs/html/class_bluetooth_a2_d_p_sink_min_r_a_m.png","docs/html/class_bluetooth_a2_d_p_sink_queued-members.html","docs/html/class_bluetooth_a2_d_p_sink_queued.html","docs/html/class_bluetooth_a2_d_p_sink_queued.png","docs/html/class_bluetooth_a2_d_p_source-members.html","docs/html/class_bluetooth_a2_d_p_source.html","docs/html/class_bluetooth_a2_d_p_source.png","docs/html/class_bluetooth_output-members.html","docs/html/class_bluetooth_output.html","docs/html/class_bluetooth_output.png","docs/html/class_bluetooth_output_audio_tools-members.html","docs/html/class_bluetooth_output_audio_tools.html","docs/html/class_bluetooth_output_audio_tools.png","docs/html/class_bluetooth_output_default-members.html","docs/html/class_bluetooth_output_default.html","docs/html/class_bluetooth_output_default.png","docs/html/class_bluetooth_output_legacy-members.html","docs/html/class_bluetooth_output_legacy.html","docs/html/class_bluetooth_output_legacy.png","docs/html/class_default_volume_control-members.html","docs/html/class_default_volume_control.html","docs/html/class_default_volume_control.png","docs/html/class_linear_volume_control-members.html","docs/html/class_linear_volume_control.html","docs/html/class_linear_volume_control.png","docs/html/class_no_volume_control-members.html","docs/html/class_no_volume_control.html","docs/html/class_no_volume_control.png","docs/html/class_one_channel8_bit_sound_data-members.html","docs/html/class_one_channel8_bit_sound_data.html","docs/html/class_one_channel8_bit_sound_data.png","docs/html/class_one_channel_sound_data-members.html","docs/html/class_one_channel_sound_data.html","docs/html/class_one_channel_sound_data.png","docs/html/class_simple_exponential_volume_control-members.html","docs/html/class_simple_exponential_volume_control.html","docs/html/class_simple_exponential_volume_control.png","docs/html/class_sound_data-members.html","docs/html/class_sound_data.html","docs/html/class_sound_data.png","docs/html/class_two_channel_sound_data-members.html","docs/html/class_two_channel_sound_data.html","docs/html/class_two_channel_sound_data.png","docs/html/class_volume_control-members.html","docs/html/class_volume_control.html","docs/html/class_volume_control.png","docs/html/classes.html","docs/html/closed.png","docs/html/config_8h_source.html","docs/html/dir_248832ff8517b5b7d5da1a6bc8750d99.html","docs/html/dir_49e56c817e5e54854c35e136979f97ca.html","docs/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html","docs/html/doc.png","docs/html/doc.svg","docs/html/docd.png","docs/html/docd.svg","docs/html/doxygen.css","docs/html/doxygen.svg","docs/html/dynsections.js","docs/html/external__lists_8h_source.html","docs/html/files.html","docs/html/folderclosed.png","docs/html/folderclosed.svg","docs/html/folderclosedd.svg","docs/html/folderopen.png","docs/html/folderopen.svg","docs/html/folderopend.svg","docs/html/functions.html","docs/html/functions_b.html","docs/html/functions_c.html","docs/html/functions_d.html","docs/html/functions_e.html","docs/html/functions_f.html","docs/html/functions_func.html","docs/html/functions_func_b.html","docs/html/functions_func_c.html","docs/html/functions_func_d.html","docs/html/functions_func_e.html","docs/html/functions_func_f.html","docs/html/functions_func_g.html","docs/html/functions_func_h.html","docs/html/functions_func_i.html","docs/html/functions_func_l.html","docs/html/functions_func_n.html","docs/html/functions_func_p.html","docs/html/functions_func_r.html","docs/html/functions_func_s.html","docs/html/functions_func_t.html","docs/html/functions_func_u.html","docs/html/functions_func_v.html","docs/html/functions_func_w.html","docs/html/functions_func_~.html","docs/html/functions_g.html","docs/html/functions_h.html","docs/html/functions_i.html","docs/html/functions_l.html","docs/html/functions_m.html","docs/html/functions_n.html","docs/html/functions_p.html","docs/html/functions_r.html","docs/html/functions_rela.html","docs/html/functions_s.html","docs/html/functions_t.html","docs/html/functions_u.html","docs/html/functions_v.html","docs/html/functions_vars.html","docs/html/functions_w.html","docs/html/functions_~.html","docs/html/globals.html","docs/html/globals_enum.html","docs/html/globals_func.html","docs/html/globals_type.html","docs/html/group__a2dp.html","docs/html/hierarchy.html","docs/html/index.html","docs/html/jquery.js","docs/html/md__r_e_a_d_m_e.html","docs/html/menu.js","docs/html/menudata.js","docs/html/minus.svg","docs/html/minusd.svg","docs/html/modules.html","docs/html/nav_f.png","docs/html/nav_fd.png","docs/html/nav_g.png","docs/html/nav_h.png","docs/html/nav_hd.png","docs/html/open.png","docs/html/pages.html","docs/html/plus.svg","docs/html/plusd.svg","docs/html/search/all_0.html","docs/html/search/all_0.js","docs/html/search/all_1.html","docs/html/search/all_1.js","docs/html/search/all_10.html","docs/html/search/all_10.js","docs/html/search/all_11.html","docs/html/search/all_11.js","docs/html/search/all_12.html","docs/html/search/all_12.js","docs/html/search/all_13.html","docs/html/search/all_13.js","docs/html/search/all_14.js","docs/html/search/all_2.html","docs/html/search/all_2.js","docs/html/search/all_3.html","docs/html/search/all_3.js","docs/html/search/all_4.html","docs/html/search/all_4.js","docs/html/search/all_5.html","docs/html/search/all_5.js","docs/html/search/all_6.html","docs/html/search/all_6.js","docs/html/search/all_7.html","docs/html/search/all_7.js","docs/html/search/all_8.html","docs/html/search/all_8.js","docs/html/search/all_9.html","docs/html/search/all_9.js","docs/html/search/all_a.html","docs/html/search/all_a.js","docs/html/search/all_b.html","docs/html/search/all_b.js","docs/html/search/all_c.html","docs/html/search/all_c.js","docs/html/search/all_d.html","docs/html/search/all_d.js","docs/html/search/all_e.html","docs/html/search/all_e.js","docs/html/search/all_f.html","docs/html/search/all_f.js","docs/html/search/classes_0.html","docs/html/search/classes_0.js","docs/html/search/classes_1.html","docs/html/search/classes_1.js","docs/html/search/classes_2.html","docs/html/search/classes_2.js","docs/html/search/classes_3.html","docs/html/search/classes_3.js","docs/html/search/classes_4.html","docs/html/search/classes_4.js","docs/html/search/classes_5.html","docs/html/search/classes_5.js","docs/html/search/classes_6.html","docs/html/search/classes_6.js","docs/html/search/classes_7.html","docs/html/search/classes_7.js","docs/html/search/classes_8.html","docs/html/search/classes_8.js","docs/html/search/close.svg","docs/html/search/enums_0.html","docs/html/search/enums_0.js","docs/html/search/enums_1.html","docs/html/search/enums_1.js","docs/html/search/enums_2.html","docs/html/search/enums_2.js","docs/html/search/enums_3.html","docs/html/search/enums_3.js","docs/html/search/enumvalues_0.html","docs/html/search/enumvalues_0.js","docs/html/search/enumvalues_1.html","docs/html/search/enumvalues_1.js","docs/html/search/enumvalues_2.html","docs/html/search/enumvalues_2.js","docs/html/search/enumvalues_3.html","docs/html/search/enumvalues_3.js","docs/html/search/files_0.html","docs/html/search/files_0.js","docs/html/search/functions_0.html","docs/html/search/functions_0.js","docs/html/search/functions_1.html","docs/html/search/functions_1.js","docs/html/search/functions_10.html","docs/html/search/functions_10.js","docs/html/search/functions_11.html","docs/html/search/functions_11.js","docs/html/search/functions_12.html","docs/html/search/functions_12.js","docs/html/search/functions_13.html","docs/html/search/functions_13.js","docs/html/search/functions_2.html","docs/html/search/functions_2.js","docs/html/search/functions_3.html","docs/html/search/functions_3.js","docs/html/search/functions_4.html","docs/html/search/functions_4.js","docs/html/search/functions_5.html","docs/html/search/functions_5.js","docs/html/search/functions_6.html","docs/html/search/functions_6.js","docs/html/search/functions_7.html","docs/html/search/functions_7.js","docs/html/search/functions_8.html","docs/html/search/functions_8.js","docs/html/search/functions_9.html","docs/html/search/functions_9.js","docs/html/search/functions_a.html","docs/html/search/functions_a.js","docs/html/search/functions_b.html","docs/html/search/functions_b.js","docs/html/search/functions_c.html","docs/html/search/functions_c.js","docs/html/search/functions_d.html","docs/html/search/functions_d.js","docs/html/search/functions_e.html","docs/html/search/functions_e.js","docs/html/search/functions_f.html","docs/html/search/functions_f.js","docs/html/search/groups_0.html","docs/html/search/groups_0.js","docs/html/search/groups_1.js","docs/html/search/mag.svg","docs/html/search/mag_d.svg","docs/html/search/mag_sel.svg","docs/html/search/mag_seld.svg","docs/html/search/nomatches.html","docs/html/search/pages_0.html","docs/html/search/pages_0.js","docs/html/search/pages_1.js","docs/html/search/pages_2.js","docs/html/search/pages_3.js","docs/html/search/pages_4.js","docs/html/search/pages_5.js","docs/html/search/pages_6.js","docs/html/search/pages_7.js","docs/html/search/related_0.html","docs/html/search/related_0.js","docs/html/search/search.css","docs/html/search/search.js","docs/html/search/search_l.png","docs/html/search/search_m.png","docs/html/search/search_r.png","docs/html/search/searchdata.js","docs/html/search/typedefs_0.html","docs/html/search/typedefs_0.js","docs/html/search/typedefs_1.html","docs/html/search/typedefs_1.js","docs/html/search/variables_0.html","docs/html/search/variables_0.js","docs/html/search/variables_1.html","docs/html/search/variables_1.js","docs/html/search/variables_2.html","docs/html/search/variables_2.js","docs/html/search/variables_3.html","docs/html/search/variables_3.js","docs/html/search/variables_4.html","docs/html/search/variables_4.js","docs/html/search/variables_5.html","docs/html/search/variables_5.js","docs/html/search/variables_6.html","docs/html/search/variables_6.js","docs/html/search/variables_7.html","docs/html/search/variables_7.js","docs/html/splitbar.png","docs/html/splitbard.png","docs/html/structapp__msg__t-members.html","docs/html/structapp__msg__t.html","docs/html/structbt__app__msg__t-members.html","docs/html/structbt__app__msg__t.html","docs/html/sync_off.png","docs/html/sync_on.png","docs/html/tab_a.png","docs/html/tab_ad.png","docs/html/tab_b.png","docs/html/tab_bd.png","docs/html/tab_h.png","docs/html/tab_hd.png","docs/html/tab_s.png","docs/html/tab_sd.png","docs/html/tabs.css","docs/html/topics.html","docs/img/esp32.jpeg","docs/img/volume.png","docs/src/external_lists.h","examples/.DS_Store","examples/bt_music_receiver/bt_music_receiver.ino","examples/bt_music_receiver_32bits/bt_music_receiver_32bits.ino","examples/bt_music_receiver_and_BLE/bt_music_receiver_and_BLE.ino","examples/bt_music_receiver_arduino_i2s/bt_music_receiver_arduino_i2s.ino","examples/bt_music_receiver_arduino_i2s_3/bt_music_receiver_arduino_i2s_3.ino","examples/bt_music_receiver_audioboards/bt_music_receiver_audioboards.ino","examples/bt_music_receiver_codec/bt_music_receiver_codec.ino","examples/bt_music_receiver_datacallback/bt_music_receiver_datacallback.ino","examples/bt_music_receiver_disconnect-reconnect/bt_music_receiver_disconnect-reconnect.ino","examples/bt_music_receiver_playing_status_callbacks/bt_music_receiver_playing_status_callbacks.ino","examples/bt_music_receiver_queued/bt_music_receiver_queued.ino","examples/bt_music_receiver_reconnect/bt_music_receiver_reconnect.ino","examples/bt_music_receiver_resample48000/bt_music_receiver_resample48000.ino","examples/bt_music_receiver_rssi/bt_music_receiver_rssi.ino","examples/bt_music_receiver_simple_with_pin/bt_music_receiver_simple_with_pin.ino","examples/bt_music_receiver_status_callback/bt_music_receiver_status_callback.ino","examples/bt_music_receiver_to_internal_dac/bt_music_receiver_to_internal_dac.ino"],"storefront":"/r/pschatzmann","claimed":false,"request_supported":{"post":"https://gitbuyer.com/r/pschatzmann/ESP32-A2DP/request-supported","requests":0},"note":"indexed from public GitHub; nothing is for sale on this page. Clone it from GitHub. Paid listings live at /search."}