我正在使用@LeffelMania库:https://github.com/LeffelMania/android-midi-lib
我是音乐家,但我总是录制成录音室录音,而不是MIDI,所以我不了解一些事情。
我想要理解的是这段代码:
// 2. Add events to the tracks
// Track 0 is the tempo map
TimeSignature ts = new TimeSignature();
ts.setTimeSignature(4, 4, TimeSignature.DEFAULT_METER, TimeSignature.DEFAULT_DIVISION);
Tempo tempo = new Tempo();
tempo.setBpm(228);
tempoTrack.insertEvent(ts);
tempoTrack.insertEvent(tempo);
// Track 1 will have some notes in it
final int NOTE_COUNT = 80;
for(int i = 0; i < NOTE_COUNT; i++)
{
int channel = 0;
int pitch = 1 + i;
int velocity = 100;
long tick = i * 480;
long duration = 120;
noteTrack.insertNote(channel, pitch, velocity, tick, duration);
}
好的,我每分钟有228次Beats,而且我知道我必须在上一张音符之后插入音符。我不明白的是持续时间..它是以毫秒为单位吗?如果我保持持续时间= 120并且我将BPM设置为60,则没有意义。我都不理解 velocity
我的目标
我想在Y持续时间内插入X音高的音符。
有人能给我一些线索吗?
答案 0 :(得分:3)
MIDI文件的设计方式,音符是音乐长度,而不是时间。因此,当您插入注释时,其持续时间是一些刻度,而不是秒数。默认情况下,每季度备注有480个刻度。因此,代码片段插入了80个十六分音符,因为每季度有四个十六分之一,而480/4 = 120.如果你改变速度,它们仍然是十六分音符,只是以不同的速度播放。
如果您想在钢琴上弹奏琴键,则速度参数是琴键敲击的速度。有效值为1到127.速度为0表示停止播放音符。通常,较高的速度意味着较大的音符,但实际上它可以控制MIDI乐器允许其控制的任何参数。
MIDI文件中的音符由两个事件组成:音符开和音符关。如果您查看insertNote
代码,您会看到它正在向轨道插入两个事件。第一个是时间tick
的Note On命令,具有指定的速度。第二个是时间tick + duration
的Note On命令,速度为0。
音高值也从0到127.如果您在Google上搜索&#34; MIDI音高数&#34;你会得到数十个点击,向你展示音高与音符和频率的关系。
MIDI文件here中有一个很好的时序描述。如果链接死亡,这里有一段摘录:
在标准的MIDI文件中,文件标题中有关于“每季度音符的刻度”,a.k.a。“每季度的部分”(或“PPQ”)的信息。出于本讨论的目的,我们将“beat”和“quarter note”视为同义词,因此您可以将“tick”视为节拍的一小部分。 PPQ在出现在文件开头的标题块的最后一个信息字(最后两个字节)中说明。 PPQ可以是较低的数字,例如24或96,这对于简单的音乐来说通常是足够的分辨率,或者对于更高的分辨率可以是更大的数字,例如480,或者如果更喜欢参考时间,甚至可以是500或1000的数字。以毫秒为单位。
PPQ在绝对时间方面的含义取决于指定的速度。默认情况下,时间签名为4/4,速度为每分钟120次。然而,这可以通过指定不同速度的“元事件”来改变。 (您可以在文件格式描述文档中阅读有关Set Tempo元事件消息的信息。)速度表示为24位数字,表示每四分音符的微秒数。这与我们通常表达速度的方式有所颠倒,但它有一些优点。因此,例如,100 bpm的速度将是每季度音符600000微秒,因此用于表达的MIDI元事件将是FF 51 03 09 27 C0(最后三个字节是600000的十六进制)。元事件之前会有一个增量时间,就像文件中的任何其他MIDI消息一样,所以速度的变化可以出现在音乐的任何地方。
Delta时间总是表示为可变长度的数量,其格式在文档中说明。例如,如果PPQ为480(大多数MIDI排序软件中的标准),则四分音符(720个标记)的增量时间将由两个字节82 D0(十六进制)表示。