7038fef67c11e825894cc93cd469aad2726942f1
7
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
aeca24ae17 |
v5 pre-release: multi-track drift fix, more self-tests, logging, CLI, version bump
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> |
||
|
|
57847ff358 |
Pan/EQ: label the advanced mode "12 band"; single recordings include the machine name
Two of Ed's test findings: the EQ mode picker still said "10 band advanced EQ" (it's 12 now); and a single-file recording's name now carries the recorder's machine name too — "<HH-mm-ss> RemSound recording <machine>.<ext>" — matching the split tracks. Held for release. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
fc4ad3bb92 |
Recording fixes: date folders on top, and multi-track honours the Source setting
Two issues Ed found testing: * The default recordings path was recordings\<machine>\, so date folders nested under a machine-name folder. Dropped the per-machine subfolder — recordings now nest by date at the top (recordings\<yyyy-MM-dd>\...); the machine name still appears in split-track file names. * Multi-track always created the "me" (sent) track regardless of the Source setting, so a receive-only recording wrongly produced a track of your own machine. Multi-track now follows Source like single-file does: peer (received) tracks unless "sent only", and your own (sent) track only when Source is "both" or "sent only". Held for next release. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
efa9435da7 |
Recording: sum each peer's streams per track (record how it sounds)
Follow-up to the multi-track feature (Ed): the split path wrote each per-peer tap straight to that peer's file, so a peer sending on more than one lane stacked their streams sequentially instead of summing. Playback and the single-file path already sum; now the per-peer path does too. Each PeerTrack accumulates that peer's block(s) per render and flushes the sum once on the block boundary (OnRecordBlockComplete = FlushPeerTracks). "Sum to listen, sum to record." Held for next release. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
de55230048 |
Multi-track + shaped/raw recording (per-peer split tracks) — held for next release
Recording Settings gains two per-profile toggles (Ed's request): * "Split recording into separate tracks" — each recording becomes a folder with one file per connected peer (their received audio only) plus one for your own send. * "Bypass pan and EQ when recording" — record the RAW audio (before pan/EQ) instead of the shaped audio you hear; applies to single and split. Engine: a per-peer record tap in SessionPlayout hands each peer's block to the recorder RAW (before pan/EQ) or SHAPED (after) per the bypass flag; PlayoutEngine propagates the tap to all sessions (+ inherits on reconnect) and fires OnRecordBlockComplete each render; AudioReceiver exposes SetPeerRecordTap / OnRecordBlockComplete. AudioRecorder now accepts an explicit path and exposes ExtensionFor. RecordingController composes one AudioRecorder per track: multi-track = a recorder per connected peer + a "me" recorder; single-track shaped = the existing mixed tap; single-track raw (bypass) = sum each peer's raw block per render, flushed on the block boundary. Naming (Ed's scheme, sortable): <recordings>/<yyyy-MM-dd>/ then, single-track, "<HH-mm-ss> RemSound recording.<ext>"; multi-track, a folder "<HH-mm-ss> RemSound recording multi track/" containing "<machine name> <HH-mm-ss>.<ext>" per peer (name or IP) and for your own send. Known edge (noted): a peer using sender-side BothIndependent (two lanes) records both lanes to one file in a split recording; single-track bypass sums per render in the Mixed path. Off by default (both toggles unticked = today's behaviour). Builds clean; pending Ed's hands-on test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
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>
|
||
|
|
c59e413c1f |
Bump to v1.2.0: recording, sound cues, drift compensation, diagnostics
New user-facing features:
* Recording. Dedicated Record menu (Alt+O — moved from Alt+R to
avoid clashing with the Receive audio checkbox), Start/Stop on
Ctrl+R, settings dialog, per-profile source / format / bit-depth /
channel-mode / folder. Three source modes (received only, sent
only, both). Files are crash-resilient — a process crash
mid-recording leaves a playable file containing everything up to
the last header refresh (~5 seconds).
* Four output formats, all functional:
- WAV: 16/24-bit PCM or 32-bit float, custom writer with
periodic RIFF re-patching.
- MP3: LAME 128–320 kbps CBR (via NAudio.Lame).
- OGG-Opus: 96–256 kbps VBR (via Concentus.Oggfile, reusing the
Concentus encoder from the wire path).
- FLAC: 16/24-bit lossless (via CUETools.Codecs.FLAKE — pure
managed, no native DLL).
* Recording start/stop sound cues. record start.wav and
record stop.wav play around the recording transition. Played via
System.Media.SoundPlayer to the default Windows output, separate
from the recording pipeline so a normal recording does not contain
the cue.
* Per-cue Preferences. The old single "Mute connect/disconnect
sounds" checkbox is replaced by a CheckedListBox: Connect /
Disconnect / Recording start / Recording stop. Old profiles with
the legacy MuteConnectionCues=true are honoured on first load via
a migration path in the new Load* helpers.
* Receiver-side drift compensation switched from discrete
single-frame splices to a continuous WdlResampler at a smoothed
rate ratio. SessionPlayout.cs rewrite.
Diagnostics (only active with Enable logs ticked):
* Per-stage discontinuity probes — sender raw capture (per backend,
PushModeWasapi + Asio both wired), sender pre-encode (now per
lane in BothIndependent, fixing a cross-stream artefact), receiver
post-decode, post-ring, post-resampler.
* Wire-level packet sequence tracking on each PCM stream — in-order
/ missed / reordered / duplicated counts in the diag log.
* Clipped-sample delta in the diag log.
* New AudioStepProbe in RemSound.Core with per-channel scan helper.
UI changes:
* Record menu uses Alt+O (Rec&ord). Inside the menu, item mnemonics
unchanged (S / T / O / C).
* Auto-tune interval combo label is mode-aware: "Auto-tune latency
interval" in classic modes, "Auto-tune interval — WASAPI and ASIO"
in BothIndependent. The combo's Enabled state now follows EITHER
lane's auto-tune checkbox (was only the WASAPI one — bug).
Wire format and audio pipeline unchanged from v1.1 — v1.1 and v1.2
peers interoperate.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|