e8dcf724d8f12fca51ebf0dddf28170fa3141f8c
18
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
aed555cc2e |
Reset-ASIO button + checkbox tick/untick sounds (parts 1-2 of the cue/preferences overhaul)
Part 1 - "Uncheck all inputs and outputs" button now also resets the ASIO driver to "(none)": renamed to say so, and UncheckAllDevices sets asioDriverBox to row 0 for a full clean WASAPI-only, nothing-selected state. Part 2 - checkbox tick/untick sounds: every checkbox toggle anywhere in RemSound now plays a short cue (check.wav on tick, uncheck.wav on untick) - instant feedback on which way a box went, especially in the inputs/outputs lists. New CheckSoundService + two machine-wide cues (CheckboxOn/Off) with the usual numbered-variant + Preferences treatment. Hooked from AccessibleCheckBox.OnCheckedChanged and the device lists' WireCheckedListAccessibility, both gated on the control being Focused so a genuine user toggle clicks but bulk programmatic (un)checking (profile load, "uncheck all") stays silent. Reloaded at startup and on cue change. Tests + manual updated; .sfk byproducts cleared. Remaining for the overhaul (next): tabbed Preferences (General / Audio cues / Startup behaviour / Update settings), the cue-list redesign with a "none" option replacing per-cue checkboxes, moving Startup behaviour out of the Options menu, and a front-most "missing sound file" error. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
8763470037 |
Audio cues: add send/receive on-off and minimise/restore cues (2 sounds each), drop .sfk byproducts
Six new machine-wide cues, each with the same numbered-variant + Preferences treatment as
the others (enable tickbox, Choose default sound picker, Play/Browse):
- Send turned on / off, Receive turned on / off: fire from OnStreamingCheckboxChanged, so
they sound whether the user clicked the in-window tickbox or pressed the mute shortcut
(the hotkey flips .Checked, which routes through the same handler). Suppressed during
profile load by the existing password-gate guard, so loading a profile doesn't blast them.
- Minimise (hide) / Restore (show): fire from the tray controller's Minimize()/Restore() on a
genuine visibility transition (guarded against no-op / startup-minimise).
Enable flags + custom-WAV overrides for these six live machine-wide in AppConfig
(EnableSendOnCue.., MachineCueCustomPaths) - they're app-level feedback, not per-profile
audio - so no Profile/settings-cache plumbing. TryLoadCueSound now also honours the
machine-wide custom path. PreferencesDialog gains a MachineRow helper + the six rows.
Sounds: shipped via the existing sounds\*.wav wildcard. Fixed an obvious typo in the
supplied files ("rcieve off 1.wav" -> "recieve off 1.wav") so receive-off has both variants.
Renamed the old single-name cue WAVs to Ed's numbered-variant set; added key/passkey and the
new cue sounds.
build-release.ps1: new step deletes the SoundForge .sfk peak-file byproducts from sounds\
before packaging (they never shipped - build is *.wav only - this just keeps the tree tidy).
Tests + manual updated for the six new cues.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
e526014e6a |
Audio cues: per-cue default-sound picker, keyboard-click typing feedback, passkey on password fields
Cue sounds now ship as numbered variants ("connect 1.wav", "connect 2.wav", ...); the
count is never hard-coded so more can be added with no code change.
- CueSounds.cs: discovers a cue's "<base> <n>.wav" variants (case-insensitive) and
resolves the active default: per-profile custom WAV > machine-wide chosen variant >
first variant > silent. Wired into MainForm.TryLoadCueSound, the startup cue in
Program.cs, and PreferencesDialog.ResolveCueFilePath.
- AppConfig: DefaultCueSounds (machine-wide cueId -> chosen filename) and
EnableKeyboardClicks (on by default).
- Preferences: a "Choose default sound" listbox under the cue checklist - it lists the
selected cue's variants, arrowing it previews each sound and makes it that cue's
default. Plus a "Play keyboard clicks when typing into any edit field" checkbox.
- KeyClickService.cs: an app-wide WM_CHAR message filter + a low-latency NAudio mixer.
Typing into any edit field plays a random key click (key 1..N.wav); password fields
also play passkey.wav at the same instant. On/off live from the Preferences toggle.
Inert if the sounds are missing or the device won't open; never consumes the keystroke.
- csproj: ship every sounds\*.wav via a wildcard (variants, key clicks, passkey, future
additions) instead of stale per-file canonical names.
- Tests: resource checks (self-test + run-tests.ps1) now verify each cue has >=1 variant
and that key 1.wav / passkey.wav are present. Accessibility audit still green with the
new Preferences controls (Alt+D, Alt+K - no mnemonic clashes).
- Manual: variant picker, keyboard clicks, and the new sound-file naming documented.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
ad66fe5364 |
Test suite: richer diagnostics, headless accessibility audit, perf/leak sanity
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> |
||
|
|
832ed40bf7 |
Test suite: add --config-dir isolation, --smoke-test alias, and a cold-start/close gate step
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> |
||
|
|
141c5e8ce1 |
Add build-and-test suite (in-app self-test + publish gate); fix release-zip missing sounds
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> |
||
|
|
05b218825d |
Release v3.9: silent-mic fix, buffer drain, idle-send guard, start-up sound, command-line
- 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>
|
||
|
|
04b17ff1ab |
Release v3.8: New profile (blank template renamed), password-mismatch warning stays up, IP-pinning docs
New profile: a File-menu item + Ctrl+N that loads a fresh blank template as a new unsaved session via a LoadBlankTemplateNext handoff to Program.cs's relaunch loop — reachable even when "start with a specific profile" boots past the picker (issue #6). Offers to save the current profile first if dirty; deliberately silent (no profile-switch cue). Renamed the user-facing "blank template" to "New profile": the picker's synthetic entry (now a distinct marker TYPE, collision-safe against a real profile named "New profile"), the window title ("RemSound — New profile"), and the manual. Fixed the password-mismatch warning flashing away: it's raised from the 1 Hz statusTimer, which kept firing into the modal loop and rebuilt the peer lists (SyncAllPeerLists) under the dialog, knocking it out of the foreground. Now the tick is frozen while it's up, it's routed through ForegroundDialog, and a re-entry guard ensures one warning that stays put. Audited: it was the only popup raised from a recurring timer. Docs: manual section "Connecting to one specific IP address (and only that one)" explaining by-name vs by-fixed-IP and that a profile saves the exact address (issue #7 — functionality already existed); About box + RELEASE_NOTES for v3.8; MANUAL.md regenerated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
9e247112cb |
Release v3.7: device-change smoothing, auto-tune spike rejection, wider mic detector, forensic logging
Coalesce capture-engine rebuilds (CompositeCaptureBackend): a swap-triggering source change now arms a 250ms debounce timer and re-arms on each further change, so a flap or quick reconfiguration produces ONE rebuild to the final state instead of a burst (Andre's 16:40 four-rebuilds-in-33s crackle). In-place updates still apply immediately; a pending rebuild whose target flaps back is cancelled. Auto-tune (TickRoute) now keys off the SECOND-highest arrival-gap/render-gap second in the lookback window instead of the single worst, so a lone ~1s OS/driver stall no longer balloons the buffer to the 200ms cap (the 16:51 trim burst); sustained jitter still reacts at full speed. Logs both gap-max (true peak) and gap-used (value acted on). Mic-privacy detector widened: also catches a per-app Deny aimed at this exe under ConsentStore\microphone\NonPackaged\<exe>, the HKLM NonPackaged gate, and the Group-Policy/MDM force-deny (AppPrivacy LetAppsAccessMicrophone=2) — the block shapes that silence WASAPI capture while ASIO sails past, and that the old three-value check missed. Forensic instrumentation so the next log proves what happened: capPeak= (loudest pre-encode sample, per lane, on the diag line), mic-privacy verdict logged at startup, ui: capture tick/untick events, and device-event: lines for Windows endpoint changes. Docs: mic-privacy + auto-tune sections updated in readme.html, MANUAL.md regenerated, About-box changelog and RELEASE_NOTES for v3.7. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
55bdcde0af |
Release v3.6: rebuild the self-updater (in-app, rollback-safe); warnings to front
Replace the generated cmd.exe + robocopy update helper — which silently
failed on some machines — with an in-app C# installer:
* Stage the new version to a per-user temp folder off the install and run
the new RemSound.exe from there, so nothing in the install is locked by
the updater itself.
* Wait for the old process to fully exit (real WaitForExit), then
back-up-and-swap files in C# with retry + rename-aside; roll the install
back to the previous version on any failure, so a failed update can never
leave a half-installed RemSound.
* Log every step to updater.log; clean up old stages and legacy batch
artefacts on launch. Removed the old BuildInstallScript batch generator.
Route the "RemSound is already running" dialog and its follow-up message
through ForegroundDialog so they surface in front from a background-relaunched
copy, matching the earlier post-update fix.
Docs: rewrite the readme update sections for the new mechanism, regenerate
MANUAL.md, refresh the About-box changelog and RELEASE_NOTES.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
4dbe9a47a0 |
Release v3.5: USB-card recovery, per-card adaptive buffer, one user folder, audit fixes
- Recover an unplugged/replugged output sound card automatically (issue #5): detect the dead WASAPI device and remember the receive-output selection so it re-ticks and re-opens when the card returns. - Adaptive per-card WASAPI buffer target sized to each card's pull chunk, held stable so it never flits about under CPU/network load. - Consolidate all per-user data (config, profiles, logs, sounds) into one "user settings and logs" folder; migrate every older layout; exclude it from the updater so custom cue sounds now survive updates. - Mic-privacy detector: warn once when a Windows-blocked mic is switched on, or a profile loads with one already on. - All warning/notice dialogs now come to the foreground even when minimised. - Apply volume + mute on profile load (were saved but not restored). - Crash-safe (atomic) profile/config saves. - Fix two resource leaks (push-mode capture MMDevice; UPnP DeviceFound handler). - Remove dead code (baseline-diff machinery, dead ASIO probes, no-op stubs). - Docs: readme.html, MANUAL.md, About-box changelog and release notes for v3.5. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
946e6f4be4 |
v3.4 refinements: WASAPI drift correction, startup-dialog sequencing, quick-switch polish, docs
Builds on the v3.4 freeze (
|
||
|
|
959720f54d |
Release v3.3: end-to-end encrypted audio, plus cue and reliability fixes
Headline: all audio is now encrypted (AES-256-GCM), keyed by a per-profile password. Mandatory — v3.3 only interoperates with v3.3+. Encryption - RemSoundCrypto (Core): PBKDF2 key derivation, AES-GCM encrypt/decrypt (low-alloc, into-span), password fingerprint, light on-disk obfuscation. - Wire: SenderLane encrypts the audio payload (PCM split across parts when the +28 overhead crosses MTU); AudioReceiver/StreamSession decrypt via a shared single-thread AudioDecryptor. Fingerprint piggybacks on the Format packet (offset 36, backward-compatible) so a peer can detect a password mismatch. - Profile.Password (scrambled), carried through BuildCurrentProfile; MainForm derives + pushes the key/fingerprint to sender + receiver (RecomputeAudioCrypto). - UX: ask-for-password on profile create; File -> Change this profile's password (ProfilePasswordDialog); Options -> Profile passwords (manager); a gate that prompts before streaming without a password; and a clear "passwords don't match" / "peer needs to update" message driven by the fingerprint. Cue fixes - CuePlayer (NAudio) replaces System.Media.SoundPlayer, which silently failed on the 96 kHz/24-bit cue WAVs (and any custom file) — cues now play reliably, resampled to 48 kHz/16-bit. Also fixes the Preferences preview button. - Connect/disconnect cues now audio-gated with hysteresis: connected when audio flows OR heartbeat healthy; lost only when audio stops AND heartbeat unreachable. Kills false disconnects and the receive-only "no cues" case. - Honest cue logging (played / muted / not loaded). Smaller - Endpoint stickiness: keep the audio target pinned to the heartbeat-proven address instead of chasing a multi-homed peer's other (unreachable) address. - "Online/offline" label now audio+heartbeat aware, not discovery-only. - "Show what's new after each update" preference (on by default). Docs: About v3.3 block, RELEASE_NOTES, README (encryption as a headline), manual section 12 "Passwords and encryption" (+ renumber), MANUAL.md regenerated. Version 3.2.0 -> 3.3.0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
cdcac859c4 |
Release v3.2: update sound cue + single-instance bring-to-front fix
- New "Update sound" cue (CueId.Update / update.wav). Plays just before an
update starts installing, on every path (manual, background-silent,
startup-silent), so a silent background update gives an audible heads-up
before RemSound closes to restart. Per-profile mute + custom-sound override
in Preferences, same infrastructure as the other cues:
* Profile.EnableUpdateCue + RemSoundSettingsStore Load/Save + round-trip
* MainForm updateSound field, TryLoadCueSound, play in InstallUpdateAsync
gated by LoadEnableUpdateCue
* PreferencesDialog "Update sound" CueRow + ResolveCueFilePath mapping
* update.wav shipped in sounds\ via csproj Content
- Single-instance "switch to the running copy" now actually brings the window
to the front. The second copy grants the running copy foreground rights via
AllowSetForegroundWindow before signalling, and lingers briefly so it can
raise itself before we exit — without this, Windows' foreground lock left
the running window only flashing in the taskbar (Ed's report).
- Docs: About box v3.2 block, RELEASE_NOTES.md, manual cue section (now seven
cues, with the update cue described), MANUAL.md regenerated.
- Version bumped 3.1.3 -> 3.2.0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
9ab0a1a20a |
Bump to v3.1.3: single-instance lock + update/read-only reliability fixes
Fixes the chained-fault runaway Andre hit after an update (multiple copies
stacking, audio climbing to deafening, terminal kill to recover).
- Single-instance lock (SingleInstanceCoordinator + SingleInstanceDialog,
wired in Program.Main). A named mutex makes two copies impossible. A second
launch offers: switch to the running copy (default; surfaces it from the
tray via a named activation event), or force the running copy closed and
start fresh (Process.Kill, retried elevated if the target is elevated).
This is the structural fix that makes the stacking runaway impossible.
- Prompt-free update exit. InstallUpdateAsync sets updatingInProgress before
Application.Exit(); the close path's skipPrompt now honours it, so no
unsaved-changes dialog (whose default button is Cancel) can abort the
update's restart.
- Read-only persistence fix. BuildCurrentProfile now carries
currentProfileReadOnly into the saved snapshot. Previously a deliberate
save of a locked profile wrote ReadOnly=false, silently unlocking it on
disk — which re-armed the save prompt that then blocked the update.
- In-process double-install guard. updateInstallStarted stops the ~4 s
startup check and the background poll both staging an install + helper.
- Docs: About box, RELEASE_NOTES.md, readme.html + MANUAL.md ("Only one copy
of RemSound runs at a time").
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
baf50baf73 |
Bump to v3.1.2: tray icon re-stamps on state change, recording shows as a flag
- Tray icon now re-registers itself (hide+re-show) whenever the meaningful
state changes — peer connect/drop, send/receive toggle, recording
start/stop — so the name a screen reader announces stays in step with
the live state. Fixes the persistent "no peers" then "1 peer" double
announcement that the old "show window then minimise again" trick used
to clear by hand. Same root cause as the v3.1.1 stuck-tooltip fix, just
exposed when the state changes a moment after the icon appears.
- Recording shows as a plain "recording" flag in the tray rather than a
live timer. A ticking timer would have either flickered the icon once a
second or left a screen reader announcing a stale time next to the live
one. Removed the now-dead FormatRecordingElapsed helper.
- Bundles the earlier Win7 updater fix (
|
||
|
|
70c2669d70 |
Bump to v3.1.0: new audio cues (save, profile-switch), per-profile custom cue paths, redesigned tray menu
Two new cues join the existing connect / disconnect / record-start /
record-stop set:
* profile-save cue (sounds\save.wav by default) fires in
SaveProfileTo after a successful Save or Save As. Honours the
Profile.EnableSaveCue per-profile flag.
* profile-switch cue (sounds\profile.wav by default) fires in the
MainForm Shown handler after a profile finishes loading - covers
both startup-with-profile and mid-session profile switches.
Honours the Profile.EnableProfileSwitchCue flag. Because cue
loading runs AFTER settings.ApplyProfile in the ctor (line 542),
the profile being entered determines which sound plays - not the
one being left, exactly as Ed asked.
The audio cue UI in PreferencesDialog stays as a CheckedListBox (up /
down navigates, Space toggles) with TWO action buttons below that
operate on whichever cue is selected:
* Play [cue name] (Alt+P) - previews via SoundPlayer.Play on the
resolved path (custom override if set, default in sounds\
otherwise). Independent of the tick state.
* Browse for [cue name]... (Alt+B) - opens a WAV picker. If the
user picks a file inside RemSound's own sounds\ folder, it's
treated as "use default" and the override is cleared - avoids
pinning the user to a specific shipped default that a future
release might replace. Right-click "Use default sound" reverts.
Custom cue paths AND enable flags are per-profile. Lives on
Profile.CustomCuePaths (Dictionary<string,string>) and the per-cue
EnableXxxCue bool? properties. Cache mirror in
RemSoundSettingsStore.Settings.
All default WAVs moved from the install-root flat layout into a
sounds\ subfolder (csproj Content rules updated). save.wav and
profile.wav are bundled defaults.
Tray menu rewritten (MainFormTrayController) per Ed's spec:
* Show RemSound (W) - now uses Win32 SetForegroundWindow after the
standard Activate() because WinForms Activate is blocked by the
foreground-lock when invoked from a tray-menu click, which left
screen-reader users having to Alt+Tab to reach the restored
window.
* Enable sending (S) / Enable receiving (R) - tickable, reflect
current state, TOGGLE rather than always-on.
* Profiles (P) - submenu populated from AppConfig.RecentProfiles
with the same &1..&5 mnemonics the File menu uses. Pre-populated
once at construction so WinForms recognises it as a submenu and
fires DropDownOpening - originally I relied entirely on the
open event, which the framework skipped for items with no
DropDownItems, producing the "Profiles does nothing" bug.
* Exit (X).
Tray tooltip now built dynamically from snapshot tick (1 Hz):
"RemSound - [recording for MM:SS,] N peer(s), sending (lane),
receiving (lane)". Recording timer only included while
RecordingController.IsRecording is true (added
RecordingStartedUtc accessor for the elapsed calculation). Lane is
derived from which device-list ticks are active, not just the audio-
mode setting, so a BothIndependent user with only WASAPI inputs ticked
honestly reads as "sending (WASAPI)".
Fixes:
* Initial tooltip "RemSound" produced a "RemSound RemSound" read on
NVDA because the process name and tooltip matched. Set to
"RemSound - starting up" so the duplicate disappears.
* Recent profile menu items no longer carry a "Recent profile N:"
AccessibleName prefix in either the tray submenu or the File
menu's Recent profiles - now just the profile name. Number-key
mnemonics (&1..&5) untouched.
Manual (readme.html) updated: new section 17 "Audio cue sounds"
documents all six cues, the Play/Browse buttons, the right-click
"Use default sound", and the per-profile semantics. Sections 17-21
renumbered to 18-22. New "System tray icon and its menu" subsection
inside section 4 documents the redesigned right-click menu and the
hover tooltip. MANUAL.md regenerated via sync-manual.py. About box
gets a v3.1 block at the top. RELEASE_NOTES.md fully rewritten for
v3.1.
No wire format change - v3.1 talks to other v3.0.x machines exactly
as before.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
0189b12668 |
Docs: rewrite README.md for users, add MANUAL.md, sync from readme.html on every release
People landing on the repo page were having to install RemSound just to read what it does and how to use it. Two doc changes fix that: 1) README.md rewritten as a plain-English landing page. Drops the developer-focused highlights / build-from-source / project-layout sections in favour of what RemSound is, who it's for, how to install it, and a prominent link to the manual. No jargon, no command lines, no NuGet / SDK / ASIO-protocol talk. The dev-side information that used to live here (build commands, source layout, relay setup) is still discoverable for anyone who wants it — the source itself is on the same page, and the relay docs are under server/README.md. 2) MANUAL.md added at the repo root as the GitHub-rendered version of the F1 help. Markdown derived directly from readme.html via sync-manual.py (new), so visitors can read the manual inline on the repo page with no download. readme.html stays exactly where it was (bundled inside RemSound, opened by F1) — it remains the canonical source of the manual content; MANUAL.md is auto-generated from it. The sync-manual.py script is invoked automatically from build-release.ps1 as step 0, before any other release work. It regenerates MANUAL.md from readme.html and then checks `git diff` on MANUAL.md — if the file changed, the release is paused with a message asking the user to commit the updated MANUAL.md alongside the release commit. That makes it structurally impossible to ship a release with a stale GitHub-facing manual: forgetting to commit MANUAL.md after editing the bundled help triggers a deliberate release-time stop. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |