Skip to content

Commit

Permalink
fix #41571: acciaccatura playback too long on slow notes
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcSabatella committed Jan 17, 2015
1 parent 53bf8d3 commit fcdff28
Show file tree
Hide file tree
Showing 4 changed files with 476 additions and 8 deletions.
42 changes: 34 additions & 8 deletions libmscore/rendermidi.cpp
Expand Up @@ -350,12 +350,26 @@ static void collectMeasureEvents(EventMap* events, Measure* m, Staff* staff, int
instr->updateVelocity(&velocity,channel, a->subtypeName());
}

for (Chord* c : chord->graceNotes()) {
QList<Chord*> gnb;
chord->getGraceNotesBefore(&gnb);
for (Chord* c : gnb) {
for (const Note* note : c->notes())
collectNote(events, channel, note, velocity, tickOffset);
}

foreach (const Note* note, chord->notes())
collectNote(events, channel, note, velocity, tickOffset);

#if 0
// TODO: add support for grace notes after - see createPlayEvents()
QList<Chord*> gna;
chord->getGraceNotesAfter(&gna);
for (Chord* c : gna) {
for (const Note* note : c->notes())
collectNote(events, channel, note, velocity, tickOffset);
}
#endif

}
}

Expand Down Expand Up @@ -909,26 +923,37 @@ void Score::createPlayEvents(Chord* chord)
instr->updateGateTime(&gateTime, 0, "");
}

int n = chord->graceNotes().size();
QList<Chord*> gnb;
int n = chord->getGraceNotesBefore(&gnb);
int ontime = 0;
if (n) {
//
// render grace notes:
// simplified implementation:
// - grace notes start on the beat of the main note
// - duration: acciacatura: 0.128 * duration of main note
// appoggiatura: 0.5 * duration of main note
// - the duration is divided by the number of grace notes
// - duration: appoggiatura: 0.5 * duration of main note
// acciacatura: min of 0.5 * duration or 65ms fixed (independent of duration or tempo)
// - for appoggiaturas, the duration is divided by the number of grace notes
// - the grace note duration as notated does not matter
//
Chord* graceChord = chord->graceNotes()[0];
ontime = (graceChord->noteType() == NoteType::ACCIACCATURA) ? 128 : 500;
Chord* graceChord = gnb[0];
if (graceChord->noteType() == NoteType::ACCIACCATURA) {
qreal ticksPerSecond = tempo(tick) * MScore::division;
int graceTimeMS = 65 * n; // value determined empirically (TODO: make instrument-specific, like articulations)
// 1000 occurs below for two different reasons:
// number of milliseconds per second, also unit for ontime
qreal chordTimeMS = (chord->actualTicks() / ticksPerSecond) * 1000;
ontime = qMin(500, static_cast<int>((graceTimeMS / chordTimeMS) * 1000));
}
else {
ontime = 500;
}
int graceDuration = ontime / n;

int on = 0;
for (int i = 0; i < n; ++i) {
QList<NoteEventList> el;
Chord* gc = chord->graceNotes().at(i);
Chord* gc = gnb.at(i);
int nn = gc->notes().size();
for (int ii = 0; ii < nn; ++ii) {
NoteEventList nel;
Expand All @@ -945,6 +970,7 @@ void Score::createPlayEvents(Chord* chord)
on += graceDuration;
}
}

SwingParameters st = chord->staff()->swing(tick);
int unit = st.swingUnit;
int ratio = st.swingRatio;
Expand Down
76 changes: 76 additions & 0 deletions mtest/libmscore/midi/testGraceBefore-ref.txt
@@ -0,0 +1,76 @@
Tick = 0 Type = 144 Pitch = 71 Velocity = 80 Channel = 0
Tick = 0 Type = 3 Pitch = 0 Velocity = 0 Channel = 0
Tick = 30 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 31 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 228 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 240 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 467 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 480 Type = 144 Pitch = 71 Velocity = 80 Channel = 0
Tick = 480 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 510 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 511 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 936 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 960 Type = 144 Pitch = 71 Velocity = 80 Channel = 0
Tick = 960 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 989 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 990 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 1440 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 1871 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 1920 Type = 144 Pitch = 71 Velocity = 80 Channel = 0
Tick = 1920 Type = 3 Pitch = 0 Velocity = 0 Channel = 0
Tick = 1949 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 1950 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 2400 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 2880 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 3360 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 3742 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 3840 Type = 144 Pitch = 74 Velocity = 80 Channel = 0
Tick = 3840 Type = 3 Pitch = 0 Velocity = 0 Channel = 0
Tick = 3869 Type = 144 Pitch = 74 Velocity = 0 Channel = 0
Tick = 3870 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 3899 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 3901 Type = 144 Pitch = 71 Velocity = 80 Channel = 0
Tick = 3930 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 3932 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 4320 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 4800 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 5280 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 5666 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 5760 Type = 144 Pitch = 71 Velocity = 80 Channel = 0
Tick = 5760 Type = 3 Pitch = 0 Velocity = 0 Channel = 0
Tick = 5879 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 5880 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 5993 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 6000 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 6227 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 6240 Type = 144 Pitch = 71 Velocity = 80 Channel = 0
Tick = 6240 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 6405 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 6406 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 6703 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 6720 Type = 144 Pitch = 71 Velocity = 80 Channel = 0
Tick = 6720 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 6885 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 6886 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 7200 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 7638 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 7680 Type = 144 Pitch = 71 Velocity = 80 Channel = 0
Tick = 7680 Type = 3 Pitch = 0 Velocity = 0 Channel = 0
Tick = 7844 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 7845 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 8160 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 8640 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 9120 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 9510 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 9600 Type = 144 Pitch = 74 Velocity = 80 Channel = 0
Tick = 9600 Type = 3 Pitch = 0 Velocity = 0 Channel = 0
Tick = 9764 Type = 144 Pitch = 74 Velocity = 0 Channel = 0
Tick = 9765 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 9929 Type = 144 Pitch = 72 Velocity = 0 Channel = 0
Tick = 9930 Type = 144 Pitch = 71 Velocity = 80 Channel = 0
Tick = 10080 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 10094 Type = 144 Pitch = 71 Velocity = 0 Channel = 0
Tick = 10097 Type = 144 Pitch = 72 Velocity = 80 Channel = 0
Tick = 10560 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 11040 Type = 4 Pitch = 0 Velocity = 0 Channel = 0
Tick = 11445 Type = 144 Pitch = 72 Velocity = 0 Channel = 0

0 comments on commit fcdff28

Please sign in to comment.