Merge Ψ-W2-T2: a bit-identical capture collapses to one lossless mono channel

# Conflicts:
#	src/shell/capture/CLAUDE.md
#	src/shell/capture/capture.cpp
#	src/shell/capture/capture.h
This commit is contained in:
2026-08-01 22:23:06 -04:00
14 changed files with 444 additions and 22 deletions
@@ -184,6 +184,10 @@ CaptureResult finalizeRecording(ReaProject* proj, MediaTrack* temp,
request.endSeconds);
}
// Channel-domain rewrite, after the frame-domain trim so it acts on the final
// frame set; it preserves the frame count, so the trimmed length above still holds.
const bool collapsedToMono = collapseCapturedFileToMono(destPath);
// Pure recorded-capture -> Sample mapping (identity, bounds echo, tier).
RecordedCapture cap;
cap.relativePath = paths.relativePath;
@@ -194,7 +198,9 @@ CaptureResult finalizeRecording(ReaProject* proj, MediaTrack* temp,
cap.wetDry = request.wetDry;
cap.displayName = request.label();
cap.trackGuids = request.trackGuids;
cap.channelCount = request.channelCount;
// channelCount deliberately left unset here: stampCaptureSample measures it from
// the file below. Echoing the request was this path's own defect — it parsed the
// recorded layout for the trim and still reported the requested 2.
result.status = CaptureStatus::Ok;
result.sample = sampleFromRecordedCapture(cap);
@@ -219,7 +225,8 @@ CaptureResult finalizeRecording(ReaProject* proj, MediaTrack* temp,
std::to_string(request.startSeconds) + "s, " +
std::to_string(request.endSeconds) + "s] (recorded " +
std::to_string(result.sample.lengthSeconds) + "s) -> " +
paths.relativePath;
paths.relativePath +
(collapsedToMono ? " (collapsed to mono)" : "");
return result;
}