* New "Opus, live latency" codec mode: 2.5 ms frames (120 samples/ch at 48 kHz)
via the float-input encode path. End-to-end codec delay drops to ~5 ms (vs
~12.5 ms at standard 10 ms Opus). Test on LAN: 400 pps/lane, zero missed /
reordered / duplicate packets, ~15 ms one-way saved end-to-end.
* Wire-format change: AudioFormatInfo.FrameDurationMilliseconds renamed to
FrameSamplesPerChannel (int sample-count at announced sample rate). Removes
the lossy 48000*ms/1000 conversion that couldn't represent 2.5 ms. v3 <-> v3
exact; v3 <-> v2 still passes audio (Opus decoder is self-describing from
packet TOC) but v2 side over-sizes its buffer wildly. v2.x profiles auto-
migrate via <120 sentinel rule in RemSoundSettingsStore (anything below 120
is treated as legacy ms and multiplied by 48). Profile JSON key kept as
OpusFrameMilliseconds via [JsonPropertyName] so old profile files still load.
* Codec dropdown rebuilt with use-case names: "PCM 48K 24 bit - uncompressed",
"Opus, broadcast quality - loss tolerant", "Opus, live latency - for jamming
and monitoring". Middle 10 ms option retired; saved 480-sample profiles
collapse to broadcast quality (safer-side default).
* Profile auto-resume after self-update: RemSoundUpdater writes a one-shot
_resume-after-update.txt sentinel containing the active profile title before
exit; Program.Main reads + deletes it on next start and silently loads that
profile, skipping the picker. Helper batch's robocopy /XF excludes the
sentinel and the failure-branch cleans it up if the install aborts. Falls
through to normal startup behaviour (StartWithProfileTitle or picker) if the
sentinel is missing, empty, or names a profile that no longer exists.
* Read-only profile saves now go through on explicit Ctrl+S / File -> Save
with a one-time TaskDialog warning ("Save anyway" / "Cancel" + Do-not-show-
again). Lock continues to suppress the automatic unsaved-changes prompt on
close / profile switch (its main job). AppConfig.SaveOnReadOnlyMessageSuppressed
renamed to SaveOnReadOnlyWarningSuppressed; v2.x suppression flag is silently
discarded since the behaviour changed and the user needs to see the warning
once on each machine.
* Manual (readme.html) updated: codec table rewritten with the three new
choices and corrected bandwidth figures, send-rate description updated, new
sections "The same profile picks up automatically after an update" and
"Saving on purpose while a profile is locked".
* Subsumes the never-separately-released v2.2 work: native Opus encoder
(~97% less per-second memory churn on Opus send path via Concentus.Native),
efficiency tidy-ups (item 4 ASIO probe rate, item 6 WaitHandle, item 7
snapshot cache, items 14/16 heartbeat + discovery), legacy cleanup
(items 30/34/35/36: KeepAlive infrastructure, drift drop/repeat/accumulator
fields, fan-out cache stat). New diagnostic columns cpu/memMB/wsMB/
allocKBps/captureMs/sendMs/recvMs/renderMs gated on Enable-logs.
About dialog updated with v3.0 block at top; v2.2 block retained for the
subsumed work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Opening an ASIO driver takes 1-3 seconds, synchronously, during MainForm
construction — confirmed in logs as a ~2.8s dead gap on an ASIO-profile
launch (a WASAPI-only launch is ~131ms for the same stretch). During that
gap the main window is blank / "Not Responding" and looks hung.
New AsioLoadingSplash shows a small "Loading audio driver, please wait..."
window on its OWN dedicated STA thread with its own message loop, so it
stays painted while the main thread is blocked opening the driver.
Program.cs starts it before new MainForm() and dismisses it after.
Deliberately, the ASIO driver open stays on the main UI thread — that
STA/message-pump thread is what ASIO/COM drivers are most compatible with,
and moving the open off it risks breaking drivers that can't be tested.
Only the cosmetic splash moved to a side thread; no ASIO/driver code is
touched. Splash shows only for profiles with an ASIO driver selected;
WASAPI-only profiles build fast and get no splash.
Version bumped to 2.0.0 to mark the milestone.
No wire-format or audio-pipeline changes — v1.5 through v2.0 interoperate.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>