diff --git a/src/midi/MidiTickLookup.ts b/src/midi/MidiTickLookup.ts index 05c4ab0ae..d1c8dd7b1 100644 --- a/src/midi/MidiTickLookup.ts +++ b/src/midi/MidiTickLookup.ts @@ -421,14 +421,15 @@ export class MidiTickLookup { if (currentMasterBar) { // pre-beat grace notes at the start of the bar we also add the beat to the previous bar if (start < 0 && currentMasterBar.previousMasterBar) { - const previousStart = currentMasterBar.previousMasterBar!.end + start; + const relativeMasterBarEnd = currentMasterBar.previousMasterBar!.end - currentMasterBar.previousMasterBar!.start; + const previousStart = relativeMasterBarEnd + start; const previousEnd = previousStart + duration; // add to previous bar - currentMasterBar.previousMasterBar!.addBeat(beat, previousStart, previousStart, currentMasterBar.previousMasterBar!.end - previousStart); + currentMasterBar.previousMasterBar!.addBeat(beat, previousStart, previousStart, duration); // overlap to current bar? - if(previousEnd > currentMasterBar.previousMasterBar!.end) { + if(previousEnd > relativeMasterBarEnd) { // the start is negative and representing the overlap to the previous bar. const overlapDuration = duration + start; currentMasterBar.addBeat(beat, start, 0, overlapDuration); diff --git a/test/audio/MidiTickLookup.test.ts b/test/audio/MidiTickLookup.test.ts index 454d23a16..3124f5554 100644 --- a/test/audio/MidiTickLookup.test.ts +++ b/test/audio/MidiTickLookup.test.ts @@ -1,3 +1,4 @@ +import { AlphaTexImporter } from '@src/importer/AlphaTexImporter'; import { ScoreLoader } from '@src/importer/ScoreLoader'; import { ByteBuffer } from '@src/io/ByteBuffer'; import { Logger } from '@src/Logger'; @@ -574,8 +575,6 @@ describe('MidiTickLookupTest', () => { }) - - it('cursor-snapping', async () => { const buffer = await TestPlatform.loadFile('test-data/audio/cursor-snapping.gp'); const settings = new Settings(); @@ -616,6 +615,38 @@ describe('MidiTickLookupTest', () => { expect(secondBeat!.beatLookup.duration).to.equal(960); }); + + it('before-beat-grace-later-bars', () => { + const settings = new Settings(); + const importer = new AlphaTexImporter(); + importer.initFromString(`\\ts 2 4 1.1.2 | 2.1.4 3.1 | 4.1{gr} 5.1{gr} 6.1.2 | 7.1.4 8.1`, settings); + const score = importer.readScore(); + const lookup = buildLookup(score, settings); + + // bar 2 contains the grace notes which stole duration from fret 3 beat. + const bar2 = lookup.masterBars[1]; + + let current = bar2.firstBeat; + expect(current!.highlightedBeats.map(b => b.beat.notes[0].fret).join(',')).to.equal("2"); + expect(current!.start).to.equal(0); + expect(current!.duration).to.equal(960); + + current = current!.nextBeat; + expect(current!.highlightedBeats.map(b => b.beat.notes[0].fret).join(',')).to.equal("3"); + expect(current!.start).to.equal(960); + expect(current!.duration).to.equal(840); // 120 ticks stolen by grace beats + + current = current!.nextBeat; + expect(current!.highlightedBeats.map(b => b.beat.notes[0].fret).join(',')).to.equal("4"); + expect(current!.start).to.equal(960 + 840); + expect(current!.duration).to.equal(60); + + current = current!.nextBeat; + expect(current!.highlightedBeats.map(b => b.beat.notes[0].fret).join(',')).to.equal("5"); + expect(current!.start).to.equal(960 + 840 + 60); + expect(current!.duration).to.equal(60); + }); + function lookupTest( tex: string,