capture: refuse the multi-track ranged item render, silence the track's children and receives for it, and gate every exact-bounds capture on its frame count
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "shell/capture/insert.h" // runInsert / InsertRequest
|
||||
#include "shell/capture/realtime_lifecycle.h" // the in-flight realtime state
|
||||
#include "shell/capture/render_selection.h" // RenderTrackSelection
|
||||
#include "shell/capture/render_isolation.h" // UpstreamIsolation
|
||||
|
||||
#include "reaper_plugin.h" // UNDO_STATE_MISCCFG
|
||||
|
||||
@@ -181,15 +182,41 @@ CaptureResult renderOffline(CaptureScope scope,
|
||||
const std::vector<MediaTrack*>& sourceTracks,
|
||||
const CaptureRequest& req)
|
||||
{
|
||||
// Refused BEFORE anything is touched, so the refusal path has nothing to
|
||||
// restore. This is the seam BOTH a fresh capture and a recipe replay cross, so
|
||||
// neither can land the multi-stem render the predicate names.
|
||||
if (isMultiTrackRangedItemRender(scope, req.sourceMode,
|
||||
static_cast<int>(sourceTracks.size())))
|
||||
{
|
||||
CaptureResult refused;
|
||||
refused.status = CaptureStatus::MultiTrackRange;
|
||||
refused.message =
|
||||
"This range is narrower than the selected items, so it renders through "
|
||||
"their tracks -- and those items span more than one track, which renders "
|
||||
"one file per track. Capture one track's items at a time, or make the "
|
||||
"range match the items' extent.";
|
||||
return refused;
|
||||
}
|
||||
|
||||
ReaProject* proj = EnumProjects(-1, nullptr, 0);
|
||||
// A selected-tracks render prints the DAW's track selection, so the request's
|
||||
// own tracks must BE that selection for the render — the plain track scope
|
||||
// already resolved them from the live selection (identity), but a ranged item
|
||||
// capture and a re-capture-from-source both name tracks the user has not
|
||||
// selected. Both guards outlive the render call and restore on every path.
|
||||
// selected. Every guard below outlives the render call and restores on every path.
|
||||
std::optional<RenderTrackSelection> selection;
|
||||
std::optional<UpstreamIsolation> isolation;
|
||||
if (req.sourceMode == SourceMode::SelectedTracks)
|
||||
{
|
||||
selection.emplace(sourceTracks);
|
||||
// An ITEM capture routed through the tracks source would otherwise print
|
||||
// everything upstream of the track — folder children, receives — which the
|
||||
// selected-items source excluded. The refusal above is what makes the single
|
||||
// source track here the whole set. Track scope is left alone: a folder
|
||||
// parent's own output IS its children summed.
|
||||
if (scope == CaptureScope::Item && !sourceTracks.empty())
|
||||
isolation.emplace(sourceTracks.front());
|
||||
}
|
||||
FxBypassGuard fxGuard(scope, sourceTracks, proj);
|
||||
OfflineRenderBackend backend;
|
||||
return backend.capture(req);
|
||||
|
||||
Reference in New Issue
Block a user