Foreword
了解一下MIDI以及实际应用场景
MIDI
MIDI,Musical Instrument Digital Interface,乐器数字接口。要解释这个先要知道一些其他概念,才能理解为什么要有这样的一个标准接口。
原声乐器,乐器本器,实际人可以演奏的乐器
电子声乐器,实际没有乐器的实际结构,而是靠喇叭播放音乐
电子合成器,MIDI必须要配合软件一起使用,合成器则是不需要软件,他自己就有各种合成编曲功能,合成器更多是对现有音频进行修改、偏移、翻转等等操作,非常像是一个滤波器,而不能像MIDI一样一个音符一个音符的设计。
音源
最初的时候人们可以拥有乐器,可以一起合奏。编曲的人就会说钢琴弹个a,小提琴拉个b,鼓敲个c…,但是这种情况就要求编曲的人全知全能,什么乐器都得会,或者是每次各种乐器要配合编曲人一起工作。这样要求太高了,一个工作耦合了很多个人,效率极低,同时对编曲的人要求又极高,就算想培养这样一个人也非常困难。于是乎就有人想到了把每个乐器每个音符在不同响度、不同音色的情况下发出的声音进行数字化,录制下来此时发出的声音,通过这种方式形成了各种音源、比如钢琴、小提琴、吉他、鼓等等。有了音源以后,就可以通过电脑直接编曲,而不需要实际会弹钢琴的人,实际会拉小提琴的人来实时工作了,这样就有了MIDI的编曲软件,同时编曲的门槛也就相对降低了,就算是普通人下了软件,有基本乐理常识也能自己独立编曲(电子编曲后的曲子可能实际中根本无法演奏,某些按键或者速率、力度是人类实现不了的)。
有了音源,但是要在不通设备上发出这个音源的声音,那就还需要一套标准接口和通信协议,这就是MIDI。通过MIDI线就可以将我所想的音源在各个设备上播放了。同样的通过MIDI,一个人就是一整个乐队了。
同时这一套标准衍生出了各种各样的电子乐器,比如MIDI键盘、吉他、鼓机、呼吸控制器等等,他们都统一使用MIDI标准,只要你会任何一种乐器,就可以做到当你发出某个音的时候,对应可以产生此时乐谱上其他伴奏乐器的声音。
接口
一般是三种接口,
MIDI OUT,发送乐谱数据
MIDI IN,接收乐谱数据
MIDI THRU,中转乐谱数据
MIDI键盘
使用类似钢琴按键排列的方式去组织一个键盘、支持MIDI输出,将信号给到电脑或者其他发生器,将实际的声音发出来。只要有音源支持就可以通过这个键盘直接弹钢琴、拉小提琴了,不仅仅是按键方式,还有各种旋钮、推杆等等控制方式
当然还有各种快捷键支持和适配,让MIDI键盘可以直接进行编曲,取代各种鼠标操作。
MIDI键盘后来也被扩展了,不仅仅是在编曲、表演中使用了。很多音游、大型控制台、剪辑快捷键、助残助障等等都是某种MIDI键盘扩展出来的
MIDI 协议
通讯协议
MIDI信息(MIDI message)可分为系统信息(System message)和通道信息(Channel message)两种,Channel message中的status byte 包含channel编号,指定信息由某个channel 接收;System message则没有,所以每一个channel都可以收。
总体框架
通道信息(Channel Messeages)
- 音符开关信息(Note On/Off),音符发声是通过两个信息控制的,当发声开始时,收到Note on信息,当持续够所规定的时值的时候,要停止的发生便发送Note off信息。
- 触后信息(After Touch),触后信息指的是当音符被“触键”发生后由于触键压力的再次变化而生成改变音色特性的信息,主要在一些高级的合成器或音源中具有此功能
- 音色程序改变(Program Change),音色程序改变也就是俗称的音色变化,即在同一个通道中如何使用多个音色,就涉及到音色变化。
- 弯音改变(Pitch Wheel Change),弯音就是让音与音之间按照规定的音程范围之间平滑地滑动,产生一个音高的偏移变化。在民族音乐中听到的倚音式的变化就是利用弯音控制器来完成的。
- 控制信息(Control Change),控制信息是为了较为对MIDI信息中各个参数进行控制的信息,它由控制器类型即控制器号码与控制数值构成。
通道模式信息(Channel Mode Messeages)
- 本地控制(Local Contro),在本地控制关闭时,所有既定通道的设备都仅对接收的MIDI数据反应。演奏数据则被忽略。本地控制打开则恢复标准控制器的功能
- 所有音符关闭(All Notes Off)在所有音符关闭接收时,所有的振荡器都会关闭
- 模式关闭(Omni Mode Off)和模式打开(Omni Mode On),将其所有模式全部关闭
- 单一模式打开(Mono Mode On)单一模式指的是音的发音模式,即同时只能发一个音
- 复音模式打开(Poly Mode On)复音指的是在同一时间内的发音,Poly Mode On表示单一关闭Mono Of
系统实时信息(System Real-time Message)
- 定时时钟(Timing Clock)定时时钟。在同步请求时每1/4音符时发送24次
- 开始播放(Start)开始当前音序的播放(该消息遵从定时时钟的指示)
- 继续(Continue)在停止点重新开始音序播放
- 停止(Stop)停止当前音序
- 活性感觉(Active Sensing)该消息使用可选。在初始发送时,接收方则会在300ms(最大)后接收另外的活性感觉信息,或者会假定连接终止。在终止时,接收方会关闭所有发音,并返回标准(非活性感觉)操作状态。
- 重设(Reset)重设所有接收方系统重新启动状态。这个命令使用起来要保守些,更适合人工操作
系统通用信息(System Common Messages)
- 系统专用信息(System exclusive message)可以以实时和非实时的方式并对特定的设备发送而作用于某个功能
- 歌曲位置指针(Song Position Pointer)内部14位注册,保存了从歌曲开始到现在的MIDI节拍
- 调音请求(Tune Request)在接收调音请求时,所有的模拟合成器都会调音各自的振荡器。
- 专属信息结束(End of Exclusive)用来终止系统专属信息的批传
协议定义
MIDI 最核心的功能是用于传输实时的音乐演奏信息,这些信息本质上是一条条包含了音高、力度、效果器参数等信息的指令,我们将这些指令称之为 MIDI 消息(MIDI message)。一条 MIDI 消息通常由数个字节组成,其中第一个字节被称为 STATUS byte,其后面有跟有数个 DATA bytes。STATUS byte 第七位为 1,而 DATA byte 第七位为 0。
开头的 STATUS byte 有两个作用:一个作用是表示系统或者某个信道状态的改变,其二个作用是确定当前 MIDI Message 的类型,MIDI 类型会确定后面 DATA byte 的数量和意义。
# select
Status byte : 1100 CCCC
Data byte 1 : 0XXX XXXX
# note on
Status byte : 1001 CCCC
Data byte 1 : 0PPP PPPP
Data byte 2 : 0VVV VVVV
第一个 Status byte 告诉我们这是一个进行乐器选择的 MIDI Message(1100
为乐器选择指令,CCCC
是信道编号)。乐器选择的 MIDI Message 只有一条 Data byte,而这条 Data Byte 的数据表示选择的乐器编号是XXX XXXX
。最多支持128种乐器,GM协议的MIDI,是将这7bits根据不通类型乐器进行了划分。
第二条 1001
开头的 Status byte 则告诉我们这是一条 Note On 类型 MIDI message,这个类型按照约定有两个 Data byte。
除了向整个系统发送的 MIDI 消息, Status byte 通常包含了信道编号(即例子中的 CCCC
),16 个信道分别从 0000 到 1111。而向整个系统发送的 MIDI 信息则以 1111
开头,原来的信道编号变成了指令编号(比如播放指令:1111 1010
,终止指令:1111 1100
)。
需要注意的是,许多时候我们会连续发送许多相同状态的 MIDI 消息,这个时候可以省略 Status byte,合成器会沿用最后一个接收的 Status byte,被合成器记录的状态称之为 MIDI Running Status 。
总结一下:
- 一条 MIDI message 由 Status byte 和 Data byte 构成。
- Status byte 以 1 开头,Data byte 以 0 开头。
- Status byte 确定消息的类型。后面的 Data 字节数取决于消息的类型。
- Status byte 通常包含信道编号,除了面向系统发送的指令。
- 连续相同的 Status byte 可以省略。
NOTE OFF
Status byte : 1000 CCCC
Data byte 1 : 0PPP PPPP
Data byte 2 : 0VVV VVVV
NOTE ON
Status byte : 1001 CCCC
Data byte 1 : 0PPP PPPP
Data byte 2 : 0VVV VVVV
NOTE OFF 消息和 NOTE ON 消息基本一样,表示开始或者终止音符。他们需要成对出现
参数1表示的是音高,参数2表示的是力度或者速度
# control
Status byte : 1011 CCCC
Data byte 1 : 0NNN NNNN
Data byte 2 : 0VVV VVVV
MIDI 设备通常会提供一些控制器用于改变合成器的某个参数,比如混响、增益等。MIDI 协议可以使用控制器消息操作 128 个不同的控制器,其中 NNN NNNN 是控制器的编号,VVV VVVV 则是控制器的值。这里的控制器,也可以理解为上面说的效果器,或者说就是改变同一个乐器的音色。上面已经将乐器通过类型进行了划分,但是每种乐器可能还有不同的细节导致他们音色不通,就可以在这里通过控制切换乐器的音色
速率的解释
note on 中的 velocity 实际上是按键的“触发速率”,你可以把其视为从键盘能感知到下按到下按结束这个过程中的键程除以按下时间,note off 则是反向的“释放速率”。
# system info
1111 0000
0iii iiii
0ddd dddd
..
..
0ddd dddd
1111 0111
系统消息是以1111
开头的,第二字节表示具体的制造商ID,如果对应乐器识别出来了,那么就监听剩余部分信息直到1111 0111
系统信息结束。非此制造商就可以忽略。
常用的System Message如下
可变长度数量(Variable-Length Quantities)
由于单个字节表示的最大范围为 0 - 256,所以在 MIDI 文件中表示较大数字时会采用可变长度数量。其每一个字节使用第 7 位表示这个字节是否为最后一个字节,1 表示不是最后一个字节,0 表示是最后一个字节, 0 - 6 位则作为有效位。
举一个例子,数字 127 可以表示为 0111 1111 ,128 则表示为 1000 0001 0000 0000,这样理论上可以表示的数字可以无限大,不过在实践中通常不会使用超过 32 位。
MIDI文件
MIDI 协议解决的是音乐设备之间的即时通讯问题,它本质上是一个硬件之间的通信协议。而当我们想把 MIDI 演奏保存在磁盘上则需要用到标准 MIDI 文件格式规范(Standard MIDI-File Format Spec)。和 MIDI 通信协议一样,MIDI 文件也是 8 位字节流,存储时也就有了一定的格式规范。
DMX与MIDI
二者想要实现的东西都非常像,DMX想控制各种灯光设备,MIDI想控制音乐设备。同样的,也有MIDI转DMX,通过音乐来控制灯光,这种设计比较符合各种表演现场的情况,音乐到某一个位置以后触发对应的灯光效果。而这种情况下多数都是以声音为主,灯光等只是附属被动触发而已。
MIDI转RJ45
搜了一下似乎MIDI本身链接都是比较近的,转以太网的比较少。
倒是有MIDI转蓝牙,电脑只需要蓝牙适配器插上就能工作了,但是更长距离的无线方式似乎就没有了。
MIDI转各种类型的USB倒是很多,同样的很多设备上的MIDI接口都被现成的USB取代了,USB可以直接做为MIDI设备接入PC,所以传统的MIDI反而变少了。
MIF4
MIDI有自己的Time Code,但是有些设备使用的是SMPTE时间,这两个需要时间转换,就有了MIF4,主要对MIDI时间和LTC SMPTE时间进行互相转换
Summary
MIDI基本这么多,实际应用可能和想象的还有些不一样
Quote
https://www.bilibili.com/video/BV16T4y1E7xF
http://www.taodudu.cc/news/show-3053738.html
https://mp.weixin.qq.com/s/m1mujGaEkwSkpMwYijjISw
https://www.midi.org/specifications
https://www.360docs.net/doc/ac18155894.html
https://blog.csdn.net/cenzmin/article/details/44317575