生成的 MIDI 音符长度
我创建了一些 JavaScript 代码,可以根据传递的音符和八度音程生成 MIDI 文件。在大多数情况下,它工作得相当好。问题是 C 音符(音符=0)比任何其他音符(1 (C#) 到 11 (B))演奏的时间要短得多。
这是我的代码:
function play(note, octave, program){
var note = (octave*12 + note).toString(16);
var velocity = 'ff';
var MIDI_DATA =
'MThd%00%00%00%06%00%01%00%01%00%C0' + // midi header
'MTrk%00%00%00%0E' + // track header
'%00%C0%'+program+
'%00%90%'+note+'%'+velocity+
'%70%30%00' +
'%00%FF%2F%00';
MIDI_DATA = btoa(unescape(MIDI_DATA));
var e = document.createElement('embed');
e.src = "data:audio/mid;base64,"+MIDI_DATA;
e.type = "video/quicktime";
document.body.appendChild(e);
return e;
}
为什么 C 音符 - play(0, 4, '18') 听起来比任何其他音符 - play(1, 4, '18') 短得多? 音高似乎是正确的,只是音符的演奏长度。
我认为这可能与 C 的值为 0 有关,但我对我在这里使用 midi 所做的事情了解不够,无法发现问题。
注意:此代码不适用于 IE(任何版本)。
I created some javascript code that generates midi files based on a passed note and octave. For the most part it works rather well. The problem is that the C note (note=0) plays much shorter than any other note (1 (C#) through 11 (B)).
Here is my code:
function play(note, octave, program){
var note = (octave*12 + note).toString(16);
var velocity = 'ff';
var MIDI_DATA =
'MThd%00%00%00%06%00%01%00%01%00%C0' + // midi header
'MTrk%00%00%00%0E' + // track header
'%00%C0%'+program+
'%00%90%'+note+'%'+velocity+
'%70%30%00' +
'%00%FF%2F%00';
MIDI_DATA = btoa(unescape(MIDI_DATA));
var e = document.createElement('embed');
e.src = "data:audio/mid;base64,"+MIDI_DATA;
e.type = "video/quicktime";
document.body.appendChild(e);
return e;
}
Why is a C note - play(0, 4, '18') sound so much shorter than any other - play(1, 4, '18')?
The pitch seems to be correct, just the note's play length.
I think it may have something to do with C being of value 0, but I don't know enough about what I'm doing here with midi to spot a problem.
NOTE: This code does not work in IE (any version).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果我没记错的话,MIDI 音符是通过给出 1 到 127 之间的音高和速度(即响度)来播放的,并通过给出相同的音高和速度 0 来停止。
If I remember correctly, MIDI notes are played by giving a pitch and a velocity (i.e., loudness) between 1 and 127, and stopped by giving the same pitch with a velocity of 0.
当注释值小于 16 时,您将得到无效的转义序列,即
%0
而不是%00
。unescape
函数不会将其转换为字符,而是保持不变。由于它是两个字符而不是一个,因此它会溢出到速度字节中,并且 MIDI 代码的其余部分会变得不同步。您可以使用这样的代码将数字格式化为两个十六进制数字:
使用它使注释值变为两位数字:
When the note value is less than 16, you will end up with an invalid escape sequence, i.e.
%0
instead of%00
. Theunescape
function will not turn that into a character, but leave it unchanged. As it is two characters instead of one, it spills over into the velocity byte and the rest of the MIDI code gets out of sync.You can use code like this to format a number into two hexadecimal digits:
Use it to make the note value two digits: