ESP32语音播报MP3播放的存储方法
介绍
在实际项目中,往往需要产品能具有语音提示功能,这样可以带来很好的产品体验。
ESP实现语音提示可以使用wav未压缩的音频格式直接播放,但此种方法需要占用大量的FLASH存储空间,而使用MP3格式的音频则只需要很少的FLASH空间,如图:
MP3格式文件大小为5.34KB,而同样音频内容的WAV格式的文件大小为85.5KB,同样都为16KHz,文件体积相差巨大。音频的播放通过WM8978芯片来实现。
存储实现
由于ESP32每次读取的最小单位为一个扇区,4096字节(4KiB),而几乎所有的MP3格式的音频文件都不可能刚好为4KiB的整数倍,因此,需要对音频文件进行4KiB补齐,python代码如下:
import os
import struct
while(True):
filePath = input("文件名:")
fsize = os.path.getsize(filePath)
file = open(filePath, 'ab')
if fsize <= 4096:
for i in range(4096-fsize):
s = struct.pack('b',0)
file.write(s)
elif fsize <= 4096*2:
for i in range(4096*2-fsize):
s = struct.pack('b',0)
file.write(s)
elif fsize <= 4096*3:
for i in range(4096*3-fsize):
s = struct.pack('b',0)
file.write(s)
elif fsize <= 4096*4:
for i in range(4096*4-fsize):
s = struct.pack('b',0)
file.write(s)
elif fsize <= 4096*5:
for i in range(4096*5-fsize):
s = struct.pack('b',0)
file.write(s)
file.close()
运行后直接将文件拖动到窗口里就行了,如果不能拖动,请将如下代码放入txt文件中,然后修改后缀为.reg,修改后双击运行即可。
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Python.File\shellex\DropHandler]
@="{60254CA5-953B-11CF-8C96-00AA00B8708C}"
文件合并
由于可能会存在很多音频文件,如果一个个烧录进去非常麻烦,所以需要对上面4KiB补齐的音频文件进行合并,Python实现代码如下:
import sys
import os
def file_name(file_dir):
L = list()
for root, dirs, files in os.walk(file_dir):
for file in files:
name = str(file)
if ".mp3" in name and "[" in name:
L.append( name )
return L
f1 = file_name(os.getcwd())
f1.sort()
fileWrite = open(file="ALL.mp3",mode="wb")
location = 0
sector_location = ""
sector_length = ""
start = 1
for f in f1:
fileRead = open(file=f,mode="rb")
data=fileRead.read()
sp = (int)(len(data)/4096)
print("["+str(location)+"]"+f)
sector_location += str(location)+", "
sector_length += str(sp)+", "
location += sp
fileWrite.write(data)
fileRead.close()
print("{"+sector_location+"}")
print("{"+sector_length+"}")
fileWrite.close()
烧录
如果ESP32的FLASH大小为4iMB,可以考虑将音频文件烧录在2MiB的位置,也即地址为0x200000。
位置映射与注意事项
首先要确定当前要播放第几个音频,该音频占用多少个扇区,该音频从第几个扇区开始,然后注意需要将buffer的长度设置大于4096字节,因为MP3解码后会有数据剩余,这些数据不能丢弃,需要存放到下一个扇区数据的前面。
测试
实际测试结果,ESP32同时开启蓝牙和wifi并且都有数据传输的情况下,MP3解码与播放仍然正常。