Skip to content

Commit a94c9c9

Browse files
committed
EngineSession.cpp:415 — OSC focus callback now uses clampFocus(v) instead of std::max(v, 0.1f), consistent with the direct setter
1 parent 79010d0 commit a94c9c9

6 files changed

Lines changed: 89 additions & 77 deletions

File tree

README.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ No Python toolchain required. Requires CMake 3.20+ and a C++17 compiler.
3636

3737
After setup, binaries are at:
3838

39-
| Binary | Path |
40-
| ---------------------------- | --------------------------------------------------------------- |
39+
| Binary | Path |
40+
| ---------------------------- | ---------------------------------------------------------------------- |
4141
| `spatialroot_realtime` | `build/source/spatial_engine/realtimeEngine/spatialroot_realtime` |
4242
| `spatialroot_spatial_render` | `build/source/spatial_engine/spatialRender/spatialroot_spatial_render` |
43-
| `cult-transcoder` | `build/internal/cult_transcoder/cult-transcoder` |
43+
| `cult-transcoder` | `build/internal/cult_transcoder/cult-transcoder` |
4444

4545
### Subsequent Builds
4646

@@ -109,7 +109,7 @@ Optional:
109109

110110
### OSC parameter control
111111

112-
When `--osc_port` is non-zero (default: 9009), the engine accepts OSC messages on `127.0.0.1:<port>` for live parameter updates: `/realtime/gain`, `/realtime/focus`, `/realtime/speaker_mix_db`, `/realtime/sub_mix_db`, `/realtime/paused`, `/realtime/elevation_mode`.
112+
When `--osc_port` is non-zero (default: 9009), the engine accepts OSC messages on `127.0.0.1:<port>` for live parameter updates: `/realtime/gain_db`, `/realtime/focus`, `/realtime/speaker_mix_db`, `/realtime/sub_mix_db`, `/realtime/paused`, `/realtime/elevation_mode`.
113113

114114
### Quick dev rebuild (engine only)
115115

@@ -153,14 +153,14 @@ Options:
153153

154154
The build system is CMake + shell scripts. No Python required.
155155

156-
| Script | Platform | Role |
157-
| ----------- | ------------- | ---------------------------------------------- |
158-
| `init.sh` | macOS / Linux | Initialize submodules + call `build.sh` |
159-
| `build.sh` | macOS / Linux | CMake configure + build |
160-
| `init.ps1` | Windows | Initialize submodules + call `build.ps1` |
161-
| `build.ps1` | Windows | CMake configure + build |
162-
| `run.sh` | macOS / Linux | Launch the ImGui GUI (builds first if needed) |
163-
| `run.ps1` | Windows | Launch the ImGui GUI |
156+
| Script | Platform | Role |
157+
| ----------- | ------------- | --------------------------------------------- |
158+
| `init.sh` | macOS / Linux | Initialize submodules + call `build.sh` |
159+
| `build.sh` | macOS / Linux | CMake configure + build |
160+
| `init.ps1` | Windows | Initialize submodules + call `build.ps1` |
161+
| `build.ps1` | Windows | CMake configure + build |
162+
| `run.sh` | macOS / Linux | Launch the ImGui GUI (builds first if needed) |
163+
| `run.ps1` | Windows | Launch the ImGui GUI |
164164

165165
The root `CMakeLists.txt` builds all components via option flags:
166166

TODO.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@
44

55
## next tasks
66

7-
- allow for setting runtime params prior to starting engine, add reset button
7+
- clean up transcode tab
8+
89
- duplicate api docs in internal and public, which is most up to date? ---
910
- clean up documentation
1011
- public facing
1112
- consolidate dev history and testing docs
1213

1314
- test speaker layout config on windows, validate code
1415

15-
- clean up transcode tab?
16-
1716
## Audits
1817

1918
api audit

internalDocs/API_internal.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ The engine enforces a strict, linear initialization sequence:
102102
| Method | Writes | Range |
103103
|---|---|---|
104104
| `setMasterGainDb(float)` | `mConfig.masterGain` | -60–+12 dB |
105-
| `setDbapFocus(float)` | `mConfig.dbapFocus` | min 0.1 |
105+
| `setDbapFocus(float)` | `mConfig.dbapFocus` | 0.1–5.0 |
106106
| `setSpeakerMixDb(float)` | `mConfig.loudspeakerMix` | -60–+12 dB |
107107
| `setSubMixDb(float)` | `mConfig.subMix` | -60–+12 dB |
108108
| `setElevationMode(ElevationMode)` | `mConfig.elevationMode` | cast to int |

internalDocs/devHistory.md

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
- Updated `--help` to document both `--adm` modes, the CULT search order, temp-dir behavior, and the source mapping convention.
6060

6161
**Offline ADM source mapping convention** (applies to the offline renderer only; not a general ADM or LUSID rule):
62+
6263
- `"N.1"` maps to 0-based WAV channel `N-1` (e.g. `"1.1"` → ch0, `"2.1"` → ch1)
6364
- `"LFE"` maps to WAV channel 3 when the file has ≥ 4 channels — matches `--lfe-mode hardcoded` passed to CULT
6465
- Sources that cannot be mapped using this convention are a hard failure (not silently skipped)
@@ -119,12 +120,14 @@
119120
**Thread safety:** Capture is only active during single-threaded startup stages. In `start()`, capture is explicitly restored before `mStreaming->startLoader()` to avoid racing with the background loader thread. No capture occurs during audio callback execution.
120121

121122
**Files changed:**
123+
122124
- `source/spatial_engine/realtimeEngine/src/EngineSession.hpp` — added `getFailureDiagnostics()` and `storeFailureDiagnostics()` declarations; added `mFailureDiagnostics` member
123125
- `source/spatial_engine/realtimeEngine/src/EngineSession.cpp` — added `TeeStreamBuf`, `StageCapture`; wired into `loadScene`, `applyLayout`, `start`; added `getFailureDiagnostics()` and `storeFailureDiagnostics()` implementations
124126
- `source/gui/imgui/src/App.hpp` — added `appendFailureDiagnostics()` declaration
125127
- `source/gui/imgui/src/App.cpp` — added `appendFailureDiagnostics()` implementation; called at all five failure points in `doLaunchEngine()`
126128

127129
**Failure log format:**
130+
128131
```
129132
=== Failure diagnostics ===
130133
Stage: load scene (ADM streaming)
@@ -150,10 +153,12 @@ Terminal output:
150153
**Motivation:** The previous Transcoder tab only exposed `cult-transcoder transcode` (ADM→LUSID Scene). CULT now supports two additional subcommands (`package-adm-wav`, `adm-author`) that were inaccessible from the GUI.
151154

152155
**Files changed:**
156+
153157
- `source/gui/imgui/src/App.hpp` — added workflow state members and constants for all three workflows
154158
- `source/gui/imgui/src/App.cpp``renderTranscodeTab()` rebuilt with `BeginTabBar("##tc_workflow")`
155159

156160
**Three sub-tabs now exposed:**
161+
157162
1. **ADM to LUSID Scene** (`cult-transcoder transcode`) — converts ADM XML or ADM WAV/BWF metadata to `scene.lusid.json`
158163
2. **ADM WAV to LUSID Package** (`cult-transcoder package-adm-wav`) — extracts ADM, converts metadata, splits interleaved audio into a LUSID package directory
159164
3. **LUSID to ADM Export** (`cult-transcoder adm-author`) — authors LUSID package material into Logic-compatible ADM BWF/WAV + sidecar ADM XML
@@ -241,6 +246,7 @@ Terminal output:
241246
**Problem:** After the April 17 normalized DBAP upgrade, fast-moving sources produced audible pops or gain steps. Root cause: `mPrevSafePos[si]` was always written as the block-center guard-resolved position (`safePos`), even for fast-mover blocks whose last rendered audio corresponded to the last sub-step (near `positionEnd`). Under normalized DBAP, the dominant speaker gain can jump 4× (from `1/sqrt(N) ≈ 0.25` equidistant to `≈1.0` near-speaker) across the normalization basin boundary. When `positionEnd` and block-center straddle that boundary, the Bug 9.1 `doBlend` anchor on the following block was wrong — it injected a discontinuity rather than smoothing one.
242247

243248
**Fix (Spatializer.hpp):**
249+
244250
- Fast-mover loop now captures `lastSubSafePos = subSafePos` at `j == kNumSubSteps - 1`
245251
- Fast-mover branch writes its own state immediately after the loop: `mPrevSafePos[si] = lastSubSafePos`, `mPrevGuardFired[si] = 0`, `mPrevWasFastMover[si] = 1`
246252
- Normal-path state update guarded by `!isFastMover`; clears `mPrevWasFastMover[si] = 0`
@@ -488,9 +494,9 @@ else:
488494

489495
**Executable paths at the time:**
490496

491-
| Tool | POSIX | Windows |
492-
| ---------------- | --------------------------------------------------------------- | ----------------------------------- |
493-
| ADM Extractor | `src/adm_extract/build/spatialroot_adm_extract` | `...spatialroot_adm_extract.exe` |
497+
| Tool | POSIX | Windows |
498+
| ---------------- | ---------------------------------------------------------------------- | ----------------------------------- |
499+
| ADM Extractor | `src/adm_extract/build/spatialroot_adm_extract` | `...spatialroot_adm_extract.exe` |
494500
| Spatial Renderer | `source/spatial_engine/spatialRender/build/spatialroot_spatial_render` | `...spatialroot_spatial_render.exe` |
495501

496502
All of `src/config/configCPP*.py` removed in Phase 6.
@@ -676,7 +682,7 @@ Locked v1 design decisions documented at the time:
676682
| `src/analyzeADM/checkAudioChannels.py` | Per-channel audio activity scan |
677683
| `src/packageADM/splitStems.py` | Mono WAV stem splitter |
678684
| `src/analyzeRender.py` | PDF render analysis |
679-
| `internal/LUSID/src/` | Python LUSID library (scene.py, xml_etree_parser.py, parser.py) |
685+
| `internal/LUSID/src/` | Python LUSID library (scene.py, xml_etree_parser.py, parser.py) |
680686

681687
### cult-transcoder CLI Invocation (historical reference)
682688

@@ -721,15 +727,15 @@ processedData/stageForRender/ — cult-transcoder writes scene.lusid.json her
721727

722728
## Key Milestones
723729

724-
| Phase | Date | Description |
725-
| ------- | -------------- | ------------------------------------------------------------------------------------------- |
726-
| Phase 1 | January 2026 | Initial ADM extraction pipeline using `spatialroot_adm_extract` |
727-
| Phase 2 | February 2026 | Codebase audit; `spatialroot_adm_extract` deprecated |
728-
| Phase 3 | March 4, 2026 | Transitioned to `cult-transcoder`; removed per-channel audio scan |
729-
| Phase 4 | March 7, 2026 | `cult-transcoder` gains `--lfe-mode` flag; ADM profile detection (Atmos, Sony360RA) |
730-
| Phase 5 | March 7, 2026 | TRANSCODE UI added to PySide6 GUI (superseded by ImGui GUI in Phase 6) |
731-
| Phase 6 | March 31, 2026 | C++ refactor complete. Python GUI/entrypoints/build/venv removed. ImGui + GLFW GUI shipped. |
732-
| Phase 7 | April 17, 2026 | Normalized DBAP (`sum(v_k²)=1`). `thirdparty/allolib``internal/cult-allolib`. Auto-compensation removed. |
733-
| Bug 10.1 | May 7, 2026 | Fast-mover continuity anchor fix for normalized DBAP (`mPrevSafePos` written as last sub-step position). |
734-
| Phase 8 | May 10, 2026 | Persistent default speaker layout + cross-platform app settings paths. `DefaultLayoutManager` added to GUI layer. Settings dir (`~/Library/Application Support/Spatial Root/` etc.) is strictly separate from session temp cache. Atomic writes, non-fatal startup fallback, GUI controls: Set as Default / Clear Default / status display. |
735-
| Phase 9 | May 10, 2026 | Offline Render tab added to Dear ImGui GUI. Wraps `spatialroot_spatial_render` via the existing `SubprocessRunner`. ADM WAV mode (experimental) and LUSID Package mode both supported. GUI does not invoke CULT directly; the offline renderer owns CULT invocation, temp dir lifecycle, and source mapping validation. Realtime engine behavior unchanged. |
730+
| Phase | Date | Description |
731+
| -------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
732+
| Phase 1 | January 2026 | Initial ADM extraction pipeline using `spatialroot_adm_extract` |
733+
| Phase 2 | February 2026 | Codebase audit; `spatialroot_adm_extract` deprecated |
734+
| Phase 3 | March 4, 2026 | Transitioned to `cult-transcoder`; removed per-channel audio scan |
735+
| Phase 4 | March 7, 2026 | `cult-transcoder` gains `--lfe-mode` flag; ADM profile detection (Atmos, Sony360RA) |
736+
| Phase 5 | March 7, 2026 | TRANSCODE UI added to PySide6 GUI (superseded by ImGui GUI in Phase 6) |
737+
| Phase 6 | March 31, 2026 | C++ refactor complete. Python GUI/entrypoints/build/venv removed. ImGui + GLFW GUI shipped. |
738+
| Phase 7 | April 17, 2026 | Normalized DBAP (`sum(v_k²)=1`). `thirdparty/allolib``internal/cult-allolib`. Auto-compensation removed. |
739+
| Bug 10.1 | May 7, 2026 | Fast-mover continuity anchor fix for normalized DBAP (`mPrevSafePos` written as last sub-step position). |
740+
| Phase 8 | May 10, 2026 | Persistent default speaker layout + cross-platform app settings paths. `DefaultLayoutManager` added to GUI layer. Settings dir (`~/Library/Application Support/Spatial Root/` etc.) is strictly separate from session temp cache. Atomic writes, non-fatal startup fallback, GUI controls: Set as Default / Clear Default / status display. |
741+
| Phase 9 | May 10, 2026 | Offline Render tab added to Dear ImGui GUI. Wraps `spatialroot_spatial_render` via the existing `SubprocessRunner`. ADM WAV mode (experimental) and LUSID Package mode both supported. GUI does not invoke CULT directly; the offline renderer owns CULT invocation, temp dir lifecycle, and source mapping validation. Realtime engine behavior unchanged. |

0 commit comments

Comments
 (0)