New Options -> Install / Uninstall RemSound on this PC: a per-user self-installer
(%LOCALAPPDATA%\Programs\RemSound, no admin) with optional desktop + Start-menu
shortcuts, login auto-start (reuses StartupAutoStart), Windows Installed-apps
registration, and copy-across of profiles+config, recordings and logs. Install
state is decided by a marker file, not a folder-path guess; the post-install
relaunch hands over foreground via AllowSetForegroundWindow so the installed copy
comes to the front; uninstall uses a batch remover (no PowerShell) and confirms
with two independent tick-boxes. All new dialogs use the house accessible controls
(AccessibleCheckBox, Theme.Heading).
Also: iOS (TestFlight) companion link alongside Android in README + manual;
slimmed-down default cue WAVs; About/RELEASE_NOTES/manual updated; version -> 5.1.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Multi-track recording drift fix (Ed's question — can the separate tracks drift over an hour?):
* Root: FlushPeerTracks skipped a peer that produced no samples in a render block, so a peer that
went quiet long enough for its session to be pruned (>4 s idle) would have its track fall behind
and desync. Now every peer track is padded to a full render block each cycle (silence when the
peer produced nothing), so all peer tracks stay sample-locked to the single render clock — they
can't drift apart however long the recording runs, and all end the same length. Same padding for
the single-file bypass path. OnRecordBlockComplete now carries the block's float count.
(The peer tracks are already resampled to the render clock per peer, so this makes peer-to-peer
sync exact; your own "me" track is capture-clocked — same soundcard for capture+playback = same
clock = no drift, different interfaces can drift slightly.)
* Self-test: two new steps — "Per-peer shaping DSP" (PeerDspChain unity/master-off/volume/parametric
+ ParametricToPeaking) and "v5 settings and shaping round-trip" (AppConfig defaults, NamedPeers,
MainTabOrder, parametric PeerShaping, recording default = Both).
* Logging (gated by the logging checkbox): master shaping switch, EQ-mode change, parametric band
add/delete, peer rename/clear/delete, and the applied Appearance settings after Preferences close.
* CLI: --list-profiles and --list-named-peers (read-only), in --help.
* Version bumped to 5.0; About-box changelog, RELEASE_NOTES.md and README updated for v5.
Build clean; --selftest passes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Audio cues
- Cues for send/receive on-off, minimise/restore, checkbox tick/untick, and tab switch
- Soft keyboard clicks while typing, with a distinct passkey sound on password fields
- Per-cue "Choose sound" variant picker; "(none)" silences a cue; front-most missing-sound warning
- Send/receive cues take priority over the generic checkbox sound; programmatic ticks stay silent
Preferences
- Redesigned into four tabs (General, Audio cues, Startup behaviour, Update settings)
- Startup behaviour moved in from the Options menu
- NVDA now announces the dialog on open (focus a real named control, not the quiet tab control)
Auto-tune
- Cause-aware: tells device render-callback stalls (more buffer can't fix) apart from genuine
network/buffer starvation, so it no longer pins latency high on chunky onboard cards
- Lowering the target eases the buffer down (glide) instead of trimming it, so no clicks while tuning
Sounds layout
- Shipped defaults moved out of the per-user folder into an install-side "default sounds" folder,
so updates can refresh them; user customs are Browse-picked file paths and are left untouched
- Startup migration removes both legacy sound folders; verified from oldest (v1.0-v3.3) and v3.4 layouts
Quiet automated launches
- New --silent launch flag mutes all cue sounds and suppresses the startup dialogs (migration notice,
update check, Realtek/mic/missing-sound warnings) so test launches never disturb the user
- run-tests / build-release / SelfTest repointed to the new "default sounds" layout
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Andre's three "bigger ideas" from RemSound-smoke-test-agent-brief.md:
- Richer diagnostics: --diagnostics now includes a live localhost audio self-check
(PCM + Opus, with packet/underrun/drop/buffer/latency counters), the most recent
session snapshot parsed from the log (codec, send/receive state, buffer, drops,
heartbeat), and a recent-warnings/errors digest from the log. BuildDiagnosticsReport
gained a runLiveAudioProbe flag so the self-test's privacy check stays fast.
- Headless accessibility audit: new --selftest step constructs the dialogs that can be
built without hardware (Startup behaviour, Recording settings, Preferences) and checks
every actionable control announces a name and that Alt-key mnemonics are unique within
a container. MainForm is out of scope (its constructor opens audio/hotkeys/sockets).
Dialogs that won't construct are skipped, not failed. Currently audits 3, no violations.
- Perf/leak sanity: new --perftest command runs several audio-loopback cycles and reports
whether handle/memory/thread counts stay bounded (handles ratcheting up cycle-on-cycle is
the leak fingerprint, given RemSound's handle-leak history). Lenient thresholds; logs the
numbers for build-to-build comparison. Wired into run-tests.ps1.
- Shared AudioLoopback helper (used by the self-test, diagnostics and perf test) so all
three exercise the identical real capture/encode/network/decode path on test port 47929.
- csproj: the four previously-unconditional cue Content items are now Exists-guarded like
the rest, so a mid-edit sounds\ folder doesn't break the dev build; the gate still
enforces the required cues before release.
Help + manual updated (--perftest, --smoke-test, --config-dir, richer --selftest).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adopted from Andre's RemSound-smoke-test-agent-brief.md - the gaps our pack didn't
already cover:
- --config-dir <folder>: redirect ALL user state (config, profiles, logs, cue
sounds) to an explicit folder for this process only, applied at the very start of
Program.Main before the layout migration runs. Lets a test exercise a real build
without touching the user's live settings (the brief's safety rule 1). Works with
every command. AppConfig gains SetUserDataDirectoryOverride / an override on
UserDataDirectory; CommandLine.TryGetConfigDir parses it early.
- --smoke-test / --smoketest: alias for --selftest, matching the brief's vocabulary.
- run-tests.ps1: a cold-start + clean-close smoke (brief baseline steps 3-4) -
launches the GUI minimized against an isolated --config-dir, confirms it stays up,
that it used the isolated folder (real settings untouched), and that --close shuts
it down with no orphan process. SKIPs cleanly if a RemSound instance is already
running (machine-wide single-instance lock).
Manual + --help updated for both switches.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The test suite, modelled on Andre's Sensor Readout (an in-app self-test + a build
script), runnable as one step before every publish.
Part 1 - in-app multi-step self-test (SelfTest.cs), run by --selftest:
audio round-trip (PCM + Opus over localhost, dedicated test port so it never
clashes with a running instance), encryption right/wrong-password + fingerprint,
packet framing + malformed rejection, client<->server wire-format compatibility,
settings save/reload, profile save/reload (temp folder), diagnostics-report
privacy (never leaks a password), and bundled-resources present. Each step is
timed and reported PASS/FAIL/SKIP; exit 0 only if nothing failed. Replaces the
old single-shot --selftest. RunDiagnostics refactored to expose
BuildDiagnosticsReport(AppConfig) for the privacy step.
Part 2 - run-tests.ps1: builds, then checks the package (sounds, readme, native
opus, framework-dependent, dll version == csproj), the About-box changelog, the
client/server wire contract (relay magic/version/port still match RemPacket),
the CLI surface, and runs --selftest. build-release.ps1 now runs this gate first
and aborts the release if it fails.
Bug caught + fixed: the published release zip carried ZERO cue sounds (startup
sound + connect/disconnect/etc.) - MSBuild's incremental Content-copy marker
skipped sounds\ on a fresh publish. Added an AfterTargets=Publish copy in the
csproj that lands every cue WAV in the published sounds\ folder regardless of
the marker. Verified: a staging publish now contains all 9 cue WAVs.
Manual/help: --selftest description updated (readme.html + MANUAL.md).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Receiver: a plain (Mixed) stream now renders on an active lane when the
receiver is in two-lane (ASIO) mode, instead of being decoded into a ring
nothing reads. Fixes one-way silence ("my mic works for me but not for them").
- Receiver: drift resampler gains a buffer-depth correction term so a bloated
standing buffer eases back to the latency target over a long session.
- App: don't send audio until a peer is genuinely reachable (issue #8); status
no longer shows phantom send traffic with nobody connected.
- App: start-up cue sound (machine-wide toggle + custom path in Preferences).
- App: command-line options (CommandLine.cs) -- --devices, --selftest,
--diagnostics, --log, --close, --profile, --connect, --minimized, --version,
--help. New "Command-line options" manual section (readme.html + MANUAL.md).
- Version 3.9; About-dialog and RELEASE_NOTES updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>