Skip to content

Commit 5f27345

Browse files
authored
feat: Different key signatures across staves (#2034)
1 parent 949f9d6 commit 5f27345

26 files changed

+328
-179
lines changed

src.compiler/csharp/CSharpAstPrinter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,7 @@ export default class CSharpAstPrinter extends AstPrinterBase {
864864

865865
protected writeNonNullExpression(expr: cs.NonNullExpression) {
866866
this.writeExpression(expr.expression);
867-
if (!cs.isNonNullExpression(expr)) {
867+
if (!cs.isNonNullExpression(expr.expression)) {
868868
this.write('!');
869869
}
870870
}

src.compiler/csharp/CSharpAstTransformer.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3217,11 +3217,18 @@ export default class CSharpAstTransformer {
32173217

32183218
csExpr.type = this._context.makeArrayTupleType(csExpr, []);
32193219

3220-
const tupleType = this._context.typeChecker.getContextualType(expression) ?? type;
3220+
let tupleType = this._context.typeChecker.getContextualType(expression);
3221+
let typeArgs = tupleType
3222+
? this._context.typeChecker.getTypeArguments(tupleType as ts.TypeReference)
3223+
: undefined;
3224+
if (!typeArgs || typeArgs.length !== expression.elements.length) {
3225+
tupleType = type;
3226+
typeArgs = this._context.typeChecker.getTypeArguments(tupleType as ts.TypeReference);
3227+
}
32213228

3222-
(csExpr.type as cs.ArrayTupleNode).types = this._context.typeChecker
3223-
.getTypeArguments(tupleType as ts.TypeReference)
3224-
.map((p, i) => this.createUnresolvedTypeNode(csExpr.type, expression.elements[i], p));
3229+
(csExpr.type as cs.ArrayTupleNode).types = typeArgs!.map((p, i) =>
3230+
this.createUnresolvedTypeNode(csExpr.type, expression.elements[i], p)
3231+
);
32253232

32263233
for (const e of expression.elements) {
32273234
const ex = this.visitExpression(csExpr, e);

src.compiler/csharp/CSharpEmitterContext.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,10 @@ export default class CSharpEmitterContext {
656656
}
657657
}
658658
break;
659+
case cs.SyntaxKind.ArrayTupleNode:
660+
return true;
659661
}
662+
660663
}
661664
return false;
662665
}
@@ -1759,7 +1762,7 @@ export default class CSharpEmitterContext {
17591762
return true;
17601763
}
17611764

1762-
return this.isEnum(tsType);
1765+
return this.isEnum(tsType) || this.typeChecker.isTupleType(tsType);
17631766
}
17641767

17651768
public isEnum(tsType: ts.Type) {

src.compiler/kotlin/KotlinEmitterContext.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ export default class KotlinEmitterContext extends CSharpEmitterContext {
6969
return undefined;
7070
}
7171

72+
protected isCsValueType(mapValueType: cs.TypeNode | null): boolean {
73+
if(mapValueType?.nodeType === cs.SyntaxKind.ArrayTupleNode) {
74+
return false;
75+
}
76+
return super.isCsValueType(mapValueType);
77+
}
78+
7279
public override getMethodNameFromSymbol(symbol: ts.Symbol): string {
7380
const parent = 'parent' in symbol ? (symbol.parent as ts.Symbol) : undefined;
7481

src/generated/model/BarSerializer.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import { Voice } from "@src/model/Voice";
1414
import { SimileMark } from "@src/model/SimileMark";
1515
import { SustainPedalMarker } from "@src/model/Bar";
1616
import { BarLineStyle } from "@src/model/Bar";
17+
import { KeySignature } from "@src/model/KeySignature";
18+
import { KeySignatureType } from "@src/model/KeySignatureType";
1719
import { BarStyle } from "@src/model/Bar";
1820
export class BarSerializer {
1921
public static fromJson(obj: Bar, m: unknown): void {
@@ -37,6 +39,8 @@ export class BarSerializer {
3739
o.set("sustainpedals", obj.sustainPedals.map(i => SustainPedalMarkerSerializer.toJson(i)));
3840
o.set("barlineleft", obj.barLineLeft as number);
3941
o.set("barlineright", obj.barLineRight as number);
42+
o.set("keysignature", obj.keySignature as number);
43+
o.set("keysignaturetype", obj.keySignatureType as number);
4044
if (obj.style) {
4145
o.set("style", BarStyleSerializer.toJson(obj.style));
4246
}
@@ -84,6 +88,12 @@ export class BarSerializer {
8488
case "barlineright":
8589
obj.barLineRight = JsonHelper.parseEnum<BarLineStyle>(v, BarLineStyle)!;
8690
return true;
91+
case "keysignature":
92+
obj.keySignature = JsonHelper.parseEnum<KeySignature>(v, KeySignature)!;
93+
return true;
94+
case "keysignaturetype":
95+
obj.keySignatureType = JsonHelper.parseEnum<KeySignatureType>(v, KeySignatureType)!;
96+
return true;
8797
case "style":
8898
if (v) {
8999
obj.style = new BarStyle();

src/generated/model/MasterBarSerializer.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import { JsonHelper } from "@src/io/JsonHelper";
88
import { SectionSerializer } from "@src/generated/model/SectionSerializer";
99
import { AutomationSerializer } from "@src/generated/model/AutomationSerializer";
1010
import { FermataSerializer } from "@src/generated/model/FermataSerializer";
11-
import { KeySignature } from "@src/model/KeySignature";
12-
import { KeySignatureType } from "@src/model/KeySignatureType";
1311
import { TripletFeel } from "@src/model/TripletFeel";
1412
import { Section } from "@src/model/Section";
1513
import { Automation } from "@src/model/Automation";
@@ -28,8 +26,6 @@ export class MasterBarSerializer {
2826
}
2927
const o = new Map<string, unknown>();
3028
o.set("alternateendings", obj.alternateEndings);
31-
o.set("keysignature", obj.keySignature as number);
32-
o.set("keysignaturetype", obj.keySignatureType as number);
3329
o.set("isdoublebar", obj.isDoubleBar);
3430
o.set("isrepeatstart", obj.isRepeatStart);
3531
o.set("repeatcount", obj.repeatCount);
@@ -67,12 +63,6 @@ export class MasterBarSerializer {
6763
case "alternateendings":
6864
obj.alternateEndings = v! as number;
6965
return true;
70-
case "keysignature":
71-
obj.keySignature = JsonHelper.parseEnum<KeySignature>(v, KeySignature)!;
72-
return true;
73-
case "keysignaturetype":
74-
obj.keySignatureType = JsonHelper.parseEnum<KeySignatureType>(v, KeySignatureType)!;
75-
return true;
7666
case "isdoublebar":
7767
obj.isDoubleBar = v! as boolean;
7868
return true;

src/importer/AlphaTexImporter.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,8 +1674,6 @@ export class AlphaTexImporter extends ScoreImporter {
16741674
const master: MasterBar = new MasterBar();
16751675
this._score.addMasterBar(master);
16761676
if (master.index > 0) {
1677-
master.keySignature = master.previousMasterBar!.keySignature;
1678-
master.keySignatureType = master.previousMasterBar!.keySignatureType;
16791677
master.timeSignatureDenominator = master.previousMasterBar!.timeSignatureDenominator;
16801678
master.timeSignatureNumerator = master.previousMasterBar!.timeSignatureNumerator;
16811679
master.tripletFeel = master.previousMasterBar!.tripletFeel;
@@ -1797,6 +1795,8 @@ export class AlphaTexImporter extends ScoreImporter {
17971795
if (newBar.previousBar) {
17981796
newBar.clef = newBar.previousBar.clef;
17991797
newBar.clefOttava = newBar.previousBar.clefOttava;
1798+
newBar.keySignature = newBar.previousBar!.keySignature;
1799+
newBar.keySignatureType = newBar.previousBar!.keySignatureType;
18001800
}
18011801
this._barIndex++;
18021802

@@ -3014,8 +3014,8 @@ export class AlphaTexImporter extends ScoreImporter {
30143014
if (this._sy !== AlphaTexSymbols.String) {
30153015
this.error('keysignature', AlphaTexSymbols.String, true);
30163016
}
3017-
master.keySignature = this.parseKeySignature(this._syData as string);
3018-
master.keySignatureType = this.parseKeySignatureType(this._syData as string);
3017+
bar.keySignature = this.parseKeySignature(this._syData as string);
3018+
bar.keySignatureType = this.parseKeySignatureType(this._syData as string);
30193019
this._sy = this.newSy();
30203020
} else if (syData === 'clef') {
30213021
this._sy = this.newSy();

src/importer/CapellaParser.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,9 @@ export class CapellaParser {
510510
if (staff.bars.length > 0) {
511511
currentBar.clef = staff.bars[staff.bars.length - 1].clef;
512512
currentBar.clefOttava = staff.bars[staff.bars.length - 1].clefOttava;
513+
currentBar.keySignature = staff.bars[staff.bars.length - 1].keySignature;
514+
currentBar.keySignatureType = staff.bars[staff.bars.length - 1].keySignatureType;
515+
513516
} else {
514517
currentBar.clef = this._currentStaffLayout.defaultClef;
515518
}
@@ -520,8 +523,6 @@ export class CapellaParser {
520523
const master: MasterBar = new MasterBar();
521524
this.score.addMasterBar(master);
522525
if (master.index > 0) {
523-
master.keySignature = master.previousMasterBar!.keySignature;
524-
master.keySignatureType = master.previousMasterBar!.keySignatureType;
525526
master.tripletFeel = master.previousMasterBar!.tripletFeel;
526527
}
527528

@@ -611,7 +612,7 @@ export class CapellaParser {
611612
this._currentBar.clefOttava = this.parseClefOttava(c.getAttribute('clef'));
612613
break;
613614
case 'keySign':
614-
this._currentBar.masterBar.keySignature = Number.parseInt(
615+
this._currentBar.keySignature = Number.parseInt(
615616
c.getAttribute('fifths')
616617
) as KeySignature;
617618
break;

src/importer/Gp3To5Importer.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ export class Gp3To5Importer extends ScoreImporter {
5959
private _trackCount: number = 0;
6060
private _playbackInfos: PlaybackInformation[] = [];
6161
private _doubleBars: Set<number> = new Set<number>();
62-
62+
private _keySignatures: Map<number, [KeySignature, KeySignatureType]> = new Map<
63+
number,
64+
[KeySignature, KeySignatureType]
65+
>();
6366
private _beatTextChunksByTrack: Map<number, string[]> = new Map<number, string[]>();
6467

6568
private _directionLookup: Map<number, Direction[]> = new Map<number, Direction[]>();
@@ -367,11 +370,10 @@ export class Gp3To5Importer extends ScoreImporter {
367370
}
368371
// keysignature
369372
if ((flags & 0x40) !== 0) {
370-
newMasterBar.keySignature = IOHelper.readSInt8(this.data) as KeySignature;
371-
newMasterBar.keySignatureType = this.data.readByte() as KeySignatureType;
372-
} else if (previousMasterBar) {
373-
newMasterBar.keySignature = previousMasterBar.keySignature;
374-
newMasterBar.keySignatureType = previousMasterBar.keySignatureType;
373+
this._keySignatures.set(this._score.masterBars.length, [
374+
IOHelper.readSInt8(this.data) as KeySignature,
375+
this.data.readByte() as KeySignatureType
376+
]);
375377
}
376378
if (this._versionNumber >= 500 && (flags & 0x03) !== 0) {
377379
this.data.skip(4);
@@ -521,6 +523,15 @@ export class Gp3To5Importer extends ScoreImporter {
521523
}
522524
mainStaff.addBar(newBar);
523525

526+
if (this._keySignatures.has(newBar.index)) {
527+
const newKeySignature = this._keySignatures.get(newBar.index)!;
528+
newBar.keySignature = newKeySignature[0];
529+
newBar.keySignatureType = newKeySignature[1];
530+
} else if (newBar.index > 0) {
531+
newBar.keySignature = newBar.previousBar!.keySignature;
532+
newBar.keySignatureType = newBar.previousBar!.keySignatureType;
533+
}
534+
524535
if (this._doubleBars.has(newBar.index)) {
525536
newBar.barLineRight = BarLineStyle.LightLight;
526537
}

src/importer/GpifParser.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { Fermata, FermataType } from '@src/model/Fermata';
1515
import { Fingers } from '@src/model/Fingers';
1616
import { GraceType } from '@src/model/GraceType';
1717
import { HarmonicType } from '@src/model/HarmonicType';
18-
import type { KeySignature } from '@src/model/KeySignature';
18+
import { KeySignature } from '@src/model/KeySignature';
1919
import { KeySignatureType } from '@src/model/KeySignatureType';
2020
import { Lyrics } from '@src/model/Lyrics';
2121
import { MasterBar } from '@src/model/MasterBar';
@@ -120,6 +120,10 @@ export class GpifParser {
120120
private _skipApplyLyrics: boolean = false;
121121

122122
private _doubleBars: Set<MasterBar> = new Set<MasterBar>();
123+
private _keySignatures: Map<number, [KeySignature, KeySignatureType]> = new Map<
124+
number,
125+
[KeySignature, KeySignatureType]
126+
>();
123127

124128
public parseXml(xml: string, settings: Settings): void {
125129
this._masterTrackAutomations = new Map<number, Automation[]>();
@@ -1203,20 +1207,23 @@ export class GpifParser {
12031207
}
12041208
break;
12051209
case 'Key':
1206-
masterBar.keySignature = Number.parseInt(
1210+
const keySignature = Number.parseInt(
12071211
c.findChildElement('AccidentalCount')!.innerText
12081212
) as KeySignature;
12091213
const mode: XmlNode = c.findChildElement('Mode')!;
1214+
let keySignatureType = KeySignatureType.Major;
12101215
if (mode) {
12111216
switch (mode.innerText.toLowerCase()) {
12121217
case 'major':
1213-
masterBar.keySignatureType = KeySignatureType.Major;
1218+
keySignatureType = KeySignatureType.Major;
12141219
break;
12151220
case 'minor':
1216-
masterBar.keySignatureType = KeySignatureType.Minor;
1221+
keySignatureType = KeySignatureType.Minor;
12171222
break;
12181223
}
12191224
}
1225+
1226+
this._keySignatures.set(this._masterBars.length, [keySignature, keySignatureType]);
12201227
break;
12211228
case 'Fermatas':
12221229
this.parseFermatas(masterBar, c);
@@ -2413,9 +2420,12 @@ export class GpifParser {
24132420
this.score.addTrack(track);
24142421
}
24152422
// process all masterbars
2423+
let keySignature: [KeySignature, KeySignatureType];
2424+
24162425
for (const barIds of this._barsOfMasterBar) {
24172426
// add all bars of masterbar vertically to all tracks
24182427
let staffIndex: number = 0;
2428+
keySignature = [KeySignature.C, KeySignatureType.Major];
24192429
for (
24202430
let barIndex: number = 0, trackIndex: number = 0;
24212431
barIndex < barIds.length && trackIndex < this.score.tracks.length;
@@ -2428,6 +2438,14 @@ export class GpifParser {
24282438
const staff: Staff = track.staves[staffIndex];
24292439
staff.addBar(bar);
24302440

2441+
const masterBarIndex = staff.bars.length - 1;
2442+
if (this._keySignatures.has(masterBarIndex)) {
2443+
keySignature = this._keySignatures.get(masterBarIndex)!;
2444+
}
2445+
2446+
bar.keySignature = keySignature[0];
2447+
bar.keySignatureType = keySignature[1];
2448+
24312449
if (this._doubleBars.has(bar.masterBar)) {
24322450
bar.barLineRight = BarLineStyle.LightLight;
24332451
}
@@ -2490,8 +2508,10 @@ export class GpifParser {
24902508
if (staffIndex === track.staves.length - 1) {
24912509
trackIndex++;
24922510
staffIndex = 0;
2511+
keySignature = [KeySignature.C, KeySignatureType.Major];
24932512
} else {
24942513
staffIndex++;
2514+
keySignature = [KeySignature.C, KeySignatureType.Major];
24952515
}
24962516
} else {
24972517
// no bar for track

0 commit comments

Comments
 (0)