当前位置:   article > 正文

MIDI文件深入剖析_midi播放器工作原理

midi播放器工作原理

midi文件组成

本文分析midi文件的组成和工作原理。

midi文件中没有任何音频数据,它仅仅是记录了该使用什么乐器演奏,演奏乐器的节拍,演奏力度等等。而真正发出音频信号数据到扬声器的是音源文件。音源文件是预先录制好的一种乐器的声音,一种乐器用一个固定的编号来表示,称之为键值,演奏的轻重程度称为力度,一种乐器演奏的时长称为tick。

废话不多,下面开始分析midi文件组成。

头块信息

数据格式:

<标志符串>(4字节) + <头块数据区长度>(4字节) + <头块数据区>(6字节)

  • 标志符串"MThd" ,MThd是头块类型,用十六进制表示就是4d 54 68 64。

  • 头块数据区长度,指的是后面接着的头块数据区长度,因为长度是6字节,所以固定显示为00 00 00 06。

  • 头块数据区,共有6字节,分别为ff ff nn nn dd dd。

    ff ff 指定midi文件格式,一般有3种:

    1. 00 00 表示只含一个音轨
    2. 00 01 表示含有多个同步音轨
    3. 00 10 表示含有多个独立音轨

    nn nn 指定轨道数,一般都会大于1,因为除了演播主音轨外,还会有全局音轨。

    dd dd 指定基本时间格式。
    dd dd 的最高位为标记位。
    0为采用ticks计时,后面的数据为一个4分音符的ticks;
    1为SMPTE格式计时,后面的数值则是定义每秒中SMTPE帧的数量及每个SMTPE帧的tick。
    用我们举例的midi来看看,dd dd 的数据为01 E0,表示采用ticks计时,1E0转十进制为480,也就是每个4分音符,包含480ticks。后面事件时间都是以ticks为单位。

音轨块

音轨块的数据格式:

<标志符串>(4字节) + <音轨块数据区长度>(4字节) + <音轨块数据区>(多个MIDI事件构成)

在头块之后,剩余的部分是一个或者多个音轨块。每个音轨块的结构如上面所示,包含3部分。
第一部分是音轨块的标志符,用ASCII码字符串表示为"MTrk",用十六进制表示就是4d 54 72 6b。
第二部分是音轨块数据区,长度也为固定4字节,指定后面的数据区长度。
第三部分是音轨块的数据区,它是由多个midi事件构成,如下面所示:

  • MIDI事件的构成格式:

< delta time > + < MIDI 消息 >

事件大体上可以分为音符、控制器和系统信息这几个种类。对于这些事件,都有统一的表达结构:种类+参
数。
“delta time”单位是tick,用动态字节表示。
MIDI消息是由一个状态字节加多个数据字节构成,状态字节最高位一直是1,所以它的范围是128255之间。数据字节最高位一直是0,所以它的范围是0127之间。
消息可分为通道消息和系统消息。
下面是MIDI通道消息的构成:
通道消息是对单一的MIDI Channle起作用,Channle的表示使用状态字节的低4位(用X表示)表示,即0~F。

状态字节状态功能数据字节
8X松开音符1字节音符号,2字节力度
9X按下音符1字节音符号,2字节力度
AX触后音符1字节音符号,2字节力度
BX控制器变化1字节控制器号,2字节参数
CX改变乐器1字节:弯音轮变换值的低字节 / 2字节:弯音轮变换值的高字节
EX滑音(弯音轮)1字节音符号,2字节力度
F0系统码系统码字节数:动态字节系统码:不含开头的 F0,但包括结尾的 F7
  • 还有一种特殊的状态字节FF,表示非MIDI事件(Non- MIDI events),也叫meta-event(元事件)。
种类字节功能数据字节长度意义
00设置轨道音序02音序号
01文字事件文本信息
02版权版权信息
03歌曲名称全局音轨名称
04指定乐器乐器名称
05歌词歌词
06标记
07注释动作或事件
2F音轨结束标记00必须有结束标记

实例分析

以下是一个midi文件实例分析:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

midi播放原理

要想播放midi文件,首先在当前机器上要有音源文件。
PC机系统自带了一套音源文件,所以在PC机上用任何播放器都可以播放midi文件。
如果在嵌入式系统上播放midi文件,难度就大了点。嵌入式系统上播放midi,就好比是要制作一台电子琴,首先要把音源烧录到flash中,在没有文件系统的情况下,需要简析midi文件,再把midi文件以数组或其它形式的方法保存下来,供代码使用。

一个midi文件在单片机上的简析

一个单片机上使用的midi文件

 0x4D , 0x54 , 0x68 , 0x64 ,  // "MThd"
 0x00 , 0x00 , 0x00 , 0x06 ,  // 头块长度:不包括前4字节和本4字节
 0x00 , 0x01 ,                // 格式;1-多轨,同步
 0x00 , 0x03 ,                // 轨道数 = 3
 0x01 , 0xE0 ,                // 基本时间格式 0x01E0 = 480;
 
 0x4D , 0x54 , 0x72 , 0x6B ,  // "MTrk"
 0x00 , 0x00 , 0x00 , 0x15 ,  // 21 该规长度:不包括前4字节和本4字节
 0x00 ,                       // 时间差
 0xFF , 0x58 , 0x04 , 0x04 , 0x02 , 0x18 , 0x08 , // 其他功能、节拍、长度4、分子4、分母4、节拍器时钟24、一个四分音符包含的32分音符的个数8
 0x00 ,                       // 时间差
 0xFF , 0x51 , 0x03 , 0x0C , 0x35 , 0x00 , // 其他功能、速度、长度3:1个四分音符的微秒数800,000
 0x84 , 0xE7 , 0x00 ,         // 时间差:128^2*4+128*103+0 = 78720
 0xFF , 0x2F , 0x00 ,         // 音轨结束标志。

//======================================================================
 0x4D , 0x54 , 0x72 , 0x6B , // "MTrk"
 0x00 , 0x00 , 0x09 , 0xC9 , // 2505 该规长度:
 0x00 ,                      // 时间差
 0xFF , 0x03 , 0x07 ,        // 歌曲标题,音轨名称,长度7
 0x54 , 0x72 , 0x61 , 0x63 , 0x6B , 0x20 , 0x31 , // "Track 1"
 0x00 ,                      // 时间差
 0xFF , 0x04 , 0x1F ,        // 乐器名称,长度31,--"Microsoft GS Wavetable SW Synth"
 0x4D , 0x69 , 0x63 , 0x72 , 0x6F , 0x73 , 0x6F , 0x66 , 0x74 , 0x20 , 0x47 , 0x53 , 0x20 , 0x57, 0x61 , 0x76 , 
 0x65 , 0x74 , 0x61 , 0x62 , 0x6C , 0x65 , 0x20 , 0x53 , 0x57 , 0x20 , 0x53 , 0x79 , 0x6E , 0x74, 0x68 , 
 
 0x00 ,                     // 时间差
 0xB0 , 0x0A , 0x40 ,       // 调换控制,控制号10(声像控制器),(CAKEWALK默认值是64)新值64
 
 0x89 , 0x30 ,              // 时间差=128*9+48=1200us
 0x90 , 0x40 , 0x50 ,       // 音符打开,音符号64,速度80  (E5 : MI)
 
 0x81 , 0x58 ,              // 时间差=128*1+88=216us
 0x80 , 0x40 , 0x40 ,       // 音符关闭,音符号64,速度64  (E5 : MI)
 
 0x18 ,                     // 时间差=24us
 0x90 , 0x45 , 0x50 ,       // 音符打开,音符号69,速度80  (A5 : La)
 
 0x81 , 0x58 ,              // 时间差=128*1+88=216us
 0x80 , 0x45 , 0x40 ,       // 音符关闭,音符号69,速度64  (A5 : La)
 
 0x18 , 
 0x90 , 0x47 , 0x50 ,       // 音符打开,音符号71,速度80  (B5 : Si)
 
 0x81 , 0x58 ,              // 时间差=128*1+88=216us
 0x80 , 0x47 , 0x40 ,       // 音符关闭,音符号71,速度64  (B5 : Si)
 
 0x18 , 
 0xB0 , 0x40 , 0x7F ,       // 调换控制,控制号64(延音控制器),新值117
 
 0x00 ,                     // 时间差
 0x90 , 0x48 , 0x64 ,       // 音符打开,音符号72,速度100 (C6 : Do)
 
 0x00 ,                     // 时间差
 0x90 , 0x45 , 0x50 ,       // 音符打开,音符号69,速度80 (A5 : La)
 
 0x83 , 0x60 ,              // 时间差=128*3+96=480us
 0x80 , 0x48 , 0x40 ,       // 音符关闭,音符号72,速度64 (C6 : Do)
 
 0x00 ,                     // 时间差
 0x80 , 0x45 , 0x40 ,       // 音符关闭,音符号69,速度64  (A5 : La)
 
 0x00 ,                     // 时间差
 0x90 , 0x4A , 0x64 ,       // 音符打开,音符号74,速度100  (D6 : RE)
 
 0x81 , 0x70 ,              // 时间差=128*1+102=230us
 0x80 , 0x4A , 0x40 ,       // 音符关闭,音符号74,速度64  (D6 : RE)
 
 0x00 ,                     // 时间差
 0x90 , 0x4C , 0x64 ,       // 音符打开,音符号76,速度100  (E6 : MI)
 
 0x81 , 0x70 ,              // 时间差=128*1+102=230us
 0x80 , 0x4C , 0x40 ,       // 音符关闭,音符号76,速度100  (E6 : MI)
 
 0x00 ,  
 0xB0 , 0x40 , 0x7F ,       // 调换控制,控制号64(延音控制器),新值117
 
 0x00 , 
 0x90 , 0x4A , 0x64 ,       // 音符打开,音符号74,速度100  (D6 : RE)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/248429?site
推荐阅读
相关标签
  

闽ICP备14008679号