Files
renato97 33bb08270d 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.
2026-05-04 01:30:19 -03:00

2.0 KiB

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