中国电子琴在线论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

用新浪微博连接

一步搞定

扫一扫,访问微社区

查看: 7044|回复: 23

图解midi文件格式分析

  [复制链接]
  • TA的每日心情
    开心
    2017-4-27 23:29
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2012-8-27 21:02:37 | 显示全部楼层 |阅读模式
    本帖最后由 gaoyunlove2008 于 2012-8-27 21:19 编辑

       
    标准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                  停止一个队列

    图片为CountryBrothers.T108.sty二进制文件,另外两张是用casmedit18软件打开,通过二进制文件和midi事件对比,分析出midi文件的格式,各个二进制所表示的midi事件

    二进制文件

    二进制文件

    雅马哈casmedit18软件打开

    雅马哈casmedit18软件打开

    雅马哈casmedit18软件打开

    雅马哈casmedit18软件打开

    评分

    参与人数 1金币 +40 收起 理由
    Ray2000 + 40 不错!

    查看全部评分

    回复

    使用道具 举报

  • TA的每日心情
    开心
    2016-11-20 17:44
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    发表于 2012-8-28 01:18:57 | 显示全部楼层
    嗯,支持~!这篇文章是我曾经参考过的文章之一,hoho~
    其实MIDI协议和MIDI文件本身并不复杂,但灵活运用起来可是蛮复杂的……
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-11-16 09:02
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    发表于 2012-11-2 17:33:00 | 显示全部楼层
    华北kingsky 发表于 2012-8-28 01:18
    嗯,支持~!这篇文章是我曾经参考过的文章之一,hoho~
    其实MIDI协议和MIDI文件本身并不复杂,但灵活运用 ...

    好深奥。。其实还是不清楚1和0格式的差别
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2016-11-20 17:44
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    发表于 2012-11-3 14:43:56 | 显示全部楼层
    为你弹琴 发表于 2012-11-2 17:33
    好深奥。。其实还是不清楚1和0格式的差别

          嗯嗯,参考偶画的这幅图:https://www.cndzq.com/bbs/thread-114440-1-1.html
          比喻嘛,就好像流媒体一样。0格式文件中所记录的所有事件,都是按照时间顺序,在一个MTrk中顺序排下去的,所以可以像流媒体一样顺序地读取并播放;而1格式文件中所记录的事件,都是分散到各个MTrk块中,所以得判断什么时候需要读取哪些信息,并且得跳跃着读取。
          我估计这就是为什么很多低端琴只能播放0格式文件的原因。0格式的这种顺序读取的方式,不需要太大的RAM空间作为缓冲区~而1格式文件需要将所有事件,在RAM中重新按照时间顺序排序之后,才能顺序播放,但低端琴的硬件不够强大,没有这么大的RAM,所以……
          当然对音序器软件来说,0和1文件都是可以被兼容的,反正所有的MIDI消息都是以各个通道为标记的,音序器只要按照通道号进行区分,将不同通道号的信息,显示到各个音轨中,就可以啦~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-11-16 09:02
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    发表于 2012-11-3 17:17:15 | 显示全部楼层
    华北kingsky 发表于 2012-11-3 14:43
    嗯嗯,参考偶画的这幅图:https://www.cndzq.com/bbs/thread-114440-1-1.html
          比喻嘛,就好像流媒 ...

    好的,我看看~~
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2012-11-29 22:48:20 | 显示全部楼层
    学习了,谢谢
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2012-12-3 13:48:37 | 显示全部楼层
    顶顶顶顶顶顶顶
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2012-12-23 11:07:06 | 显示全部楼层
    很好 很不错 谢谢分享赞一个赞一个
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2018-2-26 22:01
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    发表于 2013-6-26 14:28:45 | 显示全部楼层
    最近正在学习这个,拜读了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2013-7-23 04:20:59 | 显示全部楼层
    牛牛牛~~~很牛
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    新闻头条上一条 /3 下一条

    【重要通知】|申请友链|手机版|Archiver|中国电子琴信息网-中国电子琴在线论坛 ( 粤ICP备14036084号 )

    GMT+8, 2019-7-17 18:40 , Processed in 0.200395 second(s), 37 queries .

    Powered by Discuz! X3

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表