0-简介

本文档概述了MIDI文件的规范。 MIDI文件的目的是提供一种在相同或不同计算机上的不同程序之间交换带时间戳的MIDI数据的方法。主要设计目标之一是紧凑表示,这使其非常适合基于磁盘的文件格式,但可能不适合存储在内存中以供定序器程序快速访问。 (当读取或写入文件时,可以很容易地将其快速转换为快速访问的格式。)它不打算替代任何程序的常规文件格式,但是如果需要,可以将其用于此目的。

MIDI文件包含一个或多个MIDI流,以及每个事件的时间信息。支持歌曲,音序和音轨结构,速度和拍号信息。音轨名称和其他描述性信息可以与MIDI数据一起存储。这种格式支持多个轨道和多个序列,因此,如果支持多个轨道的程序的用户打算将文件移动到另一个轨道,则该格式可以允许这种情况发生。

该规范定义了文件中使用的8位二进制数据流。数据可以存储在一个二进制文件中,可以进行格式化,7位化以进行有效的MIDI传输,转换为十六进制ASCII或象征性地转换为可打印的文本文件。该规范解决了8位流中的问题。它没有解决如何通过MIDI传输MIDI文件的问题。一般的感觉是,将为一般文件开发MIDI传输协议,而MIDI文件将使用此方案。

1-序列,音轨,块:文件块结构

约定

在本文档中,位0表示字节的最低有效位,而位7则是最高有效位。

MIDI文件中的某些数字以一种称为“可变长度数量”的形式表示。这些数字表示为每个字节7位,最高有效位在前。除最后一个字节外,所有字节都设置了位7,最后一个字节的位7被清除。如果该数字在0到127之间,则它将精确地表示为一个字节。

以下是一些表示为可变长度数量的数字的示例:

允许的最大数字为0FFFFFFF,以便在例程中可变长度表示形式必须适合32位才能写入可变长度数字。从理论上讲,更大的数目是可能的,但是以每分钟500次的快节奏拍下2 x 10 ^ 8 96拍是四天,足以应付任何变化时间!

档案

对于任何文件系统,MIDI文件就是一系列8位字节。在Macintosh上,此字节流存储在文件(文件类型为“ MIDI”)的数据分支中,或存储在剪贴板中(数据类型为“ MIDI”)。大多数其他计算机在文件中存储8位字节流-这些计算机的命名或存储约定将根据需要进行定义。

数据块

MIDI文件由-chunks-组成。每个块具有4个字符的类型和32位长度,这是块中的字节数。这种结构允许设计将来的块类型,如果引入块类型之前编写的程序遇到这些块类型,可以很容易地忽略它们。您的程序应预期外来块,并将其视为不存在。

每个块均以4个字符的ASCII类型开头。它后面是32位长度,最高有效字节在前(长度为6的存储为00 00 00 06)。此长度是指随后的数据字节数:类型和长度的八个字节不包括在内。因此,长度为6的块实际上将在磁盘文件中占用14个字节。

这种块结构与电子艺界的IFF格式所使用的结构类似,而herin所描述的块可以轻松地放置在IFF文件中。 MIDI文件本身不是IFF文件:它不包含嵌套的块,并且块的长度不受限制为偶数个字节。将其转换为IFF文件就像填充奇数长度的块并将整个内容粘贴在FORM块中一样容易。

MIDI文件包含两种类型的块:标头块和轨道块。 -header-chunk提供有关整个MIDI文件的最少信息。 -track-块包含MIDI数据的顺序流,其中可能包含多达16个MIDI通道的信息。多个轨道,多个MIDI输出,样式,序列和歌曲的概念都可以使用几个轨道块来实现。

MIDI文件始终以标题块开头,然后是一个或多个音轨块。

MThd <length of header data>
       <header data>
       MTrk <length of track data>
       <track data>
       MTrk <length of track data>
      <track data>
      . . .

2-数据块描述

标题数据块

文件开头的标题块指定了有关文件中数据的一些基本信息。这是完整块的语法:<Header Chunk> = <chunk type><length><format><ntrks><division>

如上所述,<块类型>是四个ASCII字符“ MThd”; <length>是数字6的32位表示形式(高字节在前)。

数据段包含三个16位字,最高有效字节在前。

第一个单词<format>指定文件的整体组织。仅指定三个<format>值:0-该文件包含一个多通道音轨1-该文件包含一个或多个序列的同时轨道(或MIDI输出)2-该文件包含一个或多个顺序独立的单个-track模式下面提供了有关这些格式的更多信息。

下一个单词<ntrks>是文件中轨道块的数量。对于格式0文件,它将始终为1。第三个单词<division>指定增量时间的含义。它有两种格式,一种用于公制时间,另一种用于基于时间码的时间:

如果<division>的位15为零,则位14至0代表组成四分音符的增量时间“滴答声”的数量。例如,如果除法为96,则文件中两个事件之间的八分音符时间间隔将为48。

如果<division>的第15位为1,则文件中的增量时间对应于1秒的细分,其方式与SMPTE和MIDI时间代码一致。位14至8包含四个值-24,-25,-29或-30中的一个,对应于四个标准SMPTE和MIDI时间代码格式(-29对应于30个drop frome),并表示帧数每秒。这些负数以二进制补码形式存储。第二个字节(存储的正数)是一帧内的分辨率:典型值可以是4(MIDI时间码分辨率),8、10、80(位分辨率)或100。此流允许基于时间码的确切规范通过指定25 |帧/秒和每帧40个单位的分辨率,还允许基于毫秒的轨道。如果文件中的事件以30帧时间码的位分辨率存储,则分隔字将为E250(十六进制)。

格式0、1,和2

格式0文件具有一个标头块,后跟一个磁道块。它是最可互换的数据表示形式。它对于程序中的简单单轨播放器非常有用,该程序需要使合成器产生声音,但是主要与其他东西(例如混音器或音效盒)混为一谈。即使您的程序是基于轨道的,也能够产生这种格式是非常可取的,以便使用这些简单的程序。另一方面,也许有人会编写从格式1到格式0的格式转换,这在某些设置中可能非常容易使用,以免您将其放入程序中。

格式1或2的文件具有标题块,后跟一个或多个轨道块。支持多个同步轨道的程序应该能够以格式1(垂直一维形式,即作为轨道的集合)保存和读取数据。支持几种独立模式的程序应该能够以格式2(水平一维格式)保存和读取数据。提供这些最小的功能将确保最大的互换性。

在带有计算机和SMPTE同步器(使用乐曲指针和定时时钟)的MIDI系统中,通常会创建速度图(描述整个轨道上的速度,还可能包含时间签名信息,以便可以导出小节编号)。在电脑上面。要将它们与同步器一起使用,有必要从计算机上传输它们。为了使同步器易于从MIDI文件提取此数据,速度信息应始终存储在第一个MTrk块中。对于格式为0的文件,速度将散布在轨道中,并且速度图读取器应忽略中间的事件;对于格式1文件,速度映射必须存储为第一轨道。对速度图阅读器来说,礼貌地向您的用户提供仅使用速度即可制作格式0文件的能力,除非您可以使用格式1。

所有MIDI文件都应指定速度和拍号。如果没有,则拍号被假定为4/4,并且速度为每分钟120拍。在格式0中,这些元事件至少应发生在单个多通道轨道的开头。在格式1中,这些元事件应包含在i |中。第一首曲目。在格式2中,每个时间独立模式都应至少包含初始时间签名和速度信息。

我们可能会决定定义其他格式ID以支持其他结构。遇到未知格式ID的程序仍可以从文件中读取其他MTrk块(格式1或2),前提是该程序的用户可以理解它们并将它们安排为其他适当的结构。另外,将来可能会向MThd块中添加更多参数:即使长度大于6,读取并遵守该长度也很重要。

音轨数据块

音轨块(MTrk类型)是存储实际歌曲数据的位置。每个音轨块只是一个MIDI事件(和非MIDI事件)流,其前面是时间增量值。对于MIDI文件的所有三种格式(0、1和2:请参见上面的“标题块”),音轨块的格式(如下所述)完全相同。

这是MTrk块的语法(+表示“一个或多个”:必须存在至少一个MTrk事件):

<Track Chunk> = <chunk type><length><MTrk event>+

MTrk事件的语法非常简单:

<MTrk event> = <delta-time><event>

<delta-time>存储为可变长度量。它表示下一个事件之前的时间。如果轨道中的第一个事件发生在轨道的最开始,或者两个事件同时发生,则使用增量时间为零。增量时间始终存在。 (不存储0的增量时间需要任何其他值至少两个字节,并且大多数增量时间都不为零。)增量时间只是节拍的一小部分(或一秒钟,用于使用SMPTE记录音轨)时间),如标题块中所指定。

<event> = <MIDI event> | <sysex event> | <meta-event>

<MIDI事件>是任何MIDI通道消息。使用运行状态:如果前一个事件是具有相同状态的MIDI通道消息,则可以省略MIDI通道消息的状态字节。每个MTrk块中的第一个事件必须指定状态。增量时间不被视为事件本身:它是MTrk事件语法不可或缺的一部分。请注意,运行状态跨时间间隔发生。

<sysex event>用于指定MIDI系统独占消息,以一个单位或以数据包的形式,或以“转义”的形式指定要传输的任意字节。普通的完整系统专有消息以这种方式存储在MIDI文件中:

F0 <length> <bytes to be transmitted after F0>

长度存储为可变长度量。它指定了紧随其后的字节数,不包括F0或长度本身。例如,传输的消息F0 43 12 00 07 F7将存储在MIDI文件中,作为F0 05 43 12 00 07 F7。必须在末尾包含F7,以便MIDI文件的阅读器知道它已阅读了整个消息。

提供了另一种形式的sysex事件,它并不意味着应该发送F0。这可以用作“转义符”,以传输本来不合法的事物,包括系统实时消息,歌曲指针或选择,MIDI时间代码等。此代码使用F7代码:

F7 <length> <all bytes to be transmitted>

不幸的是,一些合成器制造商规定他们的系统专用消息将以小数据包的形式发送。每个数据包仅是整个语法系统专用消息的一部分,但是它们的传输时间很重要。例如,在CZ修补程序转储中发送的字节,或FB-01的“系统独占模式”,其中可以传输微调数据。 F0和F7 sysex事件可以一起使用,以将语法上完整的系统专用消息分解为定时数据包。

F0 sysex事件用于系列中的第一个数据包-这是一条消息,应在其中发送F0。 F7 sysex事件用于数据包的其余部分,而不以F0开头。 (当然,F7不被视为系统专用消息的一部分)。

即使实际设备没有发送F7,句法系统专用消息也必须始终以F7结尾,这样您就可以知道何时到达整个sysex消息的末尾,而无需提前等待F7的下一个事件。 MIDI文件。如果存储在一个完整的F0 sysex事件中,则最后一个字节必须为F7。多数据包系统专用消息的数据包之间也不得有任何可传输的MIDI事件。下面的段落说明了这一原理。

这是一个多数据包系统专用消息的MIDI文件:假设要发送字节F0 43 12 00,然后发送200-tick延迟,然后发送字节43 12 00 43 12 00,然后发送100-滴答延迟,后跟字节43 12 00 F7,这将在MIDI文件中:

当读取MIDI文件时,遇到F7 sysex事件而没有前面的F0 sysex事件来启动多数据包系统专用消息序列,则应该假定F7事件被用作“转义”。在这种情况下,除非希望发送F7,否则不必以F7结尾。

<meta-event>使用以下语法指定对这种格式或音序器有用的非MIDI信息:

FF <type> <length> <bytes>

所有元事件都以FF开头,然后具有事件类型字节(始终小于128),然后将数据的长度存储为可变长度数量,然后是数据本身。如果没有数据,则长度为0。与块一样,将来的元事件可能会被设计为现有程序可能不知道的元数据,因此程序必须正确忽略它们无法识别的元事件,并且确实应该期望看他们。程序永远不能忽略它们无法识别的元事件的长度,并且如果它比预期的要大的话,也不应感到惊讶。如果是这样,他们必须忽略他们所知道的一切。但是,他们一定不能在元事件的末尾添加自己的任何内容。 Sysex事件和元事件会取消所有有效的运行状态。运行状态不适用于这些消息,也不能用于这些消息。

标准MIDI文件格式规范。 1.1(机翻)相关推荐

  1. rfc4309规范原文和机翻——aead ccm

    rfc4309规范原文和机翻--aead ccm rfc4309规范原文:https://www.rfc-editor.org/rfc/rfc4309.html Network Working Gro ...

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

    动手点关注 干货不迷路 

  3. MIDI 文件格式 (转)

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

  4. 《深入理解计算机系统》实验四Architecture Lab下载和官方文档机翻

    前言 <深入理解计算机系统>官网:http://csapp.cs.cmu.edu/3e/labs.html 该篇文章是是实验四Architecture Lab中的Writeup(archl ...

  5. 【rfc6749】机翻 The OAuth 2.0 Authorization Framework

    本文禁止转载 原文地址  http://tools.ietf.org/html/rfc6749 下面内容全部是谷歌娘的翻译 = = ,写这个的目的是给自己留个备份,这样就不用每次打开谷歌娘了. --- ...

  6. 读后感与机翻《人类因果学习的分解:自下而上的联想学习和自上而下的图式推理》

    研究朱松纯FPICU体系的第 2 篇文章 <Decomposing Human Causal Learning: Bottom-up Associative Learning and Top-d ...

  7. [io_uring][自用] io_uring.pdf DeepL机翻

    [io_uring] [自用笔记] io_uring.pdf DeepL机翻 This article is intended to serve as an introduction to the n ...

  8. MySQL 5.7 服务端 错误码 (机翻)

    官方文档:https://dev.mysql.com/doc/mysql-errors/5.7/en/server-error-reference.html MySQL服务器将一些错误消息写入其错误日 ...

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

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

最新文章

  1. linux终端中运行网银盾,Linux下使用Virtualbox安装 Windows 7 操作网银攻略
  2. POJ 2749 Building roads 2-sat+二分答案
  3. C#几种常用的排序算法
  4. 软工作业2:硬币游戏——代码的分析与改进
  5. learn Linux sed command
  6. Asp.Net生命周期系列一
  7. python连接数据库设置编码_Python学习18-连接数据库
  8. PGer看过来!亚洲最大的PG技术盛会重磅来袭!墨天轮全球同步直播!
  9. 工业基础类IFC—总体架构和空间结构
  10. 吴国平:开发旅游小镇是一款养成类游戏 | 十年二十人
  11. 从零开始编写minecraft光影包(3)基础泛光绘制
  12. 电子书寻找方法汇总2
  13. HeadPose Estimation头部姿态估计头部朝向(Android)
  14. 为什么需要WhatsApp多账号批量管理,使用SendWS做WhatsApp账号多开,云控批量管理的功能介绍
  15. 【NOI2006】 生日快乐
  16. Windows下字符串替换操作java.lang.IllegalArgumentException: character to be escaped is missing
  17. SSM配置redis
  18. Mongodb从配置到应用
  19. 麦轮全向移动平台参数校准
  20. layui之ajax巨坑

热门文章

  1. 赋能聚变:大连软件产业20年发展论坛成功举办
  2. 新浪微博客户端的开发
  3. 分布式服务管理框架-Zookeeper客户端zkCli.sh使用详解
  4. 杰理之调节数字音量不起作用以及调节数字音量影响混响效果的解决办法【篇】
  5. 安静的程序,淘气的程序和编写程序
  6. 2016年底江浙沪绕行游记
  7. OA系统:实现添加岗位
  8. cordova添加android平台时选择安装版本
  9. source map 文件还原
  10. android treble项目HIDL学习总结