From b4028a245926ed23bba27c4c75fac368fb6d8c8e Mon Sep 17 00:00:00 2001 From: jonaro00 <54029719+jonaro00@users.noreply.github.com> Date: Sat, 12 Mar 2022 22:55:16 +0100 Subject: [PATCH 1/7] Add alternate endings to alphaTex --- src/importer/AlphaTexImporter.ts | 34 ++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/importer/AlphaTexImporter.ts b/src/importer/AlphaTexImporter.ts index 93db6d11c..d0f76f8f6 100644 --- a/src/importer/AlphaTexImporter.ts +++ b/src/importer/AlphaTexImporter.ts @@ -1453,7 +1453,7 @@ export class AlphaTexImporter extends ScoreImporter { } } - private isNoteText(txt: string) { + private isNoteText(txt: string): boolean { return txt === 'x' || txt === '-' || txt === 'r'; } @@ -1583,7 +1583,6 @@ export class AlphaTexImporter extends ScoreImporter { } } } - if (this._sy !== AlphaTexSymbols.RParensis) { this.error('bend-effect', AlphaTexSymbols.RParensis, true); } @@ -1789,6 +1788,27 @@ export class AlphaTexImporter extends ScoreImporter { } master.repeatCount = this._syData as number; this._sy = this.newSy(); + } else if (syData === 're') { + this._sy = this.newSy(); + if (this._sy === AlphaTexSymbols.LParensis) { + this._sy = this.newSy(); + if (this._sy !== AlphaTexSymbols.Number) { + this.error('repeatending', AlphaTexSymbols.Number, true) + } + this.applyAlternateEnding(master); + while (this._sy === AlphaTexSymbols.Number) { + this.applyAlternateEnding(master); + } + if (this._sy !== AlphaTexSymbols.RParensis) { + this.error('repeatending-list', AlphaTexSymbols.RParensis, true); + } + this._sy = this.newSy(); + } else { + if (this._sy !== AlphaTexSymbols.Number) { + this.error('repeatending', AlphaTexSymbols.Number, true) + } + this.applyAlternateEnding(master); + } } else if (syData === 'ks') { this._sy = this.newSy(); if (this._sy !== AlphaTexSymbols.String) { @@ -1881,4 +1901,14 @@ export class AlphaTexImporter extends ScoreImporter { } return anyMeta; } + + private applyAlternateEnding(master: MasterBar): void { + let num = this._syData as number; + if (num < 1) { + // Repeat numberings start from 1 + this.error('repeatending', AlphaTexSymbols.Number, true) + } + master.alternateEndings |= 1 << (num - 1); + this._sy = this.newSy(); + } } From deb2b59ae57a1ea6244a68dd3babadbe8a0e6cab Mon Sep 17 00:00:00 2001 From: jonaro00 <54029719+jonaro00@users.noreply.github.com> Date: Sun, 13 Mar 2022 14:19:33 +0100 Subject: [PATCH 2/7] Rename \re to \ae --- src/importer/AlphaTexImporter.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/importer/AlphaTexImporter.ts b/src/importer/AlphaTexImporter.ts index d0f76f8f6..5f3596ec0 100644 --- a/src/importer/AlphaTexImporter.ts +++ b/src/importer/AlphaTexImporter.ts @@ -1788,24 +1788,24 @@ export class AlphaTexImporter extends ScoreImporter { } master.repeatCount = this._syData as number; this._sy = this.newSy(); - } else if (syData === 're') { + } else if (syData === 'ae') { this._sy = this.newSy(); if (this._sy === AlphaTexSymbols.LParensis) { this._sy = this.newSy(); if (this._sy !== AlphaTexSymbols.Number) { - this.error('repeatending', AlphaTexSymbols.Number, true) + this.error('alternateending', AlphaTexSymbols.Number, true) } this.applyAlternateEnding(master); while (this._sy === AlphaTexSymbols.Number) { this.applyAlternateEnding(master); } if (this._sy !== AlphaTexSymbols.RParensis) { - this.error('repeatending-list', AlphaTexSymbols.RParensis, true); + this.error('alternateending-list', AlphaTexSymbols.RParensis, true); } this._sy = this.newSy(); } else { if (this._sy !== AlphaTexSymbols.Number) { - this.error('repeatending', AlphaTexSymbols.Number, true) + this.error('alternateending', AlphaTexSymbols.Number, true) } this.applyAlternateEnding(master); } @@ -1906,8 +1906,9 @@ export class AlphaTexImporter extends ScoreImporter { let num = this._syData as number; if (num < 1) { // Repeat numberings start from 1 - this.error('repeatending', AlphaTexSymbols.Number, true) + this.error('alternateending', AlphaTexSymbols.Number, true) } + // Alternate endings bitflag starts from 0 master.alternateEndings |= 1 << (num - 1); this._sy = this.newSy(); } From fb946102bc2976085974c5a59294f64a53d0003b Mon Sep 17 00:00:00 2001 From: jonaro00 <54029719+jonaro00@users.noreply.github.com> Date: Sun, 13 Mar 2022 14:20:38 +0100 Subject: [PATCH 3/7] Add tests for Alternate endings --- test/importer/AlphaTexImporter.test.ts | 47 ++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/test/importer/AlphaTexImporter.test.ts b/test/importer/AlphaTexImporter.test.ts index 550802bf9..16a6d990e 100644 --- a/test/importer/AlphaTexImporter.test.ts +++ b/test/importer/AlphaTexImporter.test.ts @@ -769,12 +769,59 @@ describe('AlphaTexImporterTest', () => { let tex: string = '\\ro 1.3 2.3 3.3 4.3 | 5.3 6.3 7.3 8.3 | \\rc 2 1.3 2.3 3.3 4.3 | \\ro \\rc 3 1.3 2.3 3.3 4.3 |'; let score: Score = parseTex(tex); + expect(score.masterBars[0].isRepeatStart).toBe(true); + expect(score.masterBars[1].isRepeatStart).toBe(false); + expect(score.masterBars[2].isRepeatStart).toBe(false); + expect(score.masterBars[3].isRepeatStart).toBe(true); expect(score.masterBars[0].repeatCount).toEqual(0); expect(score.masterBars[1].repeatCount).toEqual(0); expect(score.masterBars[2].repeatCount).toEqual(2); expect(score.masterBars[3].repeatCount).toEqual(3); }); + it('alternate-endings', () => { + let tex: string = '\\ro 4.3*4 | \\ae (1 2 3) 6.3*4 | \\ae 4 \\rc 4 6.3 6.3 6.3 5.3 |'; + let score: Score = parseTex(tex); + expect(score.masterBars[0].isRepeatStart).toBe(true); + expect(score.masterBars[1].isRepeatStart).toBe(false); + expect(score.masterBars[2].isRepeatStart).toBe(false); + expect(score.masterBars[0].repeatCount).toEqual(0); + expect(score.masterBars[1].repeatCount).toEqual(0); + expect(score.masterBars[2].repeatCount).toEqual(4); + expect(score.masterBars[0].alternateEndings).toEqual(0b0000); + expect(score.masterBars[1].alternateEndings).toEqual(0b0111); + expect(score.masterBars[2].alternateEndings).toEqual(0b1000); + }) + + it('random-alternate-endings', () => { + let tex: string = ` + \\ro \\ae 1 1.1.1 | \\ae 2 2.1 | \\ae 3 3.1 | + 4.3.4*4 | + \\ae 1 1.1.1 | \\ae 2 2.1 | \\ae 3 3.1 | + 4.3.4*4 | + \\ae (1 3) 1.1.1 | \\ae 2 \\rc 3 2.1 | + `; + let score: Score = parseTex(tex); + expect(score.masterBars[0].isRepeatStart).toBe(true); + for (let i = 1; i <= 9; i++) { + expect(score.masterBars[i].isRepeatStart).toBe(false); + } + for (let i = 0; i <= 8; i++) { + expect(score.masterBars[i].repeatCount).toEqual(0); + } + expect(score.masterBars[9].repeatCount).toEqual(3); + expect(score.masterBars[0].alternateEndings).toEqual(0b001); + expect(score.masterBars[1].alternateEndings).toEqual(0b010); + expect(score.masterBars[2].alternateEndings).toEqual(0b100); + expect(score.masterBars[3].alternateEndings).toEqual(0b000); + expect(score.masterBars[4].alternateEndings).toEqual(0b001); + expect(score.masterBars[5].alternateEndings).toEqual(0b010); + expect(score.masterBars[6].alternateEndings).toEqual(0b100); + expect(score.masterBars[7].alternateEndings).toEqual(0b000); + expect(score.masterBars[8].alternateEndings).toEqual(0b101); + expect(score.masterBars[9].alternateEndings).toEqual(0b010); + }) + it('default-transposition-on-instruments', () => { let tex: string = ` \\track "Piano with Grand Staff" "pno." From 0e4530a5ff0e308dc220cbcc70311e3b27d4bf55 Mon Sep 17 00:00:00 2001 From: jonaro00 <54029719+jonaro00@users.noreply.github.com> Date: Sun, 13 Mar 2022 14:27:09 +0100 Subject: [PATCH 4/7] Add test for alphaTex \ae playback --- test/audio/MidiPlaybackController.test.ts | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/audio/MidiPlaybackController.test.ts b/test/audio/MidiPlaybackController.test.ts index 5574728a6..26dd148b6 100644 --- a/test/audio/MidiPlaybackController.test.ts +++ b/test/audio/MidiPlaybackController.test.ts @@ -76,4 +76,31 @@ describe('MidiPlaybackControllerTest', () => { expect(playedBars.join(',')).toEqual(expectedBars.join(',')); }); + + it('alternate-endings-with-alphaTex', () => { + let tex: string = ` + \\ro \\ae 1 1.1.1 | \\ae 2 2.1 | \\ae 3 3.1 | + 4.3.4*4 | + \\ae 1 1.1.1 | \\ae 2 2.1 | \\ae 3 3.1 | + 4.3.4*4 | + \\ae (1 3) 1.1.1 | \\ae 2 \\rc 3 2.1 + `; + let importer: AlphaTexImporter = new AlphaTexImporter(); + importer.initFromString(tex, new Settings()); + let score: Score = importer.readScore(); + let playedBars: number[] = []; + let controller: MidiPlaybackController = new MidiPlaybackController(score); + while (!controller.finished) { + let index: number = controller.index; + playedBars.push(index); + controller.processCurrent(); + controller.moveNext(); + if (playedBars.length > 50) { + fail('Too many bars generated'); + } + } + let expectedBars: number[] = [0, 3, 4, 7, 8, 1, 3, 5, 7, 9, 2, 3, 6, 7, 8]; + + expect(playedBars.join(',')).toEqual(expectedBars.join(',')); + }); }); From 50d581a7ff82049b77268ae90849da164f739c07 Mon Sep 17 00:00:00 2001 From: jonaro00 <54029719+jonaro00@users.noreply.github.com> Date: Mon, 14 Mar 2022 22:34:52 +0100 Subject: [PATCH 5/7] alphaTex \ae test correction --- test/audio/MidiPlaybackController.test.ts | 44 +++++++++++------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/test/audio/MidiPlaybackController.test.ts b/test/audio/MidiPlaybackController.test.ts index 26dd148b6..049d8b53f 100644 --- a/test/audio/MidiPlaybackController.test.ts +++ b/test/audio/MidiPlaybackController.test.ts @@ -55,9 +55,7 @@ describe('MidiPlaybackControllerTest', () => { testRepeat(score, expectedIndexes); }); - it('repeat-with-alphaTex', () => { - let tex: string = - '\\ro 1.3 2.3 3.3 4.3 | 5.3 6.3 7.3 8.3 | \\rc 2 1.3 2.3 3.3 4.3 | \\ro \\rc 3 1.3 2.3 3.3 4.3'; + const testAlphaTexRepeat: ((tex: string, expectedBars: number[], maxBars: number) => void) = (tex: string, expectedBars: number[], maxBars: number): void => { let importer: AlphaTexImporter = new AlphaTexImporter(); importer.initFromString(tex, new Settings()); let score: Score = importer.readScore(); @@ -65,16 +63,23 @@ describe('MidiPlaybackControllerTest', () => { let controller: MidiPlaybackController = new MidiPlaybackController(score); while (!controller.finished) { let index: number = controller.index; - playedBars.push(index); controller.processCurrent(); + if (controller.shouldPlay) { + playedBars.push(index); + } controller.moveNext(); - if (playedBars.length > 50) { + if (playedBars.length > maxBars) { fail('Too many bars generated'); } } - let expectedBars: number[] = [0, 1, 2, 0, 1, 2, 3, 3, 3]; - expect(playedBars.join(',')).toEqual(expectedBars.join(',')); + } + + it('repeat-with-alphaTex', () => { + let tex: string = + '\\ro 1.3 2.3 3.3 4.3 | 5.3 6.3 7.3 8.3 | \\rc 2 1.3 2.3 3.3 4.3 | \\ro \\rc 3 1.3 2.3 3.3 4.3'; + let expectedBars: number[] = [0, 1, 2, 0, 1, 2, 3, 3, 3]; + testAlphaTexRepeat(tex, expectedBars, 50); }); it('alternate-endings-with-alphaTex', () => { @@ -85,22 +90,13 @@ describe('MidiPlaybackControllerTest', () => { 4.3.4*4 | \\ae (1 3) 1.1.1 | \\ae 2 \\rc 3 2.1 `; - let importer: AlphaTexImporter = new AlphaTexImporter(); - importer.initFromString(tex, new Settings()); - let score: Score = importer.readScore(); - let playedBars: number[] = []; - let controller: MidiPlaybackController = new MidiPlaybackController(score); - while (!controller.finished) { - let index: number = controller.index; - playedBars.push(index); - controller.processCurrent(); - controller.moveNext(); - if (playedBars.length > 50) { - fail('Too many bars generated'); - } - } - let expectedBars: number[] = [0, 3, 4, 7, 8, 1, 3, 5, 7, 9, 2, 3, 6, 7, 8]; - - expect(playedBars.join(',')).toEqual(expectedBars.join(',')); + let expectedBars: number[] = [ + 0, 4, 8, // First round: 1st, 5th and 9th bar which have the ending for 1. + 1, 5, 9, // Second round: 2nd, 6th and 10th bar which have the ending for 2. + 2, 3, 6, 7, 8 // Third round: 3rd, 4th, 7th, 8th and 9th which have the ending for 3. + // 4th and 8th bar don't have the ending explicitly + // but extended from the previous bar. + ]; + testAlphaTexRepeat(tex, expectedBars, 50); }); }); From ec6a2c5abfd6a2ed3a1bc2bc7396509997d236dc Mon Sep 17 00:00:00 2001 From: jonaro00 <54029719+jonaro00@users.noreply.github.com> Date: Thu, 17 Mar 2022 21:40:20 +0100 Subject: [PATCH 6/7] Refactor test cases --- test/audio/MidiPlaybackController.test.ts | 62 +++++++++-------------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/test/audio/MidiPlaybackController.test.ts b/test/audio/MidiPlaybackController.test.ts index 049d8b53f..19a73f950 100644 --- a/test/audio/MidiPlaybackController.test.ts +++ b/test/audio/MidiPlaybackController.test.ts @@ -6,13 +6,16 @@ import { Logger } from '@src/Logger'; import { GpImporterTestHelper } from '@test/importer/GpImporterTestHelper'; describe('MidiPlaybackControllerTest', () => { - const testRepeat: ((score: Score, expectedIndexes: number[]) => void) = (score: Score, expectedIndexes: number[]): void => { + const testRepeat: ((score: Score, expectedIndexes: number[], maxBars: number) => void) = (score: Score, expectedIndexes: number[], maxBars: number): void => { let controller: MidiPlaybackController = new MidiPlaybackController(score); let i: number = 0; while (!controller.finished) { let index: number = controller.index; controller.processCurrent(); if (controller.shouldPlay) { + if (i > maxBars) { + fail('Too many bars generated'); + } Logger.debug('Test', `Checking index ${i}, expected[${expectedIndexes[i]}]`, i, expectedIndexes[i]); expect(index).toEqual(expectedIndexes[i]); i++; @@ -23,58 +26,43 @@ describe('MidiPlaybackControllerTest', () => { expect(controller.finished).toBe(true); }; - it('repeat-close', async () => { - const reader = await GpImporterTestHelper.prepareImporterWithFile('audio/repeat-close.gp5'); + const testGuitarProRepeat: ((file: string, expectedBars: number[], maxBars: number) => Promise) = async (file: string, expectedBars: number[], maxBars: number): Promise => { + let reader = await GpImporterTestHelper.prepareImporterWithFile(file); let score: Score = reader.readScore(); + testRepeat(score, expectedBars, maxBars); + } + + const testAlphaTexRepeat: ((tex: string, expectedBars: number[], maxBars: number) => void) = (tex: string, expectedBars: number[], maxBars: number): void => { + let importer: AlphaTexImporter = new AlphaTexImporter(); + importer.initFromString(tex, new Settings()); + let score: Score = importer.readScore(); + testRepeat(score, expectedBars, maxBars); + } + + it('repeat-close', async () => { + let file = 'audio/repeat-close.gp5'; let expectedIndexes = [0, 1, 0, 1, 2]; - testRepeat(score, expectedIndexes); + testGuitarProRepeat(file, expectedIndexes, 20); }); it('repeat-close-multi', async () => { - const reader = await GpImporterTestHelper.prepareImporterWithFile('audio/repeat-close-multi.gp5'); - let score: Score = reader.readScore(); + let file = 'audio/repeat-close-multi.gp5'; let expectedIndexes = [0, 1, 0, 1, 0, 1, 0, 1, 2]; - testRepeat(score, expectedIndexes); + testGuitarProRepeat(file, expectedIndexes, 20); }); it('repeat-close-without-start-at-beginning', async () => { - const reader = await GpImporterTestHelper.prepareImporterWithFile( - 'audio/repeat-close-without-start-at-beginning.gp5' - ); - let score: Score = reader.readScore(); + let file = 'audio/repeat-close-without-start-at-beginning.gp5'; let expectedIndexes = [0, 1, 0, 1]; - testRepeat(score, expectedIndexes); + testGuitarProRepeat(file, expectedIndexes, 20); }); it('repeat-close-alternate-endings', async () => { - const reader = await GpImporterTestHelper.prepareImporterWithFile( - 'audio/repeat-close-alternate-endings.gp5' - ); - let score: Score = reader.readScore(); + let file = 'audio/repeat-close-alternate-endings.gp5'; let expectedIndexes = [0, 1, 0, 2, 3, 0, 1, 0, 4]; - testRepeat(score, expectedIndexes); + testGuitarProRepeat(file, expectedIndexes, 20); }); - const testAlphaTexRepeat: ((tex: string, expectedBars: number[], maxBars: number) => void) = (tex: string, expectedBars: number[], maxBars: number): void => { - let importer: AlphaTexImporter = new AlphaTexImporter(); - importer.initFromString(tex, new Settings()); - let score: Score = importer.readScore(); - let playedBars: number[] = []; - let controller: MidiPlaybackController = new MidiPlaybackController(score); - while (!controller.finished) { - let index: number = controller.index; - controller.processCurrent(); - if (controller.shouldPlay) { - playedBars.push(index); - } - controller.moveNext(); - if (playedBars.length > maxBars) { - fail('Too many bars generated'); - } - } - expect(playedBars.join(',')).toEqual(expectedBars.join(',')); - } - it('repeat-with-alphaTex', () => { let tex: string = '\\ro 1.3 2.3 3.3 4.3 | 5.3 6.3 7.3 8.3 | \\rc 2 1.3 2.3 3.3 4.3 | \\ro \\rc 3 1.3 2.3 3.3 4.3'; From 35e664f6890b0a24646bf5f0eb4946427b7f403c Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sat, 7 May 2022 10:44:50 +0200 Subject: [PATCH 7/7] Formatted files (just to trigger ci which appears stuck) --- src/importer/AlphaTexImporter.ts | 2 +- test/importer/AlphaTexImporter.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/importer/AlphaTexImporter.ts b/src/importer/AlphaTexImporter.ts index 5f3596ec0..a24a5ff38 100644 --- a/src/importer/AlphaTexImporter.ts +++ b/src/importer/AlphaTexImporter.ts @@ -1564,7 +1564,7 @@ export class AlphaTexImporter extends ScoreImporter { this._sy = this.newSy(); } const points = note.bendPoints; - if(points != null){ + if (points != null) { while (points.length > 60) { points.splice(points.length - 1, 1); } diff --git a/test/importer/AlphaTexImporter.test.ts b/test/importer/AlphaTexImporter.test.ts index 16a6d990e..dfa33823d 100644 --- a/test/importer/AlphaTexImporter.test.ts +++ b/test/importer/AlphaTexImporter.test.ts @@ -951,7 +951,7 @@ describe('AlphaTexImporterTest', () => { expect(score.tracks[0].name).toEqual("🎸"); expect(score.tracks[0].staves[0].bars[0].voices[0].beats[2].lyrics![0]).toEqual("🤘"); }); - + it('does-not-hang-on-backslash', () => { try { parseTex('\\title Test . 3.3 \\') @@ -961,7 +961,7 @@ describe('AlphaTexImporterTest', () => { } }) - function runSectionNoteSymbolTest(noteSymbol:string) { + function runSectionNoteSymbolTest(noteSymbol: string) { const score = parseTex(`1.3.4 * 4 | \\section Verse ${noteSymbol}.1 | 2.3.4*4`); expect(score.masterBars.length).toEqual(3);