- 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.8 KiB
Proposal: Section Energy Curve
Intent
All 9 arrangement sections sound identical — full-band at static volume. Professional reggaeton builds energy across sections via sparse-to-dense track layering, velocity variation, and section-level volume riding. This change adds the missing dynamics.
Scope
In Scope
- Centralized
TRACK_ACTIVITYdict: which track roles play in which sections build_section_structure()setsvelocity_multandvol_multper section type- Unified
_section_active()helper — single source of truth for section activity - All 7 track builders refactored to check centralized activity + apply
velocity_mult - RPPBuilder extended to apply per-clip
vol_mult(audio items getD_VOL, MIDI items get velocity scaling) - Rename
buildsection topre-chorus(professional reggaeton convention) - Update integration tests to match new section behavior
Out of Scope
- Volume automation envelopes (REAPER
VOLENV2) — deferred - Transition FX generation (risers, impacts, filtered sweeps)
- Per-section filter automation (AutoFilter cutoff sweeps)
- Section scene names in REAPER project — still flat arrangement
Capabilities
Modified Capabilities
section-structure: SectionDefvelocity_multandvol_multnow populated per section type instead of defaulting to 1.0track-generation: All builders consume centralized activity matrix + section multipliers instead of ad-hoc section name checks
New Capabilities
section-activity: Centralized activity matrix defining which track roles are active per section typeclip-volume: ClipDef receives optionalvol_multfield; RPPBuilder applies it to itemD_VOL(audio) or velocity scaling (MIDI)
Approach
Principle: Schema fields (velocity_mult, vol_mult) already exist in SectionDef. The bug is they're never populated or consumed. Add the wiring.
-
Activity matrix —
TRACK_ACTIVITYdict in compose.py mapssection_type → {role: bool}. Section types:intro,verse,pre-chorus,chorus,bridge,final,outro. -
Section multipliers —
build_section_structure()setsvelocity_mult(controls note velocity) andvol_mult(controls clip gain) based on section type:Section velocity_mult vol_mult intro 0.6 0.70 verse 0.7 0.85 pre-chorus 0.85 0.95 chorus 1.0 1.00 bridge 0.6 0.75 final 1.0 1.00 outro 0.4 0.60 -
Builder refactor — Replace ad-hoc
if section.name in ("chorus","final")with_section_active(section, role, activity)check. Multiply MIDI velocities bysection.velocity_mult. -
RPPBuilder —
_build_item()addsD_VOLfor audio clips whenclip.vol_mult != 1.0. MIDI clips already get velocity-scaled notes from step 3. -
Section rename —
build→pre-chorusinSECTIONSand all references (DRUMLOOP_ASSIGNMENTS, builder filters). Existing section name "build" only appears in compose.py SECTIONS — no external consumers.
Affected Areas
| Area | Impact | Description |
|---|---|---|
scripts/compose.py |
Modified | Add TRACK_ACTIVITY, _section_active(), update build_section_structure(), refactor all 7 builders, rename build→pre-chorus |
src/core/schema.py |
Modified | Add vol_mult field to ClipDef (optional, default 1.0) |
src/reaper_builder/__init__.py |
Modified | _build_item() applies D_VOL from clip.vol_mult |
tests/test_compose_integration.py |
Modified | Update section name references (build→pre-chorus), add activity matrix tests |
tests/test_section_builder.py |
Modified | Add velocity_mult/vol_mult population tests |
Risks
| Risk | Likelihood | Mitigation |
|---|---|---|
RPP D_VOL not recognized by REAPER |
Low | REAPER .rpp spec documents D_VOL on ITEM; test with actual REAPER load |
| Section rename breaks test fixtures | Med | Grep all .py for "build" section name; CI catches breakage |
| Activity matrix too strict — creative users want full band in bridge | Low | Activity matrix is a constant at file top — easy to edit; could be CLI flag later |
Rollback Plan
Revert commit. No schema migrations needed — vol_mult on ClipDef defaults to 1.0 (zero behavioral change if not set). Section rename is cosmetic in output RPP.
Dependencies
None — no new packages, no external APIs.
Success Criteria
- All sections sound audibly different (sparse intro → dense chorus)
- Drums + pad only in intro (no bass, no lead, no chords)
- Full band in chorus (all 7 tracks active)
- Velocity differences between verse (soft) and chorus (hard)
- 110 existing tests still pass
.rppoutput opens in REAPER without errors