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>
This commit is contained in:
Ednunp
2026-07-06 10:05:00 +01:00
co-authored by Claude Opus 4.8
parent 703e6a022d
commit de55230048
8 changed files with 294 additions and 29 deletions
@@ -125,6 +125,19 @@ internal sealed class RecordingSettingsDialog : Form
private Control? compressionColumn;
private TableLayoutPanel? grid;
private readonly AccessibleCheckBox splitTracksBox = new()
{
Text = "Split recording into separate &tracks — one file per peer, plus your own (Alt+T)",
AccessibleName = "Split recording into separate tracks, one file per peer plus your own send",
AutoSize = true,
};
private readonly AccessibleCheckBox bypassShapingBox = new()
{
Text = "Bypass pan and EQ when recording — record the &raw audio (Alt+R)",
AccessibleName = "Bypass pan and EQ when recording, record the raw audio",
AutoSize = true,
};
private readonly Button okButton = new()
{
Text = "&OK",
@@ -153,6 +166,11 @@ internal sealed class RecordingSettingsDialog : Form
public RecordingSettingsDialog(RecordingSettings current)
{
working = current?.Clone() ?? new RecordingSettings();
splitTracksBox.Checked = working.SplitTracks;
splitTracksBox.CheckedChanged += (_, _) => working.SplitTracks = splitTracksBox.Checked;
bypassShapingBox.Checked = working.BypassShaping;
bypassShapingBox.CheckedChanged += (_, _) => working.BypassShaping = bypassShapingBox.Checked;
var initialSnapshot = working.Clone();
Text = "Recording settings";
@@ -267,6 +285,20 @@ internal sealed class RecordingSettingsDialog : Form
Controls.Add(grid);
Controls.Add(buttonRow);
// The two per-recording toggles sit across the top of the dialog. Added last so docking
// resolves them to the top strip, above the option columns.
var optionsRow = new FlowLayoutPanel
{
Dock = DockStyle.Top,
FlowDirection = FlowDirection.TopDown,
AutoSize = true,
WrapContents = false,
Padding = new Padding(12, 12, 12, 0),
};
optionsRow.Controls.Add(splitTracksBox);
optionsRow.Controls.Add(bypassShapingBox);
Controls.Add(optionsRow);
AcceptButton = okButton;
CancelButton = cancelButton;