refactor(capture): drop master scope; realtime taps selected track
Capture is now item + track only (master removed as a scope; still bypassed as out-of-scope chain). Realtime records the selected track's own output via per-track post-fader sends into a hidden temp track, fixing the silent file.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// Standalone tests for reasampler::render_settings — no REAPER, no framework.
|
||||
// Covers the pure pieces behind the three-scope capture family: the source-mode ->
|
||||
// Covers the pure pieces behind the two-scope capture family: the source-mode ->
|
||||
// RENDER_SETTINGS bit mapping, P_RAZOREDITS parsing -> ranges + union, scope ->
|
||||
// source mode, range inference (razor-else-time), the FX-bypass plan (corrects
|
||||
// the "items captured through parent FX" defect), and the capture-action taxonomy
|
||||
@@ -111,15 +111,14 @@ static void testRazorUnionBounds() {
|
||||
// --- sourceModeForScope: scope -> render source mode -------------------------
|
||||
|
||||
static void testScopeSourceModes() {
|
||||
// Each scope drives a distinct render source. Item -> items, Track -> tracks,
|
||||
// Master -> master mix. These feed renderSettingsFor and must be supported.
|
||||
// Each scope drives a distinct render source. Item -> items, Track -> tracks.
|
||||
// (There is no master scope — to capture the master you render a track.) These
|
||||
// feed renderSettingsFor and must be supported.
|
||||
CHECK(sourceModeForScope(CaptureScope::Item) == SourceMode::SelectedItems);
|
||||
CHECK(sourceModeForScope(CaptureScope::Track) == SourceMode::SelectedTracks);
|
||||
CHECK(sourceModeForScope(CaptureScope::Master) == SourceMode::MasterMix);
|
||||
// Every scope's source mode is an offline-supported render source.
|
||||
CHECK(renderSettingsFor(sourceModeForScope(CaptureScope::Item), 1.0).supported);
|
||||
CHECK(renderSettingsFor(sourceModeForScope(CaptureScope::Track), 1.0).supported);
|
||||
CHECK(renderSettingsFor(sourceModeForScope(CaptureScope::Master), 1.0).supported);
|
||||
}
|
||||
|
||||
// --- inferRangeSource: razor-else-time (orthogonal to scope) -----------------
|
||||
@@ -144,29 +143,22 @@ static void testItemScopeBypassesEverythingButTake() {
|
||||
|
||||
static void testTrackScopeKeepsSelfBypassesAncestorsAndMaster() {
|
||||
// Track = item FX + the track's OWN FX. Keep self FX; bypass ancestors + master.
|
||||
// Master stays a bypass target even though it is no longer a capture scope.
|
||||
FxBypassPlan p = fxBypassPlanFor(CaptureScope::Track);
|
||||
CHECK(!p.bypassSelfFx); // the whole point: the track's own FX stays live
|
||||
CHECK(p.bypassAncestorFx); // no parent/folder FX
|
||||
CHECK(p.bypassMaster); // no master FX
|
||||
}
|
||||
|
||||
static void testMasterScopeBypassesNothing() {
|
||||
// Master = whole chain. Nothing bypassed — the full signal path renders.
|
||||
FxBypassPlan p = fxBypassPlanFor(CaptureScope::Master);
|
||||
CHECK(!p.bypassSelfFx);
|
||||
CHECK(!p.bypassAncestorFx);
|
||||
CHECK(!p.bypassMaster);
|
||||
}
|
||||
// --- captureActionTable: the two-scope taxonomy ------------------------------
|
||||
|
||||
// --- captureActionTable: the three-scope taxonomy ----------------------------
|
||||
|
||||
static void testTableHasThreeScopeRows() {
|
||||
static void testTableHasTwoScopeRows() {
|
||||
const auto& table = captureActionTable();
|
||||
// Exactly 3 scope rows: item, track, master.
|
||||
CHECK(table.size() == 3);
|
||||
// Exactly 2 scope rows: item, track. There is no master scope.
|
||||
CHECK(table.size() == 2);
|
||||
|
||||
std::set<std::string> ids;
|
||||
bool sawItem = false, sawTrack = false, sawMaster = false;
|
||||
bool sawItem = false, sawTrack = false;
|
||||
for (const auto& def : table) {
|
||||
// Every id is a non-empty CEREBELLUM_REASAMPLER_ string and is UNIQUE
|
||||
// (duplicate ids would collide on registration).
|
||||
@@ -176,26 +168,11 @@ static void testTableHasThreeScopeRows() {
|
||||
// Every scope resolves to a supported offline source.
|
||||
CHECK(renderSettingsFor(sourceModeForScope(def.scope), 1.0).supported);
|
||||
|
||||
if (def.scope == CaptureScope::Item) sawItem = true;
|
||||
if (def.scope == CaptureScope::Track) sawTrack = true;
|
||||
if (def.scope == CaptureScope::Master) sawMaster = true;
|
||||
if (def.scope == CaptureScope::Item) sawItem = true;
|
||||
if (def.scope == CaptureScope::Track) sawTrack = true;
|
||||
}
|
||||
CHECK(sawItem);
|
||||
CHECK(sawTrack);
|
||||
CHECK(sawMaster);
|
||||
}
|
||||
|
||||
static void testMasterCommandIdIsPreserved() {
|
||||
// The master scope keeps its shipped M7 id string (user keybindings depend on
|
||||
// it). Item/track mint NEW ids; master's must be exactly the old value.
|
||||
bool foundMaster = false;
|
||||
for (const auto& def : captureActionTable())
|
||||
if (def.scope == CaptureScope::Master) {
|
||||
CHECK(std::string(def.commandString) ==
|
||||
"CEREBELLUM_REASAMPLER_CAPTURE_MASTER");
|
||||
foundMaster = true;
|
||||
}
|
||||
CHECK(foundMaster);
|
||||
}
|
||||
|
||||
int main() {
|
||||
@@ -213,9 +190,7 @@ int main() {
|
||||
testRangeInference();
|
||||
testItemScopeBypassesEverythingButTake();
|
||||
testTrackScopeKeepsSelfBypassesAncestorsAndMaster();
|
||||
testMasterScopeBypassesNothing();
|
||||
testTableHasThreeScopeRows();
|
||||
testMasterCommandIdIsPreserved();
|
||||
testTableHasTwoScopeRows();
|
||||
|
||||
if (g_fail == 0) std::printf("render_settings: all tests passed\n");
|
||||
else std::printf("render_settings: %d CHECK(s) FAILED\n", g_fail);
|
||||
|
||||
Reference in New Issue
Block a user