LMMS / LMMS/lmms

MIDI Output: Events for NoteOn/NoteOff sent out in wrong order

Open
#4,437 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug core
Dominant language
C++
Stars
10.4k
Forks
1.3k
Avg merge
2d 13h
Merged PRs (30d)
7

Description

I noticed that NoteOff/NoteOff-Events are sent in the wrong order. This is an issue if a note with the same MIDI-Note-Number is played multiple times without a gap (e.g. a D3 1/2-note is played 2 times within a bar).

In that case you'll see the following Midi Events:
TIME: 0 -- NoteOn: C4, Velocity: 64
TIME: 2 -- NoteOn: C4, Velocity: 64
TIME: 2 -- NoteOff: C4
TIME: 4 -- NoteOff: C4

This is like the keyboards key for C4 is pressed, and then pressed again (after a half bar), without being actually released and then released immediately and again released (after another half bar).
This can cause issues on some MIDI devices (1st note can be "hanging" in a bad implementation) and the second note is actually stopped immediately, when it is started, and then stopped again, when it actually should be.

This instead it should be:
TIME: 0 -- NoteOn: C4, Velocity: 64
TIME: 2 -- NoteOff: C4
TIME: 2 -- NoteOn: C4, Velocity: 64
TIME: 4 -- NoteOff: C4

The issue is, that LMMS has NoteOn/NoteOff events for the same Note and sends them That means: LMMS should look for NoteOff-Events first, send them... and then look for NoteOn-Events and send them afterwards. If there is any sorted event queuing mechanism implemented, either the sorting criteria should be adapted (1st prio: timestamp, 2nd prio: NoteOff -> NoteOn) -- or there should be two seperated queues for NoteOff and NoteOn events which are then processed in correct order.

This happens with LMMS 1.1.3 and LMMS 1.20-rc6 when using the tool LoopBe1 (might also be causing the issue, but I've no way to find out right now) and SuperCollider's MidiClient, which works fine with a usual MIDI-Keyboard as input, but not with LMMS sending its data via LoopBe1 to it.

SuperCollider-Code for reproduction:

MIDIClient.init;
MIDIIn.connectAll();

MIDIdef.noteOn(\noteOn, {
arg vel, nn, chan, src;
"NoteOn: ".post;
nn.postln;
});

MIDIdef.noteOff(\noteOff, {
arg vel, nn, chan, src;
"NoteOff: ".post;
nn.postln;
});

EDIT: When I use "MuseScore" as the Midi Source and "LoopBe1" as internal Midi-Routing, the NoteOn/NoteOff-Order is as expected. So "LoopBe1" should not be the problem. However, there could be still a timing issue... I assume LMMS is sending the events in the wrong order. Maybe there is a way to produce some debug output for each NoteOn/NoteOff-Event sent and check this.

EDIT#2: To reproduce the issue, you can download/install "LoopBe1". In LMMS setup one track (e.g. the TripleOscillator from the standard template) to use "LoopBe1" as it's MIDI-Input. And then add another track that is setup to output MIDI to "LoopBe1". In this second track add two halfnotes (e.g. 2 times C4), where the second halfnote starts when the other ends. Play the pattern... you'll hear the first note on both instruments, but the second one isn't played only on one of them (with the MIDI output configured). Then move the second note event slightly to the right (or reduce the length of the first one): Then both notes can be heard on both instruments.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue using LMMS, LoopBe1, and the SuperCollider MIDI listeners described in the report, then trace the MIDI output event queue. Check whether events with the same timestamp are processed in NoteOn-before-NoteOff order. Done means adjacent same-note events produce NoteOff before NoteOn at equal times and both notes play correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
audio-video-rtc, desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.