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
3 changes: 1 addition & 2 deletions packages/alphatab/.env
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
FORCE_COLOR=1
NODE_OPTIONS=--expose-gc
UPDATE_SNAPSHOT=true
NODE_OPTIONS=--expose-gc
46 changes: 33 additions & 13 deletions packages/alphatab/src/AlphaTabApiBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import { AlphaTexImporter } from '@coderline/alphatab/importer/AlphaTexImporter';
import { Logger } from '@coderline/alphatab/Logger';
import { AlphaSynthMidiFileHandler } from '@coderline/alphatab/midi/AlphaSynthMidiFileHandler';
import type { BeatTickLookupItem } from '@coderline/alphatab/midi/BeatTickLookup';
import type { BeatTickLookupItem, IBeatVisibilityChecker } from '@coderline/alphatab/midi/BeatTickLookup';
import type {
MetaDataEvent,
MetaEvent,
Expand Down Expand Up @@ -122,6 +122,22 @@ export interface PlaybackHighlightChangeEventArgs {
highlightBlocks?: Bounds[];
}

/**
* @internal
*/
class BoundsLookupVisibilityChecker implements IBeatVisibilityChecker {
public bounds: BoundsLookup | null = null;

public isVisible(beat: Beat): boolean {
const bounds = this.bounds;
if (!bounds) {
return false;
}

return bounds.findBeat(beat) !== null;
}
}

/**
* This class represents the public API of alphaTab and provides all logic to display
* a music sheet in any UI using the given {@link IUiFacade}
Expand All @@ -132,6 +148,7 @@ export class AlphaTabApiBase<TSettings> {
private _startTime: number = 0;
private _trackIndexes: number[] | null = null;
private _trackIndexLookup: Set<number> | null = null;
private readonly _beatVisibilityChecker = new BoundsLookupVisibilityChecker();
private _isDestroyed: boolean = false;
private _score: Score | null = null;
private _tracks: Track[] = [];
Expand Down Expand Up @@ -2049,18 +2066,19 @@ export class AlphaTabApiBase<TSettings> {

const cache: MidiTickLookup | null = this._tickCache;
if (cache) {
const tracks = this._trackIndexLookup;
if (tracks != null && tracks.size > 0) {
const beat: MidiTickLookupFindBeatResult | null = cache.findBeat(tracks, tick, this._currentBeat);
if (beat) {
this._cursorUpdateBeat(
beat,
stop,
shouldScroll,
cursorSpeed,
forceUpdate || this.playerState === PlayerState.Paused
);
}
const beat: MidiTickLookupFindBeatResult | null = cache.findBeatWithChecker(
this._beatVisibilityChecker,
tick,
this._currentBeat
);
if (beat) {
this._cursorUpdateBeat(
beat,
stop,
shouldScroll,
cursorSpeed,
forceUpdate || this.playerState === PlayerState.Paused
);
}
}
}
Expand Down Expand Up @@ -3420,6 +3438,8 @@ export class AlphaTabApiBase<TSettings> {
return;
}

this._beatVisibilityChecker.bounds = this.boundsLookup;

this._currentBeat = null;
this._cursorUpdateTick(this._previousTick, false, 1, true, true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ export class RenderStylesheetSerializer {
}
}
o.set("extendbarlines", obj.extendBarLines);
o.set("hideemptystaves", obj.hideEmptyStaves);
o.set("hideemptystavesinfirstsystem", obj.hideEmptyStavesInFirstSystem);
o.set("showsinglestaffbrackets", obj.showSingleStaffBrackets);
return o;
}
public static setProperty(obj: RenderStylesheet, property: string, v: unknown): boolean {
Expand Down Expand Up @@ -120,6 +123,15 @@ export class RenderStylesheetSerializer {
case "extendbarlines":
obj.extendBarLines = v! as boolean;
return true;
case "hideemptystaves":
obj.hideEmptyStaves = v! as boolean;
return true;
case "hideemptystavesinfirstsystem":
obj.hideEmptyStavesInFirstSystem = v! as boolean;
return true;
case "showsinglestaffbrackets":
obj.showSingleStaffBrackets = v! as boolean;
return true;
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,10 @@ export class AlphaTex1LanguageDefinitions {
['firstsystemtracknameorientation', [[[[10, 17], 0, ['horizontal', 'vertical']]]]],
['othersystemstracknameorientation', [[[[10, 17], 0, ['horizontal', 'vertical']]]]],
['extendbarlines', null],
['chorddiagramsinscore', [[[[10], 1, ['true', 'false']]]]]
['chorddiagramsinscore', [[[[10], 1, ['true', 'false']]]]],
['hideemptystaves', null],
['hideemptystavesinfirstsystem', null],
['showsinglestaffbrackets', null]
]);
public static readonly staffMetaDataSignatures = AlphaTex1LanguageDefinitions._signatures([
['tuning', [[[[10, 17], 0, ['piano', 'none', 'voice']]], [[[10, 17], 5]]]],
Expand Down Expand Up @@ -530,6 +533,9 @@ export class AlphaTex1LanguageDefinitions {
['othersystemstracknameorientation', null],
['extendbarlines', null],
['chorddiagramsinscore', null],
['hideemptystaves', null],
['hideemptystavesinfirstsystem', null],
['showsinglestaffbrackets', null],
[
'tuning',
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,15 @@ export class AlphaTex1LanguageHandler implements IAlphaTexLanguageImportHandler
? AlphaTex1LanguageHandler._booleanLikeValue(metaData.arguments!.arguments, 0)
: true;
return ApplyNodeResult.Applied;
case 'hideemptystaves':
score.stylesheet.hideEmptyStaves = true;
return ApplyNodeResult.Applied;
case 'hideemptystavesinfirstsystem':
score.stylesheet.hideEmptyStavesInFirstSystem = true;
return ApplyNodeResult.Applied;
case 'showsinglestaffbrackets':
score.stylesheet.showSingleStaffBrackets = true;
return ApplyNodeResult.Applied;

default:
return ApplyNodeResult.NotAppliedUnrecognizedMarker;
Expand Down Expand Up @@ -2497,6 +2506,18 @@ export class AlphaTex1LanguageHandler implements IAlphaTexLanguageImportHandler
if (stylesheet.globalDisplayChordDiagramsInScore) {
nodes.push(Atnf.meta('chordDiagramsInScore'));
}

if (stylesheet.hideEmptyStaves) {
nodes.push(Atnf.meta('hideEmptyStaves'));
}

if (stylesheet.hideEmptyStavesInFirstSystem) {
nodes.push(Atnf.meta('hideEmptyStavesInFirstSystem'));
}

if (stylesheet.showSingleStaffBrackets) {
nodes.push(Atnf.meta('showSingleStaffBrackets'));
}

// Unsupported:
// 'globaldisplaychorddiagramsontop',
Expand Down
23 changes: 23 additions & 0 deletions packages/alphatab/src/midi/BeatTickLookup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ export class BeatTickLookupItem {
}
}

/**
* Classes implementing this interface can help in checking whether beats are currently being
* displayed so that they can be considered for a tick-search.
* @public
*/
export interface IBeatVisibilityChecker {
isVisible(beat: Beat): boolean;
}

/**
* Represents the time period, for which one or multiple {@link Beat}s are played
* @public
Expand Down Expand Up @@ -96,4 +105,18 @@ export class BeatTickLookup {
}
return null;
}

/**
* Looks for the first visible beat which starts at this lookup so it can be used for cursor placement.
* @param checker The custom checker to see if a beat is visible.
* @returns The first beat which is visible according to the given tracks or null.
*/
getVisibleBeatAtStartWithChecker(checker: IBeatVisibilityChecker): Beat | null {
for (const b of this.highlightedBeats) {
if (b.playbackStart === this.start && checker.isVisible(b.beat)) {
return b.beat;
}
}
return null;
}
}
Loading