如何使用Javascript播放任意MIDI音符?

20

澄清一下:我不想生成MIDI文件,也不想播放MIDI文件,我希望可以即兴演奏MIDI音符。

我尝试使用https://github.com/mudcube/MIDI.js作为MIDI库,它有些效果。

我可以通过调用MIDI.noteOn(0, midiNumber, 100);来演奏音符。但是,这样的话音符会持续几秒钟然后逐渐消失,即使我从未调用MIDI.noteOff

我不认为这就是MIDI的预期工作方式,我希望可以调用noteOn并且音符会一直持续到调用noteOff。

目标浏览器:现代版Firefox/Chrome。

5个回答

10

你所使用的 MIDI.js 版本存在Bug:

var playChannel = function (id) {
    var note = notes[id];
    if (!note) return;
    var nid = (channel_nid + 1) % channels.length;
    var time = (new Date()).getTime();
    var audio = channels[nid];
    channel_map[note.id] = audio;
    audio.src = MIDI.Soundfont[note.id];
    audio.volume = volume;
    audio.play();
    channel_nid = nid;
};

正如您所看到的,playChannel 将加载给定的音符并播放它。由于没有自动循环属性,因此不会重复播放,因此不需要调用 noteOff 。如果将 audio 元素设置为自动循环,则可以自行解决此问题。


2
哇,发现了一个 Bug 真不错。+1,不过你想发起一个 pull request 吗? - user529758
@H2CO3:我目前不在我的电脑前,而且我还没有习惯github的界面(我更喜欢bitbucket)。然而,我相信一些应用程序会受到这个bug的影响而无法正常工作,因为它们没有使用noteOff(毕竟可能发生)。也许大约11小时后(21:00 UTC+1)会有结果。 - Zeta
啊,我在阅读代码时注意到了这个 bug,但不太确定修复方法。考虑到一些实现甚至没有在 noteOff() 中编写任何代码,这个 bug 可能是一个有意的设计缺陷。我同意你对修改代码以满足遗留目的的疑虑。你应该提交一个 fork 请求。现在我只会打补丁来尝试解决这个问题。 - Razor Storm
1
@RazorStorm:毕竟这只是一个假设。这个 bug 可能 就在这个函数里,但由于整个项目文档不是很完善,没有实际测试很难弄清楚(目前无法进行测试 :/)。 - Zeta

5

2
这是正确的行为。您需要一个更好的样本库来播放长音频。
请查看无尽声音的教堂管风琴示例
此示例使用WebAudioFont来播放1500多种乐器和鼓。该库支持ADSR、混响和循环点。

2
不同的乐器表现不同。钢琴有固有的“音符关闭”功能,但管风琴没有。
此外,noteOn和noteOff取决于实现方式。在HTML5实现中,modcu.be为每个音符播放OGG文件,并且根本不关心noteOff。当OGG结束时,声音停止。在这种情况下,autoloop对钢琴没有帮助。

1

搜索Web MIDI API的Google。 它还没有在所有浏览器中实现,但是GitHub上有Chris Wilson的polyfill。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接