From 633c5fe50ccb28de7d685cb8a6791c87b85863f1 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Thu, 9 Apr 2026 15:18:48 +0200 Subject: [PATCH] fix(gp): check harmonic type case insensitive --- packages/alphatab/src/importer/GpifParser.ts | 16 ++++++++-------- .../test-data/guitarpro8/harmonics-lowercase.gp | Bin 0 -> 12696 bytes .../alphatab/test/importer/Gp8Importer.test.ts | 6 ++++++ 3 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 packages/alphatab/test-data/guitarpro8/harmonics-lowercase.gp diff --git a/packages/alphatab/src/importer/GpifParser.ts b/packages/alphatab/src/importer/GpifParser.ts index ceffcb228..b7bd46907 100644 --- a/packages/alphatab/src/importer/GpifParser.ts +++ b/packages/alphatab/src/importer/GpifParser.ts @@ -2393,26 +2393,26 @@ export class GpifParser { case 'HarmonicType': const htype = c.findChildElement('HType'); if (htype) { - switch (htype.innerText) { - case 'NoHarmonic': + switch (htype.innerText.toLowerCase()) { + case 'noharmonic': note.harmonicType = HarmonicType.None; break; - case 'Natural': + case 'natural': note.harmonicType = HarmonicType.Natural; break; - case 'Artificial': + case 'artificial': note.harmonicType = HarmonicType.Artificial; break; - case 'Pinch': + case 'pinch': note.harmonicType = HarmonicType.Pinch; break; - case 'Tap': + case 'tap': note.harmonicType = HarmonicType.Tap; break; - case 'Semi': + case 'semi': note.harmonicType = HarmonicType.Semi; break; - case 'Feedback': + case 'feedback': note.harmonicType = HarmonicType.Feedback; break; } diff --git a/packages/alphatab/test-data/guitarpro8/harmonics-lowercase.gp b/packages/alphatab/test-data/guitarpro8/harmonics-lowercase.gp new file mode 100644 index 0000000000000000000000000000000000000000..dfaf764d53d6c22f469932b86bedc64d0f163463 GIT binary patch literal 12696 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 R0U*46u-<-|zYPZf{txI~Xv6>j literal 0 HcmV?d00001 diff --git a/packages/alphatab/test/importer/Gp8Importer.test.ts b/packages/alphatab/test/importer/Gp8Importer.test.ts index 9fe94ed4e..0ef7ffa1d 100644 --- a/packages/alphatab/test/importer/Gp8Importer.test.ts +++ b/packages/alphatab/test/importer/Gp8Importer.test.ts @@ -504,4 +504,10 @@ describe('Gp8ImporterTest', () => { expect(score.masterBars[5].beamingRules!.groups.has(Duration.Eighth)).to.be.true; expect(score.masterBars[5].beamingRules!.groups.get(Duration.Eighth)!.join(',')).to.be.equal('4,4'); }); + + it('harmonics-lowercase', async () => { + const reader = await prepareImporterWithFile('guitarpro8/harmonics-lowercase.gp'); + const score = reader.readScore(); + GpImporterTestHelper.checkHarmonics(score); + }); });