c语言读取midi文件举例子,MIDI文件解析与实例分析

本文详细介绍了如何使用C语言读取和解析MIDI文件,包括MThd和MTrk块的内容,如轨道数量、基本时间格式、音轨名称、版权公告、速度设定、拍号标记和音轨事件等。通过对MIDI文件结构的分析,揭示了delta_time、通道和控制器在音乐数据中的重要性。

4d 54 68 64 // “MThd”

00 00 00 06 // 长度always 6,后面有6个字节的数据

00 01 // 0-单轨; 1-多轨,同步; 2-多轨,异步

00 02 // 轨道数,即为”MTrk”的个数

00 c0 // 基本时间格式,即一个四分音符的tick数,tick是MIDI中的最小时间单位

4d 54 72 6b // “MTrk”,全局轨为附加信息(如标题版权速度和系统码(Sysx)等)

00 00 00 3d // 长度

00 ff 03 // 音轨名称

05 // 长度

54 69 74 6c 65 // “Title”

00 ff 02 // 版权公告

0a // 长度

43 6f 6d 70 6f 73 65 72 20 3a // “Composer :”

00 ff 01 // 文字事件

09 // 长度

52 65 6d 61 72 6b 73 20 3a // “Remarks :”

00 ff 51 // 设定速度xx xx xx,以微秒(us)为单位,是四分音符的时值

03 // 长度

07 a1 20 // 四分音符为 500,000 us,即 0.5s

00 ff 58 // 拍号标记

04 // 长度

04 02 18 08 // nn dd cc bb 拍号表示为四个数字。nn和dd代表分子和分母。分母指的是2的dd次方,例如,2代表4,3代表8。cc代表一个四分音符应该占多少个MIDI时间单位,bb代表一个四分音符的时值等价于多少个32分音符。 因此,完整的 6 / 8拍号应该表示为 FF 58 04 06 03 24 08 。这是, 6 / 8拍号( 8等于2的三次方,因此,这里是06 03),四分音符是32个MIDI时间间隔(十六进制24即是32),四分音符等于8个三十二分音符。

00 ff 59 // 谱号信息

02 // 长度

00 00 // sf mf 。sf指明乐曲曲调中升号、降号的数目。例如,A大调在五线谱上注了三个升号,那么sf=03。又如,F大调,五线谱上写有一个降号,那么sf=81。也就是说,升号数目写成0x,降号数目写成8x 。mf指出曲调是大调还是小调。大调mf=00,小调mf=01。

00 ff 2f 00 // 音轨终止

4d 54 72 6b // “MTrk”,普通音轨

00 00 01 17 // 长度

00 ff 03 // 00: delta_time; ff 03:元事件,音轨名称

06 // 长度

43 20 48 61 72 70 // “C Harp”

00 b0 00 00 // 00:delta_time; bn:设置n通道控制器; xx:控制器编号; xx:控制器值。此处为设置0通道0号控制器值为0。

00 b0 20 00 // 此处为设置0通道32号控制器值为0。

00 c0 16   // 00:delta_time; cn:设置n通道音色; xx:音色值。此处为设置0通道音色值为22 Accordion 手风琴。

84 40 b0 65 00 // 此处为设置0通道101号控制器值为0。

00 b0 64 00 // 此处为设置0通道100号控制器值为0。

00 b0 06 18 // 此处为设置0通道6号控制器值为0。

00 b0 07 7e // 此处为设置0通道7号控制器(主音音量)值为126。

00 e0 00 40 // 00:delta_time; en:设置n通道音高; xx yy:各取低7bit组成14bit值。此处为设置0通道音高值为64。

00 b0 0a 40 // 此处为设置0通道7号控制器(主音音量)值为126。

00 90 43 40 // 00:delta_time; 9n:打开n通道发音; xx yy: 第一个数据是音符代号。有128个音,对MIDI设备,编

号为0至127个(其中中央C音符代号是60)。 第二个数据字节是速度,从0到127的一个值。这表明,用多少力量弹奏。 一个速度为零的开始发声信息被认为,事实上的一个停止发声的信息。此处为以64力度发出67音符。

81 10 80 43 40 // 81 10:delta_time; 8n:关闭n通道发音; xx yy: 第一个数据是音符代号。有128个音,对MIDI设备,编号为0至127个(其中中央C音符代号是60)。 第二个数据字节是速度,从0到127的一个值。这表明,用多少力量弹奏。 一个速度为零的开始发声信息被认为,事实上的一个停止发声的信息。此处为以64力度关闭67音符。

00 90 43 40

30 80 43 40

00 90 45 40

81 40 80 45 40

00 90 43 40

81 40 80 43 40

00 90 48 40

81 10 80 43 40 // 81 10:delta_time; 8n:关闭n通道发音; xx yy: 第一个数据是音符代号。有128个音,对MIDI设备,编号为0至127个(其中中央C音符代号是60)。 第二个数据字节是速度,从0到127的一个值。这表明,用多少力量弹奏。 一个速度为零的开始发声信息被认为,事实上的一个停止发声的信息。此处为以64力度关闭67音符。

00 90 43 40

30 80 43 40

00 90 45 40

81 40 80 45 40

00 90 43 40

81 40 80 43 40

00 90 48 40

81 10 80 43 40 // 81 10:delta_time; 8n:关闭n通道发音; xx yy: 第一个数据是音符代号。有128个音,对MIDI设备,编号为0至127个(其中中央C音符代号是60)。 第二个数据字节是速度,从0到127的一个值。这表明,用多少力量弹奏。 一个速度为零的开始发声信息被认为,事实上的一个停止发声的信息。此处为以64力度关闭67音符。

00 90 43 40

30 80 43 40

00 90 45 40

81 40 80 45 40

00 90 43 40

81 40 80 43 40

00 90 48 40

......

00 90 48 40

83 00 80 48 40

01 b0 7b 00 // 00:delta_time; bn:设置n通道控制器; xx:控制器编号; xx:控制器值。此处为设置0通道123号控制器(关闭所有音符)值为0。

00 b0 78 00 // 00:delta_time; bn:设置n通道控制器; xx:控制器编号; xx:控制器值。此处为设置0通道120号控制器(关闭所有声音)值为0。

00 ff 2f 00 // 音轨终止

好吧,和正常人看到0101010一样开始晕头转向了。而且貌似那些注释给我们的帮助也不大,但是仔细一看,注释里面“长度”这个词在注释中出现的频率很高。和其他二进制数据,比如TCP/IP协议中的数据头中描述数据包里的数据长度一样,“长度”就是用来描述以下xxx个字节都是某某某的数据。还有一个是“delta_time”,让我们考虑一下,在音乐中,哪个音符在什么时候出现,持续时间多长应该很重要吧,这个“delta_time”肯定就是关于音符或者其他特征的出现时间的相关参数了。后面将会仔细讨论“delta_time”这个字段。还有出现比较多的是“通道、控制器,通道xx、控制器编号”,说实话,这个我不是搞这一方面的,也不是很懂,唯一知道的是他们有对应的标识符和值。以上说的三个东东,将是构成midi文件的主要内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值