Old 11-30-2021, 05:50 AM   #1
AtmanActive
Human being with feelings
 
AtmanActive's Avatar
 
Join Date: Dec 2009
Location: United Kingdom
Posts: 668
Default [SOLVED] Hide tracks with no items in the time selection

I'm looking for an action or script that would be capable of analyzing which tracks have items on them in the given time selection and would then hide all tracks that have none.
Analyzing on the edit cursor level is not good enough since some tracks could have just one short item near the end of the time selection.

Of course, this would need to have one more action to unhide all previously hidden tracks.

My usage scenario:
I often have songs with many different parts. For ease of mixing, I have tracks split into instruments that play in those parts. So, I end up with ~250 tracks where each and every instrument has ~5 tracks that play in those different parts. Hence, when mixing, I have to do a lot of scrolling up and down to find the tracks I am looking for, depending on the part I am currently working on. On the other hand, I don't want to sort the tracks according to song parts since tracks have their busses and folders set according to their mixing properties.

Hence, it would be a big life saver for me if I would have a toolbar button to show only the tracks participating in the current time selection, and also, one more button, to revert it, to show all tracks as they were. In other words, I would use this as a helper tool to temporarily help me visually find all the tracks involved and to revert the state few minutes later when I'm done.

Thanks.

Last edited by AtmanActive; 11-30-2021 at 03:27 PM. Reason: Solved
AtmanActive is offline   Reply With Quote
Old 11-30-2021, 06:33 AM   #2
FeedTheCat
Human being with feelings
 
FeedTheCat's Avatar
 
Join Date: May 2019
Location: Berlin
Posts: 2,197
Default

I uploaded a similar script on Sunday. It auto-hides all tracks that don't have items in current measure (at edit or play cursor). It wasn't much trouble to modify it to work with time selection.



Look for "Auto-hide" in my ReaPack repo
__________________
Featured scripts: REAPER Update UtilityLil ChordboxGridbox/Adaptive gridMX TunerRS5K LinkMIDI Editor Magic Donate💝: PayPal|ko-fi
FeedTheCat is offline   Reply With Quote
Old 11-30-2021, 07:12 AM   #3
Rodilab
Human being with feelings
 
Rodilab's Avatar
 
Join Date: Jan 2021
Location: Paris
Posts: 255
Default

Something like that ? :

Code:
-- @description Toggle hide tracks with no items in time selection
-- @author Rodilab

--------------------------
-- User variables
--------------------------

TCP = true
MCP = false
ShowParents = true

--------------------------
-- Code
--------------------------

function ShowAllTracks()
  local count = reaper.CountTracks(0)
  if count > 0 then
    reaper.PreventUIRefresh(1)
    reaper.Undo_BeginBlock()
    for t=0, count-1 do
      local track = reaper.GetTrack(0, t)
      if TCP and reaper.GetMediaTrackInfo_Value(track, 'B_SHOWINTCP') == 0 then
        reaper.SetMediaTrackInfo_Value(track, 'B_SHOWINTCP', 1)
      end
      if MCP and reaper.GetMediaTrackInfo_Value(track, 'B_SHOWINMIXER') == 0 then
        reaper.SetMediaTrackInfo_Value(track, 'B_SHOWINMIXER', 1)
      end
    end
    reaper.TrackList_AdjustWindows(false)
    reaper.Undo_EndBlock("Show all tracks",0)
    reaper.PreventUIRefresh(-1)
    reaper.UpdateArrange()
  end
end

function HideTracks()
  local sel_start, sel_end = reaper.GetSet_LoopTimeRange(false,false,0,0,false)
  if sel_start < sel_end then
    local count = reaper.CountTracks(0)
    if count > 0 then
      local list_tracks = {}
      local rv = false
      for t=0, count-1 do
        local track = reaper.GetTrack(0, t)
        local count_items = reaper.CountTrackMediaItems(track)
        if count_items > 0 then
          for i=0, count_items-1 do
            local item = reaper.GetTrackMediaItem(track, i)
            local pos = reaper.GetMediaItemInfo_Value(item, 'D_POSITION')
            local length = reaper.GetMediaItemInfo_Value(item, 'D_LENGTH')
            local stop = pos + length
            if (pos >= sel_start and pos <= sel_end)
            or (stop >= sel_start and stop <= sel_end)
            or (sel_start >= pos and sel_start <= stop) then
              rv = true
              list_tracks[track] = true
              if ShowParents then
                local parent = reaper.GetParentTrack(track)
                while parent do
                  list_tracks[parent] = true
                  parent = reaper.GetParentTrack(parent)
                end
              end
              break
            end
          end
        end
      end
      if rv then
        reaper.PreventUIRefresh(1)
        reaper.Undo_BeginBlock()
        for t=0, count-1 do
          local track = reaper.GetTrack(0, t)
          if TCP then reaper.SetMediaTrackInfo_Value(track, 'B_SHOWINTCP', list_tracks[track] and 1 or 0) end
          if MCP then reaper.SetMediaTrackInfo_Value(track, 'B_SHOWINMIXER', list_tracks[track] and 1 or 0) end
        end
        reaper.TrackList_AdjustWindows(false)
        reaper.Undo_EndBlock("Hide tracks with no items in time selection",0)
        reaper.PreventUIRefresh(-1)
        reaper.UpdateArrange()
        return true
      end
    end
  end
  return false
end

function main()
  local is_new_value, filename, section_id, command_id = reaper.get_action_context()
  local state = reaper.GetToggleCommandStateEx(section_id, command_id)
  if state < 1 then
    if HideTracks() then
      state = 1
    end
  else
    state = 0
    ShowAllTracks()
  end
  reaper.SetToggleCommandState(section_id, command_id, state)
  reaper.RefreshToolbar2(section_id, command_id)
end

main()
Please, test it.
If every thing works fine, then I will share it in ReaPack.

Last edited by Rodilab; 11-30-2021 at 07:18 AM.
Rodilab is offline   Reply With Quote
Old 11-30-2021, 03:21 PM   #4
AtmanActive
Human being with feelings
 
AtmanActive's Avatar
 
Join Date: Dec 2009
Location: United Kingdom
Posts: 668
Default

Wow, you guys rock!
Reaper community is absolutely the most awesome community in the world!

Thank you FeedTheCat for your offer. Unfortunately, it is performing poorly. The tracks show up and disappear and the whole TCP view is jumping up and down. I understand that your function is filtering in real-time, but this brings unwanted artifacts into the whole experience. Furthermore, it also hides folder tracks which is something I could live with, but better to have folder tracks show.

On the other hand, Rodilab's script is working perfectly!
Exactly what I wanted.

Thank you both.
This will be tremendous help in my mixing sessions and hopefully, will help other Reaper users too.

Cheers!

You made my day.
AtmanActive is offline   Reply With Quote
Old 11-30-2021, 03:36 PM   #5
FeedTheCat
Human being with feelings
 
FeedTheCat's Avatar
 
Join Date: May 2019
Location: Berlin
Posts: 2,197
Default

Nice! No worries, I figured that rodilab's version is closer to what you wanted. Good stuff, reaper community does rock
__________________
Featured scripts: REAPER Update UtilityLil ChordboxGridbox/Adaptive gridMX TunerRS5K LinkMIDI Editor Magic Donate💝: PayPal|ko-fi
FeedTheCat is offline   Reply With Quote
Old 11-30-2021, 11:51 PM   #6
Bekoff
Human being with feelings
 
Join Date: Apr 2012
Posts: 8
Default

Wow! Thank you guys!

Rodilab, how to exclude two tracks at the top of a project from your script such as retrospective records and side chain tracks?

This two tracks always hidden. The first is always a record enabled (empty), the second contains a midi item.

Last edited by Bekoff; 12-01-2021 at 02:26 AM.
Bekoff is offline   Reply With Quote
Old 12-01-2021, 03:17 AM   #7
Rodilab
Human being with feelings
 
Rodilab's Avatar
 
Join Date: Jan 2021
Location: Paris
Posts: 255
Default

Glad you found it useful
You're welcome

Quote:
Rodilab, how to exclude two tracks at the top of a project from your script such as retrospective records and side chain tracks?
This script treats all tracks in the same way : they have an item or they don't. Then it displays all the tracks.

I might add:
Enable: first save the list of hidden tracks and do not make them visible even if they have an item in the selection.
Disable: show all tracks except the tracks previously saved as hidden tracks.

I won't have time today. Maybe later
Rodilab is offline   Reply With Quote
Old 12-01-2021, 09:38 AM   #8
TonE
Human being with feelings
 
Join Date: Feb 2009
Location: Reaper HAS send control via midi !!!
Posts: 4,032
Default

Thanks to all. I would suggest a "track name string containing" based solution maybe. So Bekoff could add for example "nohide" to the track name, anywhere, and the script check if track name contaings the string "nohide", if yes, those would be shown always. Would be easier and more flexible I guess.
TonE is offline   Reply With Quote
Old 12-02-2021, 03:00 AM   #9
Rodilab
Human being with feelings
 
Rodilab's Avatar
 
Join Date: Jan 2021
Location: Paris
Posts: 255
Default

Try this version.
  • Don't show already hiden tracks, even if they have items in time selection
  • Show/Hide sends destination tracks too

Code:
-- @description Toggle hide tracks with no items in time selection
-- @author Rodilab
-- @version 1.0
-- @about
--   Toggle hide tracks with no items in time selection
--
--   by Rodrigo Diaz (aka Rodilab)

--------------------------
-- User variables
--------------------------

TCP = true         -- Show/Hide in TCP
MCP = false        -- Show/Hide in MCP
IgnoreHiden = true -- Don't show already hiden tracks, even if they have items in time selection
ShowParents = true -- Show parents tracks too
SendTracks = true  -- Show/Hide sends destination tracks too

--------------------------
-- ExtState
--------------------------

extstate_id = 'RODILAB_Hide_tracks_with_no_items_in_time_selection'

function GetMediaTrackByGuid(guid)
  local count = reaper.CountTracks(0)
  if count == 0 then return end
  for i=0, count-1 do
    local track = reaper.GetTrack(0, i)
    local tmp_guid = reaper.GetTrackGUID(track)
    if tmp_guid == guid then
      return track
    end
  end
  return nil
end

function ProjExtStateSave(str)
  reaper.SetProjExtState(0, extstate_id, 'hiden_tracks', str)
end

function ProjExtStateLoad()
  local list = {}
  local rv, str = reaper.GetProjExtState(0, extstate_id, 'hiden_tracks')
  if rv == 1 then
    for guid in string.gmatch(str, '[^;]+') do
      local track = GetMediaTrackByGuid(guid)
      if track then
        list[track] = true
      end
    end
  end
  return list
end

function DeleteExtState()
  reaper.SetProjExtState(0, extstate_id, '', '')
end

--------------------------
-- Code
--------------------------

function ShowAllTracks()
  local count = reaper.CountTracks(0)
  if count > 0 then
    reaper.PreventUIRefresh(1)
    reaper.Undo_BeginBlock()
    local list_hide = {}
    if IgnoreHiden then
      list_hide = ProjExtStateLoad()
    end
    for t=0, count-1 do
      local track = reaper.GetTrack(0, t)
      if not IgnoreHiden or not list_hide[track] then
        if TCP and reaper.GetMediaTrackInfo_Value(track, 'B_SHOWINTCP') == 0 then
          reaper.SetMediaTrackInfo_Value(track, 'B_SHOWINTCP', 1)
        end
        if MCP and reaper.GetMediaTrackInfo_Value(track, 'B_SHOWINMIXER') == 0 then
          reaper.SetMediaTrackInfo_Value(track, 'B_SHOWINMIXER', 1)
        end
      end
    end
    DeleteExtState()
    reaper.TrackList_AdjustWindows(false)
    reaper.Undo_EndBlock("Show all tracks",0)
    reaper.PreventUIRefresh(-1)
    reaper.UpdateArrange()
  end
end

function HideTracks()
  local sel_start, sel_end = reaper.GetSet_LoopTimeRange(false,false,0,0,false)
  if sel_start < sel_end then
    local count = reaper.CountTracks(0)
    if count > 0 then
      local list_tracks = {}
      local list_hide = {}
      local list_send = {}
      local rv = false
      for t=0, count-1 do
        local track = reaper.GetTrack(0, t)
        if IgnoreHiden and reaper.GetMediaTrackInfo_Value(track, 'B_SHOWINTCP') == 0 then
          table.insert(list_hide, track)
        else
          local count_items = reaper.CountTrackMediaItems(track)
          if count_items > 0 then
            for i=0, count_items-1 do
              local item = reaper.GetTrackMediaItem(track, i)
              local pos = reaper.GetMediaItemInfo_Value(item, 'D_POSITION')
              local length = reaper.GetMediaItemInfo_Value(item, 'D_LENGTH')
              local stop = pos + length
              if (pos >= sel_start and pos <= sel_end)
              or (stop >= sel_start and stop <= sel_end)
              or (sel_start >= pos and sel_start <= stop) then
                rv = true
                list_tracks[track] = true
                if ShowParents then
                  local parent = reaper.GetParentTrack(track)
                  while parent do
                    list_tracks[parent] = true
                    parent = reaper.GetParentTrack(parent)
                  end
                end
                if SendTracks then
                  local count_sends = reaper.GetTrackNumSends(track, 0)
                  if count_sends > 0 then
                    for j=0, count_sends-1 do
                      local dest_track = reaper.GetTrackSendInfo_Value(track, 0, i, 'P_DESTTRACK')
                      list_tracks[dest_track] = true
                    end
                  end
                end
                break
              end
            end
          end
        end
      end
      if rv then
        reaper.PreventUIRefresh(1)
        reaper.Undo_BeginBlock()
        for t=0, count-1 do
          local track = reaper.GetTrack(0, t)
          if TCP then reaper.SetMediaTrackInfo_Value(track, 'B_SHOWINTCP', list_tracks[track] and 1 or 0) end
          if MCP then reaper.SetMediaTrackInfo_Value(track, 'B_SHOWINMIXER', list_tracks[track] and 1 or 0) end
        end
        DeleteExtState()
        if IgnoreHiden and #list_hide > 0 then
          local str
          for i, track in ipairs(list_hide) do
            local guid = reaper.GetTrackGUID(track)
            if not str then
              str = guid
            else
              str = str..';'..guid
            end
          end
          ProjExtStateSave(str)
        end
        reaper.TrackList_AdjustWindows(false)
        reaper.Undo_EndBlock("Hide tracks with no items in time selection",0)
        reaper.PreventUIRefresh(-1)
        reaper.UpdateArrange()
        return true
      end
    end
  end
  return false
end

function main()
  local is_new_value, filename, section_id, command_id = reaper.get_action_context()
  local state = reaper.GetToggleCommandStateEx(section_id, command_id)
  if state < 1 then
    if HideTracks() then
      state = 1
    end
  else
    state = 0
    ShowAllTracks()
  end
  reaper.SetToggleCommandState(section_id, command_id, state)
  reaper.RefreshToolbar2(section_id, command_id)
end

main()
Rodilab is offline   Reply With Quote
Old 12-02-2021, 04:44 AM   #10
Bekoff
Human being with feelings
 
Join Date: Apr 2012
Posts: 8
Default

Thanks a lot Rodilab! Exactly what I was looking for, and works like a charm!
Bekoff is offline   Reply With Quote
Old 12-06-2021, 01:59 AM   #11
Rodilab
Human being with feelings
 
Rodilab's Avatar
 
Join Date: Jan 2021
Location: Paris
Posts: 255
Default

"Toggle hide tracks with no items in current time selection" is now available in ReaPack
Rodilab is offline   Reply With Quote
Old 06-13-2022, 04:18 PM   #12
jonnyjupiter
Human being with feelings
 
jonnyjupiter's Avatar
 
Join Date: Jan 2022
Posts: 72
Default

Thanks so much for this script Rodilab! Essential functionality for my orchestral template, I had tried rigging up my own custom action but it wasn't nearly as smooth.

The one roadblock I've run into is if I toggle the 'hide tracks' on, then save and exit the session by accident without toggling back off, I have no way to reveal the tracks when I go back in other then revealing everything manually which destroys my folder structures.

Do you or anyone else know of a way around this? I've seen scripts where the mode is "stored in project external state" to circumvent this but I'm not familiar enough with scripting to understand how to implement...
__________________
website | youtube | imdb
jonnyjupiter is offline   Reply With Quote
Old 11-25-2023, 02:25 AM   #13
robotron
Human being with feelings
 
Join Date: May 2020
Posts: 337
Default

Quote:
Originally Posted by Rodilab View Post
Try this version.
  • Don't show already hiden tracks, even if they have items in time selection
  • Show/Hide sends destination tracks too
Many thanks for creating this, I use it a lot.

Would it be possible to create an inverse version? One that only shows empty tracks within the time selection (but works in exactly the same way).
robotron is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 12:34 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.