Files
renato97 b08dcccca2 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.
2026-05-04 09:38:58 -03:00

99 lines
4.7 KiB
Markdown

# reascript-builtin-fx Specification
Built-in REAPER plugin (ReaEQ, ReaComp, etc.) insertion and parameter configuration via ReaScript API, complementing RPPBuilder's VST3/MIDI/audio skeleton.
## Requirements
### Requirement: Insert Built-in FX via API
The ReaScript SHALL insert built-in REAPER plugins using `TrackFX_AddByName(fxname, instantiate=1)`, reading from command JSON's `plugins_to_add` list.
#### Scenario: Insert ReaEQ on target track
- GIVEN `plugins_to_add: [{"track_name": "Bass", "fx_name": "ReaEQ"}]`
- WHEN add_plugins action runs
- THEN `TrackFX_AddByName` is called on track "Bass" and the FX index is recorded in result
#### Scenario: Track not found
- GIVEN `plugins_to_add` references a non-existent track name
- WHEN insertion runs
- THEN an error with the track name is written to result; script continues to next plugin
### Requirement: Configure FX Parameters
The ReaScript SHALL call `TrackFX_SetParam(track, fx_idx, param_idx, value)` for each entry in a plugin's `params` dict.
#### Scenario: Set ReaEQ frequency and gain
- GIVEN ReaEQ at FX index 0 on "Bass" with `params: {"2": 200.0, "5": 3.0}`
- WHEN configure_fx_params runs
- THEN `SetParam(track, 0, 2, 200.0)` and `SetParam(track, 0, 5, 3.0)` are called
#### Scenario: Unknown param index
- GIVEN a params entry maps to a non-exposed index
- WHEN `TrackFX_SetParam` is called
- THEN the call proceeds (REAPER silently ignores invalid indices); no error raised
### Requirement: Post-Insertion Verification
After insertion, the ReaScript MUST verify the plugin loaded by calling `TrackFX_GetFXName`. A case-insensitive name match marks success; mismatch produces an error.
#### Scenario: Plugin loaded successfully
- GIVEN ReaEQ inserted at FX index 0
- WHEN verification runs
- THEN `GetFXName` returns "ReaEQ" (case-insensitive) and result marks it "ok"
#### Scenario: Plugin failed to load
- GIVEN insertion returned index -1 or name mismatch
- WHEN verification runs
- THEN result records `"failed to load ReaEQ on track Bass"`
### Requirement: Graceful API Degradation
The ReaScript SHALL check `TrackFX_AddByName`/`TrackFX_SetParam` availability at startup. If absent, it MUST exit with `{"status": "error"}` without attempting insertion.
#### Scenario: API functions missing
- GIVEN the REAPER version lacks `TrackFX_AddByName`
- WHEN `check_api()` runs
- THEN result is `{"status": "error", "message": "missing API: TrackFX_AddByName"}` and insertion is skipped
---
# Delta for reascript-generator
## ADDED Requirements
### Requirement: Multi-Action Dispatch
`ReaScriptCommand.action` SHALL accept an ordered string list. The generator MUST dispatch one script block per action in order. A string value like `"calibrate"` SHALL be treated as `["calibrate"]` for backward compat. Absent/empty SHALL default to `["calibrate"]`.
#### Scenario: Ordered pipeline
- GIVEN `action=["add_plugins", "verify_fx", "calibrate", "render"]`
- WHEN `_build_script()` runs
- THEN script contains insert → verify → calibrate → render blocks, each gated by its presence in the list
#### Scenario: String backward compat
- GIVEN `action="calibrate"`
- WHEN `_build_script()` runs
- THEN output matches current single-block behavior
### Requirement: Built-in FX Script Blocks
The generator SHALL produce code for `add_plugins` (iterates `plugins_to_add`, calls `TrackFX_AddByName`, verifies) and `configure_fx_params` (iterates same list, calls `TrackFX_SetParam`). Both SHALL be conditional on their action appearing in the list.
#### Scenario: Generate add_plugins + configure_fx_params
- GIVEN `plugins_to_add` with one ReaEQ entry + params, `action=["add_plugins", "configure_fx_params"]`
- WHEN script executes in REAPER
- THEN plugin is inserted then all specified params are configured
## MODIFIED Requirements
### Requirement: Extended Command/Result Schema
Command JSON SHALL include optional `plugins_to_add: [{"track_name": str, "fx_name": str, "params": {str: float}}]`. Result JSON SHALL include optional `added_plugins: [{"fx_name": str, "instance_id": int}]`.
(Previously: no plugin insertion fields.)
#### Scenario: plugins_to_add round-trip
- GIVEN command with `plugins_to_add=[{"track_name": "Bass", "fx_name": "ReaEQ", "params": {"2": 200.0}}]`
- WHEN script executes successfully
- THEN result includes `added_plugins: [{"fx_name": "ReaEQ", "instance_id": 0}]`
### Requirement: Adaptive API Check
`check_api()` SHALL require `TrackFX_AddByName`/`TrackFX_SetParam` when the action list includes `add_plugins` or `configure_fx_params`. For calibrate-only commands, the required set SHALL remain unchanged.
(Previously: required API set was static.)
#### Scenario: API check adapts
- GIVEN `action=["add_plugins"]`
- WHEN `check_api()` runs
- THEN `TrackFX_AddByName` and `TrackFX_SetParam` are required; absence produces error result