You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
**`RuntimeParams` is the canonical parameter struct.** Defaults come from `RuntimeParams::defaults()` — a single source of truth used by API, CLI, and GUI. Default values: `masterGainDb=0`, `dbapFocus=1.5`, `speakerMixDb=0`, `subMixDb=0`.
234
+
235
+
**Staging before Run:**`configureRuntime(params)` can be called before `start()` to set initial playback values. The engine starts from these staged values — it does not briefly use hardcoded defaults. GUI sliders are editable before Run as staged values.
236
+
237
+
**Live update after Run:**`configureRuntime()`, individual setters, and OSC callbacks all write to the same `RealtimeConfig` atomics and are safe to call while audio is running.
238
+
239
+
**Querying current state:**`getRuntimeParams()` returns the current values in dB, reflecting the latest `configureRuntime()`, setter, or OSC change. Use this to sync GUI controls after a `resetRuntimeParams()` call.
240
+
241
+
**Reset:**`resetRuntimeParams()` is equivalent to `configureRuntime(RuntimeParams::defaults())`. Safe before and after `start()`. Does not reload scene/layout, restart playback, or affect transport.
242
+
233
243
**Primary (in-process):** ImGui GUI calls direct C++ setters on `EngineSession`:
- See [REALTIME_ENGINE.md § OSC Parameter Reference](REALTIME_ENGINE.md#osc-parameter-reference) for full address/range table
242
254
255
+
**Output routing** is layout-derived and initialized in `applyLayout()` → `configureOutputRouting()`. `configureRuntime()` no longer touches routing setup. CSV remap override is retained as deprecated internal scaffolding only.
2.`loadScene(const SceneInput&)` — parses LUSID scene via `JSONLoader`, initializes `Streaming`. Returns `false` if scene file missing or no sources loaded.
75
-
3.`applyLayout(const LayoutInput&)` — requires `loadScene` to have succeeded (`mSceneData` guard). Loads speaker layout, initializes `Pose` and `Spatializer`.
76
-
4.`configureRuntime(const RuntimeParams&)` — writes gain/focus/mix atomics to `mConfig`. Loads remap CSV if path non-empty. **OSC ParameterServer is NOT started here — it starts in `start()`.**
77
-
5.`start()` — creates and starts `al::ParameterServer` (if `oscPort > 0`), registers OSC callbacks, starts `RealtimeBackend` + loader thread. Prints `"ParameterServer listening"` to stdout when OSC is active.
79
+
3.`applyLayout(const LayoutInput&)` — requires `loadScene` to have succeeded (`mSceneData` guard). Loads speaker layout, initializes `Pose` and `Spatializer`. Calls `configureOutputRouting()` internally.
80
+
4.`configureRuntime(const RuntimeParams&)` — clamps and writes gain/focus/mix atomics to `mConfig`. **Does not perform output routing setup** (moved to `applyLayout()`). Safe before and after `start()`. Syncs OSC param values if the OSC server is already running. **OSC ParameterServer is NOT started here — it starts in `start()`.**
81
+
5.`start()` — creates and starts `al::ParameterServer` (if `oscPort > 0`), initializes OSC params from current runtime state via `getRuntimeParams()`, registers OSC callbacks, starts `RealtimeBackend` + loader thread.
82
+
83
+
**Runtime control (before or after `start()`):**
78
84
79
-
**Runtime Control (after `start()`):**
85
+
`configureRuntime()` is safe to call at any point after `configureEngine()`:
86
+
-**Before `start()`:** stages the initial playback values; the engine will start from these.
87
+
-**After `start()`:** applies values live through the same atomic path as the individual setters.
80
88
81
-
| Method | Writes to | Notes |
89
+
| Method | Writes | Notes |
82
90
|---|---|---|
91
+
|`configureRuntime(const RuntimeParams&)`| all 4 gain/focus params | Clamps + converts dB→linear. Syncs OSC if running. |
92
+
|`getRuntimeParams() -> RuntimeParams`| — (read only) | Returns current state in dB; reflects setters, OSC changes, and `configureRuntime`. |
93
+
|`resetRuntimeParams()`| all 4 gain/focus params | Equivalent to `configureRuntime(RuntimeParams::defaults())`. Does not restart playback, reload scene/layout, or clear files. |
83
94
|`setPaused(bool)`|`mConfig.paused`| Only supported transport control. Stop/seek unsupported. |
84
-
|`update()`| — | Should be called from the main thread / host loop. Currently retained for API stability; no deferred focus-compensation work remains. |
95
+
|`update()`| — | Should be called from the main thread / host loop. Currently retained for API stability. |
85
96
|`queryStatus() -> EngineStatus`| — | Lock-free snapshot. No state mutation. |
86
97
|`consumeDiagnostics() -> DiagnosticEvents`| — | Atomically exchanges event flags. Clears them on read. |
87
98
|`shutdown()`| — | Terminal. Destroy and recreate `EngineSession` to restart. |
88
99
89
-
**Phase 6 runtime setters (direct C++ control, no OSC required):**
100
+
**Runtime setters (direct C++ control — no OSC required; no OSC sync on individual setters):**
90
101
91
-
| Method | Writes |Notes|
102
+
| Method | Writes |Range|
92
103
|---|---|---|
93
-
|`setMasterGainDb(float)`|`mConfig.masterGain`| dB → linear conversion at store time; range -60–+12 dB |
94
-
|`setDbapFocus(float)`|`mConfig.dbapFocus`| Clamped to a minimum of `0.1f`|
95
-
|`setSpeakerMixDb(float)`|`mConfig.loudspeakerMix`| dB → linear conversion at store time |
96
-
|`setSubMixDb(float)`|`mConfig.subMix`| dB → linear conversion at store time |
97
-
|`setElevationMode(ElevationMode)`|`mConfig.elevationMode`| Cast to int at store time |
98
-
99
-
All writes use `std::memory_order_relaxed`. Safe to call after `start()` and before `shutdown()`.
104
+
|`setMasterGainDb(float)`|`mConfig.masterGain`| -60–+12 dB |
105
+
|`setDbapFocus(float)`|`mConfig.dbapFocus`| min 0.1 |
106
+
|`setSpeakerMixDb(float)`|`mConfig.loudspeakerMix`| -60–+12 dB |
107
+
|`setSubMixDb(float)`|`mConfig.subMix`| -60–+12 dB |
108
+
|`setElevationMode(ElevationMode)`|`mConfig.elevationMode`| cast to int |
109
+
110
+
All writes use `std::memory_order_relaxed`. Safe to call before and after `start()`.
111
+
Individual setters do **not** sync OSC visible parameter values. Use `configureRuntime()` or
-**Resume step calculation:** Fade-in step is now `(1.0f - mPauseFade) / fadeFrames` rather than always `1/fadeFrames`. Ramp continues from current gain instead of resetting to zero (Bug 11.3).
279
279
-**`stop()` fade-before-hard-stop:** Arms pause fade and unconditionally sleeps 50ms before calling `mAudioIO.stop()`. Resets `mConfig.paused = false` afterward (Bugs 11.2, 11.4).
280
280
281
-
**Gain system (May 7, 2026):** All three gain controls now accept dB at every public surface. Conversion to linear (`std::pow(10.0f, dB / 20.0f)`) happens at the API boundary in `configureRuntime()`, `setMasterGainDb()`, `setSpeakerMixDb()`, `setSubMixDb()`, and OSC callbacks. Internal `RealtimeConfig` atomics remain linear.
281
+
**Gain system (May 7, 2026; updated May 10, 2026):** All gain controls accept dB at every public surface. Conversion to linear (`clampDb` → `dbToLinear = std::pow(10.0f, dB / 20.0f)`) happens at the API boundary via `applyRuntimeParamsToConfig()`, called by `configureRuntime()`, individual setters, and OSC callbacks. `getRuntimeParams()` performs the inverse via `linearToDb`; zero/negative linear → `-60.0f` (never -inf). Internal `RealtimeConfig` atomics remain linear.
282
+
283
+
`configureRuntime()` no longer performs output routing setup. Output routing is now initialized in `applyLayout()` → `configureOutputRouting()`. `configureRuntime()` is safe to call before or after `start()`.
284
+
285
+
`RuntimeParams::defaults()` is the single canonical source of default values for API, CLI, and GUI. `resetRuntimeParams()` is equivalent to `configureRuntime(RuntimeParams::defaults())`.
282
286
283
287
| Control | Public API | Range | Default | OSC address |
284
288
|---|---|---|---|---|
285
289
| Master gain |`RuntimeParams::masterGainDb`, `setMasterGainDb(float)`| -60–+12 dB | 0.0 dB |`/realtime/gain_db`|
**Status:** Complete. Covers `EngineSession` API, CLI, GUI, and docs.
11
+
12
+
**Motivation:** Runtime controls (gain, focus, mix) were disabled in the GUI before playback started and reset to hardcoded defaults on every Start click. Default values were duplicated across `RuntimeParams`, CLI argument parsing, and `resetRuntimeToDefaults()` in App.cpp. `configureRuntime()` mixed parameter setup with output routing setup, making it unsafe to call before `applyLayout()`.
13
+
14
+
**What changed:**
15
+
16
+
-`EngineSession.hpp` / `EngineSession.cpp`:
17
+
- Added `RuntimeParams::defaults()` — single canonical source of default values.
18
+
- Added file-local helpers: `clampDb`, `clampFocus`, `dbToLinear`, `linearToDb` (defensive: zero/negative linear → -60 dB, not -inf).
- Added public `getRuntimeParams()` — reads atomics, converts linear→dB, re-clamps; reflects setters, OSC, and `configureRuntime` changes.
21
+
- Added public `resetRuntimeParams()` — equivalent to `configureRuntime(RuntimeParams::defaults())`.
22
+
- Refactored `configureRuntime()`: now only writes gain/focus/mix atomics + syncs OSC if running. No longer touches `mSpatializer` or `OutputRemap`.
23
+
- Moved output routing setup (remap CSV scaffolding + layout-derived routing) to `configureOutputRouting()`, called at the end of `applyLayout()`. `configureRuntime()` is now safe to call before `applyLayout()`.
24
+
- Updated `start()`: initializes OSC param values from `getRuntimeParams()` instead of reading atomics directly.
25
+
- Updated individual setters to use `clampDb`/`clampFocus`/`dbToLinear` helpers consistently.
26
+
27
+
-`main.cpp`: CLI now initializes `RuntimeParams` from `RuntimeParams::defaults()` and overrides from flags, eliminating duplicated literal defaults.
28
+
29
+
-`App.cpp`:
30
+
- Removed `BeginDisabled` guard around runtime controls — sliders/inputs are always editable as staged values before Run.
31
+
- Input callbacks always clamp; setters called only when running.
32
+
- Added "Reset Parameters" SmallButton inline with the RUNTIME CONTROLS header. Before Run: resets GUI staged values via `resetRuntimeToDefaults()`. After Run: calls `mSession->resetRuntimeParams()` and syncs GUI from `mSession->getRuntimeParams()`.
33
+
- Removed `resetRuntimeToDefaults()` call from `onStart()` — staged values are now preserved when playback starts.
34
+
- Updated `resetRuntimeToDefaults()` to use `RuntimeParams::defaults()` instead of hardcoded literals.
35
+
36
+
-`internalDocs/API_internal.md`, `REALTIME_ENGINE.md`, `AGENTS.md`: updated to reflect new API methods, routing refactor, defaults source, and OSC sync semantics.
37
+
38
+
**OSC sync note:**`configureRuntime()` and `resetRuntimeParams()` sync OSC-visible parameter values when the OSC server is running. Individual setters (`setMasterGainDb` etc.) do not sync OSC values — they write atomics only. `getRuntimeParams()` reflects OSC changes because both OSC callbacks and setters write the same atomics.
0 commit comments