Skip to content

MusicXML: score is completely silent when a <technical><string> appears on a standard notation staff #2822

Description

@magmasystems

Is there an existing issue for this?

  • I have searched the existing issues

I have read the contribution rules

AI authorship

AI-assisted (disclosure block included as described in AGENTS.md)

Current Behavior

Note

AI-authored disclosure (alphatab-ai-authored-v1)

Portions of this content were authored by an AI agent. The agent has read
AGENTS.md and the human submitter accepts responsibility for
compliance with the rules in that document.

A score containing a <technical><string> element on a standard notation staff plays no audio at all. The score renders correctly and the playback cursor advances normally through every bar — only the sound is missing.

A single such note is enough to silence the whole score. In the piece where I hit this (Villa-Lobos, Prelude No. 5, 42 bars, 1484 notes) exactly one note carries the marking, and no note in the piece produces any sound.

This is common in classical guitar music: string indications — the circled number telling the player which string to use — are written on the notation staff, and carry no fret, because they are fingering annotations rather than fretted positions. MuseScore exports them as <technical><string>N</string></technical> with no <fret> sibling.

Observable through the public API on the affected note:

value
staff.tuning.length 0 (standard notation staff)
note.string 0
note.isStringed true
note.realValue -1 (the file specifies A4)

and in the generated MidiFile, 3 of the 26 events have tick of NaN.

Expected Behavior

The score should play. The annotated note should sound at the pitch written in its <pitch> element (A4, MIDI 69), and no MIDI event should carry a non-finite tick.

A string number on a staff with no tuning is a notation annotation rather than a playing position, so I would expect it not to affect audio at all. MusicXML 4.0 permits <string> inside <technical> independently of <fret> (<string>), and Finale, Sibelius and MuseScore all use it this way for right/left-hand string indications on notation staves.

The MusicXML support matrix lists <notations>, <technical>, <string> and <fret> as ✅ Supported for Audio, which is why I am reporting this rather than treating it as an unsupported feature.

Steps To Reproduce

  1. Load the MusicXML below — a single whole note, A4, on a standard notation staff, carrying <technical><string>1</string></technical> and no <fret>. The part has no <staff-details>, so the staff has no tuning.
  2. Generate the MIDI (or press play in a browser).
  3. Observe that no audio is produced, while rendering and the cursor behave normally.
import * as alphaTab from '@coderline/alphatab';

const xml = `<?xml version="1.0" encoding="UTF-8"?>
<score-partwise version="4.0">
  <part-list><score-part id="P1"><part-name>Classical Guitar</part-name></score-part></part-list>
  <part id="P1"><measure number="1">
    <attributes><divisions>1</divisions><time><beats>4</beats><beat-type>4</beat-type></time>
      <clef><sign>G</sign><line>2</line></clef></attributes>
    <note>
      <pitch><step>A</step><octave>4</octave></pitch>
      <duration>4</duration><voice>1</voice><type>whole</type>
      <notations><technical><string>1</string></technical></notations>
    </note>
  </measure></part>
</score-partwise>`;

const score = alphaTab.importer.ScoreLoader.loadScoreFromBytes(
  new TextEncoder().encode(xml), new alphaTab.Settings());

const note = score.tracks[0].staves[0].bars[0].voices[0].beats[0].notes[0];
console.log('staff.tuning.length :', score.tracks[0].staves[0].tuning.length);
console.log('note.string         :', note.string);
console.log('note.isStringed     :', note.isStringed);
console.log('note.realValue      :', note.realValue);

const midi = new alphaTab.midi.MidiFile();
new alphaTab.midi.MidiFileGenerator(score, new alphaTab.Settings(),
  new alphaTab.midi.AlphaSynthMidiFileHandler(midi)).generate();

const bad = midi.events.filter(e => !Number.isFinite(e.tick));
console.log(`\nnon-finite midi ticks: ${bad.length} of ${midi.events.length}`);

Output on 1.8.4:

staff.tuning.length : 0
note.string         : 0
note.isStringed     : true
note.realValue      : -1

non-finite midi ticks: 3 of 26

Removing only the <notations> block from that same file makes the note sound correctly.

Link to jsFiddle, CodePen, Project

No hosted example — the snippet above is self-contained and needs no score file. I can supply the original .mscz / exported MusicXML for the Villa-Lobos piece if that is useful.

Version and Environment

[AlphaTab][VersionInfo] alphaTab 1.8.4
[AlphaTab][VersionInfo] commit: 022a45c8e42370f9e12e68949d11eada370da83d
[AlphaTab][VersionInfo] build date: 2026-07-05T14:46:18.224Z
[AlphaTab][VersionInfo] High DPI: 1
[AlphaTab][VersionInfo] Platform: NodeJs
[AlphaTab][VersionInfo] WebPack: false
[AlphaTab][VersionInfo] Vite: false

Node.js v22.22.3, macOS 15.7.7 (Darwin 24.6.0)

The above is the real printEnvironmentInfo() output from the environment where the snippet was run.

The problem was originally noticed in a browser web app using the same alphaTab version, but I did not capture printEnvironmentInfo() there, so I am not quoting browser details I cannot verify.

Platform

Web (where it was first observed) and Node.js (where the reproduction above was run and verified).

Anything else?

The reason this was hard to recognise from the user side: rendering and the playback cursor are completely unaffected, so the score looks like it is playing. Nothing on screen indicates a problem, and there is no console error.

Scope, as far as I can tell from the user side: any score with a string indication on a notation staff. I have not tested how a tablature staff behaves, since the pitch there legitimately depends on the string number.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    Priority

    None yet

    Area

    None yet

    Platform

    None yet

    Work State

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions