5175| 3
|
[ESP8266/ESP32] 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单声道 [img=623,328][/img] 重新加载处理后的 8000Hzm 8Bits Wave 音频数据 第二步,使用Bin2C将这个 Wav 生成C 语言的头文件。命令如下: bin2c.exe -o audio.h 19908bits.wav 实际上数据中包含了 wav的文件头,但是因为数据量不大,对播放几乎没有影响,所以这里也没有额外处理。 [img=624,179][/img] 这样,我们就有了这个歌曲的数据。特别需要注意的有下面两点: 1. 需要设置编译模式为 3MB APP/9MB FATFS 模式 [img=624,234][/img] 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。 第四步,编写代码:
我们将音频数据放在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秒的音频。在要求不高的场合下完全能够满足要求。 |
© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed