Files
reaper-control/.sdd/changes/transitions-fx/spec.md
renato97 014e636889 feat: professional reggaeton production engine — 7 SDD changes, 302 tests
- 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.
2026-05-03 23:54:29 -03:00

96 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Transition FX Specification
## Purpose
Glue sections together by placing audio FX clips at arrangement boundaries using existing `role="fx"` library samples.
## Requirements
### Requirement: FX Track Existence
The system MUST create a dedicated "Transition FX" audio track with clips at 7 section boundaries.
#### Scenario: FX track present in arrangement
- GIVEN a 9-section song
- WHEN `compose.py` runs
- THEN a track named "Transition FX" exists with 7+ audio clips at boundary positions
### Requirement: Riser Before Climax
A riser/wash FX MUST start 24 beats before build→chorus and bridge→final boundaries, ending ON the boundary downbeat.
#### Scenario: Riser before chorus
- GIVEN build ends at beat 64 (bar 16)
- WHEN FX is built
- THEN a riser at position 60 (beat 60), length 4, `fade_in` ≥ 1.0s
#### Scenario: Riser before final
- GIVEN bridge ends at beat 176 (bar 44)
- WHEN FX is built
- THEN a riser at position 172, length 4, `fade_in` ≥ 1.0s
#### Scenario: Riser before chorus2
- GIVEN verse2 ends at beat 128 (bar 32)
- WHEN FX is built
- THEN a riser at position 124, length 4, `fade_in` ≥ 1.0s
### Requirement: Impact on Section Downbeat
An impact/stab FX MUST start on beat 1 of CHORUS (beat 64) and FINAL (beat 176).
#### Scenario: Impact on chorus beat 1
- GIVEN chorus starts at beat 64
- WHEN FX is built
- THEN an impact clip at position 64, length 12 beats, `fade_out` ≥ 0.2s
#### Scenario: Impact on final beat 1
- GIVEN final starts at beat 176
- WHEN FX is built
- THEN an impact clip at position 176, length 12 beats
### Requirement: Transition Sweeps Between Verses
Short transition FX MUST bridge chorus→verse2 (beat 96) and chorus2→bridge (beat 160).
#### Scenario: Sweep bridges chorus to verse2
- GIVEN chorus ends at beat 96
- WHEN FX is built
- THEN a transition clip at position 94, length 2 beats, `fade_in` and `fade_out` > 0
### Requirement: FX Sample Selection
The system SHALL select FX samples via `SampleSelector.select_one(role="fx")`, favoring short samples for impacts, long for risers.
#### Scenario: FX role returns candidates
- GIVEN 57 FX samples in library with ATONAL_ROLES including "fx"
- WHEN `select(role="fx")` is called
- THEN non-empty result returned; key scoring skipped (neutral 0.5)
### Requirement: Fade Curves
FX clips MUST use `fade_in`/`fade_out`. Risers: `fade_in` ≥ 0.3s. Impacts: `fade_out` ≥ 0.2s.
#### Scenario: Riser fades in, impact fades out
- GIVEN riser and impact clips defined
- WHEN ClipDef is created
- THEN riser.fade_in > 0 AND impact.fade_out > 0
### Requirement: FX Track Mixing
The FX track SHALL have volume ≤ 0.80 and send to Reverb/Delay returns.
#### Scenario: FX track has moderate volume and sends
- GIVEN "Transition FX" track created
- WHEN track is defined
- THEN volume = 0.72, send_level includes reverb (0.08) and delay (0.05)