- 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.
31 lines
2.1 KiB
Markdown
31 lines
2.1 KiB
Markdown
# Tasks: Automated Mix Calibration
|
|
|
|
## Phase 1: Foundation
|
|
|
|
- [x] 1.1 Create `src/calibrator/presets.py` — `VOLUME_PRESETS`, `EQ_PRESETS` (HPF/LPF freq per role), `PAN_PRESETS`, `SEND_PRESETS` dicts
|
|
- [x] 1.2 Add `calibrate: bool = True` optional field to `SongMeta` in `src/core/schema.py`
|
|
- [x] 1.3 Create `src/calibrator/__init__.py` with `Calibrator` class stub and `_resolve_role()` method (name → role key)
|
|
|
|
## Phase 2: Core Calibrator
|
|
|
|
- [x] 2.1 Implement `_calibrate_volumes(song)` — set track.volume from VOLUME_PRESETS by role; skip unknown roles
|
|
- [x] 2.2 Implement `_calibrate_pans(song)` — set track.pan from PAN_PRESETS by role
|
|
- [x] 2.3 Implement `_calibrate_sends(song)` — set track.send_level for reverb/delay return indices from SEND_PRESETS
|
|
- [x] 2.4 Implement `_calibrate_eq(song)` — prepend ReaEQ PluginDef with params dict (HPF/LPF) to track.plugins; skip return tracks
|
|
- [x] 2.5 Implement `_swap_master_chain(song)` — replace master_plugins with Ozone 12 triplet; fall back to Pro-Q_3/Pro-C_2/Pro-L_2 if Ozone not in PLUGIN_REGISTRY
|
|
- [x] 2.6 Implement `Calibrator.apply(song)` orchestrating all _calibrate_* methods, returning the mutated song
|
|
|
|
## Phase 3: Builder & Integration
|
|
|
|
- [x] 3.1 Modify `_build_plugin()` in `src/reaper_builder/__init__.py` — read `PluginDef.params` for built-in VST2 plugins and populate param_slots
|
|
- [x] 3.2 Wire calibrator into `scripts/compose.py` — import Calibrator, call `calibrator.apply(song)` after track construction, before RPPBuilder
|
|
- [x] 3.3 Add `--no-calibrate` flag to compose.py argparse; when set, skip calibrator call and SongMeta.calibrate=False
|
|
|
|
## Phase 4: Testing
|
|
|
|
- [x] 4.1 Create `tests/test_calibrator.py` — unit tests for `_resolve_role()`, each `_calibrate_*()` method against fixture SongDefinition
|
|
- [x] 4.2 Test `Calibrator.apply()` end-to-end — volumes, pans, sends, ReaEQ presence, master plugins all match presets
|
|
- [x] 4.3 Test `--no-calibrate` flag — calibrator not called, master_plugins unchanged
|
|
- [x] 4.4 Test Ozone fallback — mock empty Ozone registry entries, verify Pro-Q_3/Pro-C_2/Pro-L_2 used
|
|
- [x] 4.5 Run existing test suite — verify all 110+ tests still pass
|