- section-energy: track activity matrix + volume/velocity multipliers per section - smart-chords: ChordEngine with voice leading, inversions, 4 emotion modes - hook-melody: melody engine with hook/stabs/smooth styles, call-and-response - mix-calibration: Calibrator module (LUFS volumes, HPF/LPF, stereo, sends, master) - transitions-fx: FX track with risers/impacts/sweeps at section boundaries - sidechain: MIDI CC11 bass ducking on kick hits via DrumLoopAnalyzer - presets-pack: role-aware plugin presets (Serum/Decapitator/Omnisphere per role) Full SDD pipeline (propose→spec→design→tasks→apply→verify) for all 7 changes. 302/302 tests passing.
4.5 KiB
Proposal: Hook-Based Reggaeton Melody
Intent
build_lead_track() generates random pentatonic notes — no hook, no identity, no rhythmic motif. Professional reggaeton leads have memorable hooks (repeating motif), rhythmic alignment with the dembow grid, call-and-response structure, and chord-tone emphasis on strong beats. This change replaces random generation with a structured hook engine producing identifiable, repeating motifs with controlled variation.
Scope
In Scope
- Hook engine module (
src/composer/melody_engine.py) — generates motifs, variations, call-response - 3 reggaeton styles: "stabs" (syncopated hits on 1, 2.5, 3, 3.5), "smooth" (stepwise eighth notes), "hook" (arch contour, chord tones on strong beats)
- Motif + variation loop: 2–4 bar motif repeated 2–4x with transpose/rhythmic-shift variations
- Call-and-response: first half = call (ends on V/VII), second half = response (resolves to i)
- Chord-aware note selection: strong beats (1, 3) favor chord tones; weak beats use scale passing tones
- Replace
build_lead_track()incompose.pyto delegate to the new engine - Tests for deterministic output, motif identity preserved across variations, call-response resolution
Out of Scope
- MIDI velocity humanization / groove quantization
- User-selectable style at CLI (hardcoded to "hook" style initially)
- Chord progression generation (uses existing
CHORD_PROGRESSIONfrom compose.py) - Pad/chords/bass refactoring — lead only
Capabilities
New Capabilities
melody-engine: Deterministic hook generation with motif, variation, call-response, and 3 reggaeton styles. Chord-aware viaCHORD_PROGRESSIONinput.
Modified Capabilities
- None at spec level.
build_lead_track()API unchanged (same signature). Behavior changes from random to deterministic, but callers see same interface.
Approach
New module src/composer/melody_engine.py with:
-
build_motif(key_root, key_minor, style, bars=4)→list[MidiNote]- Style "hook": arch contour, chord tones on 0, 2, 4... beats, 4–8 notes
- Style "stabs": short 16th hits on [1.0, 2.5, 3.0, 3.5] per bar
- Style "smooth": stepwise scalar motion at eighth-note density
- Chords resolved from
CHORD_PROGRESSIONfor chord-tone selection
-
apply_variation(motif, shift=0, transpose=0)→ variation- Rhythmic shift: offset within the grid
- Transpose: ±octave or ±third within scale
-
build_call_response(motif, sections, key_root, key_minor)→list[ClipDef]- First half = call (motif + slight variation, ends on tension note)
- Second half = response (motif, resolves to tonic)
- Repeats for section length
compose.py build_lead_track() becomes thin wrapper calling melody_engine. All existing tests pass with updated expected values.
Affected Areas
| Area | Impact | Description |
|---|---|---|
src/composer/melody_engine.py |
New | Hook engine — motifs, variations, call-response |
scripts/compose.py |
Modified | build_lead_track() delegates to melody_engine; get_pentatonic() stays as helper |
tests/test_compose_integration.py |
Modified | Update test_melody_uses_pentatonic to assert motif structure |
tests/test_section_builder.py |
None | get_pentatonic tests unaffected |
Risks
| Risk | Likelihood | Mitigation |
|---|---|---|
| Deterministic melody sounds repetitive | Med | 3 style options + variation params provide diversity; section energy scales velocity |
| Chord-awareness breaks if CHORD_PROGRESSION changes format | Low | Hardcoded in compose.py — same module owns both; integration test catches mismatch |
| Motif too short for long sections (8+ bars) | Low | Call-response repeats motif to fill bars; edge case validated in tests |
Rollback Plan
Revert build_lead_track() to original random-pentatonic implementation (git revert). No schema or API changes — pure function replacement.
Dependencies
CHORD_PROGRESSIONconstant fromcompose.py(existing)get_pentatonic()helper fromcompose.py(kept, reused)
Success Criteria
build_lead_track()produces identical output for same seed+key input (deterministic)- Generated melody contains a repeating 2–4 bar motif with ≤2 variations
- Call section ends on V or VII degree; response resolves to i
- Strong beats (quarter positions) use chord tones ≥70% of the time
- All 110+ existing tests pass
- 5+ new tests for melody_engine: motif identity, variation bounds, call-response resolution