第一键盘 - 电子琴在线论坛

 找回密码
 现在注册

QQ登录

只需一步,快速开始

查看: 3683|回复: 10
打印 上一主题 下一主题

关于midi文件格式不能正确表达重叠音符的bug,求解

[复制链接]
跳转到指定楼层
1#
发表于 2015-12-25 16:07:49 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 chaoliu1 于 2015-12-25 16:16 编辑



上图虽是一张图,但内容是2个,此处就暂时称为图1图2吧。
现象一:在FL studio中验证
图1:用FL软件写3个音符,长度相同,开始时间不同(为看清,所以用PS画图时故意上下错位一点)。保存为midi文件
图2:用FL软件再次打开这个MIDI文件,发现3个音符的长度变了!仔细看又发现3个开始时间与图一相同,3个中止时间也与图一相同。

现象二:用C语言验证
根据midi格式技术文档编写程序,读取该midi文件,有关这3个音符的事件代码如下:
{
    "AbsTicks": 0,"DeltaTicks": 0,"Status": 144,"MsgType": "Channel",
    "Msg": [{"MidiChannel": 0,"Command": "NoteOn","Data1": 60,"Data2": 100}]
},
{
    "AbsTicks": 24,"DeltaTicks": 24,"Status": 144,"MsgType": "Channel",
    "Msg": [{"MidiChannel": 0,"Command": "NoteOn","Data1": 60,"Data2": 100}]
},
{
    "AbsTicks": 48,"DeltaTicks": 24,"Status": 144,"MsgType": "Channel",
    "Msg": [{"MidiChannel": 0,"Command": "NoteOn","Data1": 60,"Data2": 100}]
},
{
    "AbsTicks": 192,"DeltaTicks": 144,"Status": 128,"MsgType": "Channel",
    "Msg": [{"MidiChannel": 0,"Command": "NoteOff","Data1": 60,"Data2": 64}]
},
{
    "AbsTicks": 216,"DeltaTicks": 24,"Status": 128,"MsgType": "Channel",
    "Msg": [{"MidiChannel": 0,"Command": "NoteOff","Data1": 60,"Data2": 64}]
},
{
    "AbsTicks": 240,"DeltaTicks": 24,"Status": 128,"MsgType": "Channel",
    "Msg": [{"MidiChannel": 0,"Command": "NoteOff","Data1": 60,"Data2": 64}]
}

可以看出,3个noteOn的AbsoluteTicks分别是0、24、48,DeltaTicks与上一事件相对间隔分别为0,24,24
3个noteOff的AbsoluteTicks分别是192、216、240,DeltaTicks与上一事件相对间隔分别为144,24,24

这都很好理解,但由于note事件没有ID,当3个音符都开始发声之后,它们的参数完全相同(音高都是C5,Data1=60)
而发生第1个noteOff的时候(音高是C5),此时就不知道是哪个音符应该停止发声,反正FL软件是按图2来的,先让最近的一个C5停止发声,这算不算Bug呢?

疑问:
因为要编写一个音乐节奏游戏类似vos那样,所以这个问题就成了问题。我能说midi文件功能不全吗?
虽说为了节约几个字节便于设备传输,但几十年过去了,技术已经进步,完全没必要处处省略控制字符,50KB和100KB的midi在设备上差别很大吗,干嘛不制定midi2标准呢?




评分

参与人数 1金币 +200 收起 理由
华北kingsky + 200 好文章! 支持DIY与研发~!

查看全部评分

分享到: QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 支持支持1 反对反对
回复

使用道具 举报

2#
发表于 2015-12-25 16:22:11 | 只看该作者
你试过其他的音序器么?按理说不会出现这种问题的啊。
50KB和100KB的MIDI,有些硬件音源(如电子琴),MIDI体积越来就会读取有点卡。
回复 支持 反对

使用道具 举报

3#
 楼主| 发表于 2015-12-25 16:34:06 | 只看该作者
为你弹琴 发表于 2015-12-25 16:22
你试过其他的音序器么?按理说不会出现这种问题的啊。
50KB和100KB的MIDI,有些硬件音源(如电子琴),MID ...

是这样的,电脑上只装了个FL软件,所以暂时没在其它里面试验,但是在国内,用FL的绝对比cakewalk人数多(虽然一大部分都是小学生--因为初音未来的带动作用),FL目前应该和cakewalk齐名吧(所以FL软件按理说也不应该有这种错误),其它的cubase什么的没研究过,甚至有的要买苹果才能用(用不起)
50和100也是举了个例子,高手做的管弦乐应该有那么大,常见的都是50KB以下。

总之这个故障在编程时会影响到视觉上的音符绘制,在声音上遇到非乐器的音乐例如枪声时3个音符的长短会在听觉上能感觉出的。所以像中那样保存一次就变样恐怕不能视而不管
(再观望一阵,要是不行就只能下个其它软件试验看看)

一开始怀疑程序写得不对,现在开始怀疑midi文件了。

回复 支持 反对

使用道具 举报

4#
发表于 2015-12-25 16:50:17 | 只看该作者
      关于“按照先后顺序,分别演奏同一个音符”这种现象,在使用MIDI键盘演奏时,通常是不会出现的,因为一个按键一定是先抬起来才能再按下去。对于这种特殊的情况,MIDI事件里是区分不开先收到的NoteOff是用来关闭哪个音符的。而音源自己有一套规定,来处理这种情况。

      请看这张截图:


(此图出处:XG Specifications v2.00,YAMAHA公司于2001年4月发布的此标准的规格书,PDF第14页。规格书原件如下链接)
xg spec 2.00.pdf (1.22 MB, 下载次数: 17)

      红框里的文字,原文是:

      If a Key Off is received for a note and there are multiple instances of that note currently playing, the Key Off should preferably switch off the first received of these notes.

      大意是:

      如果音源收到了某个音符的Key Off,而且当时有多个此音符的声音在播放,那么Key Off将关闭这些音符当中,最先收到的那个音符的声音。



      下面回答您的两个问题:

      “因为要编写一个音乐节奏游戏类似vos那样,所以这个问题就成了问题。我能说midi文件功能不全吗?”

——确实,midi文件里的有些东西,不是那么特别地讲究和规矩。不光是这个问题,还有比如“控制器事件只能作用于一个通道,而无法作用于单个音符”,“midi文件并非全为类似流媒体的格式,解码麻烦”等等。不过这么多年了,这些问题都有相应的,变通的解决办法。

      比如您所疑问的Note On和Note Off不配套这个问题,这是个特例,本不该出现这个问题;如果为了某些特殊效果,而一定要使用这种方式的话,音源本身也是会有办法来处理。协议虽然老,但越老的东西反而越可靠~

      “虽说为了节约几个字节便于设备传输,但几十年过去了,技术已经进步,完全没必要处处省略控制字符,50KB和100KB的midi在设备上差别很大吗,干嘛不制定midi2标准呢?”

——嗯,还真有新的MIDI标准咧~这种新标准,称为“MIDI HD”。这个新标准是MMA(MIDI Manufacturers Association,MIDI厂商协会)大概在2008年的时候就着手在制定,但现在仍没有确定性的标准颁布出来。关于MIDI HD的介绍,可以参考这个网址(虽然是英文的):

      http://www.midi.org/aboutus/news/hd.php

      这个网站,www.midi.org,不要小瞧,这是MIDI协议的大本营,由MMA主办的网站。关于MIDI的所有事项,最源头都是从这里颁布出来的。

评分

参与人数 1金币 +220 收起 理由
skyerce + 220 给技术宅跪了!

查看全部评分

回复 支持 反对

使用道具 举报

5#
 楼主| 发表于 2015-12-25 16:55:33 使用第一键盘发送 | 只看该作者
好的非常感谢,学院派的解答果然严谨。
回复 支持 反对

使用道具 举报

6#
发表于 2015-12-25 17:00:39 | 只看该作者
本帖最后由 华北kingsky 于 2015-12-25 17:04 编辑
chaoliu1 发表于 2015-12-25 16:34
是这样的,电脑上只装了个FL软件,所以暂时没在其它里面试验,但是在国内,用FL的绝对比cakewalk人数多( ...

      对于您所说的,比如枪声的这个音色,您可以使用一些变通的方法,比如:

      不必等到这个音符的Note Off。一旦来了某个音符(枪声)的Note On,您的程序可以直接绘制动画。这段动画的结束时间,不一定非得等到Note Off,而是自己预先写好的一个时间。说白了,动画的时长与Note Off无关了。

      其实音源本来也是这么做的。有些音色具有绵长的声音,比如弦乐,术语讲叫“Release时间较长”,音源如果不收到Note Off,那么声音会一直响下去,所以音源一定要等到Note Off之后才关闭声音。但有些音色很短,比如鼓,颤音琴等等这类靠敲击而发声的乐器的声音,或者枪声这种很短促的声音,音源就完全不需要等到Note Off,而是达到声音所规定的发音时长之后,直接关掉。

      先写到这儿了。明天研究生入学考试,办公室要封楼。风紧,扯呼~

======

修改:打错字了,是“时长”不是“时常”……T_T
回复 支持 反对

使用道具 举报

7#
发表于 2015-12-25 20:28:05 | 只看该作者
一个键不能同时按下两次,当你第二次按键的时候,必然有一个key off,已经被发送了。电灯只有在被关掉的情况下才能打开。它们是串联的对子,所以根本不存在着我的这一次关灯是关哪一个开信号的问题。


回复 支持 反对

使用道具 举报

8#
发表于 2015-12-25 20:50:13 | 只看该作者
补充或者只有在打开的情况下才能进行关。
回复 支持 反对

使用道具 举报

9#
发表于 2015-12-25 21:39:53 | 只看该作者
chaoliu1 发表于 2015-12-25 16:34
是这样的,电脑上只装了个FL软件,所以暂时没在其它里面试验,但是在国内,用FL的绝对比cakewalk人数多( ...

作为FL的专业用户来讲,我要更正朋友的几个观点,首先FL在国外绝对不是小学生在用,都是专业的DJ,每年都会举行国际FL原创音乐制作大赛,规模与我们的音乐盛典无异。然后讲讲朋友的问题,话说朋友使用手工在输入MIDI,还是在用MIDI键盘呢?如果是再用MIDI键盘的话,华北版主的讲解是正确的。我在论坛主管这方面的软件开发,和软音源工程模板的制作:https://www.cndzq.com/bbs/thread-353217-1-1.html       同时开放了个人的一套FL编曲教程:https://www.cndzq.com/bbs/thread-349797-1-1.html
回复 支持 反对

使用道具 举报

10#
 楼主| 发表于 2015-12-25 22:17:07 | 只看该作者
好的,谢谢以上各位的解答
回复 支持 反对

使用道具 举报

11#
发表于 2015-12-25 22:29:08 | 只看该作者
够无聊的
重叠音符的话 直接把3个轨道选3个乐器就可以呗。。。非得写到一个轨道上FL也好 cubase也好 能用的轨道都不止16个 兼容midi而已
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 现在注册

本版积分规则

关闭

新闻头条上一条 /1 下一条

【重要通知】|申请友链|Archiver|手机版|第一键盘 - 电子琴信息网 - 电子琴在线论坛 ( 粤ICP备14036084号 )

GMT+8, 2024-4-28 11:18 , Processed in 0.141609 second(s), 36 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表