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>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6b1e65f418
commit
fc4ad3bb92
@@ -154,8 +154,14 @@ internal sealed class RecordingController
|
|||||||
var ext = AudioRecorder.ExtensionFor(s.FileFormat);
|
var ext = AudioRecorder.ExtensionFor(s.FileFormat);
|
||||||
var time = now.ToString("HH-mm-ss");
|
var time = now.ToString("HH-mm-ss");
|
||||||
|
|
||||||
|
// Multi-track follows the Source setting like single-file recording does: peer (received)
|
||||||
|
// tracks unless "sent only", and your own (sent) track only when you're actually recording
|
||||||
|
// your send ("both" or "sent only") — so a receive-only recording no longer makes a "me" file.
|
||||||
|
|
||||||
// One track per connected peer (their received audio only), created up front on the UI thread
|
// One track per connected peer (their received audio only), created up front on the UI thread
|
||||||
// so the audio-thread tap never has to open a file. Peers that join mid-recording aren't added.
|
// so the audio-thread tap never has to open a file. Peers that join mid-recording aren't added.
|
||||||
|
if (s.Source != RecordingSource.SentOnly)
|
||||||
|
{
|
||||||
var recs = new Dictionary<string, PeerTrack>();
|
var recs = new Dictionary<string, PeerTrack>();
|
||||||
var usedNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
var usedNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
var byAddr = new Dictionary<string, string>();
|
var byAddr = new Dictionary<string, string>();
|
||||||
@@ -171,13 +177,17 @@ internal sealed class RecordingController
|
|||||||
peerTracks = recs;
|
peerTracks = recs;
|
||||||
receiver.SetPeerRecordTap(OnPeerRecordBlock, raw: s.BypassShaping);
|
receiver.SetPeerRecordTap(OnPeerRecordBlock, raw: s.BypassShaping);
|
||||||
receiver.OnRecordBlockComplete = FlushPeerTracks;
|
receiver.OnRecordBlockComplete = FlushPeerTracks;
|
||||||
|
}
|
||||||
|
|
||||||
// Your own track — your sent audio.
|
// Your own track — your sent audio.
|
||||||
|
if (s.Source != RecordingSource.ReceivedOnly)
|
||||||
|
{
|
||||||
var mePath = Path.Combine(folder, $"{Sanitize(Environment.MachineName)} {time}.{ext}");
|
var mePath = Path.Combine(folder, $"{Sanitize(Environment.MachineName)} {time}.{ext}");
|
||||||
meRecorder = new AudioRecorder(WithSource(s, RecordingSource.SentOnly), diagnostic, OnRecorderFinished, mePath);
|
meRecorder = new AudioRecorder(WithSource(s, RecordingSource.SentOnly), diagnostic, OnRecorderFinished, mePath);
|
||||||
sender.OnSentSamples = meRecorder.WriteSent;
|
sender.OnSentSamples = meRecorder.WriteSent;
|
||||||
|
}
|
||||||
|
|
||||||
diagnostic($"recording: started multi-track → {folder} ({recs.Count} peer track(s), format={s.FileFormat}, bypass={s.BypassShaping})");
|
diagnostic($"recording: started multi-track → {folder} ({(peerTracks?.Count ?? 0)} peer track(s){(meRecorder is not null ? " + your send" : "")}, source={s.Source}, format={s.FileFormat}, bypass={s.BypassShaping})");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Audio thread. Route each peer's block to that peer's recorder. peerRecorders is fully built at
|
// Audio thread. Route each peer's block to that peer's recorder. peerRecorders is fully built at
|
||||||
|
|||||||
@@ -127,11 +127,10 @@ public sealed class RecordingSettings
|
|||||||
|
|
||||||
/// <summary>Default folder path used when <see cref="Folder"/> is blank. Computed at
|
/// <summary>Default folder path used when <see cref="Folder"/> is blank. Computed at
|
||||||
/// call time (not cached) so a launch from a different exe directory picks up that
|
/// call time (not cached) so a launch from a different exe directory picks up that
|
||||||
/// directory rather than the first-load one. The per-machine subfolder lets two
|
/// directory rather than the first-load one. Recordings nest by DATE inside this — the
|
||||||
/// machines sharing a Dropbox-backed RemSound install keep their recordings tidily
|
/// machine name lives in the split-track file names, not a top-level folder.</summary>
|
||||||
/// separated by sender identity.</summary>
|
|
||||||
public static string DefaultFolder() =>
|
public static string DefaultFolder() =>
|
||||||
Path.Combine(AppContext.BaseDirectory, "recordings", Environment.MachineName);
|
Path.Combine(AppContext.BaseDirectory, "recordings");
|
||||||
|
|
||||||
/// <summary>Returns the resolved folder this profile would record into right now —
|
/// <summary>Returns the resolved folder this profile would record into right now —
|
||||||
/// either the explicit <see cref="Folder"/> if set, or <see cref="DefaultFolder"/>.
|
/// either the explicit <see cref="Folder"/> if set, or <see cref="DefaultFolder"/>.
|
||||||
|
|||||||
Reference in New Issue
Block a user