Skip to content

Export edge cases (MusicXML/ABC) — tracking #291

Description

@joekotvas

Export edge cases (MusicXML/ABC) — tracking

Live, untracked exporter defects outside the chord-symbol (#278/#284) and key-mode (#282) issues already filed.

  • MusicXML export emits notations on chord secondary notes (spec violation: "Do not use the tuplet element with chord notes")
    • STILL PRESENT in current dev (v1.0.0-alpha.16). In src/exporters/musicXmlExporter.ts the per-note loop event.notes.forEach((note, nIndex) => { is at line 406; const isChord = nIndex > 0; is at line 412 and is consumed ONLY at line 506 to emit the <chord/> element. The tuplet-bracket notations block is at lines 472-489: if (event.tuplet) { if (event.tuplet.position === 0) { ...<tuplet type="start" bracket="yes"/>... } else if (event.tuplet.position === event.tuplet.groupSize - 1) { ...<tuplet type="stop"/>... } } — with NO isChord/nIndex === 0 guard. So for a chord event sitting at tuplet position 0 or groupSize-1, every secondary chord note (the ones that also carry <chord/>) additionally receives a <tuplet> element in its <notations>.

Empirically verified: I built a triplet (ratio [3,2], groupSize 3) whose position-0 and position-2 members are each 2-note chords (C5+E5, E5+G5) and ran it through generateMusicXML. Result: TUPLET_START_COUNT=2 and TUPLET_STOP_COUNT=2 (each should be 1), with the <chord/> note emitting <notations><tuplet type="start" bracket="yes"/></notations>. This violates the MusicXML 4.0 rule "Do not use the tuplet element with chord notes." A strict importer will reject or misread it; a balanced bracket also ends up with duplicate start/stop pairs.

Reachability confirmed: a tuplet member is a ScoreEvent and can legitimately become a chord — src/hooks/note/useNoteEntry.ts:271 explicitly allows CHORD mode to stack a chord onto a tuplet member ("CHORD legitimately stacks a chord"). So this is a normal user path (create a triplet, stack a chord on a member via Cmd+Up / addTone, export to MusicXML), not a synthetic state.

The candidate's cited line numbers match current code exactly (forEach 406, isChord 412, tuplet notations block 472-489).

NOT TRACKED: no open or closed issue covers chord secondary notes receiving tuplet notations on MusicXML export. I checked all tuplet/chord/MusicXML issues. The closest are #256 (CLOSED — reflow SPLITTING tuplets into invalid model fragments on time-sig change; a model/reflow defect, not an export-notations defect), #261 (CLOSED — audio/playback lane vs tuplets/ties via TimelineService/toneEngine; not export), #168 (CLOSED sweep checklist; no such item), and #272 (OPEN deep-QA tracking; lists unrelated nits). Full-text scan of all ~300 issue bodies for tuplet+chord co-occurrence surfaced only #245/#262/#127, none of which touch this. Note: only severity is downgraded from the candidate's "high" — the buggy output is structurally wrong but tuplet-chords are a less common path and many lenient importers tolerate it.

  • ABC export: pickup (anacrusis) measure emitted as an unmarked under-full bar
    • STILL PRESENT (confirmed by reproduction). src/exporters/abcExporter.ts:189 iterates staff.measures via .forEach with no inspection of measure.isPickup; grep for isPickup/anacrusis in abcExporter.ts returns nothing, and the only M: field is the global header at line 154. Reproduction (pickup m0 = single G4 quarter in 4/4; m1 = C5 D5 E5 F5) emits:
      M:4/4
      ...
      G | c d e f |]
      i.e. the pickup is a one-note bar followed by a plain '|' barline, with no partial-measure M: marking. padMeasureForExport (src/exporters/exportNormalize.ts:18) IS isPickup-aware but only returns the short events untouched (avoids padding) — it adds no marking. Barline logic at abcExporter.ts:311-313 emits plain '| ' for every non-final bar.

NOT TRACKED. #240 (CLOSED) addressed the same conceptual gap but explicitly only for MusicXML (emit isPickup as , confirmed implemented at musicXmlExporter.ts:553-559); it does not mention ABC. #269 (OPEN) is about ties spanning rests in under-full bars (different defect). No open or closed issue covers ABC pickup/anacrusis marking. This is a never-implemented gap, not a regression of a fixed behavior.

Caveat on candidate's proposed fix idiom: emitting M:<pickup_duration> then restoring M: is one valid ABC approach but the duration should reflect actual pickup content, and many ABC parsers auto-detect short leading bars. The defect (an unmarked under-full first bar, asymmetric with the MusicXML exporter's #240 handling) is accurate as stated.


Source: 2026-06 audit re-triage (2026-06-13); each item is tagged 🔴 LIVE in docs/audit/. Some are single-pass audit/fresh-eyes findings not independently re-verified — confirm against current code before fixing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions