1

我正在构建一个实验性的 Web MIDI 应用程序,它以图形方式向浏览器显示您在外部 MIDI 键盘上演奏的音符。我遇到了一个奇怪的错误,其中以下回调仅在我将其记录到控制台时才有效:

// ============================================================================
// Web MIDI API
// ============================================================================
var MIDI = null;

$(document ).ready(function(){

  function onMIDISuccess( midiAccess )
  {
    MIDI = midiAccess;

    // Start listening to the MIDI ports!
    var selected_input = MIDI.inputs()[0];
    console.log( selected_input );
    selected_input.onmidimessage = function( event )
    {
      if( event.data[0] == 144 )
      {
        // Zero velocity means note OFF
        if( event.data[2] == 0 )
          $("pianokey[note="+event.data[1]+"]" ).removeClass("active");

        // Non-zero velocity means note ON
        else
          $("pianokey[note="+event.data[1]+"]" ).addClass("active");
      }
    };
  }

  function onMIDIFailure( error )
  {
    console.error( "MIDI Failed! Error: ", error );
  }

  navigator.requestMIDIAccess().then( onMIDISuccess, onMIDIFailure );

});

我发现我的代码有效,但仅在console.log( selected_input );包含该行时才有效。

运行我的小提琴最容易理解我的意思:http: //jsfiddle.net/8sSMe/1/

如果您插入了外部 MIDI 键盘,您应该会看到按键在屏幕上亮起,模仿您在键盘上弹奏的内容。请记住,您可能需要重新启动 chrome 才能拾取键盘,并且您可能需要从数组中为selected_input. 您可能还需要通过转到 chrome://flags/#enable-web-midi 在您的 chrome 中打开 Web MIDI(我也只对让它在 Chrome 上工作感兴趣)。一旦您看到它正在工作,请在console.log( selected_input );注释掉的情况下尝试它,它会奇怪地停止工作。

有任何想法吗?

4

2 回答 2

1

我发现了问题...

范围/垃圾收集

我的参考var selected_input = MIDI.outputs()[0];发生在一个消失的范围内。因此,当它消失时,回调响应机制也会随之消失。将对它的引用保持在全局范围内可以解决问题。不知何故,console.log()也许正在改变范围。

所以有一个解决方案,但我的理论只是一个可行的解决方案,我很乐意欢迎任何有更多专业知识的人可以证实我的理论。我不知道如何测试变量是否正在被垃圾收集......?

唉,Javascript 语言的挑战……

于 2014-07-11T21:23:10.070 回答
0

这段代码也发生了一些奇怪的事情:当我 console.log(MIDI)navigator...它说 MIDI 为空之后立即这样做时。但是当我在页面加载后立即在控制台输入中调用 MIDI 时,我可以检索到一个非空的 MIDI 对象。

异步调用?

于 2014-11-28T17:42:58.863 回答