Note overlap
Thank you for this great library. I am developing a rhythm sequencer. If for instance, I have a kick sound lasting for 600ms, and I have two consecutive pulses of this kick separated by 500ms, I can’t achieve to play the two pulses during their original length, or without cutting their duration manually or inherited from duration
.
- Can those two pulses overlay on the same channel?
- If not, what would be a solution to get something like this:
Kick [ms
Kick Kick |--------------- |---------------
In conclusion: can midi notes overlay?
Comments
Unfortunately for you, as far as I know, this is the normal MIDI behaviour. You cannot have the same note on the same channel playing twice at the same time.
In situations like this, people have been using another channel for the second note. This is not the most convenient thing but it does the trick.
Thank you very much for your answer Jean-Philippe. Currently, I suspect my notes to be ignored because the previous one’s duration isn’t over. Considering that, what would you recommand to allow all my notes to play? Should I, for instance add a stopNote() before all playnote()?
Usually, the new note shuts down the old one. That is, there is an implicit noteoff before a noteon. This is the device's doing. You can try calling
stopNote()
but I do not think it will change anything.Fine. One more last question, I don’t find how to control volume with the library. The W3C spec is also very quiet about volume control with webmidi. Did I miss something?
Device-wide master volume control can be achieved by sending a "Universal Real Time System Exclusive message". The code to do this in v2.5.x would look something like this:
WebMidi.js does not really offer any help when it comes to system exclusive message. This is something that's on my todo list. This is the actual syntax of that message:
You can also send a control change message to whichever channel you want to assign the volume for. For example, here is how you can set the volume of channel 1 to 54:
Hope this helps!
I come back to this discussion because I have related questions you may be able to help me with.
I hope my questions are intelligible, thank you in advance for your answers.
If I understand correctly, playNote() without duration will only send a note on, and notes can’t overlap, so a note off will be automatically sent at the next note on. Is that right?
The
playNote()
method only sends a note on message if no duration is specified. If you send another note on for the same note, the device will stop the previously playing sound and start to play the new one. In this case, no note off message is ever sent.If the assumption 1. is right, is it possible to know if a note is still playing (no note off triggered yet) at any moment ?
Currently, this is not possible. However, it is on my todo lit for v3 which I will start working on heavily in the next few weeks.
Let’s say I want to stop a note at 50% of this original duration. Can I do that? Or am I forced to use an arbitrary duration because original note durations is something the library can’t retrieve?
Hmm... that's a very interesting question. If I understand you correctly, the scenario is that you use
playNote()
with a duration but want to stop note playback before the duration has expired. This is a tricky scenario. You could callstopNote()
early. This would stop the note but would not prevent the note off to be sent at the end of the duration. You would be better off simply playing the note without duration and stopping it when you need.I hope this is clear...
If I understand you correctly, the scenario is that you use
playNote()
with a duration but want to stop note playback before the duration has expired. This is a tricky scenario. You could callstopNote()
early. This would stop the note but would not prevent the note off to be sent at the end of the duration. You would be better off simply playing the note without duration and stopping it when you need.No for now I don’t have any duration attached to
playnote()
because I want it to last the longer it can. Ideally I would need a variable duration depending on my original instrument’s duration. Some extra details for you to understand:Here is my code right now
The issue with the code above is that
interval
is currently the duration of my beat (depending of course of my bpm), so if the bell note’s duration is longer than one beat duration, it will be cut anyway after a beat time.The following video demo shows how a positive border radius will trigger the duration cut at minimum the length of a beat.
Can't you simply use
setTimeout()
to triggerstopNote()
in the future depending on whatever criteria you need?