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

MIDI.noteOff does not seem to work reliably. #11

Closed
0xfe opened this issue Jan 22, 2013 · 6 comments
Closed

MIDI.noteOff does not seem to work reliably. #11

0xfe opened this issue Jan 22, 2013 · 6 comments

Comments

@0xfe
Copy link
Contributor

0xfe commented Jan 22, 2013

It seems that, on Chrome, noteOff leaves the note off forever. (I'm not sure about other browsers.)

This is what my code does on every note play:

duration = note.getTicks().value() / (@tpm/60);
MIDI.noteOn(0, midi_note, 127, 0);
MIDI.noteOff(0, midi_note, duration);

duration is usually a value between 0 and 2, midi_note is a valid note value. The noteOn part works fine -- the noteOff switches off notes, but future noteOn calls to the same note don't work.

@mudcube
Copy link
Owner

mudcube commented Jan 22, 2013

Weird, I cannot reproduce. Is this happening on the MIDIPlayer demo for you?

@Miranet
Copy link

Miranet commented Jan 23, 2013

Just an idea, and maybe also a cure for the problem mentioned above:

The code "as is" did not work for me when I tried to play notes in real time, to get the right delay for noteOff commands I had to make the following fix where the ramp time is defined with ctx.currentTime:

root.noteOff = function (channel, note, delay) {
delay = delay || 0;
if (delay < ctx.currentTime) delay += ctx.currentTime;
var source = sources[channel + "" + note];
if (!source) return;
source.gain.linearRampToValueAtTime(1, delay);
source.gain.linearRampToValueAtTime(0, delay + 0.2);
source.noteOff(delay + 0.3);
return source;
};

The problem was that after the script has been initialized.at time point x, and the delay time for noteOff occurs in the past when depressing a button to stop playing a note with the the normal script. The above fix takes notice of the currentTime to stop the note from playing at the time I want it it to stop.

midi files still play back nicely here as expected, and playing in real time will now work just as expected.

Just an idea: the values of 0.2 and 0.3 could ofcourse be used as "release" parameter for ADSR like time settings.

Maybe we could also catch and flag the use of damper info (controller 60 or 40h I believe) in the midi file to disable source.noteOff to get very much better playback of piano and other mid's I suppose?

@0xfe
Copy link
Contributor Author

0xfe commented Jan 23, 2013

@Miranet, I think you've got it. Let me patch in your fix and try.

@0xfe
Copy link
Contributor Author

0xfe commented Jan 23, 2013

@mudcube This not for the MIDIPlayer demo. I discovered this when trying to use brass (or other long sustaining) instruments in my VexFlow integration. (I didn't need to bother with noteOff for pianos or clean guitars.)

If @Miranet's patch doesn't work, I'll try to provide a short script to reproduce the bug.

@0xfe
Copy link
Contributor Author

0xfe commented Jan 25, 2013

Excellent. Everything works as expected with @Miranet's patch. @mudcube perhaps you can patch this into head?

mudcube added a commit that referenced this issue Jan 25, 2013
@mudcube
Copy link
Owner

mudcube commented Jan 25, 2013

@Miranet, thanks for the fix! It's been added into the latest master branch.

@mudcube mudcube closed this as completed Jan 25, 2013
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

3 participants