mirror of
https://github.com/9x/sheetmusictrainer.git
synced 2026-11-03 22:03:54 +01:00
Giuliani studies as own material category; beam-before-draw fix
- NEW material 'giuliani': figures require a real voicing — the generator assigns cycle positions (bass root + upper chord tones) to DISTINCT strings with valid frets per bar; bars that cannot be voiced are skipped (deterministic), clear error when nothing fits. Patterns: p-i-m, p-i-m-a, p-a-m-i, a-i-m, p-i-m-a-m-i, p-m-a-m-i-m. Honors the chord pool, string restrictions and the tuning; one figure per beat. - 6/8 meter added (numerator 6) across score model, settings, generators; meter selects now offer 4/4, 3/4, 6/8. - Arpeggio category: Giuliani entries replaced with note-sequence broken-chord figures (1-3-2-1, 1-3-2-5(8), 1-5-3-5(8), 1-2-3-5-3) — pure pitch sequences, no voicing claims. - Beam fix (root cause): setBeam now happens BEFORE voice.draw — VexFlow decides flag vs beam at draw time; registering after drawing left both flag and beam. Beams drawn after notes, flags suppressed correctly.
This commit is contained in:
@@ -324,9 +324,33 @@ export const PhraseSheetMusic: React.FC<PhraseSheetMusicProps> = ({
|
||||
formatter.joinVoices(voices.map(v => v.voice));
|
||||
formatter.format(voices.map(v => v.voice), formatWidth);
|
||||
|
||||
// --- Beams: BEFORE drawing notes. setBeam must happen prior to
|
||||
// voice.draw — VexFlow decides flag vs beam on this.beam at
|
||||
// draw time; registering late leaves BOTH flag and beam.
|
||||
const beamPairs: { a: Fragment; b2: Fragment }[] = [];
|
||||
const beamed = frags.filter(f => (f.isEighth || f.isSixteenth) && f.note instanceof StaveNote);
|
||||
for (let i = 0; i + 1 < beamed.length; i++) {
|
||||
const a = beamed[i], b2 = beamed[i + 1];
|
||||
if (a.staveKey !== b2.staveKey) continue;
|
||||
const step = a.isSixteenth ? 120 : 240;
|
||||
if (b2.start - a.start !== step) continue;
|
||||
if ((a.ticks !== step) || (b2.ticks !== step)) continue;
|
||||
const beatA = Math.floor((a.start - measureStart) / 480);
|
||||
const beatB = Math.floor((b2.start - measureStart) / 480);
|
||||
if (beatA === beatB) beamPairs.push({ a, b2 });
|
||||
}
|
||||
// Apply beams to notes FIRST (suppresses flags), then draw.
|
||||
const beams = beamPairs.map(({ a, b2 }) => {
|
||||
const beam = new Beam([a.note, b2.note], false);
|
||||
a.note.setBeam(beam);
|
||||
b2.note.setBeam(beam);
|
||||
return beam;
|
||||
});
|
||||
|
||||
treble.setContext(context).draw();
|
||||
if (bass) bass.setContext(context).draw();
|
||||
for (const { voice, stave } of voices) voice.draw(context, stave);
|
||||
for (const beam of beams) beam.setContext(context).draw();
|
||||
|
||||
if (isGrand && isFirstOfRow) {
|
||||
const brace = new StaveConnector(treble, bass!);
|
||||
@@ -337,27 +361,6 @@ export const PhraseSheetMusic: React.FC<PhraseSheetMusicProps> = ({
|
||||
line.setContext(context).draw();
|
||||
}
|
||||
|
||||
// --- Beams: consecutive eighth/16th pairs within one beat ---
|
||||
// Note: the Beam must be registered on each note via setBeam,
|
||||
// otherwise VexFlow still draws flags (beam === undefined in
|
||||
// shouldDrawFlag) and you get BOTH flag and beam.
|
||||
const beamed = frags.filter(f => (f.isEighth || f.isSixteenth) && f.note instanceof StaveNote);
|
||||
for (let i = 0; i + 1 < beamed.length; i++) {
|
||||
const a = beamed[i], b2 = beamed[i + 1];
|
||||
if (a.staveKey !== b2.staveKey) continue;
|
||||
// consecutive within the same beat, same subdivision size
|
||||
const step = a.isSixteenth ? 120 : 240;
|
||||
if (b2.start - a.start !== step) continue;
|
||||
if ((a.ticks !== step) || (b2.ticks !== step)) continue;
|
||||
const beatA = Math.floor((a.start - measureStart) / 480);
|
||||
const beatB = Math.floor((b2.start - measureStart) / 480);
|
||||
if (beatA === beatB) {
|
||||
const beam = new Beam([a.note, b2.note], false);
|
||||
a.note.setBeam(beam);
|
||||
b2.note.setBeam(beam);
|
||||
beam.setContext(context).draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Ties between consecutive fragments of one event (this row) ---
|
||||
|
||||
Reference in New Issue
Block a user