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:
OpenClaw
2026-09-15 02:44:52 +00:00
parent 9acf32a32f
commit ffb2776c8c
9 changed files with 412 additions and 69 deletions

View File

@@ -30,7 +30,7 @@ export interface MelodyConfig {
readonly keyMode: ModeId;
/** 1..8 */
readonly bars: number;
readonly meter: { readonly numerator: 3 | 4; readonly denominator: 4 };
readonly meter: { readonly numerator: 3 | 4 | 6; readonly denominator: 4 };
/** 1 = Simple (quarters/halves/wholes), 2 = Mixed (+ paired eighths, dotted quarters),
* 3 = Elaborate (+ sixteenths, sixteenth groups, dotted eighths). */
readonly rhythmLevel: 1 | 2 | 3;
@@ -86,7 +86,7 @@ const TEMPLATES_3_L3: number[][] = [
[120, 120, 120, 120, 120, 120, 120, 120, 480],
];
function templatesFor(meter: { numerator: 3 | 4 }, level: 1 | 2 | 3): number[][] {
function templatesFor(meter: { numerator: 3 | 4 | 6 }, level: 1 | 2 | 3): number[][] {
const base = meter.numerator === 4
? (level === 1 ? TEMPLATES_4_L1 : level === 2 ? [...TEMPLATES_4_L1, ...TEMPLATES_4_L2] : [...TEMPLATES_4_L1, ...TEMPLATES_4_L2, ...TEMPLATES_4_L3])
: (level === 1 ? TEMPLATES_3_L1 : level === 2 ? [...TEMPLATES_3_L1, ...TEMPLATES_3_L2] : [...TEMPLATES_3_L1, ...TEMPLATES_3_L2, ...TEMPLATES_3_L3]);