This commit is contained in:
khodowany
2026-10-04 12:27:43 -05:00
parent 8fdd736e13
commit 405066eb43
18 changed files with 810 additions and 71 deletions
+31 -1
View File
@@ -221,11 +221,12 @@ No accents, dynamics, velocity shaping, new swing interpretation or random timin
| `data/composition/harmony.json` | Add explicit optional tension/function/duration/resolution rules | Expression candidates and validation |
| `data/composition/lead_ins.json` | Add generic target-relative formulas and blues resolutions | Complete expression candidates and validation |
| `data/composition/rhythms.json` | Add purpose-bearing melodic cells and sparse comping figures | Solo joint realization, canonical comping |
| `data/composition/melodic_vocabulary.json` | Expand with 11 original purpose-bearing rhythm cells and four chord-member traversal operators; no fixed-pitch licks | Solo rhythm retrieval and complete routes only; excluded from accompaniment choice inputs |
| `data/lead_phrases/original_lead_theme.json` | Migrate unchanged to `audition/controls/`; remove from production data/build dependencies | Optional historical audition controls only |
| `data/expected/performance_summary.json` | Keep validation-only form/harmony/vocal invariants; never used in selection | Post-generation compatibility check |
| `build/*solo-[12].xml`, old generated assets, audition snapshots | Keep untouched, outside all musical input traces and caches | Explicit optional review only |
The five added JSON resources carry stable IDs, version 1, independent authorship provenance and MIT licensing. They were written from the musical brief and general principles, without extracting target notes, rhythm fingerprints, statistics or fitted weights. Existing catalog provenance is unchanged. No songs or useful combinatorial families were deleted. Legacy cell composition utilities remain for regression/explicit historical comparison; they are not a fallback production path.
The six composition JSON resources carry stable IDs, version 1, independent authorship provenance and MIT licensing. They were written from the musical brief and general principles, without extracting target notes, rhythm fingerprints, statistics or fitted weights. Existing catalog provenance is unchanged. No songs or useful combinatorial families were deleted. Legacy cell composition utilities remain for regression/explicit historical comparison; they are not a fallback production path.
#### Commands and validation boundary
@@ -258,6 +259,35 @@ Auditions export full solos plus opening/ending excerpts, solo stems, a common f
Current boundaries: source meter vocabulary is 2/4–5/4; unsupported meters or unrepresentable notation fail explicitly. The bounded composer cannot prove impossibility when it exhausts its budget. Expression vocabulary and local editing are deliberately finite, and the source-derived seven-section arrangement remains the existing product form. Independent parts can still collide or sound similar; diagnostics cannot automatically reselect either part. Playback remains one neutral mono tone profile, not a simulation of acoustic/electric timbre.
#### Purposeful phrase refinement and optional solo exports
The `purposeful-phrases-2` solo policy retains the independent role architecture. Rhythm cells now retain their authored purpose through loading and eligibility filtering. A continuation favors grouped motion over isolated short notes; an arrival can broaden; an entrance or answer retains its own vocabulary. Diverse candidates reach joint pitch/rhythm realization before stable hash tie-breaking. There is no reference-derived attack or occupancy target. This revision expands the production vocabulary with 11 independently authored rhythm cells and four transposable chord-member traversal operators. The new resource is keyed only into solo roles, so additions do not change accompaniment choices. No target fragments, distributions, or fitted weights were migrated into it.
Search units remain bounded but can finish at the heard signature's duration instead of invariably ending after two bars. Different frontier states carry their own completed musical time. Unit costs are duration-weighted before pruning. The home identity, incoming pitch, route, history, and terminal contract survive these boundaries. A provisional same-pitch endpoint may share the next continuation's attack only when all feature, timing, harmony, and protected-tail contracts still validate. Intentional repeated attacks remain distinct. Route retrieval retains arpeggio families alongside ordinary mapped movement and does not charge every third as worse than a step. Data-defined operators traverse ascending/descending chord members, a member turn, or defining chord members, then connect the complete prefix to the selected destination through an ordinary scale route. Each operator uses the actual chord at each event, preserves fixed notes, and requires full-duration collection membership; it introduces no new chromatic exception.
`--export-solo-xml` writes completed solo role views under `solo_xml/` in the atomically published assets. The CMake equivalent is `VAMP_EXPORT_SOLO_XML=ON` (default OFF). Solo 1 maps to acoustic; Solo 2 maps to electric. The exporter neither generates nor changes notes. It preserves exact durations, ties, tuplets, harmony offsets, and technical string/fret annotations, and numbers this standalone view from one. Its manifest retains the original arrangement measure numbers and offset, source fingerprint, production settings/version, and full phrase report. The runtime format and full-arrangement numbering remain unchanged. The normal source importer still rejects authored TAB as a production input; optional inspection reads the exported technical annotations directly.
Example comparison after an export-enabled build:
```sh
./modulus.py python -m audition.solo_compare \
--generated-dir build/build_x86_debug/generated_assets/solo_xml \
--reference 'all_of_me/acoustic=build/all-of-me-solo-1.xml' \
--reference 'all_of_me/electric=build/all-of-me-solo-2.xml' \
--reference 'autumn_leaves/acoustic=build/autumn-leaves-solo-1.xml' \
--reference 'autumn_leaves/electric=build/autumn-leaves-solo-2.xml' \
--form-start all_of_me/acoustic=1 --form-start all_of_me/electric=1 \
--form-start autumn_leaves/acoustic=2 --form-start autumn_leaves/electric=2 \
--reference-pitch guitar-written \
--assets build/build_x86_debug/generated_assets \
--output build/solo_comparison/review
```
This explicitly invoked, downstream command compares canonical sounding events with rational time. Tied notation fragments count as one event, repeated attacks do not. It reports pitch/onset/duration differences, separate spelling differences, rests, held-note harmonic roles, literal annotations, and legal guitar placement. The accepted user convention interprets these references as guitar-written notes; original encoded pitches remain in the report. No inferred conversion is based on their incidental `Vocal` part name. Autumn Leaves' initial material remains at negative form-relative time; no missing harmony is invented and no reference bar is discarded to manufacture equality. Reference notes beyond the source-derived solo cutoff are reported intact.
With `--assets`, it also renders generated/reference stems and identical-backing comparisons at the same neutral gains. The shared audition clock reserves room for reference-only lead-in material, explicitly reported in the manifest; this does not add notes to production or edit the reference XML. The existing production review exports baseline/new stages and final arrangements separately. All optional reports/audio live in build output and are never composition inputs. Exact matching is reported honestly and is not an acceptance requirement for independently invented melodies.
### Engraving Boundary
`generator/engraving/` is a custom Python engraver, not a wrapper around MuseScore or another notation engine. `generator.engraving.layout.layout_score(document, style, fonts)` produces immutable layout pages with exact source intervals, notation anchors and drawing primitives. `generator.engraving.raster.rasterize_page(page, fonts)` draws one page at four-times resolution and downsamples it. `generator.engraving.pipeline.engrave_tree(root, fonts)` is the asset-pipeline entry point. `fonts.Fonts`, `types.Style`, and `types.EngravingError` live in their respective engraving modules; page constants and `check_page` live in `validation`. Package initializers do not re-export these APIs. `generator/musicxml_writer.py` remains a round-trip/export utility and is not involved in engraving.