3. enter menu Bluetooth, choose "Classic Bluetooth" and do not choose "Release DRAM from Classic BT controller"
4. choose your options.
+For the I2S codec, pick whatever chip or board works for you; this code was written using a PCM5102 chip, but other I2S boards and chips will probably work as well. The default I2S connections are shown below, but these can be changed in menuconfig:
+
++-----------+--------------+
+| ESP pin | I2S signal |
++===========+==============+
+| GPIO22 | LRCK |
++-----------+--------------+
+| GPIO25 | DATA |
++-----------+--------------+
+| GPIO26 | BCK |
++-----------+--------------+
+
+If the internal DAC is selected, analog audio will be available on GPIO25 and GPIO26. The output resolution on these pins will always be limited to 8 bit because of the internal structure of the DACs.
+
+
After the program started, other bluetooth devices such as smart phones can discover this device named "ESP_SPEAKER", and after connection is established, audio data can be transmitted and there will occur a count of audio data packets printed.
--- /dev/null
+menu "A2DP Example Configuration"
+
+choice A2DP_SINK_OUTPUT
+ prompt "A2DP Sink Output"
+ default A2DP_SINK_OUTPUT_EXTERNAL_I2S
+ help
+ Select to use Internal DAC or external I2S driver
+
+config A2DP_SINK_OUTPUT_INTERNAL_DAC
+ bool "Internal DAC"
+ help
+ Select this to use Internal DAC sink output
+
+config A2DP_SINK_OUTPUT_EXTERNAL_I2S
+ bool "External I2S Codec"
+ help
+ Select this to use External I2S sink output
+
+endchoice
+
+config I2S_LRCK_PIN
+ int "I2S LRCK (WS) GPIO"
+ default 22
+ depends on A2DP_SINK_OUTPUT_EXTERNAL_I2S
+ help
+ GPIO number to use for I2S LRCK(WS) Driver.
+
+config I2S_BCK_PIN
+ int "I2S BCK GPIO"
+ default 26
+ depends on A2DP_SINK_OUTPUT_EXTERNAL_I2S
+ help
+ GPIO number to use for I2S BCK Driver.
+
+config I2S_DATA_PIN
+ int "I2S DATA GPIO"
+ default 25
+ depends on A2DP_SINK_OUTPUT_EXTERNAL_I2S
+ help
+ GPIO number to use for I2S Data Driver.
+
+
+endmenu
#include "esp_a2dp_api.h"
#include "esp_avrc_api.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "driver/i2s.h"
+
/* a2dp event handler */
static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param);
/* avrc event handler */
void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len)
{
+ i2s_write_bytes(0, (const char *)data, len, portMAX_DELAY);
if (++m_pkt_cnt % 100 == 0) {
ESP_LOGE(BT_AV_TAG, "audio data pkt cnt %u", m_pkt_cnt);
}
ESP_LOGI(BT_AV_TAG, "a2dp audio_cfg_cb , codec type %d", a2d->audio_cfg.mcc.type);
// for now only SBC stream is supported
if (a2d->audio_cfg.mcc.type == ESP_A2D_MCT_SBC) {
- ESP_LOGI(BT_AV_TAG, "audio player configured");
+ int sample_rate = 16000;
+ char oct0 = a2d->audio_cfg.mcc.cie.sbc[0];
+ if (oct0 & (0x01 << 6)) {
+ sample_rate = 32000;
+ } else if (oct0 & (0x01 << 5)) {
+ sample_rate = 44100;
+ } else if (oct0 & (0x01 << 4)) {
+ sample_rate = 48000;
+ }
+ i2s_set_clk(0, sample_rate, 16, 2);
+
+ ESP_LOGI(BT_AV_TAG, "configure audio player %x-%x-%x-%x\n",
+ a2d->audio_cfg.mcc.cie.sbc[0],
+ a2d->audio_cfg.mcc.cie.sbc[1],
+ a2d->audio_cfg.mcc.cie.sbc[2],
+ a2d->audio_cfg.mcc.cie.sbc[3]);
+ ESP_LOGI(BT_AV_TAG, "audio player configured, samplerate=%d", sample_rate);
}
break;
}
#include "esp_gap_bt_api.h"
#include "esp_a2dp_api.h"
#include "esp_avrc_api.h"
+#include "driver/i2s.h"
/* event for handler "bt_av_hdl_stack_up */
enum {
}
ESP_ERROR_CHECK( ret );
+ i2s_config_t i2s_config = {
+#ifdef CONFIG_A2DP_SINK_OUTPUT_INTERNAL_DAC
+ .mode = I2S_MODE_DAC_BUILT_IN,
+#else
+ .mode = I2S_MODE_MASTER | I2S_MODE_TX, // Only TX
+#endif
+ .sample_rate = 44100,
+ .bits_per_sample = 16,
+ .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels
+ .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
+ .dma_buf_count = 6,
+ .dma_buf_len = 60, //
+ .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 //Interrupt level 1
+ };
+
+
+ i2s_driver_install(0, &i2s_config, 0, NULL);
+#ifdef CONFIG_A2DP_SINK_OUTPUT_INTERNAL_DAC
+ i2s_set_pin(0, NULL);
+#else
+ i2s_pin_config_t pin_config = {
+ .bck_io_num = CONFIG_I2S_BCK_PIN,
+ .ws_io_num = CONFIG_I2S_LRCK_PIN,
+ .data_out_num = CONFIG_I2S_DATA_PIN,
+ .data_in_num = -1 //Not used
+ };
+
+ i2s_set_pin(0, &pin_config);
+#endif
+
+
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
if (esp_bt_controller_init(&bt_cfg) != ESP_OK) {
# Classic BT is enabled and BT_DRAM_RELEASE is disabled
CONFIG_BT_ENABLED=y
CONFIG_CLASSIC_BT_ENABLED=y
-