The MIDI event stream
Feed a hardware synth over MIDI-out. Drive a stage-light show off the beat pulses. Log every note-on for post-session analysis. Anywhere you need something to happen the moment the audio plays it, subscribe to midiEventsPlayed. alphaTab surfaces every event the synthesizer sees β note-on, note-off, tempo changes, program changes, metronome ticks, and rests β filtered to only the types you asked for.
Filter first, then subscribeβ
For performance, alphaTab only fires events that match midiEventsPlayedFilter. Without a filter, the event does not fire even if you subscribe. Populate the filter with entries from alphaTab.midi.MidiEventType:
NoteOn/NoteOffβ every note the synth plays.AlphaTabMetronomeβ the metronome ticks generated by alphaTab (carry beat position, subdivision, and duration).AlphaTabRestβ synthetic events marking rests.TempoChangeβ tempo automation, useful for converting ticks to wall-clock time.TimeSignature,ProgramChange,ControlChange,PitchBendβ for timing UIs and DAW-style integrations.
Latency and bufferingβ
Events fire once the audio buffer has actually played them, not when they enter the synth. Expect a delay proportional to player.bufferTimeInMilliseconds β around 50 to 100 ms in a typical browser setup. If your UI needs frame-accurate feedback, keep the buffer small; if it needs stability, keep the buffer large and compensate with a lookahead.
Show it in codeβ
import * as alphaTab from '@coderline/alphatab';
const container = getAlphaTabContainer();
const api = new alphaTab.AlphaTabApi(container, {
core: { file: '/scores/song.gp' },
player: {
playerMode: alphaTab.PlayerMode.EnabledSynthesizer,
soundFont: '/soundfont/sonivox.sf2',
},
});
api.midiEventsPlayedFilter = [
alphaTab.midi.MidiEventType.NoteOn,
alphaTab.midi.MidiEventType.NoteOff,
alphaTab.midi.MidiEventType.AlphaTabMetronome,
];
api.midiEventsPlayed.on((e) => {
for (const event of e.events) {
if (event.type === alphaTab.midi.MidiEventType.NoteOn) {
console.log(`note on: key=${event.noteKey} vel=${event.noteVelocity} ch=${event.channel}`);
} else if (event.type === alphaTab.midi.MidiEventType.NoteOff) {
console.log(`note off: key=${event.noteKey} ch=${event.channel}`);
} else if (event.isMetronome) {
console.log(`metronome: beat ${event.metronomeNumerator + 1}`);
}
}
});
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. midiEventsPlayed fires with the same event shape on every runtime.
Where to look nextβ
- Count-in and metronome β the built-in metronome that produces the
AlphaTabMetronomeevents. - Audio buffer size β the latency trade-off that governs event timing.
- Seeking by tick and time β the tick coordinate every event carries.
midiEventsPlayed,midiEventsPlayedFilter, anddownloadMidiin the API reference.MidiEventType,MidiEvent,AlphaTabMetronomeEvent, andAlphaTabRestEventin the model reference.