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
15 changes: 12 additions & 3 deletions packages/alphatab/src/Environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ import { createGolpeEffectInfo } from '@coderline/alphatab/rendering/effects/Gol
import { createHarmonicsEffectInfo } from '@coderline/alphatab/rendering/effects/HarmonicsEffectInfo';
import { leftHandTapEffectInfo } from '@coderline/alphatab/rendering/effects/LeftHandTapEffectInfo';
import { letRingEffectInfo } from '@coderline/alphatab/rendering/effects/LetRingEffectInfo';
import { lyricsEffectInfo } from '@coderline/alphatab/rendering/effects/LyricsEffectInfo';
import {
lyricsAboveEffectInfo,
lyricsBelowEffectInfo
} from '@coderline/alphatab/rendering/effects/LyricsEffectInfo';
import { markerEffectInfo } from '@coderline/alphatab/rendering/effects/MarkerEffectInfo';
import { noteOrnamentEffectInfo } from '@coderline/alphatab/rendering/effects/NoteOrnamentEffectInfo';
import { numberedBarKeySignatureEffectInfo } from '@coderline/alphatab/rendering/effects/NumberedBarKeySignatureEffectInfo';
Expand Down Expand Up @@ -467,6 +470,8 @@ export class Environment {
//
// Slash
new SlashBarRendererFactory([
{ effect: lyricsAboveEffectInfo, mode: EffectBandMode.OwnedTop },
{ effect: lyricsBelowEffectInfo, mode: EffectBandMode.OwnedBottom },
{ effect: tempoEffectInfo, mode: EffectBandMode.SharedTop },
{ effect: tripletFeelEffectInfo, mode: EffectBandMode.SharedTop },
{ effect: markerEffectInfo, mode: EffectBandMode.SharedTop },
Expand All @@ -482,6 +487,8 @@ export class Environment {
//
// Score (standard notation)
new ScoreBarRendererFactory([
{ effect: lyricsAboveEffectInfo, mode: EffectBandMode.OwnedTop },
{ effect: lyricsBelowEffectInfo, mode: EffectBandMode.OwnedBottom },
{ effect: capoEffectInfo, mode: EffectBandMode.SharedTop },
{ effect: fermataEffectInfo, mode: EffectBandMode.SharedTop },
{ effect: beatBarreEffectInfo, mode: EffectBandMode.SharedTop },
Expand Down Expand Up @@ -535,6 +542,8 @@ export class Environment {
//
// Numbered
new NumberedBarRendererFactory([
{ effect: lyricsAboveEffectInfo, mode: EffectBandMode.OwnedTop },
{ effect: lyricsBelowEffectInfo, mode: EffectBandMode.OwnedBottom },
{ effect: numberedBarKeySignatureEffectInfo, mode: EffectBandMode.OwnedTop, order: 1000 },
{ effect: slideLabelEffectInfo, mode: EffectBandMode.OwnedTop },
{ effect: hammerPullLabelEffectInfo, mode: EffectBandMode.OwnedTop }
Expand All @@ -543,8 +552,8 @@ export class Environment {
//
// Tabs
new TabBarRendererFactory([
{ effect: lyricsEffectInfo, mode: EffectBandMode.SharedTop },

{ effect: lyricsAboveEffectInfo, mode: EffectBandMode.OwnedTop },
{ effect: lyricsBelowEffectInfo, mode: EffectBandMode.OwnedBottom },
{ effect: tabWhammyEffectInfo, mode: EffectBandMode.OwnedTop },
{ effect: trillEffectInfo, mode: EffectBandMode.OwnedTop },
{ effect: wideBeatVibratoEffectInfo, mode: EffectBandMode.OwnedTop },
Expand Down
2 changes: 1 addition & 1 deletion packages/alphatab/src/NotationSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export enum NotationElement {
EffectLetRing = 23,

/**
* The lyrics of the track shown above the staff.
* The lyrics of the track, placed as configured in `RenderStylesheet.lyricsPlacement`.
*/
EffectLyrics = 24,

Expand Down
2 changes: 1 addition & 1 deletion packages/alphatab/src/generated/SerializerSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ export class SerializerSchema {
/**
* A hash of the field ids, keys and types of all serialized classes (50 classes).
*/
public static readonly fingerprint: number = 0xb9644837;
public static readonly fingerprint: number = 0xc4694831;
}
89 changes: 47 additions & 42 deletions packages/alphatab/src/generated/model/RenderStylesheetSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { RecordFields } from "@coderline/alphatab/io/RecordFields";
import { BracketExtendMode } from "@coderline/alphatab/model/RenderStylesheet";
import { JsonHelper } from "@coderline/alphatab/io/JsonHelper";
import { TuningDisplayMode } from "@coderline/alphatab/model/RenderStylesheet";
import { LyricsPlacement } from "@coderline/alphatab/model/RenderStylesheet";
import { TrackNamePolicy } from "@coderline/alphatab/model/RenderStylesheet";
import { TrackNameMode } from "@coderline/alphatab/model/RenderStylesheet";
import { TrackNameOrientation } from "@coderline/alphatab/model/RenderStylesheet";
Expand All @@ -22,7 +23,7 @@ import type { IObjectWriter } from "@coderline/alphatab/io/IObjectWriter";
* @internal
*/
export class RenderStylesheetSerializer {
private static readonly _fields: RecordFields = new RecordFields(["hidedynamics", "bracketextendmode", "usesystemsignseparator", "globaldisplaytuning", "tuningdisplaymode", "pertrackdisplaytuning", "globaldisplaychorddiagramsontop", "pertrackchorddiagramsontop", "globaldisplaychorddiagramsinscore", "singletracktracknamepolicy", "multitracktracknamepolicy", "firstsystemtracknamemode", "othersystemstracknamemode", "firstsystemtracknameorientation", "othersystemstracknameorientation", "multitrackmultibarrest", "pertrackmultibarrest", "extendbarlines", "hideemptystaves", "hideemptystavesinfirstsystem", "showsinglestaffbrackets", "barnumberdisplay", "scoreconfig", "tabconfig", "slashconfig", "numberedconfig"]);
private static readonly _fields: RecordFields = new RecordFields(["hidedynamics", "bracketextendmode", "usesystemsignseparator", "globaldisplaytuning", "tuningdisplaymode", "lyricsplacement", "pertrackdisplaytuning", "globaldisplaychorddiagramsontop", "pertrackchorddiagramsontop", "globaldisplaychorddiagramsinscore", "singletracktracknamepolicy", "multitracktracknamepolicy", "firstsystemtracknamemode", "othersystemstracknamemode", "firstsystemtracknameorientation", "othersystemstracknameorientation", "multitrackmultibarrest", "pertrackmultibarrest", "extendbarlines", "hideemptystaves", "hideemptystavesinfirstsystem", "showsinglestaffbrackets", "barnumberdisplay", "scoreconfig", "tabconfig", "slashconfig", "numberedconfig"]);
public static read(obj: RenderStylesheet, reader: IObjectReader): void {
reader.readRecord(RenderStylesheetSerializer._fields, (id, k, r) => {
switch (id) {
Expand All @@ -42,66 +43,69 @@ export class RenderStylesheetSerializer {
obj.tuningDisplayMode = JsonHelper.parseEnum<TuningDisplayMode>(r.readValue(), TuningDisplayMode)!;
return true;
case 5:
RenderStylesheetSerializer._readPerTrackDisplayTuning(obj, r);
obj.lyricsPlacement = JsonHelper.parseEnum<LyricsPlacement>(r.readValue(), LyricsPlacement)!;
return true;
case 6:
obj.globalDisplayChordDiagramsOnTop = r.readBoolean();
RenderStylesheetSerializer._readPerTrackDisplayTuning(obj, r);
return true;
case 7:
RenderStylesheetSerializer._readPerTrackChordDiagramsOnTop(obj, r);
obj.globalDisplayChordDiagramsOnTop = r.readBoolean();
return true;
case 8:
obj.globalDisplayChordDiagramsInScore = r.readBoolean();
RenderStylesheetSerializer._readPerTrackChordDiagramsOnTop(obj, r);
return true;
case 9:
obj.singleTrackTrackNamePolicy = JsonHelper.parseEnum<TrackNamePolicy>(r.readValue(), TrackNamePolicy)!;
obj.globalDisplayChordDiagramsInScore = r.readBoolean();
return true;
case 10:
obj.multiTrackTrackNamePolicy = JsonHelper.parseEnum<TrackNamePolicy>(r.readValue(), TrackNamePolicy)!;
obj.singleTrackTrackNamePolicy = JsonHelper.parseEnum<TrackNamePolicy>(r.readValue(), TrackNamePolicy)!;
return true;
case 11:
obj.firstSystemTrackNameMode = JsonHelper.parseEnum<TrackNameMode>(r.readValue(), TrackNameMode)!;
obj.multiTrackTrackNamePolicy = JsonHelper.parseEnum<TrackNamePolicy>(r.readValue(), TrackNamePolicy)!;
return true;
case 12:
obj.otherSystemsTrackNameMode = JsonHelper.parseEnum<TrackNameMode>(r.readValue(), TrackNameMode)!;
obj.firstSystemTrackNameMode = JsonHelper.parseEnum<TrackNameMode>(r.readValue(), TrackNameMode)!;
return true;
case 13:
obj.firstSystemTrackNameOrientation = JsonHelper.parseEnum<TrackNameOrientation>(r.readValue(), TrackNameOrientation)!;
obj.otherSystemsTrackNameMode = JsonHelper.parseEnum<TrackNameMode>(r.readValue(), TrackNameMode)!;
return true;
case 14:
obj.otherSystemsTrackNameOrientation = JsonHelper.parseEnum<TrackNameOrientation>(r.readValue(), TrackNameOrientation)!;
obj.firstSystemTrackNameOrientation = JsonHelper.parseEnum<TrackNameOrientation>(r.readValue(), TrackNameOrientation)!;
return true;
case 15:
obj.multiTrackMultiBarRest = r.readBoolean();
obj.otherSystemsTrackNameOrientation = JsonHelper.parseEnum<TrackNameOrientation>(r.readValue(), TrackNameOrientation)!;
return true;
case 16:
obj.perTrackMultiBarRest = new Set<number>(r.readValue() as number[]);
obj.multiTrackMultiBarRest = r.readBoolean();
return true;
case 17:
obj.extendBarLines = r.readBoolean();
obj.perTrackMultiBarRest = new Set<number>(r.readValue() as number[]);
return true;
case 18:
obj.hideEmptyStaves = r.readBoolean();
obj.extendBarLines = r.readBoolean();
return true;
case 19:
obj.hideEmptyStavesInFirstSystem = r.readBoolean();
obj.hideEmptyStaves = r.readBoolean();
return true;
case 20:
obj.showSingleStaffBrackets = r.readBoolean();
obj.hideEmptyStavesInFirstSystem = r.readBoolean();
return true;
case 21:
obj.barNumberDisplay = JsonHelper.parseEnum<BarNumberDisplay>(r.readValue(), BarNumberDisplay)!;
obj.showSingleStaffBrackets = r.readBoolean();
return true;
case 22:
ScoreStaffConfigSerializer.readFlexible(obj.scoreConfig, r);
obj.barNumberDisplay = JsonHelper.parseEnum<BarNumberDisplay>(r.readValue(), BarNumberDisplay)!;
return true;
case 23:
TabStaffConfigSerializer.readFlexible(obj.tabConfig, r);
ScoreStaffConfigSerializer.readFlexible(obj.scoreConfig, r);
return true;
case 24:
SlashStaffConfigSerializer.readFlexible(obj.slashConfig, r);
TabStaffConfigSerializer.readFlexible(obj.tabConfig, r);
return true;
case 25:
SlashStaffConfigSerializer.readFlexible(obj.slashConfig, r);
return true;
case 26:
NumberedStaffConfigSerializer.readFlexible(obj.numberedConfig, r);
return true;
}
Expand Down Expand Up @@ -133,50 +137,51 @@ export class RenderStylesheetSerializer {
w.booleanField(2, obj.useSystemSignSeparator);
w.booleanField(3, obj.globalDisplayTuning);
w.numberField(4, obj.tuningDisplayMode as number);
w.numberField(5, obj.lyricsPlacement as number);
if (obj.perTrackDisplayTuning !== null) {
w.mapField(5);
w.mapField(6);
for (const [k, v] of obj.perTrackDisplayTuning!) {
w.prop(k.toString());
w.writeBoolean(v);
}
w.endMap();
}
w.booleanField(6, obj.globalDisplayChordDiagramsOnTop);
w.booleanField(7, obj.globalDisplayChordDiagramsOnTop);
if (obj.perTrackChordDiagramsOnTop !== null) {
w.mapField(7);
w.mapField(8);
for (const [k, v] of obj.perTrackChordDiagramsOnTop!) {
w.prop(k.toString());
w.writeBoolean(v);
}
w.endMap();
}
w.booleanField(8, obj.globalDisplayChordDiagramsInScore);
w.numberField(9, obj.singleTrackTrackNamePolicy as number);
w.numberField(10, obj.multiTrackTrackNamePolicy as number);
w.numberField(11, obj.firstSystemTrackNameMode as number);
w.numberField(12, obj.otherSystemsTrackNameMode as number);
w.numberField(13, obj.firstSystemTrackNameOrientation as number);
w.numberField(14, obj.otherSystemsTrackNameOrientation as number);
w.booleanField(15, obj.multiTrackMultiBarRest);
w.booleanField(9, obj.globalDisplayChordDiagramsInScore);
w.numberField(10, obj.singleTrackTrackNamePolicy as number);
w.numberField(11, obj.multiTrackTrackNamePolicy as number);
w.numberField(12, obj.firstSystemTrackNameMode as number);
w.numberField(13, obj.otherSystemsTrackNameMode as number);
w.numberField(14, obj.firstSystemTrackNameOrientation as number);
w.numberField(15, obj.otherSystemsTrackNameOrientation as number);
w.booleanField(16, obj.multiTrackMultiBarRest);
if (obj.perTrackMultiBarRest !== null) {
const a: number[] = [];
for (const v of obj.perTrackMultiBarRest!) {
a.push(v);
}
w.valueField(16, a);
w.valueField(17, a);
}
w.booleanField(17, obj.extendBarLines);
w.booleanField(18, obj.hideEmptyStaves);
w.booleanField(19, obj.hideEmptyStavesInFirstSystem);
w.booleanField(20, obj.showSingleStaffBrackets);
w.numberField(21, obj.barNumberDisplay as number);
w.field(22);
ScoreStaffConfigSerializer.write(obj.scoreConfig, w);
w.booleanField(18, obj.extendBarLines);
w.booleanField(19, obj.hideEmptyStaves);
w.booleanField(20, obj.hideEmptyStavesInFirstSystem);
w.booleanField(21, obj.showSingleStaffBrackets);
w.numberField(22, obj.barNumberDisplay as number);
w.field(23);
TabStaffConfigSerializer.write(obj.tabConfig, w);
ScoreStaffConfigSerializer.write(obj.scoreConfig, w);
w.field(24);
SlashStaffConfigSerializer.write(obj.slashConfig, w);
TabStaffConfigSerializer.write(obj.tabConfig, w);
w.field(25);
SlashStaffConfigSerializer.write(obj.slashConfig, w);
w.field(26);
NumberedStaffConfigSerializer.write(obj.numberedConfig, w);
w.endObject();
}
Expand Down
25 changes: 25 additions & 0 deletions packages/alphatab/src/importer/BinaryStylesheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Color } from '@coderline/alphatab/model/Color';
import {
BarNumberDisplay,
type BracketExtendMode,
LyricsPlacement,
TrackNameMode,
TrackNameOrientation,
TrackNamePolicy,
Expand Down Expand Up @@ -145,8 +146,16 @@ export class BinaryStylesheet {
}

public apply(score: Score): void {
let hideLyrics = false;
let drawLyricsUpside = false;
for (const [key, value] of this.raw) {
switch (key) {
case 'System/hideLyrics':
hideLyrics = value as boolean;
break;
case 'System/drawLyricsUpside':
drawLyricsUpside = value as boolean;
break;
case 'StandardNotation/hideDynamics':
score.stylesheet.hideDynamics = value as boolean;
break;
Expand Down Expand Up @@ -385,6 +394,12 @@ export class BinaryStylesheet {
break;
}
}

if (hideLyrics) {
score.stylesheet.lyricsPlacement = LyricsPlacement.Hidden;
} else if (drawLyricsUpside) {
score.stylesheet.lyricsPlacement = LyricsPlacement.Above;
}
}
private _toTextAlign(value: number): TextAlign {
switch (value) {
Expand Down Expand Up @@ -566,6 +581,16 @@ export class BinaryStylesheet {
}

binaryStylesheet.addValue('System/ExtendedBarLines', score.stylesheet.extendBarLines, DataType.Boolean);
binaryStylesheet.addValue(
'System/hideLyrics',
score.stylesheet.lyricsPlacement === LyricsPlacement.Hidden,
DataType.Boolean
);
binaryStylesheet.addValue(
'System/drawLyricsUpside',
score.stylesheet.lyricsPlacement === LyricsPlacement.Above,
DataType.Boolean
);

const scoreStyle = score.style;
if (scoreStyle) {
Expand Down
17 changes: 16 additions & 1 deletion packages/alphatab/src/importer/MusicXmlImporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import { NoteOrnament } from '@coderline/alphatab/model/NoteOrnament';
import { Ottavia } from '@coderline/alphatab/model/Ottavia';
import { PercussionMapper } from '@coderline/alphatab/model/PercussionMapper';
import { PickStroke } from '@coderline/alphatab/model/PickStroke';
import { BarNumberDisplay } from '@coderline/alphatab/model/RenderStylesheet';
import { BarNumberDisplay, LyricsPlacement } from '@coderline/alphatab/model/RenderStylesheet';
import { Score } from '@coderline/alphatab/model/Score';
import { Section } from '@coderline/alphatab/model/Section';
import { Staff } from '@coderline/alphatab/model/Staff';
Expand Down Expand Up @@ -282,6 +282,8 @@ export class MusicXmlImporter extends ScoreImporter {
* Used to only store custom bar numbers where the measure number differs from it.
*/
private _nextBarNumber: number = 1;
private _lyricsCount: number = 0;
private _lyricsAboveCount: number = 0;

private _divisionsPerQuarterNote: number = 1;
/**
Expand All @@ -308,6 +310,7 @@ export class MusicXmlImporter extends ScoreImporter {
this._parseDom(dom);
this._applySpans();
this._applyDynamics();
this._applyLyricsPlacement();
ModelUtils.consolidate(this._score);
this._score.finish(this.settings);
this._score.rebuildRepeatGroups();
Expand Down Expand Up @@ -3654,7 +3657,19 @@ export class MusicXmlImporter extends ScoreImporter {
newBeat.updateDurations();
}

private _applyLyricsPlacement() {
// the placement is per lyric, the stylesheet score-wide: above only if no lyric is below
if (this._lyricsCount > 0 && this._lyricsAboveCount === this._lyricsCount) {
this._score.stylesheet.lyricsPlacement = LyricsPlacement.Above;
}
}

private _parseLyric(element: XmlNode, beat: Beat, track: Track) {
this._lyricsCount++;
if (element.getAttribute('placement', '') === 'above') {
this._lyricsAboveCount++;
}

const info = this._indexToTrackInfo.get(track.index)!;
const index = info.getLyricLine(element.getAttribute('number', ''));
if (beat.lyrics === null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type { Rasgueado } from '@coderline/alphatab/model/Rasgueado';
import type {
BarNumberDisplay,
BracketExtendMode,
LyricsPlacement,
TrackNameMode,
TrackNameOrientation,
TrackNamePolicy,
Expand Down Expand Up @@ -222,6 +223,14 @@ export class AlphaTex1EnumMappings {
public static readonly tuningDisplayModeReversed = AlphaTex1EnumMappings._reverse(
AlphaTex1EnumMappings.tuningDisplayMode
);
public static readonly lyricsPlacement = new Map<string, LyricsPlacement>([
['below', 0],
['above', 1],
['hidden', 2]
]);
public static readonly lyricsPlacementReversed = AlphaTex1EnumMappings._reverse(
AlphaTex1EnumMappings.lyricsPlacement
);
public static readonly textAlign = new Map<string, TextAlign>([
['left', 0],
['center', 1],
Expand Down
Loading
Loading