零、引言
该篇博文主要面向需要处理MIDI相关计算机项目或课题的同学,全面介绍了MIDI技术相关的技术及原理,对于处理MIDI编程、基于MIDI的深度学习,音乐生成、音乐表示等任务具有极高的指导意义,部分资料源于互联网收集。文章稍长,可以根据目录来进行导航。接下来,就让我们开始吧!
目录
零、引言
一、MIDI背景
1.1 产生与发展历史
1.2 MIDI工作方式
1.3 MIDI文件
二、常见MIDI Message介绍
2.1 Note On & Note Off
2.2 Mono Pressure(Aftertouch)
2.3 Program Change
2.4 Pitch Bend
2.5 Control Change
三、MIDI文件格式解析
3.1 MIDI文件结构简介
3.2 Header Chunk结构
3.3 Track Chunk结构
3.4 Delta-Time及MIDI事件结构
3.5 总结
3.5.1 MIDI文件的总体组织结构
3.5.2 Header Chunk解析
3.5.3 Track Chunk解析
3.5.4 例子
四、MIDO与MIDI原理实践(MIDI编程)
4.1 Mido库简介
4.1.1 Message
4.1.2 Meta-Message
4.2 MIDI原理实践
4.2.1 使用Mido来生成简单的MIDI乐曲文件
4.2.2 使用Mido来解析示例MIDI文件
附录
GM音色表
GM鼓乐器音色表
MIDI CC List(常用的标红)
音高编号对照表
Mido官方文档
一、MIDI背景
MIDI是Musical Instrument Digital Interface的缩写,直接翻译过来的意思就是乐器数字化接口,也就是说它的真正涵义是一个供不同设备进行信号传输的接口的名称。它在20世纪80年代初为解决电声乐器之间的通信问题而被提出,一直沿用至今。我们如今的MIDI音乐制作全都要靠这个接口,在这个接口之间传送的信息也就叫MIDI信息。MIDI是一种协议、一种标准、或是一种技术,而并不是某个硬件设备。
1.1 产生与发展历史
MIDI不是首先出现在计算机里面的,它是由电子乐器生产厂家为了不同型号的电子乐器的“交流”而产生的,早期的MIDI设备除了都能接受MIDI信号之外没有统一的标准,尤其是在音色排列的方式上更是“随心所欲”的。也就是说在这台琴上制作完成的音乐拿到另一台不同型号的琴上播放时会变得面目全非,小提琴可能会变成小号,长笛可能会变成吉他,钢琴可能会变成大鼓……这对于专业音乐人士的工作并不会产生太大的影响,毕竟他们制作一次灌成唱片也就完事儿了,但是对于音乐爱好者之间的交流,尤其是多媒体的发展却极为不利。
因此,1983年,为了统一标准,并建立起一种连接电子乐器和计算机的规则,国际乐器制造者协会的十几家厂商(主要来自美国和日本)开会通过了美国Sequential Circuits公司的Dave Smith提出的“通用合成器接口(USI)”的方案,并改名为“乐器数字接口(MIDI)”。
1983年,MIDI协议1.0版正式问世。此后,几乎所有电子乐器的背后都出现了五孔的MIDI接口。只要通过几根MIDI线,电子乐器与电子乐器、电子乐器与电脑之间就可以实现通信。
MIDI接口
值得一提的是,Dave Smith和其他一同参与制定该协议的人向全世界免费开放了MIDI协议的使用权。这一举措直接影响了未来几十年应用MIDI协议的各种硬件和软件的发展。包括我们现在能够使用和了解到这项技术,并基于这项技术进行编程、创造等,很大程度上也是受益于这一举措。
1984年,在原有的MIDI协议之上,日本罗兰公司提出了GS(General Synthesizer)标准。此标准定义了最常用的128种乐器、音效和控制器的排列。
GS标准的内容分为五个部分:
16个声部
最大复音数为24或更多
GS格式的乐器音色排列(包含有各种不同风格的音乐所使用的乐器音色和打击乐音色)
鼓音色可以通过音色改变信息进行选择
两种可以调节的效果,包括混响和合唱
1991年,国际MIDI生产者协会(MMA)以GS标准为基础,制定了通用MIDI标准 ——GM(General MIDI system Level 1)。在GS标准的基础上,GM标准规定了MIDI设备的最大同时发音数不得少于24个、鼓等打击乐器作为一组单独排列以及128种乐器音色有统一的排列方式等。GM的音色排列方式与GS标准几乎一致。GM标准的提出得到了Windows操作系统的支持,此时MIDI才算是真正意义上与计算机开始挂钩了。
1994年,YAMAHA公司在GM标准的基础上推出了XG(Extended General MIDI)标准,增加了更多的乐器组,扩大了MIDI标准的定义范围。在兼容GM的基础上,XG标准做了大幅度的扩展,其有520种音色,32复音,3种可编辑效果,并支持多轨音频输入。
2020年,MIDI 2.0版的协议正式发布,这个新版本的协议拥有256个MIDI通道和最高32位的解析度(MIDI 1.0只有16条通道以及8位的解析度),并且具有双向交互、向下兼容的特点。得益于此,应用了MIDI 2.0协议的不同设备之间的更为复杂的交流将成为可能,演奏时值与参数控制会更加精确、高效,错误也会因此减少。不过由于刚提出相对来讲目前还不够成熟,因此我们对MIDI的分析与研究大部分还是针对之前标准的,涉及MIDI2.0标准相对较少。
1.2 MIDI工作方式
与大多数数字连接器一样,有一个 MIDI 端口和一条MIDI 电缆。前者有五个孔,由后者插头上的五个销子塞住。设备具有三种 MIDI 端口类型中的一种或多种:MIDI 输出、MIDI 输入和 MIDI 直通。MIDI Out 允许从设备发送信息,MIDI In 可以接收它,而 MIDI Thru 允许信息通过该设备传输到另一个设备。在每种情况下,通常都需要辅助电缆来回传输信息,而不是仅在一个方向上传输信息。
当想要扩展 MIDI 连接时,可以使用MIDI 耦合器,它可以让使用者将两根 MIDI 电缆插入其中。或者,可以使用MIDI 分离器和 Y 型电缆。
对于多个设备之间更复杂的 MIDI 连接,可以使用 MIDI 接口,它可以在一个中央位置将更多 MIDI 兼容设备连接在一起,从而帮助将所有信息传输到正确的乐器或设备。
现代设备通常同时具有传统的 MIDI 和 USB 连接,这两种连接都允许相同的 MIDI 消息传输或接收。对于没有 USB 的设备,可以使用 USB 转 MIDI 适配器。有些,例如 Cable Matters 的 USB 到 MIDI 电缆,甚至支持 USB-C 设备,如平板电脑。
MIDI设备连接示意图
当谈到使用多个 MIDI 连接设备创作音乐时,MIDI 序列器使过程变得更加简单。它们存储 MIDI 数据并管理其播放、录制和编辑。大多数现代数字音频工作站 (DAW) 都包含 MIDI 音序器,并且在许多情况下,在它们成为当今更现代的 DAW 接口之前就开始使用它们了。
或者,可以使用通过 USB 连接连接到 DAW 的硬件音序器,这可以让创作者使用 VST 插件访问近乎无限的数字乐器阵列。也可以在没有计算机的情况下专门使用硬件音序器将各种支持 MIDI 的设备和乐器连接在一起。然后它们可以代替 DAW 进行编辑和作曲。
更详细的MIDI工作方式涉及到更多的硬件知识,相比之下我们作为编程以及算法研究人员更关心MIDI的软件层次方面,因此在此不对工作方式进行更深入的介绍。
1.3 MIDI文件
在计算机中一切都是以文件的形式来进行存储的,因此为了让MIDI与计算机相通,MIDI文件便出现了。应用MIDI标准协议创建的文件我们称之为MIDI文件。我们可以把MIDI文件理解成一种计算机也可以读懂的乐谱,只不过MIDI文件不像用文字写成的纸面文件那样有着可以直接观测到的外形,而是以计算机可以理解的底层二进制代码的形式存储在了计算机的内存和磁盘之中。
一个标准的MIDI文件往往以二进制代码的形式包含了多层次的信息,通常以“事件(消息)”来刻画这些信息。如音符开启事件(Note On),音符力度(Velocity),音符结束事件(Note Off),触后(Aftertouch),还有弯音(Pitch Wheel)、调制(Modulation)、主音量(Main Volume)、表情(Expression)等。在这些不同层次的信息中,绝大多数值的取值范围都在0~127,在后面也会对这些事件信息进行更深入的分析。
在计算机系统中,MIDI文件的文件后缀往往表示成“.mid”。虽然MIDI只是一种乐谱性质的东西,但是这种文件往往可以直接用计算机上的音乐播放器打开。此时计算机所播放出的音乐是其在读取到MIDI乐谱信息后,调用自带的合成音色所奏出的。此外,一些市面现有的音乐软件也支持MIDI文件的直接播放,作为MIDI文件的使用者,我们不必去读复杂难懂的底层二进制代码就可以直接播放使用这些MIDI文件。但是作为MIDI编程人员,我们仍有必要了解MIDI文件的底层格式。因此在后续会对MIDI文件的底层格式进行详细的介绍与解析。
创建MIDI文件一般来说有三种方式:
运用连接到计算机的MIDI设备来进行输入:这类设备主要就是MIDI键盘和一些键盘合成器,此外也有一些像MIDI吉他之类的较为少见的MIDI设备。
将音频文件转化成MIDI文件:这种方式一般对于音频文件的要求比较高,最好其本身就是由MIDI文件生成的,否则转换出来的MIDI文件往往都是一堆乱码,完全不能用。
在一些宿主软件(DAW)中用鼠标和键盘等外设来进行输入:这也是目前来讲输入精度最高的一种MIDI创建方式,无论是用MIDI键盘还是别的MIDI设备进行输入,都不可能做到百分之百的时值和节奏的准确,但直接在宿主里面进行编辑就不存在这个问题。
此外,对于我们编程研究人员来说,还有一种额外的不可忽略的创建MIDI文件的方式,就是MIDI编程,同样可以用高精度的方式来创建MIDI文件。这也是我们需要着重关注的一种方式,与后续研究息息相关。
二、常见MIDI Message介绍
MIDI在乐器、计算机、控制器和其他 MIDI 设备之间发送的信号称为MIDI消息(MIDI Message)。MIDI消息是一种二进制数据,它包含了音符、音量、音色等音乐信息。
MIDI消息分为三种类型:实时消息、系统消息和通道消息。实时消息是指在任何时候都可以发送的消息,如时钟、定位器和开始/停止消息。系统消息是指用于控制整个MIDI系统全部通道的消息,如重置、全局控制和设备控制消息。通道消息是指用于控制单个MIDI通道的消息,如音符、音量和音色消息。这些消息最终决定了不同设备如何相互交互。例如,使用调音台来控制连接的键盘的声音。在其他情况下,没有自己特定接口的声音模块可能需要连接 MIDI 控制器才能产生声音。通过MIDI消息的作用便不难发现MIDI消息是整个MIDI技术中的核心,是MIDI技术中各个部分相互连接、通信、交互的纽带。
我们通常会把实时消息和系统消息统称为系统消息,因而将MIDI消息大体上分为系统消息和通道消息两大类。每类消息包括主要的消息类型大致如下图所示:
MIDI消息类型
相比于系统信息,通道信息与最终形成MIDI文件的听感息息相关,联系更为紧密,因此我们在编程研究时更为关注通道信息。接下来将对通道信息中最常用到的信息类型进行介绍。
2.1 Note On & Note Off
NOTE ON 和 NOTE OFF 是最主要的两个 MIDI Message。当演奏者敲击音乐键盘的琴键时发送 NOTE ON 消息,它包含了音高以及“力度”的参数。当合成器收到此消息时,它会开始以相应的音高和“力度”播放该音符。当收到 NOTE OFF 消息时,合成器会终止该音符。
每个 NOTE ON 消息都需要相应的 NOTE OFF 消息,否则该音符将一直处于播放状态。但打击乐器可以只发送 NOTE ON,因为打击乐音符会自动停止。但最好养成始终发送 NOTE OFF 的习惯,因为不同合成器对这一特性的实现可能不一样。
2.2 Mono Pressure(Aftertouch)
触后信息指的是当音符被“触键”发生后由于触键压力的再次变化而生成改变音色特性的信息,主要在一些高级的合成器或音源中具有此功能。主要又可以分为两类:
键位触后(Key Aftertouch)或复音触后(Polyphonic Aftertouch):键位触后主要针对的是某些要被变化的音符,所以它的两个数据是键位压力值和音符编号。在同一个通道,有些音符可以被设置为键位触后,有些则不设置。
通道触后(Channel Aftertouch):通道触后主要针对的是要被改变的某个通道,所以它的两个数据值是压力值(力度)和通道号。也就是说,可以将某1个或2个不同的通道都设为键位触后,这样每个通道的所有音符都具备触后功能。
2.3 Program Change
音色程序改变也就是俗称的音色变化,即如何使用多个乐器的音色。音色程序的改变是由两个数值控制的:第一个数值是音色库选择(Bank Select),第二个数据则是具体的音色程序改变号(Patch Select),一些合成器利用这个数值就可以改变音色。我们通常先选取一个音色库,再从音色库中选择具体的音色所对应的音色程序改变号,这样就可以得到或者改变一个自己想要的音色,音色库和音色程序改变号分别用7位存储,这样音色就有了$$2^7*2^7=16384$$种选择,给予了我们极大的灵活性。GM音色表见附录。
在 GM 标准下,信道 10 是保留给打击乐器的(实际上合成器可以在任何信道上使用鼓),在这个信道上乐器编码遵循通用 MIDI 鼓乐器列表,列表见附录。
2.4 Pitch Bend
MIDI支持以弯音信息的方式来模拟合成器中弯音轮的作用。弯音轮最早是合成器上的一个控件,用于以连续可变的形式改变音高,也就是滑音表情。一般 MIDI键盘的弯音默认范围为 ±2 个半音。弯音就是一个乐音被向上弯至不同的音高,或向下弯至另一个不同的音高,向上或向下的弯音的音高均不确定,整个音高变化的过程是连续的,而非通常的离散音符的切换。弯音信息的存在给予了MIDI音乐更高的质量、更多的可能性,给MIDI音乐的创作者留足了空间。
2.5 Control Change
MIDI 设备通常会提供一些控制器用于改变合成器的某个参数,比如混响、增益等。MIDI 协议可以使用控制器消息操作 128 个不同的控制器。控制器消息一方面可以用于改变合成器的某些参数,另一方面,控制器编码可以通过“组合”的方式实现一些更复杂的指令。在 MIDI 中控制器消息和音源与效果器的参数密切相关,不同编号的控制器有一些约定俗成的含义,在程序中实现控制器时需要尽量与已有的规范对齐,目前规定的控制器参数详细规范见附录。
至此,我们已经对所有常用的MIDI Channel Message都进行了简单的介绍,光这样对他们的功能进行简单的概括并不能让我们完全理解这些消息的作用与含义,因此,接下来,我们便从最底层的二进制代码出发,来对MIDI进行详细透彻的解析,在解析的过程中也同样会有助于我们对这些消息的理解。前面也有提到,MIDI消息是整个MIDI技术中的核心,理解上面提及到的这些消息是极其有必要的。
三、MIDI文件格式解析
3.1 MIDI文件结构简介
MIDI文件是二进制文件,其内部主要记录了乐曲播放时,音序器应发送给音源的MIDI指令和每条指令发送的时间点。音序器读取这些时间信息和MIDI指令,通过在相应的时间发送相应的指令,以实现乐曲中音符的顺序播放和节拍信息。除了音序器需要发送的MIDI事件之外,MIDI文件内部也