diff --git a/src/importer/Gp3To5Importer.ts b/src/importer/Gp3To5Importer.ts index 9dac2c9c6..db0aeac5a 100644 --- a/src/importer/Gp3To5Importer.ts +++ b/src/importer/Gp3To5Importer.ts @@ -499,8 +499,11 @@ export class Gp3To5Importer extends ScoreImporter { if ((flags & 0x04) !== 0) { newBeat.text = GpBinaryHelpers.gpReadStringIntUnused(this.data, this.settings.importer.encoding); } + + + let allNoteHarmonicType = HarmonicType.None; if ((flags & 0x08) !== 0) { - this.readBeatEffects(newBeat); + allNoteHarmonicType = this.readBeatEffects(newBeat); } if ((flags & 0x10) !== 0) { this.readMixTableChange(newBeat); @@ -508,7 +511,13 @@ export class Gp3To5Importer extends ScoreImporter { let stringFlags: number = this.data.readByte(); for (let i: number = 6; i >= 0; i--) { if ((stringFlags & (1 << i)) !== 0 && 6 - i < bar.staff.tuning.length) { - this.readNote(track, bar, voice, newBeat, 6 - i); + const note = this.readNote(track, bar, voice, newBeat, 6 - i); + if(allNoteHarmonicType !== HarmonicType.None) { + note.harmonicType = allNoteHarmonicType; + if(note.harmonicType === HarmonicType.Natural) { + note.harmonicValue = this.deltaFretToHarmonicValue(note.fret); + } + } } } if (this._versionNumber >= 500) { @@ -614,7 +623,7 @@ export class Gp3To5Importer extends ScoreImporter { } } - public readBeatEffects(beat: Beat): void { + public readBeatEffects(beat: Beat): HarmonicType { let flags: number = this.data.readByte(); let flags2: number = 0; if (this._versionNumber >= 400) { @@ -687,6 +696,16 @@ export class Gp3To5Importer extends ScoreImporter { break; } } + + if (this._versionNumber < 400) { + if ((flags & 0x04) !== 0) { + return HarmonicType.Natural; + } else if ((flags & 0x08) !== 0) { + return HarmonicType.Artificial; + } + } + + return HarmonicType.None; } public readTremoloBarEffect(beat: Beat): void { @@ -812,7 +831,7 @@ export class Gp3To5Importer extends ScoreImporter { } } - public readNote(track: Track, bar: Bar, voice: Voice, beat: Beat, stringIndex: number): void { + public readNote(track: Track, bar: Bar, voice: Voice, beat: Beat, stringIndex: number): Note { let newNote: Note = new Note(); newNote.string = bar.staff.tuning.length - stringIndex; let flags: number = this.data.readByte(); @@ -860,6 +879,7 @@ export class Gp3To5Importer extends ScoreImporter { if ((flags & 0x08) !== 0) { this.readNoteEffects(track, voice, beat, newNote); } + return newNote; } public toDynamicValue(value: number): DynamicValue { @@ -909,14 +929,6 @@ export class Gp3To5Importer extends ScoreImporter { } if ((flags2 & 0x10) !== 0) { this.readArtificialHarmonic(note); - } else if (this._versionNumber < 400) { - if ((flags & 0x04) !== 0) { - note.harmonicType = HarmonicType.Natural; - note.harmonicValue = this.deltaFretToHarmonicValue(note.fret); - } - if ((flags & 0x08) !== 0) { - note.harmonicType = HarmonicType.Artificial; - } } if ((flags2 & 0x20) !== 0) { this.readTrill(note); diff --git a/test/importer/Gp3Importer.test.ts b/test/importer/Gp3Importer.test.ts index a0defad10..a94082b92 100644 --- a/test/importer/Gp3Importer.test.ts +++ b/test/importer/Gp3Importer.test.ts @@ -4,6 +4,7 @@ import { DynamicValue } from '@src/model/DynamicValue'; import { Score } from '@src/model/Score'; import { SlideOutType } from '@src/model/SlideOutType'; import { GpImporterTestHelper } from '@test/importer/GpImporterTestHelper'; +import { HarmonicType } from '@src/model/HarmonicType'; describe('Gp3ImporterTest', () => { it('score-info', async () => { @@ -52,8 +53,14 @@ describe('Gp3ImporterTest', () => { expect(score.tracks[0].staves[0].bars[0].voices[0].beats[3].notes[0].isLetRing).toBe(true); }); - it('testGuitarPro3Harmonics', async () => { - // TODO: Find out about GP3 harmonics! + it('harmonics', async () => { + const reader = await GpImporterTestHelper.prepareImporterWithFile('guitarpro3/harmonics.gp3'); + let score: Score = reader.readScore(); + expect(score.tracks[0].staves[0].bars[0].voices[0].beats[0].notes[0].harmonicType).toBe(HarmonicType.Natural); + expect(score.tracks[0].staves[0].bars[0].voices[0].beats[1].notes[0].harmonicType).toBe(HarmonicType.Artificial); + expect(score.tracks[0].staves[0].bars[0].voices[0].beats[2].notes[0].harmonicType).toBe(HarmonicType.Artificial); + expect(score.tracks[0].staves[0].bars[0].voices[0].beats[3].notes[0].harmonicType).toBe(HarmonicType.Artificial); + expect(score.tracks[0].staves[0].bars[0].voices[0].beats[4].notes[0].harmonicType).toBe(HarmonicType.Artificial); }); it('hammer', async () => {