I2S 是一种电气串行总线接口标准,用于将数字音频设备连接在一起。它用于在电子设备中的集成电路之间传输 PCM 音频数据。
因此,我们可以将蓝牙的输入馈送到 I2S 输出:乐鑫的示例可以在 Github 上找到。
不幸的是,这个例子并没有让我高兴,所以我决定将其转换为一个简单的 Arduino 库 ,该库非常易于从 Arduino 软件 IDE 中使用。
顾名思义,它支持仅提供音频流的 A2DP 蓝牙协议 !
它还支持音频/视频远程控制配置文件 (AVRCP) 和 A2DP。
不支持免提配置文件 (HFP)、耳机配置文件 (HSP) 和不带 A2DP 的独立 AVRCP!
乐鑫将停用旧版 I2S API:因此,在 Arduino v3.0.0 (IDF v5) 中, 我的旧 I2S 集成将不再可用。只要您不升级,旧语法仍然有效。
为了支持与版本无关的唯一输出 API,建议安装和使用 AudioTools 库。因此,文档和所有示例都已更新以使用这种新方法。
但是,您也可以输出到继承自 Arduino Print 的任何其他类:例如 Arduino ESP32 I2SClass,或者您可以使用下面描述的数据回调 。
例如,这可用于构建您自己的蓝牙扬声器。
这是最简单的示例,它只使用正确的默认设置:
#include "AudioTools.h"
#include "BluetoothA2DPSink.h"
I2SStream i2s;
BluetoothA2DPSink a2dp_sink(i2s);
void setup() {
    a2dp_sink.start("MyMusic");
}
void loop() {
}这将创建一个名为“MyMusic”的新蓝牙设备,输出将发送到以下需要连接到外部 DAC 的默认 I2S 引脚:
请注意,与旧版 API 相比,这些默认引脚已更改!
您可以在开始前轻松定义自己的引脚。
#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() {
}您还可以使用 Arduino ESP32 I2S API:您无需为此安装任何其他库。
#include "ESP_I2S.h"
#include "BluetoothA2DPSink.h"
const uint8_t I2S_SCK = 5;       /* Audio data bit clock */
const uint8_t I2S_WS = 25;       /* Audio data left and right clock */
const uint8_t I2S_SDOUT = 26;    /* ESP32 audio data output (to speakers) */
I2SClass i2s;
BluetoothA2DPSink a2dp_sink(i2s);
void setup() {
    i2s.setPins(I2S_SCK, I2S_WS, I2S_SDOUT);
    if (!i2s.begin(I2S_MODE_STD, 44100, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_STD_SLOT_BOTH)) {
      Serial.println("Failed to initialize I2S!");
      while (1); // do nothing
    }
    a2dp_sink.start("MyMusic");
}
void loop() {}请注意,此 API 还取决于安装的版本:上面的示例适用于 ESP32 >= 3.0.0!
您还可以使用 AudioTools 中的 AnalogAudioStream 将输出直接发送到 ESP32 的内部 DAC:
#include "AudioTools.h"
#include "BluetoothA2DPSink.h"
AnalogAudioStream out;
BluetoothA2DPSink a2dp_sink(out);
void setup() {
    a2dp_sink.start("MyMusic");
}
void loop() {
}输出现在连接到 DAC 引脚 GPIO25(通道 1)和 GPIO26(通道 2)。
收到数据包时,您可能会收到通知。该 API 使用的 PCM 数据通常格式为 44.1kHz 采样率、双通道 16 位采样数据。
// In the setup function:
a2dp_sink.set_on_data_received(data_received_callback);
// Then somewhere in your sketch:
void data_received_callback() {
  Serial.println("Data packet received");
}或者您可以访问数据包:
// In the setup function:
a2dp_sink.set_stream_reader(read_data_stream);
// Then somewhere in your sketch:
void read_data_stream(const uint8_t *data, uint32_t length)
{
  int16_t *samples = (int16_t*) data;
  uint32_t sample_count = length/2;
  // Do something with the data packet
}在 a2dp_sink.set_stream_reader() 方法中,您可以提供一个可选参数来定义您希望 I2S 的输出是活动还是非活动 - 因此,您可以使用此方法例如,只需调用 a2dp_sink.set_stream_reader(read_data_stream, false)
可以注册一个方法,当系统收到任何 AVRC 元数据 (esp_avrc_md_attr_mask_t) 时将调用该方法。这是一个例子
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");默认情况下,您应该获得最重要的信息,但是您可以通过调用以下 set_avrc_metadata_attribute_mask 方法来调整此信息,例如,如果您只需要标题和播放时间,您可以调用:
set_avrc_metadata_attribute_mask(ESP_AVRC_MD_ATTR_TITLE | ESP_AVRC_MD_ATTR_PLAYING_TIME);在启动 A2DP 接收器之前。请注意,data2 实际上是一个 char* 字符串,因此即使 ESP_AVRC_MD_ATTR_PLAYING_TIME 被记录为媒体持续时间的毫秒,您也需要在对其进行数学运算之前对其进行解析。有关详细信息,请参阅元数据示例。
与 avrc_metadata_callback 类似,ESP IDF v4+ 支持选定的 esp_avrc_rn_param_t 回调,如 set_avrc_rn_playstatus_callback set_avrc_rn_play_pos_callback , set_avrc_rn_track_change_callback 可用于分别获取 esp_avrc_playback_stat_t playback 播放状态、uint32_t play_pos 播放位置和轨道更改标志 uint8_t elm_id。有关更多详细信息,请参阅 playing_status_callbacks 示例。
我添加了以下 AVRC 命令,您可以使用它们来“控制”您的 A2DP 源:
这可用于向您的蓝牙扬声器提供音频数据。
我们还可以生成声音并将其发送到蓝牙扬声器。
ESP32 A2DP 中支持的音频编解码器是 SBC:API 使用通常格式为 44.1kHz 采样率、双通道 16 位采样数据的 PCM 数据。
当您启动 BluetoothA2DPSource 时,您需要传递要连接的蓝牙名称和提供声音数据的“回呼功能”:
#include "BluetoothA2DPSource.h"
BluetoothA2DPSource a2dp_source;
// callback 
int32_t get_sound_data(uint8 *data, int32_t byteCount) {
    // generate your sound data 
    // return the effective length in bytes
    return byteCount;
}
void setup() {
  a2dp_source.set_data_callback(get_sound_data)
  a2dp_source.start("MyMusic");  
}
void loop() {}除了 set_data_callback 回调方法,您还可以使用 set_data_callback_in_frames,它使用帧而不是字节。在 Arduino 中,您还可以提供流(例如文件)作为数据源或提供流的回调。
在示例中,您可以找到借助 sin() 函数生成声音的实现。
您还可以指定多个备选蓝牙名称。系统仅连接到第一个可用的:
bt_names = {"MyMusic","RadioPlayer","MusicPlayer"}; a2dp_source.set_data_callback(get_sound_data) a2dp_source.start(bt_names); } void setup() { static std::vector
更多信息可以在相关的类文档中找到!
该库使用 ESP32 记录器,您可以在 Arduino 中 - 工具 - 核心调试日志中激活该记录器。
当前代码完全依赖于 ESP-IDF(也由 Arduino ESP32 内核提供)。没有其他依赖项,这包括 Arduino API!
因此,我们支持:
然而,此限制限制了所提供的示例。
在克隆项目之前,请阅读以下信息,这些信息可以在 Wiki 中找到。
您可以独立使用这个库,但它是我的音频工具项目的一部分。因此,您可以轻松地通过音效增强此功能、使用滤波器或均衡器、使用替代音频接收器或音频源、执行 FFT 等。这是一个简单的示例 ,如何使用 FFT 分析音频数据。
 
            图灵测试的方法是:被测试人,和一个待测试的机器。测试时,测试人与被测试人是分开的,测试人只有以纯文本的方式向被测试人问一些问题,这些问题随便是什么问题都可以。问过一些问题后,如果测试人能够正确地分出谁是人谁是机器,那机器就没有通过图灵测试,如果测试人没有分出谁是机器谁是人,那这个机器就是有智能的。
ESP32-P4 采用 400MHz 双核 RISC-V 处理器,支持最大 32MB PSRAM,具备 USB 2.0、MIPI-CSI / DSI 和 H.264 编码等外设,满足低成本、高性能和低功耗的多媒体开发需求。
 
            本产品是一款 2.8 寸且自带 ESP32-S3 主控的 IPS 显示模块,采用 ILI9341V 屏显驱动 IC,分辨率为 240x320,内置麦克风和音频编解码芯片,提供 音频喇叭、锂电池、MicroSD 卡、串口、I2C、扩展 IO 等外设接口。
 
            小鹏物联网自动浇花套件-用户手册 V1.0
 
            ESP32遥控船,不仅可以在湖面上自由巡游,还能作为鱼饵板在钓鱼时使用。
 
            CustoBlocks 是一套模块化组件,旨在帮助用户构建定制化的框架结构。它允许用户像拼积木一样,将不同的模块连接起来,创造出满足特定需求的个性化框架。
 
            本资源文件包含了多个ESP32模型的元件,方便用户在Fritzing中进行电路设计和仿真。
米思齐手册,包含28个小实验。
ESP32-S3 技术参考手册面向使用 ESP32-S3 系列产品进行底层软件开发的人员,介绍了 ESP32-S3 系列产品 中内置的硬件模块,包括概述、功能列表、硬件架构、编程指南、寄存器列表等信息。
 
            ESP32技术参考手册 v5.5
 
            Arduino UNO 乐高兼容底座3D模型
