Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jtackaberry/379d7da05b2a696620e0 to your computer and use it in GitHub Desktop.
Save jtackaberry/379d7da05b2a696620e0 to your computer and use it in GitHub Desktop.
REAPER script: Toggle visibility of disabled instrument tracks (i.e. tracks with a VSTi that have FX bypassed).
-- Version 1.2
--
-- This script toggles visibility of all tracks that have a VSTi FX.
-- It requires that the FX be prefixed with "VSTi:" (which Reaper
-- does do by default). Care is taken to preserve existing TCP/MCP
-- visibility when the filter is toggled off.
--
-- SWS is required (http://www.sws-extension.org/)
--
-- Released to the public domain.
SCRIPT_NAME = "toggle_disabled_instrument_tracks"
-- If true, ensures all parents (and ancestors) of unfiltered child tracks
-- are not filtered. Set this to false if you want to hide parent tracks
-- with no MIDI items.
PRESERVE_PARENT_FOLDERS = true
function isVSTi(track, fxidx)
_, name = reaper.TrackFX_GetFXName(track, fxidx, "")
return string.sub(name, 0, 5) == "VSTi:" or string.sub(name, 0, 6) == "VST3i:"
end
function isInstrumentTrack(track)
-- Iterate over all FX and look for FX names prefixed with
-- "VSTi:" or "VST3i:". We can't use TrackFX_GetInstrument because it skips
-- offlined instruments.
for fxidx = 0, reaper.TrackFX_GetCount(track) - 1 do
if isVSTi(track, fxidx) then
return true
end
end
return false
end
function setTrackVisibility(track, tcp, mcp)
if tcp == 0 then
-- Unselect the track if it's being hidden
reaper.SetTrackSelected(track, false)
end
reaper.SetMediaTrackInfo_Value(track, "B_SHOWINTCP", tcp)
reaper.SetMediaTrackInfo_Value(track, "B_SHOWINMIXER", mcp)
end
function setTrackFiltering(track, filtered)
local guid = reaper.GetTrackGUID(track)
local tcp, mcp
if filterOn then
-- Filter is being enabled. Store current track setting.
tcp = reaper.GetMediaTrackInfo_Value(track, "B_SHOWINTCP")
mcp = reaper.GetMediaTrackInfo_Value(track, "B_SHOWINMIXER")
reaper.SetProjExtState(0, SCRIPT_NAME, guid, math.floor(tcp) .. math.floor(mcp))
if filtered then
setTrackVisibility(track, 0, 0)
end
else
-- Filter is being turned off. Restore tcp/mcp setting.
exists, state = reaper.GetProjExtState(0, SCRIPT_NAME, guid)
--reaper.ShowConsoleMsg(guid .. exists .. " " .. state .. "\n")
reaper.SetProjExtState(0, SCRIPT_NAME, guid, "")
if exists == 1 then
tcp = tonumber(string.sub(state, 1, 1))
mcp = tonumber(string.sub(state, 2, 2))
setTrackVisibility(track, tcp, mcp)
else
setTrackVisibility(track, 1, 1)
end
end
end
function markParents(parents, track, hasVisibleChildren)
local parent = reaper.GetParentTrack(track)
while parent ~= nil do
-- Small optimization: if parent is already known to have
-- visible children then there's no need to traverse up the
-- parent hierarchy.
if parents[parent] == 1 then
break
end
parents[parent] = (parents[parent] or 0) | hasVisibleChildren
parent = reaper.GetParentTrack(parent)
end
end
function updateView()
reaper.TrackList_AdjustWindows(0)
reaper.UpdateArrange()
reaper.UpdateTimeline()
if reaper.CountSelectedTracks(0) == 0 then
-- There are no selected tracks. Scroll to the top now that we have filtered
-- the view.
cmd = reaper.NamedCommandLookup('_XENAKIOS_TVPAGEHOME')
reaper.Main_OnCommandEx(cmd, 0, 0)
else
-- Track: Vertical scroll selected tracks into view.
reaper.Main_OnCommandEx(40913, 0, 0)
end
end
function main()
local parents = {}
_, _, section, cmd, _, _, _ = reaper.get_action_context()
exists, filterOn = reaper.GetProjExtState(0, SCRIPT_NAME, "filter_on")
-- Toggle filter
if filterOn == "1" then
filterOn = false
else
filterOn = true
end
reaper.Undo_BeginBlock2(0)
for trackIdx = 0, reaper.CountTracks(0) - 1 do
track = reaper.GetTrack(0, trackIdx)
if isInstrumentTrack(track) then
if not filterOn then
-- disabling filter
setTrackFiltering(track, false)
markParents(parents, track, 1)
else
if reaper.GetMediaTrackInfo_Value(track, "I_FXEN") > 0 then
setTrackFiltering(track, false)
markParents(parents, track, 1)
else
markParents(parents, track, 0)
setTrackFiltering(track, true)
end
end
end
end
for track, hasVisibleChildren in pairs(parents) do
if hasVisibleChildren == 1 and PRESERVE_PARENT_FOLDERS then
setTrackFiltering(track, false)
else
setTrackFiltering(track, true)
end
end
filterOn = filterOn and "1" or "0"
reaper.SetProjExtState(0, SCRIPT_NAME, "filter_on", filterOn)
reaper.SetToggleCommandState(section, cmd, filterOn)
reaper.RefreshToolbar2(section, cmd)
updateView()
reaper.Undo_EndBlock2(0, "Toggle visibility of disabled instrument tracks", -1)
end
reaper.defer(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment