WAV音频播放器

WAV音频播放器

来自 MicroBlocks

Boards
主板:

Citilab ED1 M5 Stack

Component/s
配件:

无需配件

概述

通过学习本教程,你将开发一个播放(无压缩)WAV音频文件的程序,该程序运行在M5Stack或者ED1设备内,通过图形用户界面选择要播放的音频文件。

WAV文件(Waveform Audio)存储的是数字音频,易于提取和播放——只要数据没有被压缩。

播放WAV音频文件需要具有以下功能的主板:

  • 用于存储WAV文件的文件系统;
  • 数字信号转换为模拟信号的转换器,供输出数字音频环节使用。

基于ESP32芯片的板子都有上述两项功能。另外,M5Stack和ED1都有LED显示屏,可用来显示用户界面。

本教程面向M5Stack描述用户界面,然而只要少量改动,用户界面也可以用到Citilab ED1主板上。教程最后给出的压缩包内包含一版适配ED1的项目文件。

用户界面设计

下面是用户界面的设想:

显示屏最多显示6个WAV文件名。用户可以通过以下操作来选择和播放歌曲:按 Sel (Selection)按钮选择歌曲;按下 Play 按钮播放歌曲。

Screen Header (屏幕标题)

用一幅由画图程序生成的位图作为M5Stack屏幕的标题(下简称为标题位图)。M5Stack屏幕是320x240像素,标题位图的分辨率是:320x55。

由于ED1板子的屏幕更小,ED1版程序不使用标题位图,改用文字标题。

Song List (歌曲列表)

显示屏中间区域列出可供播放的WAV文件名。整个屏幕最多显示6个文件名。

这个程序将在歌曲名字的左侧显示 " > "字符,这表明该歌曲被选中。

Button Controls (按钮)

整个程序由两个按钮来控制。

  • 按钮A(左侧按钮):选择将被播放的歌曲文件;
  • 按钮B(中间按钮):播放歌曲。

按下按钮A," > "字符将向下移动一行。最后一行再向下移动的话,将跳回到第一行。

按下按钮B,将播放选中的歌曲。

UI界面在按钮的正上方显示按钮的名字,以表明按钮的功能。

流程

把文件上传到闪存

第一步是把标题位图文件和WAV文件上传到ESP32闪存文件系统。本教程所需的文件包含在教程尾部给出的文件包内,供下载。

点击“设置”按钮,在弹出的下拉菜单内选择“显示高级积木”。

这将使“把文件上传到主板”和“从主板获取文件”命令出现在“文件菜单”内。

当你单击“把文件上传到主板”时,将弹出文件选择对话框。浏览目录,选择WAV文件和标题位图文件的存储位置,而后把下面的文件上传到ESP32板子:

  • M5WavPlayer_Header.bmp
  • spaceripple.wav
  • squawk.wav
  • triumph.wav

我们提供3个时长较短的WAV文件用于测试。以后,你可以自行添加WAV文件。

添加积木库

本教程构建的程序用到如下积木库:

  • BMP(上级目录:图形与显示):display BMP file 积木用于显示图形用户界面的标题位图。
  • TFT(上级目录:图形与显示):在TFT上写…积木在屏幕上显示文字,清除显示积木清除屏幕上的文字。
  • 文件(上级目录:其他):文件名积木列出存储在ESP32闪存内的文件。
  • WAV(上级目录:声音):播放积木会播放选中的歌曲。

要加载上述积木库,单击“积木库”右侧的“+”,打开各个积木库所在的文件夹(比如,图形与显示目录),而后选择要加载的积木库。

获取WAV文件名

一开始,让我们定义一个定制积木,它的作用是扫描文件系统,提取出其内各个WAV文件的名字。

创建两个变量,叫songsmaxSongssongs变量存储WAV文件名列表,maxSongs变量存储文件名数目。

单击我的积木,新建一个命令积木,名字叫collectWAVfiles。这个积木将提取WAV文件名,存入songs列表。

我们该如何获取WAV文件名呢?文件积木库内的文件名积木列出文件系统内所有文件的名字,不过这些文件时WAV文件和其他类别的文件的组合。

要选出WAV文件,使用“数据”目录下的查找积木,以检测文件名后缀“.wav”有没有出现在文件名内。

collectWAVfiles-1.png

查找积木没能找到目标串,它将返回-1。

为了让歌曲名字更易读,通过复制积木,把不带尾部4个字母(即“.wav”)的文件名,也就是不含后缀名的文件名,存入songs列表。

collectWAVfiles-2.png

把上述积木用作当启动时脚本的开头。

whenStarted-1.png

由于UI界面最多只能放下6首歌曲的名字,上面的最小值积木限定maxsongs变量的值不大于6。

绘制UI界面

下一步是定义绘制用户界面的积木。从清除屏幕和绘制标题位图开始。

drawUI-1.png

接着,绘制songs列表内的WAV文件名。文件名的前面附加一个编号。

drawUI-2.png

最后,绘制两个按钮的名字。

drawUI-3.png

选择要播放的歌曲

下一步是定义选择要播放的歌曲和标出所选歌曲的积木。

该积木的第一部分是简单的。新建一个名为selection的变量。当按下select按钮时,selection变量的值增1,而当selection大于maxSongs变量的值时,selection变量的值变回到1。

selectNextSong-1.png

通过在文件编号之前绘制>字符,表明相应歌曲已被选中。

selectNextSong-2.png

等一下!上述代码有必要清除上次的选择。绘制黑色的>字符将达成清除效果。

selectNextSong-3.png

上述代码做了不必要的工作。它在每一首歌曲名字的左侧绘制黑色的>字符,以达成清除上次的选择的效果。然而,这段代码是简短的,少量的多余工作不会造成明显的延时。

修改当启动时脚本,加入绘制UI界面和选择第一首歌曲的步骤。

whenStarted-2.png

按钮操作

Play按钮的响应处理比较简单。

playButton.png

连接积木把后缀名.wav加到文件名尾部。

选择按钮的响应处理也比较简单。

selectButton-1.png

不过,上述代码不允许用户终止播放中的歌曲,立即开始播放新的歌曲。下面代码中,当选中新的歌曲时,停止其他任务积木会停止正在播放的歌曲。于是,选中的新歌曲将立即播放。

selectButton-2.png

进一步讨论

你有可能想上传你自己的WAV文件。需要确保这些文件是未压缩的WAV文件(也叫做“线性脉冲编码调制”)。MicroBlocks WAV积木库能够播放未压缩的8位或者16位、单声道或者立体声WAV文件。不过,由于ESP32只有一个8位输出口,选用16位WAV文件或者立体声WAV文件,没有好处;既不会提升音质,上传WAV文件到主板上的闪存时又需要更长的耗时。

以下是值得你考虑的改进措施:

  • 使用列表积木库内的sort积木,对歌曲名字排序。
  • 去除最多6首歌曲的限制。考虑令屏幕上的文件名清单是可滚动的。
  • 用你自己设计的图片替换标题位图。更好的做法是,设计一个完全不同的用户界面。例如,如果你的主板有一个加速度计,你可以使用tilt积木来控制UI界面。

下载文件压缩包

这里的 文件压缩包 包含了程序代码,标题位图文件,和若干个WAV文件。下载并解压即可获得这些文件。