feat: reascript-first — built-in REAPER plugin insertion via ReaScript API
Hybrid pipeline: RPPBuilder writes VST3/MIDI/audio skeleton, ReaScript handles built-in plugins (ReaEQ, ReaComp) via TrackFX_AddByName + TrackFX_SetParam with multi-action dispatch, adaptive API check, and builtin plugin auto-detection from PLUGIN_REGISTRY. 326 tests (298 existing + 28 new), 12/12 spec scenarios compliant.
This commit is contained in:
81
.sdd/changes/archive/reascript-first/proposal.md
Normal file
81
.sdd/changes/archive/reascript-first/proposal.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Proposal: ReaScript-First Built-in Plugin Configuration
|
||||
|
||||
## Intent
|
||||
|
||||
RPPBuilder writes `.rpp` text that REAPER loads, but **built-in plugins** (ReaEQ, ReaComp, ReaVerb, etc.) need the REAPER API (`TrackFX_AddByName`, `TrackFX_SetParam`) to configure parameters correctly. Text-mode `VST "ReaEQ" "reaeq.dll"` loads the plugin but leaves all 19 param slots at zero — no EQ curve, no compression threshold. ReaScript already handles verify/render; it must also handle **built-in plugin insertion and parameter configuration** while RPPBuilder keeps generating VST3/MIDI/audio structure.
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
- New ReaScript actions: `add_track`, `add_fx`, `add_midi_item`, `configure_fx_params`
|
||||
- `ReaScriptCommand` dataclass extended with `plugins_to_add: list[PluginDef]`, `fx_params: list[dict]`
|
||||
- `ReaScriptGenerator` generates script blocks for `InsertTrackAtIndex`, `TrackFX_AddByName`, `CreateNewMIDIItemInProj`, `MIDI_InsertNote`, `TrackFX_SetParam`
|
||||
- `scripts/run_in_reaper.py` supports multi-action pipeline: skeleton → inject plugins → verify → render
|
||||
- `commands.py` decoupled: action dispatch mapping, `ReaScriptResult` gains `added_plugins: list[tuple[str, int]]`
|
||||
- RPPBuilder marks built-in plugins with `params` field; ReaScript reads these and applies via API
|
||||
|
||||
### Out of Scope
|
||||
- VST3 plugin insertion via ReaScript (RPPBuilder handles these)
|
||||
- ReaScript-based arrangement/track ordering (RPPBuilder remains source of truth)
|
||||
- OSC/HTTP-based REAPER control
|
||||
- Multi-DAW support
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `reascript-builtin-fx`: ReaScript generates code to insert built-in REAPER plugins with configured parameters via the native API, reading a `plugins_to_add` section from the command JSON.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `reascript-generator`: (existing) expands beyond verify/calibrate/render to support add_track, add_fx, add_midi_item, configure_fx_params actions with action dispatch.
|
||||
|
||||
## Approach
|
||||
|
||||
**Hybrid pipeline**: RPPBuilder writes a skeleton `.rpp` with VST3 plugs + MIDI + audio. ReaScript then executes:
|
||||
1. Open skeleton `.rpp`
|
||||
2. Add tracks reserved for built-in plugins (`InsertTrackAtIndex`)
|
||||
3. Insert FX by name (`TrackFX_AddByName("ReaEQ")`)
|
||||
4. Configure params (`TrackFX_SetParam(track, fx_idx, param_idx, value)`)
|
||||
5. Add MIDI items/notes for ReaScript-generated MIDI (if needed)
|
||||
6. Verify all FX → calibrate volumes → render → measure LUFS
|
||||
|
||||
`ReaScriptCommand.action` becomes an ordered list: `["add_plugins", "verify_fx", "calibrate", "render"]`. `ReaScriptGenerator._build_script()` dispatches per-action code blocks.
|
||||
|
||||
## Affected Areas
|
||||
|
||||
| Area | Impact | Description |
|
||||
|------|--------|-------------|
|
||||
| `src/reaper_scripting/commands.py` | Modified | New action types + `plugins_to_add` field |
|
||||
| `src/reaper_scripting/__init__.py` | Modified | New script generation blocks for built-in FX |
|
||||
| `scripts/run_in_reaper.py` | Modified | Multi-action pipeline orchestration |
|
||||
| `src/reaper_builder/__init__.py` | Modified | Mark built-in plugins in RPP with params dict |
|
||||
| `tests/test_reaper_scripting.py` | Modified | New tests for add_fx/configure_fx_params |
|
||||
|
||||
## Risks
|
||||
|
||||
| Risk | Likelihood | Mitigation |
|
||||
|------|------------|------------|
|
||||
| Built-in plugin API missing in REAPER version | Low | API check in generated script; fallback to text-only |
|
||||
| Param indices differ across REAPER versions | Medium | Pin known indices; version-detect at script startup |
|
||||
| Multi-action execution breaks existing tests | Medium | Extensible action dispatch; existing `"calibrate"` action preserved |
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
1. Revert `commands.py` to single-action model (backward compat: `action: "calibrate"` still works)
|
||||
2. Revert `_build_script()` to single-block generation
|
||||
3. RPPBuilder changes are additive (new `params` field); no rollback needed
|
||||
4. Existing 298 tests must remain green throughout
|
||||
|
||||
## Dependencies
|
||||
|
||||
- REAPER v7+ with Python ReaScript
|
||||
- No new Python packages
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- [ ] `ReaScriptCommand(action="add_plugins")` generates valid Python that calls `TrackFX_AddByName` and `TrackFX_SetParam`
|
||||
- [ ] Built-in plugin (ReaEQ) loaded with correct params in generated `.rpp` verified by REAPER
|
||||
- [ ] Existing 298 tests pass unchanged
|
||||
- [ ] `scripts/run_in_reaper.py` runs multi-action pipeline end-to-end
|
||||
- [ ] Generated ReaScript handles missing API gracefully with `check_api()` guard
|
||||
Reference in New Issue
Block a user