Google
 Wap技术相关栏目
 相关文章

MIDI文件结构分析及生成方法


 日期:2005-9-22 15:48:00     [Host01.Com]   访问:     [全屏查看全文]

从网上找的,已经将用bc写的改成了vc的,由于对音乐的理解比乐盲还差,对于程序中转换是否有问题我也不得而知,反正用vc生成的midi文件听起来惨不忍睹。


 对于制作midi音乐来说,比播放midi文件本身更复杂得多。我们得了解一些乐理常识和midi文件结构。

一、midi文件结构分析   midi文件包含首部块(header chunk)和音轨块(track chunk)两部分。其格式一般如下:

  mthd <数据长度> <header数据> //首部块
  .......
  mtrk <数据长度> <track数据> //音轨块
  header chunk 结构为:
  char midiid[4];
  long length;
  int foarmt;
  int tracknum;
  int division;

其中:

  midiid称为midi文件头标志,一般将其设置为mthd;

  length为文件首部数据长度(除它本身和文件头标志占用的字节以外),通常它设置为6,即format,tracknum和division共占用的字节数据长度;

  format表示midi文件存放的格式,当前只有3种格式:

  0 表示midi文件只有一个track chunk;
  1 表示midi文件只有一个或多个track chunk;
  2 表示midi文件只有一个或多个各处独立的track chunk。
  division指定计数的方法,一种随时间计数(最高位设置为0时),另一种使用制式的时间码(最高位设置为1时)。这里,主要介绍随时间计数的一种格式。其各位意义如下:

  ┌─┬─────────┐
  │0 │ 每一拍的计数值 │
  └─┴─────────┘
  b15 b14  ̄ b0

  其最高位一定要设置为0,其它的15位表示每一拍的计数值。如该数据为96(以八分音符为一拍),则表示一个四分音符延时数应该为192。

  另外,在midi文件中,long和int型数据均将高字节值存放入低地址上,如一个long型数据为0x45678,则在文件中,存放的结果为:0x00,0x04,0x56,0x78。而在内存中,int,long的变量值通常将崐高字节值存放高地址上。因此,存放数据时,应该作一下调整。

  track chunk为用来播放歌曲的数据信息。每一个track chunk是一组简单的midi码(包括一些非midi码)的集合。它又由头部信息和崐若干个mtrk event组合而成。

  头部结构和意义为:

  char trackchunkid[4]; //track chunk标志mtrk
  long trackchunkmsglength; //该track chunk信息长度

  而mtrk event是由时间计数值(dela-time)和event(midi码信崐息)组合成的。即:

  <mtrk event>=<dela-time> <event>

  <dela-time>使用可变长度的形式存储数据,它代表处理event之前要计数时间值。 它在音乐中,即表示拍数。通常音乐开始演奏时,总是将计数时间值设置为0。为了能连续处理两个event,我们可以将deta-time设置为0。如:3和5同时演奏2拍(每一拍计数值为24),可以设置如下:

  deta-time event
  0 开始演奏3
  0 开始演奏5
  48 停止3演奏
  0 停止5演奏

  event表示midi码信息集,如0x9n表示开始发音,0x8n表示关闭发音等等(下有说明)。

  上述的dela-time使用可变长度的形式表示数据值。可变长度形崐式是midi文件中对于大于8位的数据打用的一种存储方式,它把每一个数据定义为7位,剩下的最高位作为数据长度的识别。当这一位为0时,表示数据是最后一个,若为1,则表示还有下一个。

  如:数值0x3fff,可变长度形式便为0xff,0x7f;0x4000则应该为0x81,0x80,0x00。此数据的转换可以参阅writelenghttobuf()函数。

二、常见midi码说明

  midi码是制定音乐交换的信息码,它使用串行非同步传送,因此数据码是用多码形式。第一个midi码是状态码,剩余的都是数据码,其长度视状态而定。

  以下是一些常见的midi码。

  1、开始发音(0x9n)

  格式为:0x9n note speed

  它一共占用3个字节,n表示通道号,取值0-15。midi可以同时演奏16个通道,用此指定在哪一个通道上发音(以下n相同)。

  note表示音高数值,即音阶码值。如c4(中音1)为60,它的取值在0xc和0x6c之间(具体码值,可参考「参考书籍1」)。

  speed表示按键时的速度,用此表示音的力度。若没有力度感,可以将其设置为64,若为0,表示关闭发音。

  如:在第2通道上开始演奏3,则midi码便为0x91,63,40。

  midi规范还规定,若连续向同一通道上发送多个音,则可以不指出状态码。如上述同时演奏3,5,midi码便为:0x91,63,40,65,40。

  2、关闭发音(0x8n)。

  格式:0x8n note speed

  说明同上。通常它用0x9n,note,0来代替。

  3、切换音色(0xcn)。

  格式:0xcn,program

  program表示音色代码,0 ̄255之间,如acou piano 1(电钢1值为0),synth bass 1(电贝司1值为64)等(详见「参考书籍1」)。

  4、设置音量大小

  格式:0xbn ,07,size

  0xbn,39,size

  7,表示设置主音量的高字节值;39表示设置主音量的低字节值。

[1] [2] [3] [4] [5]  下一页

上一篇:短消息服务(SMS)编程介绍  下一篇:EMS图片格式转换(Java)程序