- 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.
3.2 KiB
3.2 KiB
Proposal: transitions-fx
Intent
9 sections play back-to-back with zero transition — the song feels like disjointed loops. Add transition FX (risers, impacts, sweeps) at section boundaries to glue sections into a coherent arrangement.
Scope
In Scope
- Place transition FX clips (audio samples) on a dedicated "Transition FX" track at section boundaries
- Riser/wash FX: 2–4 beats before section changes (e.g., build → chorus drop)
- Impact/hit FX: on the downbeat of CHORUS, FINAL, VERSE2 entries
- Filter sweep simulation via fade-in/fade-out on adjacent clips
- Transition plan: which boundary gets which FX type + duration
- Reuse existing FX-role samples from library (impacts, risers, transition FX, wash)
Out of Scope
- Synthesized FX generation (numpy waveform synthesis) — deferred to future
- MIDI CC filter automation in RPP (no CC support in builder today)
- Per-track volume automation curves
- Reverse cymbal (no suitable samples in library)
Capabilities
New Capabilities
transition-fx: Placement of audio FX clips at section boundaries for arrangement glue
Modified Capabilities
None — existing section/track structure unchanged.
Approach
Audio samples from library — the library has 57 FX-role samples including:
- Impacts:
fx_C2_126_boomy(2.5s, fromimpact.wav) - Risers:
fx_C#5_123_aggressive(30s),fx_G3_143_boomy(6.6s, "RISER 3") - Transition FX: 4 "transicion fx" variants (1.0–1.7s)
- Wash/noise:
fx_G#6_136_aggressive(3.3s) - Short shots/gates: "CAMTAZO 1–2" (1.5–2.0s), "PUERTA" (0.2s)
Place audio clips on a new "FX" track at section boundaries:
- Riser/wash: starts 2–4 beats BEFORE boundary, ends on boundary downbeat
- Impact: starts on boundary downbeat, short duration (1–2 beats)
- Use existing
fade_in/fade_outon ClipDef for filter-like sweeps - Use SampleSelector with
role="fx"to pick compatible samples
Affected Areas
| Area | Impact | Description |
|---|---|---|
scripts/compose.py |
Modified | Add build_fx_track() — places FX clips between sections |
src/core/schema.py |
Unchanged | ClipDef already has position, length, audio_path, fade_in, fade_out |
src/reaper_builder/__init__.py |
Unchanged | Audio clip building already works |
Risks
| Risk | Likelihood | Mitigation |
|---|---|---|
| FX samples may not match project key | Low | FX role is ATONAL_ROLES — key scoring skipped by selector |
| Long riser samples exceed needed duration | Low | Clip length sets playback window; sample trimmed automatically |
| No suitable riser for specific boundary | Med | Fall back to fade_in on next section clip |
Rollback Plan
Remove build_fx_track() call from main(). Existing tracks untouched.
Dependencies
data/sample_index.json(already exists)SampleSelectorwithrole="fx"(already works)
Success Criteria
python scripts/compose.py --bpm 99 --key Amproduces .rpp with FX clips at section boundaries- At least one FX clip between: build→chorus, chorus→verse2, bridge→final, outro end
- FX clips have appropriate fade_in/fade_out curves
- 110 existing tests continue to pass
- Song renders without gaps — FX clips overlap/bridge sections