1. 首页
  2. 综合百科
  3. midi是什么意思(音乐研发必备)

midi是什么意思(音乐研发必备)

简介:关于midi是什么意思(音乐研发必备)的相关疑问,相信很多朋友对此并不是非常清楚,为了帮助大家了解相关知识要点,小编为大家整理出如下讲解内容,希望下面的内容对大家有帮助!
如果有更好的建议或者想看更多关于综合百科技术大全及相关资讯,可以多多关注茶馆百科网。

1.MIDI简介

MIDI协议,即数字音乐接口(MusicalInstrumentDigitalInterface),是电子乐器、合成器和其他演奏设备之间的即时通信协议,用于硬件之间的实时演奏数据传递。在MIDI协议诞生之初,我希望解决的就是通过统一的通信协议,让不同乐器厂商的设备能够互相兼容,比如把罗兰键盘连接到雅马哈合成器上。MIDI协议经过扩展后也可以作为记录音乐信息的文件格式,称为& quot标准MIDI文件格式"

在音乐技术的研发中,除了处理音频,音符信息在很多场景下都需要直接处理。如果说wav和mp3记录了音乐的物理现象,那么MIDI协议和MIDI文件记录了& quot单词& quot音乐。本文的目的是让参与音乐发展的学生& quot本体"知道这种最常见的性能信息交互和文件存储格式的编码规则。同时,通过对MIDI事件流等概念的理解,可以更好的抽象出自己在开发中的业务逻辑。

1.1MIDI数据流编码

不同于HTTP协议。当使用MIDI作为传输协议时,所有传输的信息都需要实时响应。例如,一个触摸键信息和效应器的参数变化需要立即执行,因此它使用数据流来传输数据。MIDI定义了一个8位二进制数据流,很多时候我们可以用ASCII码将其表示为十六进制字符进行传输和存储。

对于MIDI标准文件格式,存储的内容也是MIDI生成的事件流。典型的MIDI文件如下所示:

4d 54686400000000060000000100000301 e04d 54726 b 000000001 a00ff 0303132300 ff 5103087 a 2300 ff 58040402180800 ff 2f 00.上面的例子可能会引起一些混乱,因为MIDI文件确实对人类阅读不友好,但它的编码规则实际上是

注意:在本文中,一个字节的最低有效位是第0位,最高有效位是第7位。例如,在X000000Y中,X是第7位,Y是第0位。

1.2MIDI消息

MIDI的核心功能是传输实时音乐演奏信息,本质上是包含音高、力度、效果器参数等信息的指令。我们称这些指令为MIDImessage。MIDI信息通常由几个字节组成,其中第一个字节称为STATUSbyte,后面是几个数据字节。STATUSbyte的第七位是1,DATAbyte的第七位是0。

开头的STATUSbyte有两个作用:一是表示系统或者某个通道状态的变化,二是确定当前MIDIMessage的类型,MIDI类型将决定后面DATAbyte的个数和意义。这是空的。我们举个例子:

状态字节:1100 CCCC数据字节133600 XXXXXXXX状态字节:1001 CCCC数据字节133600 PPPPPP数据字节2:0 vvvvvvv第一个状态字节告诉我们这是一个乐器选择的MIDI消息(1100是乐器选择指令,CCCC是通道号)。乐器选择的MIDIMessage中只有一个数据字节,该数据字节的数据代表所选乐器的编号。以1001开始的第二个STATUSbyte告诉我们这是一个NoteOn类型的MIDImessage,根据协议它有两个数据字节。

除了发送到整个系统的MIDI消息,STATUSbyte通常包含通道号(例子中的CCCC),16个通道的范围分别是0000到1111。发送到整个系统的MIDI信息以1111开始,原来的通道号变成指令号(比如播放指令:11111010,终止指令:1111100)。

需要注意的是,很多时候我们会连续发送很多相同状态的MIDI消息。此时,STATUSbyte可以省略,合成器将继续使用最后接收到的STATUSbyte。合成器记录的状态称为MIDIRUNNINGSTATUS。

总而言之:

MIDImessage由STATUSbyte和Databyte组成。

STATUSbyte从1开始,DATAbyte从0开始。

STATUSbyte确定消息的类型。随后的数据字节数取决于消息的类型。

除了发送给系统的指令之外,STATUSbyte通常包含通道号。

连续的相同状态字节可以省略。

2.常用MIDIMessage

MIDIMessage不需要完全掌握。必要时可以直接查询MIDI标准,日常开发只需要知道几种常用的MIDIMessage即可。下面笔者介绍一下最常用的MIDI。

Message。

2.1NOTEON&NOTEOFF-音符的触发与终止

NOTEON和NOTEOFF是最主要的两个MIDIMessage。当演奏者敲击音乐键盘的琴键时发送NOTEON消息,它包含了音高以及“力度”的参数。当合成器收到此消息时,它会开始以相应的音高和“力度”播放该音符。当收到NOTEOFF消息时,合成器会终止该音符。

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

下面我们举例说明NOTEON:

Statusbyte:1001CCCCDatabyte1:0PPPPPPPDatabyte2:0VVVVVVV

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

PPPPPPP表示音高值,在GeneralMIDI协议中(后文会提到),通常使用69表示标准音A4(440Hz),音高值增减一,就增减一个半音。比如60表示C4(中央C),61表示C#4。同样,升高或者降低八度只需要在当前音高上增减12即可。

VVVVVVV表示速率(velocity),这个速率可以理解为敲击键盘的速度,或者管乐器气流的速度。在最基础的合成器中,速率仅用于确定弹奏音符的力度,唯一的效果是音符音量变大或变小。总体来说,下面这张表可以作为速率和乐谱中的力度记号的对应关系参考:

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

图片来源:https://zhuanlan.zhihu.com/p/19964066

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

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

NOTEOFF消息和NOTEON消息基本一样:

Statusbyte:1000CCCCDatabyte1:0PPPPPPPDatabyte2:0VVVVVVV

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

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

2.2乐器选择

乐器选择消息的格式如下:

Statusbyte:1100CCCCDatabyte1:0XXXXXXX

其中唯一的一个DATAbyte表示乐器编号,支持128个不同的乐器。由于不同的软件上存在的乐器音源并不一致,为了让A设备上创建的标准MIDI文件在B设备上播放时听起来相似,乐器厂商边采用GeneralMIDI协议来编排音源。GerneralMIDI通常简写为GM,它提供了一个标准化的音库,将128个乐器排列成16个系列,每个系列有8个同类型的乐器,并为每个乐器分配一个特定的程序编号。GM乐器表可以参考:

http://www.harfesoft.de/aixphysik/sound/midi/pages/genmidi.html

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

https://en.wikipedia.org/wiki/General_MIDI#Percussion

由于鼓是总体上是噪音乐器,所以之前的音高参数则被映射为不同的鼓音效。

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

2.3控制器消息

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

Statusbyte:1011CCCCDatabyte1:0NNNNNNNDatabyte2:0VVVVVVV

其中NNNNNNN是控制器的编号,VVVVVVV则是控制器的值。

控制器消息一方面可以用于改变合成器的某些参数,比如我们可以用以下指令将某个信道的力度值设置为100:

Statusbyte:1011CCCCDatabyte1:00000111Databyte2:01100100

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

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

这段代码选择了一个编号为2,并且音色编号为MSB=0,LSB=32的乐器。由于MSB和LSB的范围都是2^7=128,所以理论上可以选择的音色为(2^7)^2=16384

在MIDI中控制器消息和音源与效果器的参数密切相关,不同编号的控制器有一些约定俗称的含义,在程序中实现控制器时尽量与已有的规范对齐,具体内容可以参考这个表格:MIDICCList(https://professionalcomposers.com/midi-cc-list/)

注:MSB指最高有效字节(mostsignificantbyte),LSB指最低有效字节(leastsignificantbyte)。一个14位的数据XXXXXXXYYYYYYY可以用MSB+LSB表示为:0XXXXXXX0YYYYYYY

2.4弯音消息

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

Statusbyte:1110CCCCDatabyte1:0LLLLLLLDatabyte2:0MMMMMMM

其中LLLLLLL表示LSB,MMMMMMM表示MSB,弯音值0x2000(即0b10000000000000)为同音高,0x3FFF(即0b11111111111111)表示上方大二度,0x0000(即0b00000000000000)表示下方大二度。在实践中,我们可以通过连续发送递增或者递减的弯音消息来表现滑音。

2.5系统独占消息

所有系统消息都以1111开头,其中有两个特殊的消息。一个是11110000它表示后面的消息是系统独有的。另外一个11110111则表示系统独有消息结束,消息结构如下:

111100000iiiiiii0ddddddd....0ddddddd11110111

当合成器监听到11110000时,检查下一个字节0iiiiiii,iiiiiii是一个7位的制造商ID。如果合成器识别出这个代码则会继续监听后面的数据,否则则忽略掉收到的消息,直到结束消息11110111出现。

3.宿主的MIDIAPI

许多宿主环境都提供了用于编写MIDI交互程序的API,在浏览器上是WebMIDIAPI,在iOS&Mac上是CoreMIDI,Android上则有AMidi。为了方便读者进行实际操作,我们以WebMIDIAPI为例展示如何编写一个最基本的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向用户索要访问MIDI设备的权限,用户允许后我们会拿到一个midiAccess对象,可以通过这个对象拿到所有的输入和输出设备。我们可以通过设备对象提供的onmidimessage回调监听midimessage。

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

如果想要MIDI可以发音,我们可以使用WebAudioAPI提供的振荡器:

constbutton=document.getElementById('play-sound')constoscillators={};letcontextbutton.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事件为11000000if(message.data[0]===144){playNote(frequency);}//noteoffif(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();}

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

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

演示地址:muse-training(https://muse-training-8gwn0lc039762917-1252681582.tcloudbaseapp.com/)

仓库地址:https://github.com/lipd/muse-training

4.标准MIDI文件格式规范

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

4.1Chunk

Chunk是构成MIDI文件的基本单元。一个Chunk由三个部分组成:Chunk类型、Chunk长度以及Chunk数据。Chunk类型是4个ASCII字符,之后使用32位表示Chunk数据的长度,最后才是Chunk需要存储的数据。

MIDI中一共有两种Chunk,分别为HeaderChunk和TrackChunk。HeaderChunk标记为MThd,存储的是整个MIDI文件的基本信息,和PNG等文件的HeaderChunk类似。TrackChunk标记为MTrk,每个TrackChunk都存储了一个MIDI事件流,一个事件流可以包含16个MIDI信道的消息。一个典型MIDI文件的结构如下:

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

4.2HeaderChunk

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

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

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

MIDI文件格式(MIDIFileFormats)

MIDI文件格式分为三种,格式0的MIDI文件只有一个HeaderChunk和一个TrackChunk。对于只有一个轨道的程序可以采用这种格式。

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

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

我们用一张表总结一下:


音轨数量

时间轴

格式0

1个

1条

格式1

多个

1条

格式2

多个

多条

MIDI时间类型

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

“按音符分割的”时间类型15位为0,被称为TPQN(TicksPerQuarter-Note),即一个四分音符中包含了多少Tick。在前文的例子中00DC表示TPQN为220,那么一个八分音符为110Ticks,一个二分音符为440Ticks。另外TPQN也被称为PulsesPerQuarter-Note(每四分音符的脉冲数),如果你在代码中看到PPQ、PPQN这样的简写,你知道他们是一个意思即可。

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

四分音符的Tick数


15位

14-8位

7-0位

按音符

0

按帧

1

SMPTE格式

每帧Tick数

4.3TrackChunk

TrackChunk的主要功能是用于存储实际的演奏数据。它的ChunkData中存储的是一串事件流,被TrackChunk记录的事件我们称为MTrk事件,其结构如下:

<MTrkevent>=<deltatime><event>

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

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

deltatime

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

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

sysexevent

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

metaevent

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

需要注意的是FF2F00是一个特殊的元事件,表示轨道结束。所有TrackChunk都以这个元事件结束。下面这张表是标准中已定义的元事件:


意义

FF0002

序列号

FF01lentext

文本事件

FF02lentext

版权声明

FF03lentext

轨道名称

FF04lentext

轨道中使用的乐器类型

FF05lentext

歌词

FF06lentext

某个点的名称,比如“第一乐章”

FF07lentext

CuePoint某个舞台事件描述

FF2001cc

MIDI通道前缀

FF2F00

EndofTrack

FF5103tttttt

设置速度

FF5405hrmnsefrff

SMPTEOffset

FF5804nnddccbb

拍号

FF5902sfmi

调号

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

5.1MIDI2.0&MPE

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

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

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

原视频链接:https://www.youtube.com/watch?v=6SCug5kUsBs

为了解决让控制器消息能按“音”发送,seaboard的制造商ROLI制订了MIDIPolyphonicExpression(MPE,MIDI复音表示法)。其原理基本上可以概括为:让每个发声的音符都会在其NoteOn和NoteOff之间临时分配一个MIDI通道。这样便把控制器消息和弯音消息与特定音符建立了联系,并且很好的兼容了MIDI协议。

上述问题现在都正在通过新的MIDI2.0得到解决,在MIDI2.0中volocity从0-128扩展到0-65535,信道从16个增加到256个,同时MIDI2.0也支持MPE以及远程控制。

5.2如何拓展MIDI

如果MIDI2.0和MPE这类现成的解决方案无法满足你的需求,那么你可以考虑自己来拓展MIDI协议或者MIDI标准格式。目前来看,可靠的拓展方式有几下几种:

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

6.思考与讨论

6.1什么时候使用MIDI格式,什么时候不用?

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

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

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

绝大部分这类问题可以通过不使用MIDI编码来解决。原则很简单,只要不涉及现场演奏场景和向其他工具导出数据,就避免使用MIDI编码来做任何事情。只用确保在需要MIDI的场景可以导出MIDI文件就行。

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

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

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

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

附录

可变长度数量(Variable-LengthQuantities)

由于单个字节表示的最大范围为0-256,所以在MIDI文件中表示较大数字时会采用可变长度数量。其每一个字节使用第7位表示这个字节是否为最后一个字节,1表示不是最后一个字节,0表示是最后一个字节,0-6位则作为有效位。

举一个例子,数字127可以表示为01111111,128则表示为1000000100000000,这样理论上可以表示的数字可以无限大,不过在实践中通常不会使用超过32位。

总结一下就是:

7位

0-6位

是否为最后一个字节

有效位

速率的解释

noteon中的velocity实际上是按键的“触发速率”,你可以把其视为从键盘能感知到下按到下按结束这个过程中的键程除以按下时间,noteoff则是反向的“释放速率”。速率的计算方式和更多细节可以参考这篇论文:TheInterpretationofMIDIVelocity

一堆速查表

查十进制的MIDI消息:ExpandedMIDI1.0MessagesList(StatusBytes)查GM乐器表:GeneralMIDIInstrumentList查MIDI事件流:StandardMIDI-FileFormatSpec.1.1,updated

参考文献

https://www.midi.org/specificationsMIDITutorialStandardMIDI-FileFormatSpec.1.1,updatedMIDIPolyphonicExpression(MPE)SpecificationAdopted钢琴的触键方式是如何影响弹出来的音色的?(https://zhuanlan.zhihu.com/p/19964066)MIDITick、Meta-event、变长数表示法、区分MIDI文件中单个字节的含义(https://www.cndzq.com/bbs/thread-117332-1-1.html)MPEinLive11(https://help.ableton.com/hc/en-us/articles/360019144999-MPE-in-Live-11)GDX-620使用说明书(https://de.yamaha.com/files/download/other_assets/9/334239/DGX-620_ZH.pdf)

推荐读物

《音乐声学——音响、乐器、计算机音乐、MIDI、音乐厅声学原理及应用》-龚镇雄TheComputerMusicTutorial-CurtisRoads

本文主要介绍了关于midi是什么意思(音乐研发必备)的相关养殖或种植技术,综合百科栏目还介绍了该行业生产经营方式及经营管理,关注综合百科发展动向,注重系统性、科学性、实用性和先进性,内容全面新颖、重点突出、通俗易懂,全面给您讲解综合百科技术怎么管理的要点,是您综合百科致富的点金石。
以上文章来自互联网,不代表本人立场,如需删除,请注明该网址:http://23.234.50.4:8411/article/91468.html