Multi-track and grand staff
alphaTab renders any number of tracks as a single vertical system, connects grand-staff instruments with a brace, and prints per-track tunings for stringed instruments. Reach for it whenever the reader needs to see how parts line up โ a band-in-a-box view for a rehearsal app, a piano-and-voice pedagogical layout, or a full-score view of a jazz combo where soloists want the rhythm section on the same page.
The score below is the 8-bar ground of Pachelbel's Canon in D (c. 1680, PD) rendered as three tracks โ Lead Guitar, Bass Guitar with proper 4-string tuning, and Piano with treble + bass staves โ so every rendering feature that only shows up in multi-track scoring (bracket grouping, per-track tuning, grand-staff brace) is on display.
The grand staff for pianoโ
A piano Track carries two Staff entries โ a treble staff and a bass staff, tied together with a curly brace. alphaTab detects this from the source file and renders them stacked; the brace comes from the default bracketExtendMode of GroupStaves. Keep showStandardNotation on for both staves and showTablature off (piano staves ship with no tuning, so the tab staff is hidden automatically).
Multiple tracks in one systemโ
Selecting more than one track renders them as a single vertical system: the top track sits on the first line, brackets group multi-staff tracks, and every track shares the same barlines. Two paths get you there:
- On the API constructor โ set
core.tracksto an array of track indexes when you build theAlphaTabApi. The initial render includes exactly those tracks. - At runtime โ call
api.renderTracks(tracks)with an array ofTrackobjects. Use it to switch which players are visible without reloading the file: focus on a single soloist, expand to the whole ensemble, or hide backing parts on demand.
Each track keeps its own tuning label, transposition, and staff configuration. A score that mixes a 6-string guitar in standard tuning with a 5-string bass in drop-D prints both tunings above their respective staves at the start of the first system.
Show it in codeโ
import * as alphaTab from '@coderline/alphatab';
const container = getAlphaTabContainer();
const api = new alphaTab.AlphaTabApi(container, {
core: {
file: '/scores/song.gp',
tracks: [0, 1],
},
});
api.scoreLoaded.on((score) => {
// Switch to the piano alone at runtime.
api.renderTracks([score.tracks[2]]);
});
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. Every other line runs unchanged on all three runtimes.
Where to look nextโ
- Selecting and switching tracks โ the full lifecycle of loading, switching, and reacting to track changes.
- Bracket extend mode โ how brackets and braces group staves across tracks.
- Tuning display โ controlling the tuning block that appears above each track.
AlphaTabApiBase.renderTracks,AlphaTabApiBase.tracks, andcore.tracksin the API reference.