标准的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文件格式相关推荐

  1. 标准MIDI文件格式规范。 1.1(机翻)

    0-简介 本文档概述了MIDI文件的规范. MIDI文件的目的是提供一种在相同或不同计算机上的不同程序之间交换带时间戳的MIDI数据的方法.主要设计目标之一是紧凑表示,这使其非常适合基于磁盘的文件格式 ...

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

    动手点关注 干货不迷路 

  3. MIDI 文件格式 (转)

    MIDI 文件格式 (转)[@more@] MIDI 文件格式 MIDI 文件结构 Chunks MIDI 文件由 chunks 组成:XML:namespace prefix = o ns = &q ...

  4. MIDI文件格式分析(补充和勘误)

    MIDI文件格式分析(补充和勘误) 本文是对<MIDI文件格式分析>博客链接的一点补充: 原文复制 vim编辑二进制文件的方法 文中制作的midi文件内容和改动 原文复制 MIDI文件属于 ...

  5. MIDI 文件格式分析

    MIDI 文件属于二进制文件,这种文件一般都有如下基本结构: 文件头+数据描述 文件头一般包括文件的类型,因为 Midi 文件仅以.mid 为扩展名的就有 0 类和 1 类两种,而大家熟悉的位 图文件 ...

  6. MIDI文件格式解析

    乐器数字接口MIDI(Musical Instrument Digital Interface)是数字音乐国际的标准,定义了计算机音乐程序.合成器及其他电子设备交换信息和电子信号的方式,解决不同电子乐 ...

  7. 【BLE MIDI】MIDI 文件格式分析总结 ★★★

    文章目录 一.MIDI 文件简介 二.MIDI 文件头解析 1.MIDI 文件头标识 2.MIDI 文件头长度 3.MIDI 文件格式 4.MIDI 轨道个数 5.基本时间 三.MIDI 轨道分析 四 ...

  8. 【BLE MIDI】MIDI 文件格式分析 ( FF 58 04 拍号 | 音符开指令 | 音符关指令 | 音轨结束标志 )

    文章目录 前言 一.FF 58 04 拍号 二.音符开指令 三.音符关指令 四.音轨结束标志 前言 在博客 [BLE MIDI]MIDI 文件格式分析 ( MIDI 文件头解析 | MIDI 文件头标 ...

  9. 【BLE MIDI】MIDI 文件格式分析 ( FF 03 轨道名称 | FF 51 03 四分音符时长 )

    文章目录 前言 一.FF 03 轨道名称 二.FF 51 03 四分音符时长 前言 在博客 [BLE MIDI]MIDI 文件格式分析 ( MIDI 文件头解析 | MIDI 文件头标识 | MIDI ...

  10. 【BLE MIDI】MIDI 文件格式分析 ( MIDI 轨道分析 | MIDI 轨道头 | MIDI 轨道长度 | delta-time 间隔 )

    文章目录 前言 一.MIDI 轨道分析 二.MIDI 轨道头 三.MIDI 轨道长度 四.delta-time 间隔 前言 上一篇博客 [BLE MIDI]MIDI 文件格式分析 ( MIDI 文件头 ...

最新文章

  1. 帮我看看这个是什么意思 c++代码
  2. ruby简单的基本 6
  3. oracle number类型能存空吗_《听雪楼》《白发》成爆款类型剧的效仿者,古装剧真的能回暖吗?...
  4. jQuery-图片上传裁剪插件--imgAreaSelect(分析一) 放大缩小
  5. Redis的管道pipeline
  6. 虚拟仿真引擎消息机制
  7. 95-136-041-源码-Operator-AbstractStreamOperator
  8. 大数据、人工智能如何融合?来自微软、阿里、滴滴、科大讯飞等的 120 多位专家要用 3 天为你解答!
  9. 【每日一题】leetcode 二叉树层序遍历 - 介绍
  10. JS弹窗确认Ajax封装方法
  11. Glusterfs的安装及简单使用
  12. Springboot整合阿里云短信SDK发送短信验证码笔记
  13. 广州市车联网先导区建设总体技术规范
  14. 猿创征文 | 国产数据库之人大金仓数据库详解安装和使用
  15. iOS:iOS开发非常全的三方库、插件等等
  16. 由于计算机启动了配置文件,提示由于启动计算机时出现了页面文件配置问题解决方法...
  17. AI如何修改画布尺寸? ai怎么设置画布大小_AI教程自学网
  18. P5.js创意自画像编程
  19. Nacos @RefreshScope 配置不生效问题
  20. jmetter持续时间_【转】Jmeter做web压力测试时设置持续时间注意点

热门文章

  1. Kubernetes — 监控方案
  2. 羡慕别人表格做的快?6个Excel小技巧+25个Excel快捷键!收藏没错
  3. [转]外贸出口流程图
  4. 编译原理(紫龙书)第2版习题答案
  5. 对计算机的一些浅显的认识
  6. 实现折叠工具栏CollapsingToolbarLayout(折叠工具栏布局)
  7. 标签上title属性与alt属性的区别是什么
  8. 开三个iframe不断刷访问量
  9. 电感 电容耦合的判断
  10. 华为路由器NAT经典配置