Simplification

This commit is contained in:
khodowany
2026-10-05 16:40:22 -05:00
parent 654299decd
commit bcaf2f1403
49 changed files with 922 additions and 3327 deletions
+26 -11
View File
@@ -184,29 +184,44 @@ The analyzer requires a declared tonic and mode in the song's MusicXML key. A on
Selection first preserves every required pitch. Recognized ii-V pairs, resolving dominants, and leading-tone diminished resolutions establish local destinations; the declared key provides the default context elsewhere. Minor cadences prefer harmonic minor and major cadences prefer the destination's major collection when compatible. The arrival chord is evaluated afresh, so a plain D-minor tonic need not retain a preceding cadence's raised seventh. Among equally appropriate choices, a deterministic dynamic program minimizes collection changes, then contextual pitch differences. Equivalent modes share a pitch collection rather than forcing new boundaries. This is a conservative harmonic heuristic, not a claim that ambiguous harmony has only one interpretation.
Only the soloing part receives compact `scale_spans`, with absolute rational start/end offsets, labels, and matched status. `N.C.` and solo boundaries stop annotations. The composer consumes the structured scale choices directly and checks every sounding note across its entire duration. It may select another permitted collection to preserve an exact melody quotation, but never silently changes that quotation's notes. A harmony with no exact compatible collection, invalid scale data, or missing tonal metadata fails generation before publication. The standalone scale-analysis utility can still report unmatched chords without composing them.
Only the soloing part receives compact `scale_spans`, with absolute rational start/end offsets, labels, and matched status. `N.C.` and solo boundaries stop annotations. The composer consumes the structured scale choices directly and checks every sounding note across its entire duration. Source features are adapted within those choices; original source melodies retain their own notes. A harmony with no exact compatible collection, invalid scale data, or missing tonal metadata fails generation before publication. The standalone scale-analysis utility can still report unmatched chords without composing them.
Scale labels appear above chord symbols at collection changes and system starts. Detailed parent collections, source and arranged positions, chord-root modes, degrees, chord-tone targets, and selection reasons are written to `generated_assets/analysis/<song>.txt`. These reports are published transactionally with the build output but excluded from both installation and Docker runtime assets. The C++ runtime only displays the generated pages; it does not load the scale library or run harmonic analysis.
### Independent Musical Generation
Production composes six roles independently from the original source and relevant resources in `data/`: acoustic accompaniment/solo, electric accompaniment/melody/solo, and vocal melody. `production.SourceAnalysis` provides immutable source harmony, melody, meter, tempo, form and participation windows. Assembly applies those windows and protects the returning vocal pickup without inspecting generated solos to compose another part.
`production.generate_role` composes each role from immutable original-song content and relevant `data/` resources. Separate role seeds and keyed caches preserve standalone, order-independent and parallel behavior. The ordinary default is two spawned workers (`--composition-jobs`); a single worker has identical musical semantics. Composition reads are audited; comparison files, other roles' concrete outputs and previous scores are prohibited inputs.
`production.generate_role` runs in a bounded spawn process pool, default two workers (`VAMP_COMPOSITION_JOBS` / `--composition-jobs`). Role-specific keyed caches support incremental rebuilds. Serial and parallel modes use the same deterministic musical choices; worker completion order is not an input. Actual composition reads are audited. Optional targets, prior scores and other roles' caches are excluded.
The solo path is `composer.compose → construction.Builder → phrases.Phrases → placement → validate → notation/export`. Source pitch/rhythm relationships seed one realized idea. The composer coordinates whole rhythmic groups, written-chord arpeggios, complete scale routes, deliberate rests and harmonic arrivals into a complete phrase candidate. It considers at most 24 alternatives per incoming history, retaining four histories at common source-derived horizons (up to eight measures). These are bounded search settings, not a library of 24 licks. Boundaries may remain open; source breaths inform them without forcing a cadence at every bar. Introductory identity and current development remain distinct.
The active path is `composer.compose → construction.Builder → operators.Operators + selection.Selector → placement → validation → notation/export`. Complete action candidates include scalar/arpeggiated routes, heard-theme returns/answers, rests, colors, approaches and anticipations. Ordinary actions need no chord-tone endpoint. Pending contracts retain exact future targets through internal boundaries. The search ranks actions by cost per quarter with bounded repair; reporting groups are not evidence of global phrase optimization. See the [active-path audit](docs/composer/active_path_audit.md) for budgets and limitations.
Rhythm choices are purpose-aware. Arrival values come from authored arrival cells. Fast subdivision groups have a difficulty budget rather than being selected uniformly from every catalog entry. Sequence indexing retains octave crossings. Catalog families contribute representatives, not probabilities proportional to XML file count. Source notes are never changed by generated rhythm transformations.
Both solo roles use strings 1–6, frets 1–12, no open strings, with soft overlapping register preferences. Exact timing, source transposition, ties, harmonic interpretation and runtime representation remain unchanged. The 21 scale patterns govern ordinary movement. Exceptions need actual typed preparation/target/duration evidence. A tonic/predominant natural minor sixth may be a bounded stable color; mapped-upper enclosures must verify their upper neighbor's collection membership. No chord is rewritten to excuse an ornament.
The complete-phrase evaluator reports continuity, contextual repetition, rhythmic interruption, broad activity feasibility, harmonic exposure, soft register and declared return fidelity. Histories covering the same span use duration-weighted phrase totals. The final report also contains an independent whole-stream diagnostic; it is labeled separately from the selection total. No reference-fitting schema, target-loss term, constructor bonus or optional training dependency remains. This evaluator is an inspectable engineering preference, not a model of listener enjoyment or a guarantee of globally optimal melody.
The authoritative evaluator reports validity, normalized components, weights and the actual selection total. It does not read reference events or compute runtime reference similarity. Development-only shared-weight fitting is explicit and bounded. Production catalogs have a checksummed non-executable JSON cache, separate from concrete role caches. Pure chord, expression, rhythm-group and legal-position analysis is memoized.
Both solo roles allow all six strings at frets 1–12 without opens. Overlapping register preferences never impose octave copies or string quotas. Ordinary notes remain in the mapped collection throughout their full sounding interval. Typed color, approach, enclosure, anticipation and suspension rules validate real targets, preparation and exposure. Tied fragments reconstruct one sounding event; reattacks remain distinct. The 21 scale patterns and authoritative written chord semantics are unchanged. Unsupported written harmony fails rather than silently substituting another chord.
Accompaniment remains source-only canonical sparse comping, reused at corresponding form positions. It does not respond to generated lead notes or borrow their grips. No new dynamics, velocity shaping, random timing or instrument effects are introduced.
Accompaniment remains source-derived and canonical across iterations, with independently chosen sparse voicings and rhythms. It neither reads nor reacts to solo notes. Source-defined participation masks keep accompaniment off the physical guitar while it solos. Source vocals, electric melody, pickup timing and runtime representation are preserved.
The resource inventory is documented in [data migration](docs/composer/data_migration.md). Scales, 2,954 relative paths and 3,538 meter-specific rhythms remain useful; the catalogs are not uniformly sampled. New resources store general musical purposes and target-relative rules, not reference phrases or bar recipes. The current user-authorized reference analysis informed these general rules; provenance states that explicitly.
Production exports `*-solo1.xml` (acoustic), `*-solo2.xml` (electric), and `manifest.solo`. Optional `python -m tests.solo_compare` accepts references only after completed generation; it cannot affect candidate selection. It preserves annotations and raw encoding and separately applies the confirmed guitar-written octave convention. No exact-output reproduction is promised. Compare whole pitches, onsets, releases, rests and phrase relationships; attack counts alone are insufficient. The previous fitting experiments and `audition/` and `docs/` directories are removed.
Production exports `*-solo1.xml` (acoustic) and `*-solo2.xml` (electric) plus `manifest.solo`. Optional `audition.solo_compare` and `audition.theory_review` accept explicit reference paths after generation. The four supplied scores use the separately confirmed guitar-written octave convention in this adapter only. Autumn Leaves aligns at measure 2 / first Gm7; preceding material is retained. References are untouched and missing files never change normal generation.
Source songs, scales and useful rhythm/sequence catalogs remain in `data/`. Versioned general rules live in `data/composition`; optional references stay in `build/`, and compatibility expectations live in `tests/fixtures`. Keep only the current comparison and one compact baseline under `build/solo_comparison`. Cached catalogs are checksummed derivatives of production data; a clean build recreates them. Legal TAB is a feasibility approximation, not a finger-assignment or ergonomic guarantee.
One review folder, `build/solo_reference_comparison/`, holds the previous four XMLs, the new four, the complete reference comparison and audio. Historical audition controllers and obsolete generated experiment trees were removed. [Commands](docs/composer/commands.md), [active path](docs/composer/active_path_audit.md), [evaluation contract](docs/composer/evaluation_contract.md), and [implementation evidence](docs/composer/implementation_report.md) describe the current behavior and limits. Technical validity and measured similarity do not establish listener preference.
Current resource and code migration:
| Resource | Disposition and live consumer |
| --- | --- |
| `data/songs`, `data/scales` | Keep authoritative source music and the 21 collections; importer and scale mapper. |
| `data/sequences`, `data/rhythms` | Keep 2,954 relative paths and 3,538 meter-indexed snippets; complete routes and representative rhythm groups, with immutable catalog caching. |
| `data/composition/solo.json` | Simplify to authored groups/cells and bounded phrase search. Remove per-action budgets and redundant single-note groups. Consumer: `phrases`, `construction`, `rhythm`. |
| `data/composition/roles.json` | Keep independent role/register/difficulty policy; remove fitted selection coefficients. Consumer: `production`, `profiles`, `vocabulary`. |
| `data/composition/harmony.json`, `lead_ins.json`, `rhythms.json` | Keep general harmonic treatments, target-relative formulas, rhythm and sparse-comping vocabulary; preserve their original provenance. |
| `data/expected/performance_summary.json` | Move unchanged to `tests/fixtures`; validation-only form/vocal compatibility, never composition. |
| Old `solo/operators.py`, action-frontier search and learned selector | Replace with complete phrase construction/selection; remove unused path and register-cost helpers. No legacy fallback. |
| `audition/`, `docs/`, historical build trials/training packages | Remove. Keep one optional read-only `tests/solo_compare.py`, current comparison, and compact baseline. |
The new constructor and search policy are independently authored. Existing general harmony rules acknowledge prior reference-guided review in their provenance; they contain no reference phrases or fitted parameters. Target files remain outside production and do not supply musical seeds. The optional comparison reports pitch-sequence edit distance, exact timed-attack distance, and duration of aligned pitch agreement separately, without a combined optimization score.
The current bounded constructor still uses heuristics: source features are short, phrase horizons are chosen before surface realization, and only a small number of histories survive. “Extend” develops a longer continuation; it does not rewrite a previously committed phrase. Prepared suspensions and anticipations require an eligible editable boundary and may remain unselected. Supported validation vocabulary does not imply every treatment is a construction operation. Technical validity and these comparisons cannot establish that the resulting melody is preferred by a listener.
### Engraving Boundary
@@ -246,7 +261,7 @@ The six compact source files were replaced, not retained as a second authoring f
References: [MusicXML durations](https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/duration/), [tuplets](https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/tuplet/), [degree alterations](https://www.w3.org/2021/06/musicxml40/musicxml-reference/elements/degree-alter/), and [SMuFL accidentals](https://smufl.formats.music/latest/tables/standard-accidentals-12-edo.html).
Generator checks compare the generated performance summary against `data/expected/performance_summary.json`. The summary stores compatibility invariants such as section layout, chord-label placement, absence of uncomposed solo slashes, and vocal timing without committing the generated score files themselves. Refresh that file only when an intentional arrangement-logic change should become the new baseline.
Generator checks compare the generated performance summary against `tests/fixtures/performance_summary.json`. The summary stores compatibility invariants such as section layout, chord-label placement, absence of uncomposed solo slashes, and vocal timing without committing the generated score files themselves. Refresh that file only when an intentional arrangement-logic change should become the new baseline.
## Pico Runtime