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