djipco / webmidi

Tame the Web MIDI API. Send and receive MIDI messages with ease. Control instruments with user-friendly functions (playNote, sendPitchBend, etc.). React to MIDI input with simple event listeners (noteon, pitchbend, controlchange, etc.).
Apache License 2.0
1.52k stars 115 forks source link

sendPitchBend() causes MIDI feedback in LoopBe1 #10

Closed kristianpedersen closed 7 years ago

kristianpedersen commented 7 years ago

Background info

Setup:

I'm sending a constant stream of MIDI messages from a trigger() function which runs continuously.

sendControlChange() works, but sendPitchBend() causes LoopBe1 to be muted due to MIDI feedback.

I'm running them separately, and there's no other MIDI being output.

Code examples

This code successfully changes my software synth's modwheel:

function trigger() {
    i++
    output.sendControlChange(1, i%127, 1)
}

When I try to do a similar thing with pitchbend, LoopBe1 shuts down after a second or so.

function trigger() {
    i+=0.01
    output.sendPitchBend(i%1)
}

The weird thing is, with vvvv I can send random pitchbend values to LoopBe1 at ~115fps, with no problems at all.

Test code

Pitchbend MIDI feedback starts occuring at around 50ms on my machine. sendControlChange() works fine at any speed, even 1.

The code below produces feedback, but works fine if setInterval() is set to 60 or higher:

WebMidi.enable(function(err) {
    output = WebMidi.outputs[0]
    setInterval(() => {
        i += 0.1
        output.sendPitchBend(i % 1)
    }, 50)
});

(To unmute LoopBe1 again, right-click the tray icon.)

djipco commented 7 years ago

Unless there is some clearer evidence, I do not see how this could be an issue with WebMidi.js. Unless a device is configured to do so, what comes through the IN port is not spit out the OUT port. This is from LoopBe1's home page:

Think of an application opening in- and outport of LoopBe1 and connecting both ports via MIDI through: you would get an infinite loop of MIDI data, circling in realtime, which would seriously slow down the whole computer. As modern MIDI applications may open several ports, this happens all too easily.

Unfortunately, I do not have a PC on hand to test your setup. Can you do a test with a simple setup to try an isolate the source of the problem?

By the way, you are aware that output.sendPitchBend(i % 1) sends the message to all 16 channels, right? It might be wiser, performance-wise, to specify a single channel to send to (by using the second parameter).

Regarding the performance, I ran the following code on my machine:

WebMidi.enable(function() {

  var i = 0,
      total = 0,
      duration = 10;

  console.log("Results in " + duration + " seconds...");

  var interval = setInterval(function(){
    i += 0.1;
    WebMidi.outputs[1].sendPitchBend(i % 1, 1);
    total++;
  }, 0);

  setTimeout(function() {
    clearInterval(interval);
    console.log("Average: " + total/duration + " messages/sec.");
  }, 1000 * duration);

});

Basically, it sends pitchbend messages as fast as possible (interval of 0). On my Macbook, I steadily get about 250 messages/seconds.

kristianpedersen commented 7 years ago

Specifying one channel in sendPitchBend() worked. Thanks!