Files
reasampler/src/core/capture/capture_name.h
T
daniel d7e5c59547 Remediate Phase P render-in-place review findings
Fix the ProjectMedia refusal path's false bank claims and file relocation, an unreachable-undo idiom, and eight comment/doc accuracy issues.
2026-08-02 14:51:55 -04:00

85 lines
3.7 KiB
C++

#pragma once
// capture_name — the REAPER-free composition of one capture's label and file-stem base
// from its source-track name(s), a local-calendar discriminator, and an optional batch
// ordinal. The shell reads the names and the clock; the SHAPE of a capture's name is
// decided here so it is testable without a DAW.
#include <cstddef>
#include <string>
#include <vector>
namespace reasampler::capture {
// The capture's own moment, already broken down into LOCAL calendar fields by the shell.
// Passing fields rather than an epoch is what keeps the format deterministic under test:
// an epoch would render differently per machine timezone. month < 1 or day < 1 means
// "no stamp" and suppresses the discriminator entirely.
struct CaptureStamp {
int month = 0; // 1-12
int day = 0; // 1-31
int hour = 0; // 0-23
int minute = 0; // 0-59
};
// Longest source-name prefix kept in either the label or the stem. Real track names sit
// far under it; the bound exists so a pathological name cannot push the rendered file
// path toward the platform's limit, and so a label and its file still read as the same
// name.
inline constexpr std::size_t kMaxSourceNameBytes = 64;
struct CaptureNameInputs {
// Source-track names in source order — the first non-empty one names the capture,
// the rest only contribute the "+N" multi-source marker.
std::vector<std::string> sourceNames;
CaptureStamp stamp;
// Batch unit ordinal; <= 0 for a single capture.
int ordinal = 0;
// The scope literal ("item"/"track"/"realtime"), used ONLY when no source name
// resolved at all — otherwise the source name wins.
std::string fallback = "capture";
};
struct CaptureName {
// Sample::displayName. Legible, carries the source name verbatim, and is explicitly
// NOT unique (core/model/CLAUDE.md §resample_name) — the stamp serves the eye.
std::string label;
// deriveBankPaths' baseName. Still passes through sanitizeStem, and stem uniqueness
// is still entirely makeUniqueTag's job.
std::string stemBase;
};
// "MM-DD HHMM" (e.g. "08-01 1432"); empty when the stamp carries no calendar date.
// Year is deliberately omitted: the card and the browse list are narrow, and Sample
// carries the full createdTimestamp for anything needing the exact moment.
std::string formatCaptureStamp(const CaptureStamp& stamp);
CaptureName composeCaptureName(const CaptureNameInputs& in);
// The single source of truth for the word itself — kCaptureTrackPrefixBare and
// kCaptureTrackPrefix below both expand from this one token, so editing it can never
// desync captureTrackName's "no readable source name" bare-word fallback from the
// separator-terminated prefix it is derived from.
#define REASAMPLER_CAPTURE_TRACK_WORD "Capture"
// The bare word behind kCaptureTrackPrefix, needed by captureTrackName's
// no-readable-source-name fallback.
inline constexpr const char* kCaptureTrackPrefixBare = REASAMPLER_CAPTURE_TRACK_WORD;
// Prefixed onto a source track's name to name the track a render-in-place created.
// A display convention, not a persisted key — unlike a lane prefix or an action-id
// suffix, changing it later strands nothing.
inline constexpr const char* kCaptureTrackPrefix = REASAMPLER_CAPTURE_TRACK_WORD " ";
// The new track's name for a render of `sourceName`. IDEMPOTENT — a fixed point on
// its own output, so a second render over a result track yields "Capture MONEY"
// again rather than "Capture Capture MONEY". A counter suffix is deliberately not
// offered: REAPER does not uniquify track names either, and what distinguishes two
// renders of one source is their position, not their name.
std::string captureTrackName(const std::string& sourceName);
} // namespace reasampler::capture