Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delay in noteOn() can be arbitrarily offset #168

Open
espadrine opened this issue Feb 21, 2016 · 2 comments
Open

Delay in noteOn() can be arbitrarily offset #168

espadrine opened this issue Feb 21, 2016 · 2 comments

Comments

@espadrine
Copy link

Even for something as simple as the basic example which plays a single note, we can notice the following by playing around in the JS console:

var wac = MIDI.getContext()
wac.currentTime  // 26.485333333333333
wac.currentTime  // 27.68

The WebAudioContext's currentTime is perpetually increasing, starting from a value of zero. So far so good.

However, the following line of code, present since the very beginning, will negatively impact the delay parameter of the noteOn() method:

/// convert relative delay to absolute delay
if (delay < ctx.currentTime) {
  delay += ctx.currentTime;
}

Consider the case where we play two notes, one with a delay of 2, the other with a delay of 4, with two calls to noteOn() at the same moment, when currentTime is 3. The first note will be played in 5 seconds (because of delay += ctx.currentTime), while the second will be played in 4 seconds (before the first)!

What is the point of modifying the delay? It is unclear to me what the difference between the relative delay and the absolute delay is, but the end result is that the following code gives results that are highly different from what I would assume it to do:

MIDI.noteOn(channel, note1, velocity, 2);
MIDI.noteOff(channel, note1, velocity, 4);
MIDI.noteOn(channel, note2, velocity, 4);
MIDI.noteOff(channel, note2, velocity, 6);

Could you help me understand and hopefully fix this issue in MIDI.js, be it a matter of documentation or a bug in the code?

@espadrine
Copy link
Author

It appears that this PR assumes that this is a bug.

@gagern
Copy link

gagern commented Jul 27, 2016

Seems I missed this issue when I filed #188. As I wrote there, it seems as if timing in WebAudio is sometimes absolute sometimes relative, as you pointed out here. Compared to that, AudioTag is always relative, and WebMIDI appears to be always absolute. What a mess! The longer I think about it, the more I believe that the correct fix would be to

  1. always use absolute time and
  2. provide a way to compute absolute time from current time and a relative offset, as I did in Provide MIDI.now() to allow computing timestamps relative to that #189.

In a sense this is talking the solution opposite to #150, by making things absolute by default instead of relative. The main point is that otherwise it's impossible to perfectly time notes, since while you are computing the method invocations you need, the ctx.currentTime will continue to increase so you don't have a common basis for all the notes you enqueue. If backwards compatibility is an issue, this could be made configurable. I guess I'll write yet another pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants