Programmatic score construction
Generating a warm-up exercise on the fly, converting a proprietary format into alphaTab's model, or emitting etudes from a music-theory tool โ none of these have a source file to import. Instantiate Score, Track, Staff, Bar, Voice, Beat, and Note, wire them together, and hand the root Score to api.renderScore(). No file format, no importer, no round-trip through alphaTex.
The demo above is built entirely from new alphaTab.model.Score() and its children โ no file, no alphaTex, no importer. One Track, one Staff, two Bars, eight beats, then a single api.renderScore(score) call. The same construction, line for line, appears in the sample below.
Model shapeโ
Every score built from scratch follows the same tree:
Scoreโ the root. HoldsmasterBars(shared time signature, tempo, repeats) andtracks.MasterBarโ one per bar of music, added toScore.masterBars. Sets time signature and tempo automations.Trackโ one per instrument. Holdsstaves.Staffโ one per notation view (standard notation staff, tablature staff). Holdsbarsand tuning.Barโ one per masterBar, added toStaff.bars. Holdsvoicesand clef.Voiceโ one per polyphonic voice within a bar. Holdsbeats.Beatโ one per rhythmic event. Holdsnotes(or is a rest) and carriesdurationanddots.Noteโ one pitched note. Carriesstring+fretfor tab, oroctave+tonefor pitched non-tab staves.
Each level's collection has a corresponding add* method (score.addTrack(track), track.addStaff(staff), and so on) that also sets parent references and indices. Use the setters, not the arrays directly.
Show it in codeโ
import * as alphaTab from '@coderline/alphatab';
const score = new alphaTab.model.Score();
score.title = 'Built in code';
// Two shared master bars in 4/4. The initial tempo lives on the first
// master bar as a tempo automation โ Score.tempo itself is derived.
for (let i = 0; i < 2; i++) {
const masterBar = new alphaTab.model.MasterBar();
masterBar.timeSignatureNumerator = 4;
masterBar.timeSignatureDenominator = 4;
score.addMasterBar(masterBar);
}
score.masterBars[0].tempoAutomations.push(
alphaTab.model.Automation.buildTempoAutomation(false, 0, 120, 2),
);
// One guitar track, one staff, standard six-string tuning (high E โ low E).
const track = new alphaTab.model.Track();
track.name = 'Guitar';
track.shortName = 'Gtr';
score.addTrack(track);
const staff = new alphaTab.model.Staff();
staff.stringTuning.tunings = [64, 59, 55, 50, 45, 40];
track.addStaff(staff);
// One bar per master bar, one voice per bar.
for (let i = 0; i < score.masterBars.length; i++) {
const bar = new alphaTab.model.Bar();
staff.addBar(bar);
const voice = new alphaTab.model.Voice();
bar.addVoice(voice);
// Four quarter-note beats per bar, ascending then descending the third string.
// Note.string is 1-based counted from the lowest string.
const frets = i === 0 ? [3, 5, 7, 8] : [8, 7, 5, 3];
for (const fret of frets) {
const beat = new alphaTab.model.Beat();
beat.duration = alphaTab.model.Duration.Quarter;
voice.addBeat(beat);
const note = new alphaTab.model.Note();
note.string = 4;
note.fret = fret;
beat.addNote(note);
}
}
const container = getAlphaTabContainer();
const api = new alphaTab.AlphaTabApi(container);
// Compute ties, tick positions, and other derived state before rendering.
score.finish(api.settings);
api.renderScore(score);
getAlphaTabContainer() is a placeholder for the platform-specific step of obtaining the render target โ a <div> on Web, an AlphaTab control on .NET, or an AlphaTabView on Android.
Post-construction finalizationโ
Calling score.finish(settings) derives ties, resolves tuplet durations, computes measure end positions, and links repeat groups. Until finish runs, fields like Note.realValue, resolved Beat.duration, and master-bar tick positions are unset. Run it explicitly before you hand the score to renderScore() โ the sample above does this via score.finish(api.settings).
For scores serialized to JSON, run finish first so the JSON snapshot carries the finalized model.
Where to look nextโ
- Traversing and mutating the model โ the mirror workflow: walk and rewrite a loaded score instead of building one from scratch.
Score,MasterBar,Track,Staff,Bar,Voice,Beat, andNotein the model reference.DurationandAutomationโ the enum used forBeat.durationand the helper behind the tempo automation on the first master bar.renderScoreโ the entry point that accepts a hand-built score.