d9ad8e4adf
ICaptureBackend/CaptureRequest seam + OfflineRenderBackend driving snapshotted RENDER_* with dither/normalize forced off for bit-identical output, RenderFailed via filesystem check, and a pure capture_paths lib with tests. Spike action registered.
66 lines
2.2 KiB
C++
66 lines
2.2 KiB
C++
#include "capture_paths.h"
|
|
|
|
namespace reasampler {
|
|
|
|
std::string normalizeSlashes(const std::string& path) {
|
|
std::string out = path;
|
|
for (char& c : out) {
|
|
if (c == '\\') c = '/';
|
|
}
|
|
// Strip a single trailing slash so joins do not double up. Preserve a lone
|
|
// "/" (root) — stripping it would turn root into empty.
|
|
if (out.size() > 1 && out.back() == '/') {
|
|
out.pop_back();
|
|
}
|
|
return out;
|
|
}
|
|
|
|
std::string sanitizeStem(const std::string& baseName) {
|
|
std::string out;
|
|
out.reserve(baseName.size());
|
|
for (unsigned char c : baseName) {
|
|
const bool keep = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
|
|
(c >= '0' && c <= '9') || c == '.' || c == '_' ||
|
|
c == '-';
|
|
out.push_back(keep ? static_cast<char>(c) : '_');
|
|
}
|
|
// Collapse to a stable default if nothing usable survived (e.g. all spaces).
|
|
// A stem of only separators ('.', '_', '-') is also unhelpful as a name.
|
|
bool hasAlnum = false;
|
|
for (unsigned char c : out) {
|
|
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
|
|
(c >= '0' && c <= '9')) {
|
|
hasAlnum = true;
|
|
break;
|
|
}
|
|
}
|
|
if (out.empty() || !hasAlnum) {
|
|
return "capture";
|
|
}
|
|
return out;
|
|
}
|
|
|
|
BankPaths deriveBankPaths(const std::string& projectDir,
|
|
const std::string& baseName,
|
|
const std::string& uniqueTag) {
|
|
const std::string dir = normalizeSlashes(projectDir);
|
|
|
|
std::string stem = sanitizeStem(baseName);
|
|
if (!uniqueTag.empty()) {
|
|
stem += "_" + sanitizeStem(uniqueTag);
|
|
}
|
|
const std::string fileName = stem + ".wav";
|
|
|
|
BankPaths p;
|
|
p.fileStem = stem; // stem only — REAPER appends extension
|
|
p.fileName = fileName;
|
|
p.relativePath = std::string(kBankSubfolder) + "/" + fileName;
|
|
// absoluteDir intentionally omits a trailing slash (RENDER_FILE wants the
|
|
// directory itself; RENDER_PATTERN supplies the file name separately).
|
|
p.absoluteDir = dir.empty() ? std::string(kBankSubfolder)
|
|
: dir + "/" + kBankSubfolder;
|
|
return p;
|
|
}
|
|
|
|
} // namespace reasampler
|