// render_isolation.cpp — see the header. // // Compiled into the reaper_reasampler module. Includes reaper_plugin_functions.h // WITHOUT REAPERAPI_IMPLEMENT — main.cpp is the one TU that defines the API // pointers; here they are extern. #include "shell/capture/render_isolation.h" #include #include "core/capture/track_topology.h" // directChildIndices #define REAPERAPI_MINIMAL #define REAPERAPI_WANT_CountTracks #define REAPERAPI_WANT_GetTrack #define REAPERAPI_WANT_GetMediaTrackInfo_Value #define REAPERAPI_WANT_SetMediaTrackInfo_Value #define REAPERAPI_WANT_GetTrackNumSends #define REAPERAPI_WANT_GetTrackSendInfo_Value #define REAPERAPI_WANT_SetTrackSendInfo_Value #include "reaper_plugin_functions.h" namespace reasampler::capture { namespace { // GetTrackNumSends / *TrackSendInfo_Value category: < 0 selects the RECEIVE list // (SDK header ~3644, ~3676). constexpr int kReceivesCategory = -1; } // namespace UpstreamIsolation::UpstreamIsolation(MediaTrack* track) : track_(track) { if (!track_) return; // One pass over the track list for both the depth deltas and this track's index; // the pure walk turns the flat delta list into the direct-child set. The master // is absent from GetTrack's index space (it is reached only via GetMasterTrack) // and has no send-to-parent to cut, so nothing is missed by ignoring it. const int total = CountTracks(nullptr); std::vector tracks; std::vector depths; tracks.reserve(static_cast(total < 0 ? 0 : total)); depths.reserve(static_cast(total < 0 ? 0 : total)); int parentIndex = -1; for (int i = 0; i < total; ++i) { MediaTrack* tr = GetTrack(nullptr, i); tracks.push_back(tr); depths.push_back(tr ? static_cast( GetMediaTrackInfo_Value(tr, "I_FOLDERDEPTH")) : 0); if (tr == track_) parentIndex = i; } for (int idx : directChildIndices(depths, parentIndex)) { MediaTrack* child = tracks[static_cast(idx)]; if (!child) continue; // B_MAINSEND: "track sends audio to parent" (SDK header ~2238/~2957). children_.push_back({child, GetMediaTrackInfo_Value(child, "B_MAINSEND")}); SetMediaTrackInfo_Value(child, "B_MAINSEND", 0.0); } const int receives = GetTrackNumSends(track_, kReceivesCategory); receiveMutes_.reserve(static_cast(receives < 0 ? 0 : receives)); for (int i = 0; i < receives; ++i) { receiveMutes_.push_back( GetTrackSendInfo_Value(track_, kReceivesCategory, i, "B_MUTE")); SetTrackSendInfo_Value(track_, kReceivesCategory, i, "B_MUTE", 1.0); } } UpstreamIsolation::~UpstreamIsolation() { for (std::size_t i = 0; i < receiveMutes_.size(); ++i) SetTrackSendInfo_Value(track_, kReceivesCategory, static_cast(i), "B_MUTE", receiveMutes_[i]); for (const ChildSend& c : children_) SetMediaTrackInfo_Value(c.track, "B_MAINSEND", c.mainSend); } } // namespace reasampler::capture