88 lines
4.3 KiB
C++
88 lines
4.3 KiB
C++
#pragma once
|
|
// Scope/source resolution shared by every capture entry point. Three concerns:
|
|
// * range inference — razor union else time selection, orthogonal to scope;
|
|
// * source-track collection — selected tracks (Track scope) or selected items'
|
|
// owning tracks (Item scope), deduped, with canonical GUIDs;
|
|
// * provenance-assembly inputs — resample-from-sample detection + the thin
|
|
// capture-recipe fingerprint built from the live (un-bypassed) chain.
|
|
//
|
|
// All reads are non-destructive: selection, razor, and time selection are read,
|
|
// never mutated. The .cpp includes reaper_plugin_functions.h WITHOUT
|
|
// REAPERAPI_IMPLEMENT (main.cpp owns the API pointers). MediaTrack is forward-
|
|
// declared (via capture.h) so this header stays SDK-lite.
|
|
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "shell/capture/capture.h" // CaptureRequest, MediaTrack fwd
|
|
#include "core/capture/render_settings.h" // CaptureScope
|
|
#include "core/model/provenance.h" // model::Provenance
|
|
|
|
namespace reasampler {
|
|
class BankBook;
|
|
}
|
|
|
|
namespace reasampler::capture {
|
|
|
|
// The resolved source: exact bounds + the source tracks (for FX-bypass + Sample
|
|
// provenance GUIDs). `sourceTracks` holds the item-owning tracks (Item scope) or the
|
|
// selected tracks (Track scope).
|
|
struct ResolvedSource
|
|
{
|
|
double startSeconds = 0.0;
|
|
double endSeconds = 0.0;
|
|
std::vector<MediaTrack*> sourceTracks;
|
|
std::vector<std::string> trackGuids;
|
|
|
|
// Parallel to sourceTracks (one entry per track, in the same order) — the names the
|
|
// capture is labeled and filed after. trackGuids is NOT parallel: an unreadable GUID
|
|
// is dropped there, while an unreadable name still holds its track's slot.
|
|
std::vector<std::string> trackNames;
|
|
|
|
// Item scope only: does the selected items' own extent already print
|
|
// [startSeconds, endSeconds)? Feeds sourceModeForScope. Defaults false so a
|
|
// hand-built source fails closed to the time-bounded render — a caller whose
|
|
// range IS the item extent (batch item capture) says so explicitly.
|
|
bool itemExtentIsWindow = false;
|
|
};
|
|
|
|
// Reads every track's P_RAZOREDITS and returns the union of parsed track-audio
|
|
// areas. Reads only — never clears the razor selection.
|
|
bool resolveRazorRange(double& start, double& end);
|
|
|
|
// Infers the render range for any scope: razor union when present, else the time
|
|
// selection. Returns false with a reason when neither yields a non-empty range.
|
|
bool resolveRange(double& start, double& end, std::string& why);
|
|
|
|
// Collects the selected tracks (Track scope) into out.sourceTracks + GUIDs + names.
|
|
bool collectSelectedTracks(ResolvedSource& out);
|
|
|
|
// The track's display name. GetTrackName (SDK header ~3626) is used rather than P_NAME
|
|
// because it already answers REAPER's own convention for an unnamed track ("Track N"),
|
|
// which is exactly the deterministic fallback a capture label wants; P_NAME would hand
|
|
// back an empty string instead. `[verify]` the SDK header states neither that the read is
|
|
// non-mutating nor what a `false` return means; the call site treats it as read-only and
|
|
// treats `false` (or a `true` with an untouched buffer) the same way — an empty name, which
|
|
// falls through to the scope literal fallback either way, so both readings are safe.
|
|
// Callers that build a ResolvedSource by hand (batch capture) use this directly.
|
|
std::string trackName(MediaTrack* tr);
|
|
|
|
// Resolves the source for a scope: the selection tracks (item/track), plus the
|
|
// inferred range. Returns false with a reason on nothing to do.
|
|
bool ResolveScopeSource(CaptureScope scope, ResolvedSource& out, std::string& why);
|
|
|
|
// Current project's directory (parent of its .rpp), forward-slashed, no trailing
|
|
// slash. Empty for an unsaved project (no false parentage). Read-only.
|
|
std::string currentProjectDir();
|
|
|
|
// Builds the provenance for a capture if it genuinely resamples from a bank sample
|
|
// (detectParent over `book`'s resolved file refs), else returns nullopt (the common,
|
|
// non-resample case). Must run BEFORE the FxBypassGuard neutralizes the in-scope
|
|
// chain — the source FX-chain identity is read from the live chain.
|
|
std::optional<model::Provenance> buildCaptureProvenance(
|
|
const BankBook& book, const CaptureRequest& req,
|
|
CaptureScope scope, const ResolvedSource& src);
|
|
|
|
} // namespace reasampler::capture
|