diff --git a/Source/AlphaTab.Test/VisualTests/Features/SpecialNotesTests.cs b/Source/AlphaTab.Test/VisualTests/Features/SpecialNotesTests.cs index 7f4da1834..9ea130476 100644 --- a/Source/AlphaTab.Test/VisualTests/Features/SpecialNotesTests.cs +++ b/Source/AlphaTab.Test/VisualTests/Features/SpecialNotesTests.cs @@ -23,6 +23,13 @@ public void GraceNotes() RunVisualTest(settings, new[] { 0 }, "TestFiles/Docs/Features/GraceNotes.gp5", "TestFiles/VisualTests/Features/SpecialNotes/GraceNotes.png"); } + [TestMethod, AsyncTestMethod] + public void GraceNotesAdvanced() + { + var settings = new Settings(); + RunVisualTest(settings, new[] { 0, 1 }, "TestFiles/VisualTests/Features/SpecialNotes/GraceNotesAdvanced.gp", "TestFiles/VisualTests/Features/SpecialNotes/GraceNotesAdvanced.png"); + } + [TestMethod, AsyncTestMethod] public void DeadNotes() { diff --git a/Source/AlphaTab/Audio/MidiTickLookup.cs b/Source/AlphaTab/Audio/MidiTickLookup.cs index 605bc6dd2..4111646bc 100644 --- a/Source/AlphaTab/Audio/MidiTickLookup.cs +++ b/Source/AlphaTab/Audio/MidiTickLookup.cs @@ -221,7 +221,8 @@ public MidiTickLookupFindBeatResult FindBeat(Track[] tracks, int tick) for (var b = index + 1; b < beats.Count; b++) { var currentBeat = beats[b]; - if (currentBeat.Start > beat.Start && + if (currentBeat.Beat.GraceType == GraceType.None && + currentBeat.Start > beat.Start && trackLookup.ContainsKey(currentBeat.Beat.Voice.Bar.Staff.Track.Index)) { nextBeat = currentBeat; @@ -237,7 +238,8 @@ public MidiTickLookupFindBeatResult FindBeat(Track[] tracks, int tick) for (var b = 0; b < beats.Count; b++) { var currentBeat = beats[b]; - if (trackLookup.ContainsKey(currentBeat.Beat.Voice.Bar.Staff.Track.Index)) + if (currentBeat.Beat.GraceType == GraceType.None && + trackLookup.ContainsKey(currentBeat.Beat.Voice.Bar.Staff.Track.Index)) { nextBeat = currentBeat; break; diff --git a/Source/AlphaTab/Model/Voice.cs b/Source/AlphaTab/Model/Voice.cs index 4c337d9bb..d18102537 100644 --- a/Source/AlphaTab/Model/Voice.cs +++ b/Source/AlphaTab/Model/Voice.cs @@ -191,12 +191,12 @@ internal void Finish(Settings settings) nonGrace.UpdateDurations(); } - // grace beats have 1/4 size of the non grace beat following them - var perGraceDuration = nonGrace == null + // grace beats have 1/4 size of the non grace beat preceeding them + var perGraceDisplayDuration = beat.PreviousBeat == null ? Duration.ThirtySecond.ToTicks() - : nonGrace.DisplayDuration / 4 / numberOfGraceBeats; + : beat.PreviousBeat.DisplayDuration / 4 / numberOfGraceBeats; - // move all grace beats + // move all grace beats var graceBeat = Beats[i]; for (var j = 0; j < numberOfGraceBeats && graceBeat != null; j++) { @@ -204,8 +204,8 @@ internal void Finish(Settings settings) graceBeat.UpdateDurations(); graceBeat.DisplayStart = - currentDisplayTick - (numberOfGraceBeats - j + 1) * perGraceDuration; - graceBeat.DisplayDuration = perGraceDuration; + currentDisplayTick - (numberOfGraceBeats - j + 1) * perGraceDisplayDuration; + graceBeat.DisplayDuration = perGraceDisplayDuration; stolenDuration += graceBeat.PlaybackDuration; diff --git a/TestData/VisualTests/Features/SpecialNotes/GraceNotes.png b/TestData/VisualTests/Features/SpecialNotes/GraceNotes.png index bb6bb0cc5..7cd42a498 100644 Binary files a/TestData/VisualTests/Features/SpecialNotes/GraceNotes.png and b/TestData/VisualTests/Features/SpecialNotes/GraceNotes.png differ diff --git a/TestData/VisualTests/Features/SpecialNotes/GraceNotesAdvanced.gp b/TestData/VisualTests/Features/SpecialNotes/GraceNotesAdvanced.gp new file mode 100644 index 000000000..c0a901217 Binary files /dev/null and b/TestData/VisualTests/Features/SpecialNotes/GraceNotesAdvanced.gp differ diff --git a/TestData/VisualTests/Features/SpecialNotes/GraceNotesAdvanced.png b/TestData/VisualTests/Features/SpecialNotes/GraceNotesAdvanced.png new file mode 100644 index 000000000..ad3085cf3 Binary files /dev/null and b/TestData/VisualTests/Features/SpecialNotes/GraceNotesAdvanced.png differ