FireBeetle 直接放声(DAC篇)
本帖最后由 zoologist 于 2021-4-6 21:13 编辑声音,是物体振动产生的,通常情况下通过空气将震动传递到耳朵我们就能听到了声音。常见的喇叭就是一种将电能转换为机械能的器件。FireBeetle 核心是 ESP32-WROOM-32D, 主控频率高达240Mhz,Flash Rom 有 16MB。这里介绍一种直接通过它来播放声音的方法。用这种方法可以直接通过喇叭来播放音乐,但是因为 ESP32 输出功率有限,直接推动喇叭产生的声音很小。为此,这里使用“Gravity:带功放喇叭模块”来实现更大的声音输出。基本原理是将数据存储在 FireBeetle 的Flash上,然后通过 ESP32 的DAC直接输出之。具体步骤如下:第一步,将音乐转化为8位单声道。我是用 Golden Wave ,将罗大佑的 “恋曲1990.mp3“转为8000Hz 8 Bits的Wav 格式。Golden Wave 打开音频文件
这里重新采样为8000Hz 保存为8Bits单声道重新加载处理后的 8000Hzm 8Bits Wave 音频数据第二步,使用Bin2C将这个 Wav 生成C 语言的头文件。命令如下:bin2c.exe -o audio.h 19908bits.wav实际上数据中包含了 wav的文件头,但是因为数据量不大,对播放几乎没有影响,所以这里也没有额外处理。这样,我们就有了这个歌曲的数据。特别需要注意的有下面两点:1. 需要设置编译模式为3MB APP/9MB FATFS 模式2. 原始的 Wav 最好不要超过2.7MB(2,831,155.2Bytes, 0x2B3333Bytes),否则会超过最大程序的限制。这次我使用的 WAV 是 2,527,766 字节的,编译后结果如下:Sketch uses 2746845 bytes (87%) of program storage space.Maximum is 3145728 bytes.Global variables use 15372 bytes (4%) of dynamic memory,leaving 312308 bytes for local variables. Maximum is 327680 bytes.
第三步,我们需要一些基本的测试。首先,编写一个循环,使用dacwrite() 输出数值,输出2000000次花费了11102ms,也就是说一次 dac 输出需要花费0.005551ms。前面提到使用的Wav采样率是 8000Hz。这样一个周期是 1/8000=0.125ms。 因此,为了重建一个声音,我们需要 0.125/0.005551=22.5184次 dacwrite。第四步,编写代码:
#include "audio\SoundData.h"
void setup() {
}
void loop() {
for (unsigned int i=0;i<2527766;i++) {
for (int j=0;j<21;j++) dacWrite(25,WarOfWorldsWav);
}
}
我们将音频数据放在audio目录下的SoundData.h文件中,这样每次Arduino打开ino 文件的时候并不会一起打开音频数据,否则因为音频数据很大,会耽误很多时间,有时候甚至会导致Arduino编译器崩溃。另外,和前面提到的22次 dacwrite 不同,代码使用的是21次,因为for循环有一些开销,所以实际测量下来22次有一点点慢。第五步,Gravity:带功放喇叭模块,上面有3个线,VCC和GND 连接到 FireBeetle上,信号输入Pin连接到 FireBeetle D2 (IO25)。下载代码后即可播放出音乐了。很明显,上述方法足够简单,能够存储2.7*1024*1024/8000=354秒的音频。在要求不高的场合下完全能够满足要求。
工作的视频
https://www.bilibili.com/video/BV1Df4y1x7WF?share_source=copy_web 8 Bits WAV歌曲
完整的代码
这个音质惨不忍睹,基本只能尝尝鲜,做一些简单音效交互效果还可以
页:
[1]