Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/alphatab/scripts/smufl-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const metadata: SmuflMetadata = JSON.parse(await fs.promises.readFile(input, 'ut

const outputMetadata:SmuflMetadata = {
engravingDefaults: metadata.engravingDefaults,
glyphBBoxes: {},
glyphsWithAnchors: {}
glyphBBoxes: {} as SmuflMetadata['glyphBBoxes'],
glyphsWithAnchors: {} as SmuflMetadata['glyphsWithAnchors']
};

const alphaTabUsedGlyphs = new Set<string>();
Expand Down
12 changes: 12 additions & 0 deletions packages/alphatab/src/EngravingSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,10 @@ export class EngravingSettings {
bBoxNE: [1.876, 1.18],
bBoxSW: [0, 0]
},
buzzRoll: {
bBoxNE: [0.624, 0.464],
bBoxSW: [-0.62, -0.464]
},
cClef: {
bBoxNE: [2.796, 2.024],
bBoxSW: [0, -2.024]
Expand Down Expand Up @@ -1884,6 +1888,14 @@ export class EngravingSettings {
bBoxNE: [0.6, 1.112],
bBoxSW: [-0.6, -1.12]
},
tremolo4: {
bBoxNE: [0.6, 1.496],
bBoxSW: [-0.6, -1.48]
},
tremolo5: {
bBoxNE: [0.6, 1.88],
bBoxSW: [-0.604, -1.84]
},
tuplet0: {
bBoxNE: [1.2731041262817027, 1.5],
bBoxSW: [-0.001204330173715796, -0.032]
Expand Down
9 changes: 5 additions & 4 deletions packages/alphatab/src/exporter/GpifWriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -792,16 +792,17 @@ export class GpifWriter {
beatNode.addElement('Fadding').innerText = FadeType[beat.fade];
}
if (beat.isTremolo) {
switch (beat.tremoloSpeed) {
case Duration.Eighth:
switch (beat.tremoloPicking!.marks) {
case 1:
beatNode.addElement('Tremolo').innerText = '1/2';
break;
case Duration.Sixteenth:
case 2:
beatNode.addElement('Tremolo').innerText = '1/4';
break;
case Duration.ThirtySecond:
case 3:
beatNode.addElement('Tremolo').innerText = '1/8';
break;
// NOTE: guitar pro does not support other tremolos
}
}
if (beat.hasChord) {
Expand Down
3 changes: 2 additions & 1 deletion packages/alphatab/src/generated/model/BeatCloner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Beat } from "@coderline/alphatab/model/Beat";
import { NoteCloner } from "@coderline/alphatab/generated/model/NoteCloner";
import { AutomationCloner } from "@coderline/alphatab/generated/model/AutomationCloner";
import { BendPointCloner } from "@coderline/alphatab/generated/model/BendPointCloner";
import { TremoloPickingEffectCloner } from "@coderline/alphatab/generated/model/TremoloPickingEffectCloner";
/**
* @internal
*/
Expand Down Expand Up @@ -54,7 +55,7 @@ export class BeatCloner {
clone.chordId = original.chordId;
clone.graceType = original.graceType;
clone.pickStroke = original.pickStroke;
clone.tremoloSpeed = original.tremoloSpeed;
clone.tremoloPicking = original.tremoloPicking ? TremoloPickingEffectCloner.clone(original.tremoloPicking) : undefined;
clone.crescendo = original.crescendo;
clone.displayStart = original.displayStart;
clone.playbackStart = original.playbackStart;
Expand Down
16 changes: 13 additions & 3 deletions packages/alphatab/src/generated/model/BeatSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { JsonHelper } from "@coderline/alphatab/io/JsonHelper";
import { NoteSerializer } from "@coderline/alphatab/generated/model/NoteSerializer";
import { AutomationSerializer } from "@coderline/alphatab/generated/model/AutomationSerializer";
import { BendPointSerializer } from "@coderline/alphatab/generated/model/BendPointSerializer";
import { TremoloPickingEffectSerializer } from "@coderline/alphatab/generated/model/TremoloPickingEffectSerializer";
import { BeatStyleSerializer } from "@coderline/alphatab/generated/model/BeatStyleSerializer";
import { Note } from "@coderline/alphatab/model/Note";
import { BendStyle } from "@coderline/alphatab/model/BendStyle";
Expand All @@ -21,6 +22,7 @@ import { BendPoint } from "@coderline/alphatab/model/BendPoint";
import { VibratoType } from "@coderline/alphatab/model/VibratoType";
import { GraceType } from "@coderline/alphatab/model/GraceType";
import { PickStroke } from "@coderline/alphatab/model/PickStroke";
import { TremoloPickingEffect } from "@coderline/alphatab/model/TremoloPickingEffect";
import { CrescendoType } from "@coderline/alphatab/model/CrescendoType";
import { GolpeType } from "@coderline/alphatab/model/GolpeType";
import { DynamicValue } from "@coderline/alphatab/model/DynamicValue";
Expand Down Expand Up @@ -75,7 +77,9 @@ export class BeatSerializer {
o.set("chordid", obj.chordId);
o.set("gracetype", obj.graceType as number);
o.set("pickstroke", obj.pickStroke as number);
o.set("tremolospeed", obj.tremoloSpeed as number | null);
if (obj.tremoloPicking) {
o.set("tremolopicking", TremoloPickingEffectSerializer.toJson(obj.tremoloPicking));
}
o.set("crescendo", obj.crescendo as number);
o.set("displaystart", obj.displayStart);
o.set("playbackstart", obj.playbackStart);
Expand Down Expand Up @@ -201,8 +205,14 @@ export class BeatSerializer {
case "pickstroke":
obj.pickStroke = JsonHelper.parseEnum<PickStroke>(v, PickStroke)!;
return true;
case "tremolospeed":
obj.tremoloSpeed = JsonHelper.parseEnum<Duration>(v, Duration) ?? null;
case "tremolopicking":
if (v) {
obj.tremoloPicking = new TremoloPickingEffect();
TremoloPickingEffectSerializer.fromJson(obj.tremoloPicking, v);
}
else {
obj.tremoloPicking = undefined;
}
return true;
case "crescendo":
obj.crescendo = JsonHelper.parseEnum<CrescendoType>(v, CrescendoType)!;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// <auto-generated>
// This code was auto-generated.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
import { TremoloPickingEffect } from "@coderline/alphatab/model/TremoloPickingEffect";
/**
* @internal
*/
export class TremoloPickingEffectCloner {
public static clone(original: TremoloPickingEffect): TremoloPickingEffect {
const clone = new TremoloPickingEffect();
clone.marks = original.marks;
clone.style = original.style;
return clone;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// <auto-generated>
// This code was auto-generated.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
import { TremoloPickingEffect } from "@coderline/alphatab/model/TremoloPickingEffect";
import { JsonHelper } from "@coderline/alphatab/io/JsonHelper";
import { TremoloPickingStyle } from "@coderline/alphatab/model/TremoloPickingEffect";
/**
* @internal
*/
export class TremoloPickingEffectSerializer {
public static fromJson(obj: TremoloPickingEffect, m: unknown): void {
if (!m) {
return;
}
JsonHelper.forEach(m, (v, k) => TremoloPickingEffectSerializer.setProperty(obj, k, v));
}
public static toJson(obj: TremoloPickingEffect | null): Map<string, unknown> | null {
if (!obj) {
return null;
}
const o = new Map<string, unknown>();
o.set("marks", obj.marks);
o.set("style", obj.style as number);
return o;
}
public static setProperty(obj: TremoloPickingEffect, property: string, v: unknown): boolean {
switch (property) {
case "marks":
obj.marks = v! as number;
return true;
case "style":
obj.style = JsonHelper.parseEnum<TremoloPickingStyle>(v, TremoloPickingStyle)!;
return true;
}
return false;
}
}
21 changes: 8 additions & 13 deletions packages/alphatab/src/importer/Gp3To5Importer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { BeamDirection } from '@coderline/alphatab/rendering/utils/BeamDirection
import { Ottavia } from '@coderline/alphatab/model/Ottavia';
import { WahPedal } from '@coderline/alphatab/model/WahPedal';
import { AccidentalType } from '@coderline/alphatab/model/AccidentalType';
import { TremoloPickingEffect } from '@coderline/alphatab/model/TremoloPickingEffect';

/**
* @internal
Expand All @@ -63,7 +64,10 @@ export class Gp3To5Importer extends ScoreImporter {
private _playbackInfos: PlaybackInformation[] = [];
private _doubleBars: Set<number> = new Set<number>();
private _clefsPerTrack: Map<number, Clef> = new Map<number, Clef>();
private _keySignatures: Map<number, [KeySignature, KeySignatureType]> = new Map<number, [KeySignature, KeySignatureType]>();
private _keySignatures: Map<number, [KeySignature, KeySignatureType]> = new Map<
number,
[KeySignature, KeySignatureType]
>();
private _beatTextChunksByTrack: Map<number, string[]> = new Map<number, string[]>();

private _directionLookup: Map<number, Direction[]> = new Map<number, Direction[]>();
Expand Down Expand Up @@ -1356,18 +1360,9 @@ export class Gp3To5Importer extends ScoreImporter {
}

public readTremoloPicking(beat: Beat): void {
const speed: number = this.data.readByte();
switch (speed) {
case 1:
beat.tremoloSpeed = Duration.Eighth;
break;
case 2:
beat.tremoloSpeed = Duration.Sixteenth;
break;
case 3:
beat.tremoloSpeed = Duration.ThirtySecond;
break;
}
const effect = new TremoloPickingEffect();
beat.tremoloPicking = effect;
effect.marks = this.data.readByte();
}

public readSlide(note: Note): void {
Expand Down
9 changes: 6 additions & 3 deletions packages/alphatab/src/importer/GpifParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import { Direction } from '@coderline/alphatab/model/Direction';
import { ModelUtils } from '@coderline/alphatab/model/ModelUtils';
import { BackingTrack } from '@coderline/alphatab/model/BackingTrack';
import { Tuning } from '@coderline/alphatab/model/Tuning';
import { TremoloPickingEffect } from '@coderline/alphatab/model/TremoloPickingEffect';

/**
* This structure represents a duration within a gpif
Expand Down Expand Up @@ -1693,15 +1694,17 @@ export class GpifParser {
}
break;
case 'Tremolo':
const tremolo = new TremoloPickingEffect();
beat.tremoloPicking = tremolo;
switch (c.innerText) {
case '1/2':
beat.tremoloSpeed = Duration.Eighth;
tremolo.marks = 1;
break;
case '1/4':
beat.tremoloSpeed = Duration.Sixteenth;
tremolo.marks = 2;
break;
case '1/8':
beat.tremoloSpeed = Duration.ThirtySecond;
tremolo.marks = 3;
break;
}
break;
Expand Down
21 changes: 11 additions & 10 deletions packages/alphatab/src/importer/MusicXmlImporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { SimileMark } from '@coderline/alphatab/model/SimileMark';
import { SlideOutType } from '@coderline/alphatab/model/SlideOutType';
import { Staff } from '@coderline/alphatab/model/Staff';
import { Track } from '@coderline/alphatab/model/Track';
import { TremoloPickingEffect, TremoloPickingStyle } from '@coderline/alphatab/model/TremoloPickingEffect';
import { TripletFeel } from '@coderline/alphatab/model/TripletFeel';
import { VibratoType } from '@coderline/alphatab/model/VibratoType';
import { Voice } from '@coderline/alphatab/model/Voice';
Expand Down Expand Up @@ -3579,17 +3580,17 @@ export class MusicXmlImporter extends ScoreImporter {
break;
// case 'schleifer': Not supported
case 'tremolo':
switch (c.innerText) {
case '1':
note.beat.tremoloSpeed = Duration.Eighth;
break;
case '2':
note.beat.tremoloSpeed = Duration.Sixteenth;
break;
case '3':
note.beat.tremoloSpeed = Duration.ThirtySecond;
break;
const tremolo = new TremoloPickingEffect();
note.beat.tremoloPicking = tremolo;
tremolo.marks = Number.parseInt(c.innerText, 10);

if (
(c.getAttribute('type', '') === 'unmeasured' && tremolo.marks === 0) ||
c.getAttribute('smufl', '') === 'buzzRoll'
) {
tremolo.style = TremoloPickingStyle.BuzzRoll;
}

break;
// case 'haydn': Not supported
// case 'other-element': Not supported
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
TrackNamePolicy
} from '@coderline/alphatab/model/RenderStylesheet';
import type { SimileMark } from '@coderline/alphatab/model/SimileMark';
import type { TremoloPickingStyle } from '@coderline/alphatab/model/TremoloPickingEffect';
import type { TripletFeel } from '@coderline/alphatab/model/TripletFeel';
import type { WhammyType } from '@coderline/alphatab/model/WhammyType';
import type { TextAlign } from '@coderline/alphatab/platform/ICanvas';
Expand Down Expand Up @@ -397,6 +398,13 @@ export class AlphaTex1EnumMappings {
['dadoublecoda', 18]
]);
public static readonly directionReversed = AlphaTex1EnumMappings._reverse(AlphaTex1EnumMappings.direction);
public static readonly tremoloPickingStyle = new Map<string, TremoloPickingStyle>([
['default', 0],
['buzzroll', 1]
]);
public static readonly tremoloPickingStyleReversed = AlphaTex1EnumMappings._reverse(
AlphaTex1EnumMappings.tremoloPickingStyle
);
public static readonly keySignaturesMinorReversed = new Map<KeySignature, string>([
[-7, 'abminor'],
[-6, 'ebminor'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,15 @@ export class AlphaTex1LanguageDefinitions {
],
['volume', [[[[16], 0]]]],
['balance', [[[[16], 0]]]],
['tp', [[[[16], 0, ['8', '16', '32']]]]],
[
'tp',
[
[
[[16], 0],
[[10, 17], 1, ['default', 'buzzroll']]
]
]
],
[
'barre',
[
Expand Down
Loading
Loading