MIDI.js音符持续时间不会改变

时间:2014-01-22 23:40:01

标签: javascript html jquery-ui audio midi

由于mudcube MIDI.js的文档在这方面似乎缺乏,我希望有人能够指出我正确的方向。说白了,使用midi.js,你如何调整midi音符的持续时间和结束?

对于某些背景,我创建了一个带有可拖动和可放置音符(jQuery-ui)的音乐人员小部件,可以添加或删除,以形成可以调用播放midi的序列。到目前为止,一切都有效,但是,当我试图用更复杂的时间扩展这个小部件的功能时,我遇到了一些问题。

似乎我只能在设定的时间内播放音符,并且尽管我付出了很多努力,却无法实现可能会改变此持续时间的更改,例如半音符,四分音符,八个音符等。此外,这可能是原因之一,MIDI.noteOff对输出没有可感知的影响。人们会认为给定音符将无限播放,直到调用MIDI.noteOff为止,然而,无论是否调用noteOff,所述音符都将播放然后逐渐关闭。

我在这里说,我已经对SO和网络进行了广泛的研究,以便深入研究。我发现有类似问题的人并应用他们的修复程序,但他们的答案对我不起作用。请参阅how do I play arbitrary notes in Midi with javascriptMIDI.noteOff does not seem to work reliably

我有一系列名为noteSequence的音符,其中每个音符都是具有noteValue(即'C4')和noteDuration属性的对象,这些属性在convertToMidiSequence函数中被转换为midiSequence。一切都适用于旋律序列和和弦,我只想添加持续时间功能。我还应该说调整'delay'变量或noteDuration属性只会增加序列播放前的时间。然后在初始延迟之后,序列以与之前相同的时序播放。

感谢您花些时间来看一下,希望能帮忙。非常感谢。

以下是运行我的MIDI的适用代码:

$(document).ready(function() {
  MIDI.loadPlugin({
    soundfontUrl: GLOBALS.SOUNDFONT_URL,
    instrument: 'acoustic_grand_piano',
    callback: function() {
      var channel = 0,
          instrument = 0,
          velocity = 127,
          delay = 1;
      MIDI.programChange(0, instrument);
    }
  });
});

function playCurrentSequence() {
  playSequence(noteSequence);
}

function playSequence(sequence) {
  var midiSequence = convertToMidiSequence(sequence);
  for (var i = 0; i < midiSequence.length; i++) {
    if (!(midiSequence[i] instanceof Array)) {
      playNote(midiSequence[i], i);
    }
    else {
      playChord(midiSequence[i], i);
    }
  }
}

function playNote(midiNote, notePositionInMeasure) {
  var channel = 0,
      velocity = 127,
      delay = 1;
  MIDI.noteOn(channel, midiNote, velocity, delay + notePositionInMeasure + 1);
  MIDI.noteOff(channel, midiNote,
    delay + midiNote.noteDuration + notePositionInMeasure + 1);
  MIDI.Player.stop();
}

function playChord(midiChord, notePositionInMeasure) {
  var channel = 0,
      velocity = 127,
      delay = 1;
  for (var i = 0; i < midiChord.length; i++) {
    MIDI.noteOn(channel, midiChord[i], velocity, delay + notePositionInMeasure + 1);
    MIDI.noteOff(channel, midiChord[i],
      delay + midiChord[i].noteDuration + notePositionInMeasure + 1);
    MIDI.Player.stop();
  }
}

1 个答案:

答案 0 :(得分:1)

值得指出MIDI NoteOff实际意味着什么 - 通常是因为之前收到NoteOn的音符进入其ADSR envelope的释放状态,并最终没有任何结果。直到一段时间后它才会释放频道。

现在在大多数打击乐声音的情况下,没有NoteOff本身的概念 - 在维持阶段的初始攻击之后它们只会衰减到什么(有点用词不当)。钢琴上的音符关闭应用了阻尼器,但此时声音可能已经消失。

其他声音可能是直接的样本触发器,没有NoteOff的概念。

因此行为不一致,并且很大程度上取决于您选择的语音。你确认NoteOffs对它有意义吗?