summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeikki Tauriainen <g034737@welho.com>2016-06-26 17:47:03 +0300
committerJames Lowe <pkx166h@gmail.com>2016-07-11 06:02:35 +0100
commite7121831390ef4b0d09c1d509e1ccb0de2ea36a8 (patch)
tree291ce1444fbf07ae5c24954d7ebde206d77d20ea
parent0f3898aade7077c15adb2b457e6a5e1238939085 (diff)
Issue 4907: Midi_walker::do_start_note: skip ignored notes in stop_note_queue
For each semitone pitch value, stop_note_queue is likely supposed to contain at most one Midi_note event with its "ignore_" flag set to false, and the comparisons between notes of equal semitone pitch to be always done between the input note and this unique queued note that is not (yet) being ignored. If notes which are already being ignored are not skipped in the loop, the task of raising the "ignore_" flags for note events of equal semitone pitch (overlapping in time) which stop before the maximum stopping time of these notes may, due to breaking out of the loop, fail to work if the queue grows to contain three or more notes of equal semitone pitch, leading to the emission of premature "note off" events for this pitch, as demonstrated, for example, in <http://lists.gnu.org/archive/html/bug-lilypond/2016-06/msg00042.html>.
-rw-r--r--input/regression/midi/midi-overlapping-notes.ly22
-rw-r--r--lily/midi-walker.cc5
2 files changed, 25 insertions, 2 deletions
diff --git a/input/regression/midi/midi-overlapping-notes.ly b/input/regression/midi/midi-overlapping-notes.ly
new file mode 100644
index 0000000000..e808bb9ada
--- /dev/null
+++ b/input/regression/midi/midi-overlapping-notes.ly
@@ -0,0 +1,22 @@
+\header {
+
+ texidoc = "Notes with equal pitch overlapping in time on the same
+MIDI channel should produce multiple MIDI note-on events, but no
+isolated note-off events before the last of these notes ends."
+
+}
+
+\version "2.19.45"
+
+\score {
+ \new Staff \with { midiInstrument = "church organ" }
+ \new Voice \relative c' <<
+ % This combination of music expressions should not produce audible
+ % pauses between notes in the MIDI output, in particular, before the
+ % 'g1' note in the first expression.
+ { c1 s1 g1 }
+ { s4 c4 }
+ { s2 c2~ c1 s1 }
+ >>
+ \midi { }
+}
diff --git a/lily/midi-walker.cc b/lily/midi-walker.cc
index bc6c93dc56..d9765c6814 100644
--- a/lily/midi-walker.cc
+++ b/lily/midi-walker.cc
@@ -89,8 +89,9 @@ Midi_walker::do_start_note (Midi_note *note)
Real (384 * 4)) + now_ticks;
for (vsize i = 0; i < stop_note_queue.size (); i++)
{
- /* if this pitch already in queue */
- if (stop_note_queue[i].val->get_semitone_pitch ()
+ /* if this pitch already in queue, and is not already ignored */
+ if (!stop_note_queue[i].ignore_ &&
+ stop_note_queue[i].val->get_semitone_pitch ()
== note->get_semitone_pitch ())
{
int queued_ticks