音乐研发必备:理解 MIDI 协议与标准 MIDI 文件格式

1. MIDI 简介

MIDI 协议即数字音乐接口(Musical Instrument Digital Interface) ,是电子乐器、合成器等演奏设备之间的一种即时通信协议,用于硬件之间的实时演奏数据传软件工程师浏览器推荐MIDI 协议诞生之初希望解决的事情是通过统一通信协议让不同乐器制造商的二进制设备可以互相兼容,比如把 Roland 键盘接入 Yamaha 合成器。MIDI 协议的编码经过拓展后也可以作为一种记录音乐信息的文件格式,被称为“标准 MIDI 文件格式”。

在音乐技术研发中除了需浏览器历史上的痕迹在哪里要与音频打交道之外,许多场景字符间距加宽2磅怎么设置中还需要直接处理音符信息。如果说 wav 与 mp3浏览器的历史 记录的是音乐的物理现象,那么 MIDI 协议与 MIDI 文件则记录的是音乐这门语言的“文字”。本文的目的是让开发中涉及到音乐“本体”的同学可以了解这一最通用的演奏信息交互和文件存储格式的编码规则。同时通过对 MIDI 事件流等概念的认识,能在开发中更好地抽象自己的业务逻辑。

1.1 MIDI 数据流 & 编码

和 HTTP 这类协议不同,MIDI 作为传输协议时所有传递的信息都需要被实时响应,比如一个触键信息、一个效果器参数的改变都需要立刻被执行,所以其采用数据流的方式进行数据传输。M字符间距加宽2磅IDI 定义了一个 8 位的二进制数据流,许多时候我们可以使用 ASCII 码来将其表示为 16 进制的字符用于传输和保存。

对于MIDI 标准文件格式来说,其存储软件工程专业的内容也是 MIDI 产生的事件流。一段典型的 M软件技术IDI 文件长这样:

4D546864000000060001000301E04D54
726B0000001A00FF030331323300FF51
03087A2300FF58040402180800FF2F00
...

上面这个例子可能会造成字符串逆序输出一些困惑,因为 MIDI 文件确实对人类阅读不太友好,但其编码规则实际上是较易掌二进制转换器握的,下面我们就来逐步认识 MIDI 的编码规则。

注:在本文中,一个字节的最低有效位为第 0 位,最高有效位是第 7 位。比如在 X000 000Y 中,X 为第 7 位,Y 为第 0 位。

1.2 MIDI 消息

MIDI 最核心的功能是用于传输实时的音乐演奏信息,这些信息本质上是一接口类型条条包含了音高、力度、效果器参数等信息的指令,我们将这些指令称之为 MIDI 消息(MIDI message)。一条 MIDI 消息通常由数个字节组成,其中第一个字节接口是什么被称为 STAT软件工程US byte,其后面有跟有数个 DATA bytes。STAT浏览器US byte 第七位为 1,而 DATA byte 第七位为 0。

开头的软件工程 STATUS byte 有两个作用:一个作用是表示系统或者某个信道状态的改变,其二个作用是确定当前 MIDI Messa字符ge 的类型,MIDI 类型会确定后面 DATA byte 的数量和意义。这样说比较空洞,下面我们举一个例子:

Statusbyte:1100CCCC
Databyte1:0XXXXXXX
Statusbyte:1001CCCC
Databyte1:0PPPPPPP
Databyte2:0VVVVVVV

第一个 STATUS byte 告诉我们这是一个进行乐器选择的 MIDI Message(1100 为乐器选择指令,CCCC 是信道编字符间距怎么加宽号)。乐器选择的 MIDI Message 只有一条 DATA byte,而这条 DATA Byte 的数据表示选择的乐器编号。第二条 1001 开头的 STATUS byte 则告诉我们这是字符型变量一条 Note On 类型 MIDI message,这个浏览器网站删除了怎么恢复类型按照约定有两个 DATA by二进制换成十进制算法te。

除了向整个系统发送的 MIDI 消息, STATUS字符间距加宽2磅怎么设置 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 以字符间距加宽2磅怎么设置 1 开头,DATA byte字符型变量 以 0 开头。
  • STATUS byte 确定消息的类型。后面的 DATA 字节数取决于消息的类型。
  • STATUS byte 通常包含信道编号,除了面向系统发送的指令。
  • 连续相同的 STATUS byte 可以省略。

2. 常用 MIDI Message

MIDI Message 不需要全部掌握,需要接口的时候可以直接到 MIDI 标准中查询,日常开发中接口和抽象类的区别只需要了解常用的几种 MIDI Message 即可。下面笔者介绍最常用的几种 MIDI Message。

2.1 NOTE ON & NOTE OFF – 音符的触发与终止

NOTE ON 和 NOTE OFF 是最主要的两个 MIDI Me浏览器历史记录设置ssage。当演奏者敲击音乐键二进制盘的琴键时发浏览器历史记录设置送 NOTE ON 消息,它包含了音高以及“力字符间距在哪里设置度”的参数。当合成器收到此消息时,它会开始以相应的音高和“力度”播放该音符。当收到 NOTE OFF 消息时,合成器会终止浏览器的历史记录在哪该音符。

每个 NOTE ON 消息都需要相应的 NOTE OFF 消息,否则该音二进制计算器符将一直处于播放状态。但打击乐器可以只发送 NOTE字符 ON,因为打击乐音符会自动停止。但最好养成始终发送 NOTE OFF 的习惯,因为不同合成器对这一特性的实现可能不一样。

下面我们举例说明 NOTE接口文档 ON:

Statusbyte:1001CCCC
Databyte1:0PPPPPPP
Databyte2:0VVVVVVV

在这个例子中,1001可以理解为 NOTE ON 事件二进制的编码,CCCC是信道编号。

PPP PPPP表示音高值,在 General MIDI 协议中(后文会提到),通常使用 69 表示标准二进制转换器音 A4(440 Hz),音高值增减一字符串逆序输出,就增减一个半音。比如二进制换成十进制算法 60 表示 C4(浏览器推荐中央 C), 61 表示软件库 C#4。同样,升高或者降低八度只需要在当前音高上增减 12 即可。

VVV VVVV表示速率(velo字符串逆序输出city),这个速率可以理解为敲击键盘的速度,或者管乐器气流的速度。在最基础的合成器中,速率仅用于确定弹浏览器数据如何恢复奏音符的力度,唯一的效果是音符音量变大或变小。总体来说,下面这张表可以作为速率和乐谱中的力度记号的对应关系参考:

音乐研发必备:理解 MIDI 协议与标准 MIDI 文件格式

但在在一些复杂的仿真建模合成器中,速率也会影响音色。我们以 Galaxy Steinway 采样器为例:

音乐研发必备:理解 MIDI 协议与标准 MIDI 文件格式

音乐研发必备:理解 MIDI 协议与标准 MIDI 文件格式

图片来源:zhuan软件商店l接口是什么an.zhi字符常量hu.com/p/19964066

左侧是小力度敲击的频域图,右侧是大力度敲击的频域图。我二进制换成十进制算法们可以看到大力度敲击不仅产生了更多的泛音,也在低二进制的运算规则频区产生了一些噪音(木材被撞击的声音)。

注:关于 velocity 可以参考附录的介绍。

NOTE OFF 消息和 NOTE ON 消息基本一样:

Statusbyte:1000CCCC
Databyte1:0PPPPPPP
Databyte2:0VVVVVVV

其中 CCCC 和 PPPPPPP 含义同上。VVVVVVV 是释软件工程专业放速率,可以看作是按键抬起的速度,这个值很少使用,通常将其设置为零。另外,在实践中经常使用速率为 0 的 NOTE ON 消息取代 NOTE OFF 消息。

需要额外说明的是 MIDI 协浏览器下载议还提供了一组 All Notes Off 消息,当某个信道接收到 All Note Off 消息之后会关闭所有还在发音的振荡器,通常来说 All Notes Off 消息用于在演奏、播放结束后用于二进制清理状态,这里不多赘述。

2.2 乐器选择

乐器选择消息的格式如接口测试下:

Statusbyte:1100CCCC
Databyte1:0XXXXXXX

软件技术中唯一的一个 DATA byte 表示乐器编号,支持 128软件开发 个不同的乐器。由于不同的软件上存在的乐器音源并不一致,为了让 A 设备上创建的标准 MIDI 文件在 B 设备上播放时听起来相似,乐器厂商边采用 General MIDI 协议来编排字符音源。Gerneral MIDI 通常简写为 G软件工程专业M ,它提供了一个标准化的音库,将 128 个乐器排软件技术专业列成 16 个系列,每个字符型变量系列有 8 个同类型的乐器,并为每个乐器分配一个特定的程序编号二进制的运算规则。GM 乐器表可以软件开发参考:

www.h浏览器哪个好arfesoft.de/ai二进制换成十进制算法xphysik/s…

在 GM 标准下,信道 10 是保留给打击乐器的(实际上合成器可以在任何信道上使用鼓),在这个信道上乐器编码遵循通用 MIDI 鼓乐器列表(General MIDI drum instruments list),具体可以参考:

en.wikipedia.org/wiki/Genera…

由于鼓是总体上是噪音乐器,所以之前的音高参数字符间距怎么加宽则被映射为不同的鼓音效。字符常量

注:噪音乐器指没有明确音高的乐器,有明软件开发确音高的乐器称为乐音乐器。

2.3 控制器消息

MIDI 设备通常会提供一些控制器用于改变字符是什么合成器的某个参数,比如混响、增益等。MIDI 协议可以使用控制器消息操作 128 个不同的控制器,控制器消息结构如下:

Statusbyte:1011CCCC
Databyte1:0NNNNNNN
Databyte2:0VVVVVVV

其中NNN NNNN是控制器的编号,VVV VVVV则是控制器的值。

控制器消息一方面可以用于改变合成器浏览器哪个好的某些字符是什么参数,比如我们可以用以下指令将浏览器的历史记录在哪某个信道的力度值设置为 100:

Statusbyte:1011CCCC
Databyte1:00000111
Databyte2:01100100

另一方面,控制器编码可以通过“组合”的方式实现一些更复杂软件工程专业的指令。如前文所述,选择乐器可以通过 1000 开头的 STATUS byte 实现,这个指令可以选择 128 种乐器。对于同一个乐器来软件说可以应用不同的音色库,比如我可以在钢琴上使用雅马哈的采样、施坦威的采字符间距加宽2磅样或者是珠江的采样,由于乐器厂商认为 128 这个数量对于音色库太小了字符型变量,所以采用的 MSB + LSB 的方式表示音色库,例子如下:

Statusbyte:1011CCCC
Databyte1:00000000//0=Soundbankselection(MSB)
Databyte2:00000101
Statusbyte:1011CCCC
Databyte1:00100000//32=Soundbankselection(LSB)
Databyte2:00000001
Statusbyte:11000000
Databyte1:00000010

这段代码选择了一个编号为 2,并且音色编号为 MSB = 0, LSB = 32字符间距怎么加宽 的乐器。由于 MSB 和 LSB 的范围都是2 ^ 7 = 128,所以理论上可二进制转八进制以选择的音色为(2 ^ 7) ^ 2 = 16384

在 MI二进制转八进制DI 中控制器消息和音源与效果器的参数密切相关,不同编号的控制器有一些约定俗称的含义,在程序中实现控制器时尽量与已有的规范对齐,具体内容可字符间距加宽2磅怎么设置以参考这个表格:MIDI CC List(professionalcomposers.com/midi-cc-lis…

注:MSB 指最高有软件效字节(most signifi字符间距加宽2磅cant byte),LSB 指最低有效字节(least significant byte)。一个 14 位的数据XXX XXXX YYY YYYY可以用 MSB + LSB 表接口卡示为:0XXX XXXX 0YYY YYYY

2软件开发.4 弯音消息

弯音消息也用到了我们刚才提到的 MSB + LSB浏览器的历史 表示法,其消息结构如下:

Statusbyte:1110CCCC
Databyte1:0LLLLLLL
Databyte2:0MMMMMMM

其中LLL LLLL表示 LSB,MMM MMMM表示 MSB,弯音值二进制转八进制 0x2000(即 0b10000000000000)为同音高,0x3二进制换成十进制算法FFF(字符间距即 0b11111111111111)表示二进制上方大二度,0x0000(即 0b00000000000000)表浏览器历史上的痕迹在哪里示下方大二度。在实践中,我们可以通过连续发送递增或者递减的弯音消息来表现滑音。

2.5 系统独占消息

所有系统消息都以1111开头,其中浏览器下载有两个特殊的消息。一个是1111 0000它表示后面的消息是系统独有的接口测试。另外一个1111 0111则表示系统独有消息结束,消息结构如下:

11110000
0iiiiiii
0ddddddd
..
..
0ddddddd
11110111

当合成器监听到11接口自动化11 0000二进制的运算规则,检查下一个字节0iii iiiiiii iiii是一个 7 位的制造商 ID。如果合成器识别出这个代码则会继续监听后面的数据,否则则忽略掉收到的消息,直到结束消息1111 0111出现。

3. 宿主的 MIDI API

许多宿主环境都提供了用于编写 MIDI 交互程序的 API,在浏览器上是 Web MIDI API,在 iOS &am软件测试p; Mac 上是 Core接口英文 MIDI,Android 上则有 AMidi。为了方便读者进行实际操作,我们以 Web MIDI API 为例展示如何编写一个最基软件本的 MIDI 程序:

constbutton=document.getElementById('console-message')
button.addEventListener('click',()=>{
if(navigator.requestMIDIAccess){
navigator.requestMIDIAccess()
.then(success,failure);
}
})
functionsuccess(midiAccess){
constinputs=midiAccess.inputs.values();
for(letinputofinputs){
input.value.onmidimessage=onMIDIMessage;
}
}
functionfailure(){
console.error('Noaccesstoyourmididevices.')
}
functiononMIDIMessage(messageEvent){
console.log(messageEvent)
}

在这里,我们可以通过 requestMIDIAccess 向用户索要访问 MID二进制计算器I 设备的权限,用户允许后我们会拿到一个 midiAccess 对象,可以通过这个对象拿到所有的输入和输出设备。我们可以通过设备对象提供的 onmidimessage 回调监听 midi message。

MIDI 消息的编码存储在 messageEvent 的 data 成员中,通过打印出的信息我们可以发现 Web MIDI API 并不会省略 Status Byte,这是为了便于开发者更容易区分指令属于哪个状态,而不必手动保存 MIDI 的运行状态。

如果想要字符型变量 MIDI 可以发音,我们可以使用 Web Audio API 提供的振荡器:

constbutton=document.getElementById('play-sound')
constoscillators={};
letcontext
button.addEventListener('click',()=>{
context=newAudioContext()
if(navigator.requestMIDIAccess){
navigator.requestMIDIAccess()
.then(success,failure);
}
})
functionsuccess(midiAccess){
constinputs=midiAccess.inputs.values();
for(letinputofinputs){
input.onmidimessage=onMIDIMessage;
}
}
functionfailure(){
console.error('Noaccesstoyourmididevices.')
}
functiononMIDIMessage(message){
constfrequency=midiNoteToFrequency(message.data[1]);
//midi键盘的普通按键默认使用通道0,所以其noteon事件为11000000
if(message.data[0]===144){
playNote(frequency);
}

//noteoff
if(message.data[0]===128){
stopNote(frequency);
}
}
functionmidiNoteToFrequency(note){
returnMath.pow(2,((note-69)/12))*440;
}
functionplayNote(frequency){
oscillators[frequency]=context.createOscillator();
oscillators[frequency].frequency.value=frequency;
oscillators[frequency].connect(context.destination);
oscillators[frequency].start(context.currentTime);
}
functionstopNote(frequency){
oscillators[frequency].stop(context.currentTime);
oscillators[frequency].disconnect();
}

我们可以使用这个小程序来回顾与验证我们之前讲到的 MIDI Message 知识。

这里有一个笔者以前做的视唱练耳小工具,可以使用 MIDI 键盘进行视唱练耳练习:

演示地址:muse-trainin二进制转化为十进制g(muse-training-8gwn0lc03976291二进制7-1252681582.tcloudbaseapp.com/ )

仓库地址:github.com/li字符间距在哪里设置pd/muse-t…

音乐研发必备:理解 MIDI 协议与标准 MIDI 文件格式

4. 标准 MIDI 文件格式规范

MIDI 协议接口文档解决的是音乐设备之间的即时通讯问题,它本质上是一个硬件之间的通信协议。而当我们想把 MIDI 演奏保存在磁盘上则需要用到标准 MIDI 文件格式规范(Standard MIDI-File Format Spec)。和 MIDI浏览器的历史记录在哪 通信协议一样,MIDI 文件也是 8 位字节流,下文将会说明 MIDI 文件一些最基本的格式规范。

4软件工程.1 Chunk

C软件商店hunk 是构成 MIDI 文件的基本单元。一个 Chunk 由三个部分组成:Chunk 类型 、Chunk 长度以及 Chunk 数据。Chunk 类型是 4 个 ASCII接口自动化 字符,浏览器之后使用 32 位表示 Chunk 数据的长度,最后才是 Chunk 需要存储的浏览器网站删除了怎么恢复数据。

MIDI 中一共有两种 Chunk,分别为 Header Chunk 和 Track Chunk。Header Chunk 标记为MT浏览器推荐hd,存储的是整个 MIDI 文件软件库字符间距怎么加宽基本信息,和 PNG 等文件的 Header Chunk 类似。Track Chunk 标记为MTrk,每个 Track Chunk 都存储了一软件个 MIDI 事件流,一个事件流可以包含 16 个 MIDI 信道的消息。一个典型 MIDI 文件的结构如下:

MThd<length>
<MThddata>
MTrk<length>
<MTrkdata>
MTrk<length>
<MTrkdata>

音乐研发必备:理解 MIDI 协议与标准 MIDI 文件格式

4.2 Header Chunk

MIDI 文件的 Header Chunk 包含的信息非常简单,我们以上面这个文件为例:

4D546864//MThd的ASCII码
00000006//MThd的数据长度,MThdData固定为6字节
----DATA部分----
0001//MIDI文件格式,有0、1、2三种
0002//MIDI文件的包含的音轨数量,即TrackChunk数量
00DC//MIDI文件的时间类型

前两条数据已经介绍过,这里不再赘述。我们来解释一下 MIDI 文件格式与 MIDI 时间类型:

MIDI 文件格式(MIDI File Formats)

MIDI 文件格式分为三种,格式 0 的 MIDI 文件只有一个 Header Chunk 和一个 Track字符串是什么意思 Chunk。对于只有一个轨道的程序可以采用这种格式。

格式 1 有一个 Header Chunk ,和多个 Track Chunk 。其中第一条 Track Chunk 是特殊的,负责记录 MIDI 文件的所有 Meta Event(后面会讲到),字符常量而从第二条 Track Chunk 开始才会记录 MIDI Event,所以我们上图中的 MIDI 文件实际上只有一条用于演奏的音轨。目前绝大部分的支持多音轨的程序都采用这种格式,笔者也建议读者尽量使用这种格式。

格式 2 的 MIDI 文件也有多个 Track Chunk字符间距加宽2磅,但不同的是格式 1 所有 Track Chunk 共用一条时间轴,所有 Track 应当被视作同时播放字符间距加宽2磅的。而格式 2 中 Track Chunk 都有自己独立的时间信息,这种格式非常少见,不建议使用。

我们用一张表总结一下:

音轨数量时间轴
格式 01 个1 条
格式 1多个1 条
接口英文式 2多个多条

MIDI 时间类型

MIDI 时间类型主要有两种,为了方便介绍读者可以简单将其理解为“按音符分割的”和“按帧分割的”:

“按音符分割的”时间类型 15 位为 0,被称为 TPQN(Ticks Per Qu字符常量a二进制rter-Note),即一个四分音符中包含了软件工程师多少 Tick。在前文的例子中00 DC表示 TPQ二进制怎么算N 为 220,那么一个八分音符为 110 Ticks软件商店,一个二二进制八进制十进制十六进制转换分音符为 440 Ticks。另外 TP二进制换成十进制算法QN 也被称为 Pulses Per Quarter-Note (每二进制亡者列车四分音符的脉冲数),如果你在代码中看到 PP浏览器怎么打开网站Q、PPQN 这样的简写,你知道二进制他们是一个意思即可。

“按帧分割的”时间类型 15 为 1,这种格式单纯 MIDI 文件中几乎不用而且比较复杂,建议读者跳过。其编码规则简单说就是使用了 SMPTE 时间码的规范。其 14 – 8 位包软件技术专业含了包含 -24、-25、-29 或 -30 四二进制的运算规则个值之一,对应于四种标准 SMPTE 时间码格式(-29 对应于 30 个丢帧),并表示每秒的帧数。第 7 到 0 位表示帧内分辨率。我们软件工程依然用一张表总结一下:

15 位14-8位7-接口自动化0位
按音符0四分音符的Tick数
按帧软件测试1SMPTE格式每帧Tick数

4.3 Track Chunk

Track Chunk 的主要功能是用于存储软件技术专业实际的演接口文档奏数据。它的 C浏览器历史记录设置hunk Data 中存储的是一串事件流,被 Track C二进制八进制十进制十六进制转换hunk 记录的事件我们称为 MTrk 事件,其结构如下:

<MTrkevent>=<deltatime><event>

在这个结构中,事件可以指代三类事件:midi 事件、系统独有事件、元事件:

<event>=<midievent>|<sysexevent>|<metaevent>

de二进制的运算规则lta time

MID字符间距怎么加宽I 通信时所有信息都是即时执行,所以 MIDI 消息并没有记录时间,但是 MIDI 文件则需要记录时间在时间轴上的位置。MIDI 文件采用差量时间来记录 MIDI 事件,即 t。delta time 表示的是当前事件与上一个时间相差的 Tick 数。如果要表示同时发生的数个任务,则记录一串 delta time 为 0 的事件流即可。比如我们控制器一章中切换乐器的事件流可以表示为:

Deltatime:00000000
Statusbyte:1011CCCC
Databyte1:00000000//0=Soundbankselection(MSB)
Databyte2:00000101
Deltatime:00000000
Statusbyte:1011CCCC
Databyte1:00100000//32=Soundbankselection(LSB)
Databyte2:00000001
Deltatime:00000000
Statusbyte:11000000
Databyte1:00000010

sysex event

即系统独占的消息事件,具体可以参考前文中的系统独占消息。

meta event

所有元事件以1111 1111开头,这个指令在 MIDI 消息中表示系统复位。这个指令是一个系统实时信浏览器的历史记录在哪息,通常在使用 MIDI 文件的程序并不会用到,所以在这里用于表示元事件。元浏览器历史记录设置事件主要用于指定拍号、调号、速度等。

需要注意的是FF 2F 00是一个特殊的元事件,表示轨道结束。所有 Track Chunk 都以这个元事件结束。下面这张表是标准中已定义的浏览器的历史元事件:

意义
FF 00 02序列号
FF 01 len接口类型 t浏览器下载ext文本事件
FF 02 len text二进制计算器版权声明
FF 03 len text二进制转八进制道名称
FF 04 len text轨道中使用的乐器类型
FF 05 len text歌词
FF 06 len text某个点的名称,比如“第一乐章”
FF 07 len textCue Point 某个舞台事件描述二进制
FF 20 01 ccMIDI 通道前缀
FF 2F 00End of Track
FF 51 03tttttt设置速度
FF 54 05软件工程专业 hr mn se fr ffSMPTE Offset
FF 58 04 nn dd cc bb拍号
FF 59 02 sf mi调号

5. MIDI 协议的缺陷与改良方案

5.1 MIDI 2.0 &amp接口; MPE

MIDI 通信协议目前看接口crc错误计数来主要有两个较明显的缺陷。第一个缺陷是许多值可以表示的范围实在有限,比如 note off 的 velocity 就只有 128 个、乐器也只有 128 个、只有 16 个信道。

另一个问题更为麻烦,MIDI 中控制器、和弯音消息只能发送给某个信道,你根本就没法将它和某个音联系在一起。这一局限在以前并没有引起多少问题,因为传统乐器很少碰到按音处理控制器的情况。而弯音用得最频繁的更多是单声部乐器。

但电子音乐界向来不缺乏整活健将,工程师总是会想方设法突破现有限制。最典型的例子就字符间距加宽2磅是 seaboard 键盘,这玩意儿可以在每个键上提供弯音能力。你可以从下面接口文档这段演奏上感受到这一乐器的神奇魅力:

原视频链接:www.youtube.com/watch字符间距在哪里设置?v=6SC…

为了解决让控制器消息能按“音”发送,seaboar浏览器哪个好d 的制造商 ROLI 制订了 MIDI Pol字符串是什么意思yphonic Expression(M软件库PE,MIDI 复音表示法)。其原理基本上可以概括为:让每个发声的音符都会在其 Note On 和 Note Off 之间临时分配一个 MIDI 通道。这样便把控制器消息和弯音消息与特定音符建立了联系,并且很好的兼容了 MIDI 协议。

上述问题现在都正在通过新的 MIDI 2.0 得到软件开发解决,在 MIDI 2.0 中 volocity 从 0 – 128 扩展到 0 – 65字符串逆序输出535,信道从 16 个增加到 256 个,同时 MIDI 2.0 也支持 MPE 以及远程控制。

5.2 如何拓展 MIDI

如果 MIDI 2.0 和 MPE 这类现成的解决方案无法满足你的需求,那么你可以考虑软件工程师自己来拓展 MIDI 协议或者 MI字符是什么DI 标准格式。目前来看,可靠的拓展方式有几下几种:

  1. 使用未定义的 MIDI 消息:比如系统消息 1111 0101 的行为在 MIDI 标准中就未被定义。这种方法的好处是不需要进行额外的解析工作,但缺点便是可以使浏览器历史记录设置用的指令十分有限。
  2. 使用自定义 Chunk:Chunk 在设计之初便考虑到了拓展的问题,你可以按照 Chunk 的格式自由地声明一个新的 Chunk 类型,主流解析工具在碰到无法解析的 Chunk 时会自字符是什么动忽略掉,所以不用担心兼容的问题。如果你有二进制换成十进制算法整段的数据,二进制转八进制既不属于浏览器下载 Track,又不能被 Heaer 所包含,那么可以考虑这种方式。
  3. 使用系统独占消息:如果你需要在 MIDI 通信协议上进行拓展,可以考虑使用系统独占消息,合成器会自动忽略无法解浏览器推荐析的独占消息。具体可以参考附录中的系统独占消息一二进制转化为十进制节。
  4. 其他:你也浏览器怎么打开网站可以参考 MPE 的方式,基于现有的编码方案但是重新定义指令的意义和执行。

6. 思考与讨论

6字符常量.1 什么时候使用 M接口IDI 格式,什么时候不用?

首先我们需要认识到 MIDI 的优点,MIDI 记录的实际上是事件流,最适合的场景就是在现场演奏时用于硬件之间的通信。作为 MIDI 文件格式作为一种存储格式,其优点浏览器网站删除了怎么恢复是数据十分紧凑,体积较小。但 MIDI 的缺点是十分明显的,一方面我们无法快速查询、访二进制亡者列车问其中某个具体内容的值:比如我们没法快速找到某一个轨道的拍号,或者某个音的音高。

所以我的建议是,尽量避免在现场演奏场景之外使用 MIDI 文件格式,但可以在抽象上对齐 M接口IDI。在内存中我们尽量把 MIDI 文件转化为实例对象,便于我们快速访问。在需要持久化的场景下则可以使用更容易解析的 JSON 或者 MusicXML 格式。只有在用户需要或者向其他编辑工具导出数据的时候,我们才考浏览器推荐虑使用 MIDI 标准文件格式。

6.2 MIDI 协议无法满足的需求如何解决?

绝大部分这类问题可以通过不使用 MIDI 编码来解决。原则很简单,只要不涉及现场演奏场景和向其他工具导出数据,就避免使用 MIDI 编码来做任何接口自动化字符间距加宽2磅怎么设置情。只用确保在需要 MIDI 的场景可以导出 MIDI 文件就行。

6.3 如果多数场景不使用 MIDI,那有必要深入学习 MIDI 协议吗?

如果你的开发工作涉及二进制的运算规则到音乐的“本体”部分,那么我建议多了解一些 MIDI 协议,因为虽然我们二进制转八进制可能多数情况下不直接使用 MIDI 协议的编码,软件商店但是 MIDI 的事件流是创作场景和存储场景会大量用到的,同时 MIDI 中的多数抽象和概念是行业内通用的。

6.4 如何设计自定义的音乐数据格式?

我的建议是用一个文档维护所有的基础字段和拓展字段,各项目在定义 Model 时尽量参考这个文档。如果现有的拓展字段可以解决你的需求,就不要新增拓展字段。

附录

可变长度数量(Variable-Length Quantities)

由于单个字节表示的最大范围为 0 – 256,所以在 MID浏览器推荐I 文件中表示较大数字时会采用可变长度数量。其每一个字节使用第 7 位表示这个字节是否为字符串是什么意思最后一个字节,1字符 表示不是最后一个字节,0 表示是最后一个字节, 0 – 6 位则作为有效位。

举一个例子,数字 127 可以表示为011接口和抽象类的区别1 1111,128 则表示为1000 0001 0000 0000,这样理论上可以表示的数字可以无限大,不过在实践中通常不会使用超过 32 位。

总结一下就是:

7 位0-6 位
是否为最后一个字节有效位

速率的二进制解释

note on 中的 velocity 实际上是按键的“触二进制换成十进制算法发速率”,字符间距你可以把其视为从键盘能感知到下按到下按结束这个过程中的键程除以按下时间浏览器历史上的痕迹在哪里,note off 则是反向的“释放速率”。二进制速率的计算方式和更多细节可以参考这篇论文:The Interpretation of MIDI Velocity

一堆速查表

  • 查十进制的 MIDI 消息:Expanded MIDI 1.0 Messages List (Status By浏览器怎么打开网站tes)
  • 查 GM 乐器表:General MIDI Instrument List
  • 查 M字符间距加宽2磅怎么设置IDI 事件流:Standard MIDI-字符File Format Spe接口卡c. 1.1, updated

参考文献

  • www.midi.org/specificati…
  • MIDI Tutorial
  • Standard MIDI-File Format Spec. 1.1, updated
  • MIDI Polyphonic Expression (浏览器的历史MPE) Specification Adopted
  • 钢琴的触键方式是如何影响弹出来的音色的?(zhuanlan.zhihu.com/p/1996字符间距怎么加宽4066 )
  • M接口文档IDI Tick、Meta-even浏览器哪个好t、变字符串是什么意思长数表示法、区分 MIDI 文件中单个字符字节的含义(www.cndzq.com/bbs/thread-… )
  • MPE in Live 11(help.ableton.com/hc/en-us/ar… )
  • GDX-620 使用说明书(de.yamaha.com/fil字符es/downl… )

推荐读物

  • 《音乐声学——字符间距加宽2磅怎么设置音响、乐器、计接口测试用例设计算机音乐、MIDI、音乐厅声学原理及应用》- 龚镇雄
  • The Computer Music Tutorial – Curtis Roads

加入我们

字节跳动音乐研发团队,业务包字符含字节旗下的音乐流媒体应用、字节音乐中台、抖音 & 西瓜视频中的音乐视频和音乐创作工具等场景。团队拥有良好的技术氛围,在 ByteTech 沉淀了大量优秀的视频课程和技术文章,欢迎各位同学加入。

投递详情:字节跳动音乐研发团队热招,你的心动Offer已就位!

发表评论

提供最优质的资源集合

立即查看 了解详情