fix: musical content — 808 timing, chord voicings, melody range, pad arpeggiation, Ozone paths
- 808 bass: fixed note positions to beat 1.0 per bar (i-iv-i-V, 1.5 beat duration) - Chords: 4-note 7th voicings (Am7, F7, C7, G7) instead of 2-note intervals - Lead: constrained to 8-semitone range, pentatonic scale - Pad: arpeggiated eighth-notes instead of static 2-note drones - Ozone 12: fixed .vst3 filename paths in Calibrator - Delta-encoding: fixed cumulative timing drift in _build_midi_source() with CC events 298/298 tests pass.
This commit is contained in:
40
.sdd/changes/fix-musical-coherence/design.md
Normal file
40
.sdd/changes/fix-musical-coherence/design.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Design: Fix Musical Coherence
|
||||
|
||||
## Architecture Decisions
|
||||
|
||||
### AD1: Bass pattern — constant over composition
|
||||
The 808 bass pattern is a static 8-bar loop transposed by key. No section-specific variation needed since energy and velocity_mult handle intensity changes.
|
||||
|
||||
### AD2: Lead range constraint — filter in _resolve_chord_tones
|
||||
Rather than post-filter melody output, constrain chord_tones at the source. Remove oct_shift -12/+12 from _resolve_chord_tones(), keeping only oct_shift=0. This limits all chord tones to one octave around tonic (octave 4), producing melodies within ~12 semitones.
|
||||
|
||||
### AD3: Chord 7ths — change progression quality strings
|
||||
CHORD_TYPES already has m7=[0,3,7,10] and 7=[0,4,7,10]. Switch EMOTION_PROGRESSIONS from "min"/"maj" to "m7"/"7". Voice leading code handles any voicing size transparently.
|
||||
|
||||
### AD4: Pad movement — arpeggiate in build_pad_track
|
||||
Replace 3 sustained notes with ascending arpeggio: for each beat, play one chord note, cycling through chord tones. 0.5 beat duration (eighth note), 0.55 volume. Different octave (3) from chords (4).
|
||||
|
||||
### AD5: Ozone path — verify and harden
|
||||
The `_build_plugin()` lookup in `_build_master_fxchain()` already resolves correctly from PLUGIN_REGISTRY. Fix by verifying the path and adding an assertion/guard so empty path never reaches the VST element.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### File changes
|
||||
1. `scripts/compose.py`:
|
||||
- Replace BASS_PATTERN_8BARS with 4-note sparse pattern
|
||||
- Replace build_pad_track() with arpeggiated version
|
||||
|
||||
2. `src/composer/melody_engine.py`:
|
||||
- `_resolve_chord_tones()`: remove oct_shift in (-12, 12), keep only 0
|
||||
|
||||
3. `src/composer/chords.py`:
|
||||
- EMOTION_PROGRESSIONS: "min"→"m7", "maj"→"7"
|
||||
|
||||
4. `src/reaper_builder/__init__.py`:
|
||||
- `_build_master_fxchain()`: use PLUGIN_REGISTRY to populate PluginDef path
|
||||
|
||||
### Test updates
|
||||
- test_compose.py: verify bass note positions
|
||||
- test_melody_engine.py: verify range constraint
|
||||
- test_chords.py: verify 4-note voicings
|
||||
- test_calibrator.py: verify Ozone master chain
|
||||
Reference in New Issue
Block a user