diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d82788..3114f2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -125,6 +125,55 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and starts a fresh subdirectory). Surfaced via `MainViewModel.RollRecordingCommand`, REST `POST /recording/roll`, and OSC `/teamsiso/recording/roll`. Useful for chaptering between show segments. +- **Engine audio peak metering** — `IsoHealthStats.PeakAudioLevel` now + reports real values (was always 0.0). New `INdiInterop.CaptureAudioPeak` + method polls audio frames; production `NdiInteropPInvoke` parses + `NDIlib_audio_frame_v3_t` and computes max-absolute peak across all + channels. `NdiReceiver` runs a sibling audio capture loop on the same + lifetime so the existing video path is unaffected. UI VU bars in the + participants DataGrid now animate against real source audio. Failures + in the audio loop are caught + logged but never re-thrown — a + misbehaving audio path must never tear down the live video pipeline. + 14 new unit tests in `AudioPeakComputerTests` covering FLTP / FLT / PCM + s16 across edge cases (clipping, `short.MinValue` overflow, defensive + `totalSamples`-vs-buffer mismatch handling). + +#### LAN-reachable control surface +- `ControlSurfaceServer.Start(port, bindToLan)` and `OscBridge.Start(port, + bindToLan)` switch between `127.0.0.1` and all-interfaces (`http://+:port/`, + `IPAddress.Any`) based on the new `ControlSurfaceLanReachable` UI preference. + Settings VM persists the toggle, restarts both surfaces on flip, and + surfaces a `ControlSurfaceUrl` (computed from the host's first physical-NIC + routable IPv4 — Tailscale / VPN / APIPA addresses are skipped) plus a Copy + button. Use case: headless host PC running Teams + TeamsISO; thin client + on the same LAN drives `/ui` or hits the REST endpoints. Closed-network + deployment, no auth — documented as a trusted-LAN-only mode in + `docs/CONTROL-SURFACE.md`. First-time use requires a one-shot + `netsh http add urlacl url=http://+:9755/ user=Everyone` (so the listener + can bind without admin); the diagnostic warning fires the exact command + string in the log if the bind fails. + +#### UI polish — visible affordances on the dark canvas +- Hover state on every themed button (Ghost / Caption / RailIcon / IsoToggle) + was barely distinguishable from the resting state. Bumped `Wd.SurfaceHover` + + `Wd.SurfaceActive` colours for sufficient contrast, added dedicated + `Wd.Button.HoverBg` / `Wd.Button.PressBg` brushes with a slight chroma tint, + and added cyan accent borders so mouse-hover and tab-focus give an + unmistakable affordance regardless of which surface the button sits on. + IsoToggle keeps its status-coded background (LIVE cyan / ERROR coral / + NO SIGNAL amber) on hover; the affordance is a 2px cyan border pop. +- `IsKeyboardFocused` triggers added on every themed button so tab-cycling + through the UI gives visual feedback (was nothing — `FocusVisualStyle` + was `x:Null` with no replacement). +- ScrollBar restyled: slim transparent track + tinted thumb (Edge / VS Code + pattern) in place of the chunky Win9x default with line-up / line-down + arrow buttons. Track-clicks above/below the thumb still page-scroll. +- ToolTip restyled: SurfaceElevated card with rounded 6px corner + 320px + text wrap, replacing the cream Win98 popup. Affects every tooltip across + MainWindow. +- ContextMenu / MenuItem restyled: dark card with rounded corners + cyan- + tinted hover. Affects the right-click menu on participant rows + (Toggle ISO / Restart this ISO / Open preview / Record / Copy NDI source name). #### Control surface - REST API on `127.0.0.1:9755` with endpoints for participant ISO toggle (by @@ -164,5 +213,13 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). (`width*height*4 > Pixels.Length`). - `HasThumbnail` correctly fires `PropertyChanged` when `Thumbnail` transitions from null. +- WinForms / WPF `Application` and `MessageBox` namespace collision + (introduced when `true` was added for + the system tray) resolved via project-wide `GlobalUsings.cs`. +- `GetLanIPv4()` now skips Tailscale / VPN tunnel adapters and APIPA + (`169.254.x`) so the displayed control-surface URL points at the + routable LAN IP (verified on a host with both Ethernet 10.x and a + Tailscale 169.254 link-local — picker now correctly returns the + Ethernet address). [Unreleased]: https://forge.wilddragon.net/zgaetano/teamsiso/compare/v0.1.0...HEAD