`
844604778
  • 浏览: 550526 次
文章分类
社区版块
存档分类
最新评论

标准MIDI文件格式

 
阅读更多

标准MIDI文件格式
达思挺·考德威尔

标准的MIDI文件格式就像奇异的兽。总体看来,它是那样的让你无法抗拒。当然,你怎样看它无关紧要,可是用足够多的描述符描述一段音乐并使它能够重现,可不是很少的工作就可以完成的。然而,它虽然复杂,但是真正理解之后,MIDI文件格式的结构还是很直观明了的。

在这里我必须放弃一些东西,因为毕竟我不是MIDI也不是MIDI文件专家!最近我为我的PC准备了一块Gravis 超音频音效卡,利用它听完几段MIDI文件(.mid)之后,想:“呵,我要是能够制作自己的MIDI(.mid)文件该多好啊!”嗯,经过烦人的几个小时之后,我发现,那些并不是没有价值的工作。但是,我是不会让一个冗长的文件格式就能够阻止的(此外,我告诉过我的妻子,计算机不是很难用的,而且我十分憎恨当一个伪君子)。那么,在这篇文章中如果发现什么错误,请让我知道,我会修改它的。同时,这份文档的范围并没有提供所有类型的MIDI命令和任何可能的文件配置!这篇基本指南将使读者能够(以中等的时间投资)制作出MIDI类型的文件。

1.概述:

一个MIDI文件基本上由两个部分组成,头块和轨道块。第二节讲述头块,第三节讲述轨道块。一个MIDI文件有一个头块用来描述文件的格式、许多的轨道块等内容。一个轨道可以想象为像一个大型多音轨录音机那样,你可以为某种声音、某种乐谱、某种乐器或者你需要的任何东西分配一个轨道。

2.头块:

头块出现在文件的开头,有三种方式来描述文件。头块看起来一直是这样的:
4D 54 68 64 00 00 00 06 ff ff nn nn dd dd

前4个字节等同于ASCII码MThd,接着MThd之后的4个字节是头的大小。它将一直是00 00 00 00 06,因为现行的头信息将一直是6字节。

ff ff是文件的格式,有3种格式:
0-单轨
1-多规,同步
2-多规,异步

单轨,很显然就只有一个轨道。同步多轨意味着所有轨道都是垂直同步的,或者其他的措辞为他们都在同一时间开始,并且可以表现一首歌的不同部分。异步多轨没有必要同时开始,而且可以完全的不同步。

nn nn 是MIDI文件中的轨道数。
dd dd 是每个4分音符delta-time节奏数(这之后将做详细介绍)。

3.轨道块:

头块之后剩下的文件部分是轨道块。每一个轨道包含一个头,并且可以包含你所希望的许多MIDI命令。轨道头与文件头及其相似:

4D 54 72 6B xx xx xx xx

与头一致,前4个字节是ASCII吗,这个是MTrk,紧跟MTrk的4个字节给出了以字节为单位的轨道的长度(不包括轨道头)。

在头之下是MIDI事件,这些事件同现行的可以被带有累加的MIDI合成器端口接受和发送的数据是相同的。一个MIDI 事件先于一个delta-time。一个delta-time是一个MIDI事件被执行后的节奏数,每个四分之一音符的节奏数先前已经定义在了文件的头块中。这个delta-time是一个可变长度的编码值。这种格式虽然混乱,可是允许根据需要利用多位表示较大的数值,这不会因为需求小的数值情况下以添零的方式浪费掉一些字节!数值被转换为7位的字节,并且除了最后一个字节以最高有效位是0外,各个字节最有意义的一位是1,。这就允许一个数值被一次一个字节地读取,你如果发现最高有效位是0,则这就是这个数值的最后一位(意义比较小)。依照MIDI说明,全部delta-time的长度最多超过4字节。

delta-time 之后就是MIDI事件,每个MIDI事件(除了正在运行的事件外)带有一个最高有效位总是1的命令字节(值将>128)。大部分命令的列表在附录A中。每个命令都有不同的参数和长度,但是接下来的数据将是最高有效位为零(值将<128)。这里有个例外就是meta-event,最高有效位可以是1。然而,meta-events需要一个长的参数以区分。

微小失误就可以导致混乱的是运行模式,这是现行MIDI命令所忽略的地方,并且最终发行的MIDI命令是假定的。这就意味这如果包含了命令,那么MIDI事件就是由delta-time与参数组成而转换的。

4.综述:

如果这份说明仅仅是使问题更加混乱,那么以下提供的例子可能有助于澄清问题!同时,两个公用程序和一个图解文件包含在这个文档里面:

DEC.EXE——这个公共程序是将二进制文件(比如.MID)转换成以十进制表示的对应每个字节的有标记界限的文本文件。

REC.EXE——这个公共程序是将有标记界限的十进制数文本文件对应的每一字节转换成二进制文件。

MIDINOTE.PS——这是一个对应键盘和五线谱的音符数字附录页。


附录A

1.MIDI事件命令

每个命令字节有两部分,左nybble(4位)包含现行的命令,右nybble包含将被执行的命令的通道号,这里有16各MIDI通道8个MIDI命令(命令nybble必须最高有效位是1的)。在下表中,X表示MIDI通道号。所有的音符即数据字节都<128(最高有效位是0)。

十六进制 二进制 数据 描述

8x 1000xxxx nn vv 音符关闭 (释放键盘)
nn=音符号
vv=速度

9x 1001xxxx nn vv 音符打开 (按下键盘)
nn=音符号
vv=速度

Ax 1010xxxx nn vv 触摸键盘以后
nn=音符号
vv=速度

Bx 1011xxxx cc vv 调换控制
cc=控制号
vv=新值

Cx 1100xxxx pp 改变程序(片断)
pp=新的程序号

Dx 1101xxxx cc 在通道后接触
cc=管道号

Ex 1110xxxx bb tt 改变互相咬和的齿轮 (2000H 表明缺省或没有改变)(什么意思搞不懂:)
bb=值的低7位(least sig)
tt=值的高7位 (most sig)

下表是没有通道的 meta-events列表 ,他们的格式是:

FF xx nn dd

所有的 meta-events 是以 FF 开头的命令 (xx),长度,或者含在数据的字节数(nn),现行的数据(dd)

十六进制 二进制 数据 描述
00 00000000 nn ssss 设定轨道的序号
nn=02 (两字节长度的序号)
ssss=序号

01 00000001 nn tt .. 你需要的所有文本事件
 nn=以字节为单位的文本长度
tt=文本字符

02 00000010 nn tt .. 同文本的事件, 但是用于版权信息
nn tt=同文本事件

03 00000011 nn tt .. 序列或者轨道名
nn tt=同文本事件

04 00000100 nn tt .. 轨道乐器名
nn tt=同文本事件

05 00000101 nn tt .. 歌词
nn tt=同文本事件

06 00000110 nn tt .. 标签
nn tt=同文本事件

07 00000111 nn tt .. 浮点音符
nn tt=同文本事件

2F 00101111 00 这个事件一定在每个轨道的结尾出现

51 01010001 03 tttttt 设定拍子
tttttt=微秒/四分音符

58 01011000 04 nn dd cc bb 拍子记号
nn=拍子记号分子
dd=拍子记号分母2=四分之一
3=8分拍, 等等.
cc=节拍器的节奏
bb=对四分之一音符标注的第32号数字

59 01011001 02 sf mi 音调符号
sf=升调/降调(-7=7 降调, 0=基准C调,7=7 升调)
mi=大调/小调(0=大调, 1=小调)

7F 01111111 xx dd .. 音序器的详细信息
xx=被发送的字节数
dd=数据

下表列出了控制整个系统的系统消息。这里没有MIDI通道数 (这些一般仅应用于MIDI键盘等.)

十六进制 二进制 数据 描述

F8 11111000 同步所必须的计时器
FA 11111010 开始当前的队列
FB 11111011 从停止的地方继续一个队列
FC 11111100 停止一个队列

下表列出的是与音符相对应的命令标记。
八度音阶¦¦ 音符号
# ¦¦
¦¦ C ¦ C# ¦ D ¦ D# ¦ E ¦ F ¦ F# ¦ G ¦ G# ¦ A ¦ A# ¦ B
-----------------------------------------------------------------------------
0 ¦¦ 0 ¦ 1 ¦ 2 ¦ 3 ¦ 4 ¦ 5 ¦ 6 ¦ 7 ¦ 8 ¦ 9 ¦ 10 ¦ 11
1 ¦¦ 12 ¦ 13 ¦ 14 ¦ 15 ¦ 16 ¦ 17 ¦ 18 ¦ 19 ¦ 20 ¦ 21 ¦ 22 ¦ 23
2 ¦¦ 24 ¦ 25 ¦ 26 ¦ 27 ¦ 28 ¦ 29 ¦ 30 ¦ 31 ¦ 32 ¦ 33 ¦ 34 ¦ 35
3 ¦¦ 36 ¦ 37 ¦ 38 ¦ 39 ¦ 40 ¦ 41 ¦ 42 ¦ 43 ¦ 44 ¦ 45 ¦ 46 ¦ 47
4 ¦¦ 48 ¦ 49 ¦ 50 ¦ 51 ¦ 52 ¦ 53 ¦ 54 ¦ 55 ¦ 56 ¦ 57 ¦ 58 ¦ 59
5 ¦¦ 60 ¦ 61 ¦ 62 ¦ 63 ¦ 64 ¦ 65 ¦ 66 ¦ 67 ¦ 68 ¦ 69 ¦ 70 ¦ 71
6 ¦¦ 72 ¦ 73 ¦ 74 ¦ 75 ¦ 76 ¦ 77 ¦ 78 ¦ 79 ¦ 80 ¦ 81 ¦ 82 ¦ 83
7 ¦¦ 84 ¦ 85 ¦ 86 ¦ 87 ¦ 88 ¦ 89 ¦ 90 ¦ 91 ¦ 92 ¦ 93 ¦ 94 ¦ 95
8 ¦¦ 96 ¦ 97 ¦ 98 ¦ 99 ¦ 100 ¦ 101 ¦ 102 ¦ 103 ¦ 104 ¦ 105 ¦ 106 ¦ 107
9 ¦¦ 108 ¦ 109 ¦ 110 ¦ 111 ¦ 112 ¦ 113 ¦ 114 ¦ 115 ¦ 116 ¦ 117 ¦ 118 ¦ 119
10 ¦¦ 120 ¦ 121 ¦ 122 ¦ 123 ¦ 124 ¦ 125 ¦ 126 ¦ 127 ¦

参考资料:
"MIDI Systems and Control" Francis Rumsey 1990 Focal Press
"MIDI and Sound Book for the Atari ST" Bernd Enders and Wolfgang Klem 1989 M&T Publishing, Inc.
MIDI file specs and general MIDI specs were also obtained by sending e-mail to LISTSERV@AUVM.AMERICAN.EDU with the phrase GET MIDISPEC PACKAGE in the message.
------------------------------ DEC.CPP ------------------------------------

/* file dec.cpp

by Dustin Caldwell (dustin@gse.utah.edu)

*/


#include <dos.h>
#include <stdio.h>
#include <stdlib.h>

void helpdoc();

main()
{
FILE *fp;

unsigned char ch, c;

if((fp=fopen(_argv[1], "rb"))==NULL) /* open file to read */
{
printf("cannot open file %s/n",_argv[1]);
helpdoc();
exit(-1);
}

c=0;
ch=fgetc(fp);

while(!feof(fp)) /* loop for whole file */
{
printf("%u/t", ch); /* print every byte's decimal equiv. */
c++;
if(c>8) /* print 8 numbers to a line */
{
c=0;
printf("/n");
}

ch=fgetc(fp);
}

fclose(fp); /* close up */
}

void helpdoc() /* print help message */
{
printf("/n Binary File Decoder/n/n");

printf("/n Syntax: dec binary_file_name/n/n");

printf("by Dustin Caldwell (dustin@gse.utah.edu)/n/n");
printf("This is a filter program that reads a binary file/n");
printf("and prints the decimal equivalent of each byte/n");
printf("tab-separated. This is mostly useful when piped /n");
printf("into another file to be edited manually. eg:/n/n");
printf("c:/>dec sonata3.mid > son3.txt/n/n");
printf("This will create a file called son3.txt which can/n");
printf("be edited with any ascii editor. /n/n");
printf("(rec.exe may also be useful, as it reencodes the /n");
printf("ascii text file)./n/n");
printf("Have Fun!!/n");
}

---------------------------- REC.CPP ----------------------------------

/* File rec.cpp
by Dustin Caldwell (dustin@gse.utah.edu)
*/

#include <dos.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

void helpdoc();

main()
{
FILE *rfp, *wfp;

unsigned char ch, c;
char s[20];

if((rfp=fopen(_argv[1], "r"))==NULL) /* open the read file */
{
printf("cannot open file %s /n",_argv[1]);
helpdoc();
exit(-1);
}

if((wfp=fopen(_argv[2], "wb"))==NULL) /* open the write file */
{
printf("cannot open file %s /n",_argv[1]);
helpdoc();
exit(-1);
}

c=0;

ch=fgetc(rfp);

while(!feof(rfp)) /* loop for whole file */
{

if(isalnum(ch)) /* only 'see' valid ascii chars */
{
c=0;
while(isdigit(ch)) /* only use decimal digits (0-9) */
{
s[c]=ch; /* build a string containing the number */
c++;
ch=fgetc(rfp);
}
s[c]=NULL; /* must have NULL terminator */

fputc(atoi(s), wfp);/* write the binary equivalent to file */

}

ch=fgetc(rfp); /* loop until next number starts */


}

fclose(rfp); /* close up */
fclose(wfp);
}


void helpdoc() /* print help message */
{
printf("/n Text File Encoder/n/n");

printf("/n Syntax: rec text_file_name binary_file_name/n/n");

printf("by Dustin Caldwell (dustin@gse.utah.edu)/n/n");
printf("This is a program that reads an ascii tab-/n");
printf("delimited file and builds a binary file where/n");
printf("each byte of the binary file is one of the decimal/n");
printf("digits in the text file./n");
printf(" eg:/n/n");
printf("c:/>rec son3.txt son3.mid/n/n");
printf("(This will create a file called son3.mid which is/n");
printf("a valid binary file)/n/n");
printf("(dec.exe may also be useful, as it decodes binary files)/n/n");
printf("Have Fun!!/n");
}

分享到:
评论

相关推荐

    MIDI消息和标准MIDI文件格式剖析及应用

    MIDI消息和标准MIDI文件格式剖析及应用

    MIDI消息和标准MIDI文件格式剖析及应用.

    MIDI消息和标准MIDI文件格式剖析及应用.

    标准MIDI文件格式.wps

    标准的MIDI文件格式就像奇异的兽。总体看来,它是那样的让你无法抗拒。当然,你怎样看它无关紧要,可是用足够多的描述符描述一段音乐并使它能够重现,可不是很少的工作就可以完成的。然而,它虽然复杂,但是真正理解...

    MIDI文件格式分析

    MIDI消息和标准MIDI文件格式剖析及应用.

    Midi.rar_fm midi_midi

    标准MIDI文件格式,MIDI信息规范,FM理论基础

    midi piano(MIDI文件播放与录制)

    该软件能够使用电脑键盘模拟钢琴弹奏,也可以用模拟钢琴弹奏的方式播放标准MIDI格式文件,通过不同的音轨模拟双手弹奏效果,用不同的按键颜色表示左右手。 支持MIDI格式文件录制,通过钢琴卷帘界面还可以简单的编辑...

    midifile:用于读写标准MIDI文件的C ++类

    Midifile:C ++ MIDI文件解析库 ...MidiFile的帮助程序类,允许以ASCII格式读取/写入MIDI文件,以描述二进制标准MIDI文件的字节。一个可选的便捷类,用于在示例程序中解析命令行选项。 可以从库中删除此类,因为使用M

    MIDI歌曲解析文档

    本文档主要讲解MIDI文件的解析,前5章主要介绍MIDI歌曲规范,并引入大量实例加深理解,使读者学会查看MIDI歌曲的构成,及如何写MIDI格式的歌曲有初步了解。第6章第7章将具体的分析几道MIDI歌曲,并阐述如何快速的...

    audio_to_midi:一个CNN,可将钢琴音频转换为简化的MIDI格式

    然后可以将该输出重构为标准MIDI文件格式。主要目标CNN执行的自动转换是朝自动音乐转录(AMT)更大目标迈出的一步。 AMT和音乐信息检索在行业中有许多应用,包括数字音频工作站软件开发和音乐推荐系统。设置首先,...

    rimd:用于在Rust中处理Midi和标准Midi文件的库

    框线 rimd是一组用于处理Midi消息和标准Midi文件(SMF)的实用程序。 它既处理标准Midi消息,又处理SMF中找到的元消息。 rimd的级别很低,并且消息以其基本格式(即u8的向量)进行存储和访问。 有一些实用的方法可以...

    ktmidi:Kotlin库,用于MIDI访问抽象和数据处理(到目前为止,Android)

    MidiMusic :反映带有读取器和写入器的标准MIDI文件格式结构。 MidiPlayer :基于可定制调度程序的基本MIDI播放器功能。 不是实时严格的(如在GC-ed语言/ VM上),但足以满足一般用途。 它通常是C# 库的Kotlin...

    Arduino-MD_MIDIFile.zip

    Arduino-MD_MIDIFile.zip,标准midi文件(smf)处理库md_midi file标准midi文件解释器库,Arduino是一家开源软硬件公司和制造商社区。Arduino始于21世纪初,深受电子制造商的欢迎,Arduino通过开源系统提供了很多灵活...

    MIDI Dump

    Dump标准格式的MIDI文件。 供多媒体开发人员使用,用于查看、分析MIDI文件格式及结构。

    midi-unit-test-cases:开始收集一组最小单元测试用例的Midi文件,以用于测试标准Midi文件解析

    是从收集一组最小单元测试用例midi文件开始的,用于测试标准midi文件解析。 这些测试用例听起来并不漂亮。 只是应该测试SMF Midi标准的功能。 希望在每个测试用例中创建包含最少指令集的测试用例,以测试特定功能或...

    MD_MIDIFile:标准MIDI文件(SMF)处理库

    MD_MIDIFile:标准MIDI文件(SMF)处理库

    JZZ-midi-SMF:标准MIDI文件

    标准MIDI文件:读/写/播放 安装 npm install jzz-midi-smf --save 或bower install jzz-midi-smf 或yarn add jzz-midi-smf 或从获取完整的开发版本和缩小的脚本 用法 纯HTML &lt; script src =" JZZ.js " &gt; &...

    mml2smf:MML到标准MIDI文件转换器

    MML到标准MIDI文件转换器该实用程序是为开发中的MIDI合成创建的,但可用于一般用例。 目前,功能非常有限。用法从命令行$ npm install -g mml2smf$ mml2smf test.mml$ mml2smf test.mml -o output.mid$ mml2smf -m ...

    9月9的酒.mid(midi文件 初试)

    MIDI是编曲界最广泛的音乐标准格式,可称为“计算机能理解的乐谱”。它用音符的数字控制信号来记录音乐。一首完整的 MIDI音乐只有几十KB大,而能包含数十条音乐轨道。几乎所有的现代音乐都是用MIDI加上音色库来制作...

    MidiKlavar:MIDI文件转换为其他音乐文件格式的转换器。-开源

    MidiKlavar是从MidiXml到其他文件格式的MIDI文件转换器。 MidiXml是由MusicXml.com(MusicXml文件格式背后的组织)管理的文件格式规范。 它与midi.org定义的MIDI二进制文件标准结合使用。 本质上,MidiXml使MIDI二...

    midi:使用Go读取和写入MIDI消息和MIDI文件(SMF)的库

    模块化库,用于使用Go读取和写入MIDI消息和MIDI文件。 注意:如果您正在Github上阅读此文件,请注意,该存储库已移至Gitlab(gitlab.com/gomidi/midi),并且这只是一面镜子。 Go版本:&gt; = 1.14 操作系统/体系...

Global site tag (gtag.js) - Google Analytics