20

To clarify: I don't want to generate a MIDI file nor do I want to play a MIDI file, I wish to play MIDI notes on the fly.

I tried using https://github.com/mudcube/MIDI.js as the MIDI library, and it works somewhat.

I am able to play notes by calling MIDI.noteOn(0,midiNumber,100);. However, this plays a note for a couple seconds and then tapers off even if I never call MIDI.noteOff.

I don't believe this is how MIDI is intended to work. I wish to be able to call noteOn and have a note play and sustain until noteOff is called.

Intended browsers: modern firefox/chrome.

Razor Storm
  • 12,167
  • 20
  • 88
  • 148

5 Answers5

10

It's a bug your version of MIDI.js:

var playChannel = function (id) {
    var note = notes[id];
    if (!note) return;
    var nid = (channel_nid + 1) % channels.length;
    var time = (new Date()).getTime();
    var audio = channels[nid];
    channel_map[note.id] = audio;
    audio.src = MIDI.Soundfont[note.id];
    audio.volume = volume;
    audio.play();
    channel_nid = nid;
};

As you can see playChannel will load a given note and play it. Since there is no autoloop attribute it won't repeat, so the call of noteOff isn't necessary. You could fix this yourself if you set the audio element to auto-loop.

Zeta
  • 103,620
  • 13
  • 194
  • 236
  • 2
    Wow. Nice to have spotted a bug. +1, though don't you want to make a pull request? –  Jan 13 '13 at 08:36
  • @H2CO3: I'm currently not at my PC and I'm still not used to the github interface (I prefer bitbucket). However, I believe some applications use this bug and would stop to work, as they didn't use `noteOff` (could be possible after all). Maybe in ~11h (21:00 UTC+1). – Zeta Jan 13 '13 at 08:46
  • Ah, I noticed this bug while reading the code but wasn't too sure what the fix was. Seeing as some of the implementations don't even have any code in noteOff() this bug might actually be an intended design flaw. I agree with your qualms against modifying the code for legacy purposes. You should make a fork request instead. For now I'll just monkey patch this and see if it works. – Razor Storm Jan 13 '13 at 10:19
  • 1
    @RazorStorm: After all it is just an assumption. The bug _could_ be in this very function, however, since the whole project isn't very well documentated it is hard to get it right without actually testing it (can't do that at the moment :/). – Zeta Jan 13 '13 at 10:21
5

Alternatively, http://mohayonao.github.io/timbre.js/ provides various sound generators for which noteOn and noteOff can be called.

Tirno
  • 1,568
  • 2
  • 16
  • 21
2

Different instruments behave differently. A piano has an "intrinsic" note off, but an organ doesn't.

Also, noteOn and noteOff depend on the implementation. modcu.be in the HTML5 implementation plays a OGG file for each note, and it doesn't care of noteOff at all. When the OGG ends, the sound stops. And autoloop wouldn't help for a piano in this case.

dmcontador
  • 660
  • 1
  • 8
  • 18
2

This is right behavour. You need a better samples library to play long sounds.

See church organ example of endless sound.

this exanple uses WebAudioFont to play more then 1500 instruments and drums. This lib supports ADSR, reverberation and loop points.

user1024
  • 1,121
  • 1
  • 9
  • 17
1

Google for Web MIDI API. It is not implemented in all browsers yet, but there is a polyfill by Chris Wilson at GitHub.