Arduino模拟MIDI键盘

网友投稿 2019-09-17 12:42

简介

MIDI(Musical Instrument Digital Interface)中文是乐器数字接口,通过MIDI协议可以解决电声乐器之间的通信,MIDI也是一种广泛应用于编曲的音乐格式。
https://cdn.china-scratch.com/timg/190919/1242214330-0.jpg
MIDI传输的不是声音信号,而是一些指令,比如音色、音量、通道以及一些其他的参数,合成器接收到这些指令后会根据这些指令合成声音。MIDI规定了16个轨道,也表示MIDI支持16个轨道同时发声。MIDI键盘可以通过MIDI接口发出MIDI指令,但有些MIDI键盘需要外接电脑或合成器才能发出声音。通过MIDI协议我们就可以用一个键盘模拟多种乐器的音色。

MIDI指令

MIDI指令需要遵循MIDI协议,具体的内容可以去查阅《MIDI 1.0版的细节规定》,我在这里只是简单介绍一下用到的部分。一条MIDI指令通常由三个字节构成,第一个字节为状态字节,第二第三字节为数据字节,我们要做的MIDI键盘实际就是给电脑或合成器发送这三个字节的设备。那就必须要讲一下这三个字节的格式。
首先是状态字节的格式,状态字节的8个位可以分为3部分,最高位是状态识别位,这一位为1说明这1字节为状态位。第6、5、4这3位用于表示命令,第3、2、1、0这4位用于MIDI协议中16个轨道的选择。
https://cdn.china-scratch.com/timg/190919/124221A55-1.jpg
上表列举了一些状态字节的格式,可以根据这个表编写状态字节,例如1001 0000就表示第1轨道开始演奏。
数据字节的8个位可以分为两部分,同样最高位用于状态识别,当最高位为0说明这是数据字节。剩余的7位是资料位,共可以表示128个数值。这128个数值可以用来表示音调或者按键力度或者其他数据。
当表示音调时可以查看文章后面附带的MIDI音符代码表。
之前讲过一条MIDI指令是由一个状态字节和两个数据字节组成的,状态字节的几种格式我在之前已经给出对照表了,对于数据字节目前只知道能表示128个数,但是具体后面跟着的两个数据字节应该表示什么还需要看第一个状态字节表示什么功能。
上面的功能表列出来了8种功能,在这里我只说一下其中两种的格式,剩余的大家可以自行查阅MIDI指令状态位与数据位的关系了解一下。Note Off为停止发音,后面跟的两个数据位依次表示音调和音量。Note On为开始发音,后面两位数据位依次为音调和音量。

具体实现

通过上面的简单介绍我们已经知道了应该向电脑发送什么数据了,接下来就应该考虑如何将数据从Arduino发送到电脑。
MIDI设备一般带有MIDI接口和USB接口,但是由于我的电脑上没有MIDI接口,所以MIDI指令传输就依靠开发板自带的USB接口了。这里我用的开发板是Arduino UNO,这一块开发板上的USB接口应该是通过ATmega8U2或者ATmega16U2连接到主控芯片的,我们可以通过更换芯片里的固件,将开发版配置为一个HID MIDI设备。
但由于部分开发板生产厂家为节省成本,选择了CH340代替了这两块芯片,这种开发板是不能进行上述操作的,由于我目前的开发板上的芯片就是CH340的所以就要选择其他方法。
然后我选择通过两个软件让电脑将开发板识别为一个MIDI设备。首先我们需要安装一个名为loopMIDI的软件。
https://cdn.china-scratch.com/timg/190919/1242215133-2.jpg
这个软件可以可以在电脑上创建一个MIDI端口,安装好后我们打开这个软件。
https://cdn.china-scratch.com/timg/190919/1242214P4-3.jpg
点击界面左下角的“+”号,我们就可以创建一个MIDI端口了。
https://cdn.china-scratch.com/timg/190919/1242213144-4.jpg
如图所示,我们已经创建了一个名为loopMIDI Port的MIDI接口。不过由于我的Arduino开发板上带的是CH340,所以我还需要将CH340传输过来的信号转换为符合MIDI协议的信号。我们可以通过Hairless MIDI这个软件实现这个转换。
https://cdn.china-scratch.com/timg/190919/1242224R5-5.jpg
这个软件可以前往GitHub下载。
安装好这两个软件后就可以开始编写Arduino的程序了。Arduino程序的编写就很简单了,我们只需要开启串口通信,然后把我们需要的三个字节的MIDI命令发送出去就可以了。
https://cdn.china-scratch.com/timg/190919/1242223G2-6.jpg
例如这段程序就是发送MIDI指令的一个例子,这条指令的意思就是第一个轨道发B音调。程序写好后我们就要测试一下电脑能否成功接收我们发送的MIDI指令。首先我们打开loopMIDI开启我们虚拟的MIDI端口,然后再打开Hairless MIDI这个软件。
https://cdn.china-scratch.com/timg/190919/1242222245-7.jpg
在Serial port这一栏我们选择开发板的端口号,在MIDI Out这一栏我们选择由loopMIDI创建的MIDI端口。选择好后我们再勾选Serial<—>MIDI Bridge On和Debug MIDI messages这两个选项,我们就可以接收Arduino发来的消息了。
https://cdn.china-scratch.com/timg/190919/124222G43-8.jpg
如上图所示,我们就成功接收到了Arduino发送来的MIDI指令。我们可以给Arduino外接一个矩阵键盘,并给每个按键设置一条MIDI指令,当按下按键后就发送指令。
最后我们需要安装一个音乐软件来合成声音。可以选择的音乐软件有很多,这里我选择的是EOPmidi这个软件。
https://cdn.china-scratch.com/timg/190919/124223M07-9.jpg
这个软件可以模拟钢琴的音色,操作也比较简单,我们也可以选择其他更全面的音乐软件比如FL Studio等等......

--end--

声明:本文章由网友投稿作为教育分享用途,如有侵权原作者可通过邮件及时和我们联系删除:freemanzk@qq.com