Had a similar idea not too long ago. Turns out that signal level is quite unstable. (Tracks keep showing and hiding very fast which makes it hard to mix ) I slowed it down so visibility changes only happen once a measure. And I also show tracks that have items in that measure.
Let me know what you think. I might clean it up and turn into an "official" script
Note: Code outdated. Check my ReaPack repo for latest version.
Code:
local peak_threshold = 0.0001
local extname = 'FTC.AutoHideMCP'
local GetTrackInfoValue = reaper.GetMediaTrackInfo_Value
local SetTrackInfoValue = reaper.SetMediaTrackInfo_Value
function print(msg) reaper.ShowConsoleMsg(tostring(msg) .. '\n') end
function SaveTracksVisibilityState()
local states = {}
for t = 0, reaper.CountTracks(0) - 1 do
local track = reaper.GetTrack(0, t)
local track_guid = reaper.GetTrackGUID(track)
local visible = GetTrackInfoValue(track, 'B_SHOWINMIXER')
local bus_comp = 0
local is_folder = GetTrackInfoValue(track, 'I_FOLDERDEPTH') == 1
if is_folder then
local _, chunk = reaper.GetTrackStateChunk(track, '')
bus_comp = chunk:match('\nBUSCOMP %d+ (%d+)')
if bus_comp == '1' then
chunk = chunk:gsub('(\nBUSCOMP %d) %d', '%1 0', 1)
reaper.SetTrackStateChunk(track, chunk)
end
end
local state = ('%s:%d:%d'):format(track_guid, visible, bus_comp)
states[#states + 1] = state
end
local states_str = table.concat(states, ';')
reaper.SetProjExtState(0, extname, 'track_states', states_str)
end
function RestoreTracksVisibilityState()
-- Restore track states
local _, states_str = reaper.GetProjExtState(0, extname, 'track_states')
if states_str == '' then return end
for t = 0, reaper.CountTracks(0) - 1 do
local track = reaper.GetTrack(0, t)
local track_guid = reaper.GetTrackGUID(track)
track_guid = track_guid:gsub('%-', '%%-')
local visible, bus_comp = states_str:match(track_guid .. ':(%d):(%d)')
if visible then
SetTrackInfoValue(track, 'B_SHOWINMIXER', tonumber(visible))
if bus_comp == '1' then
local _, chunk = reaper.GetTrackStateChunk(track, '')
chunk = chunk:gsub('(\nBUSCOMP %d) %d', '%1 1', 1)
reaper.SetTrackStateChunk(track, chunk)
end
end
end
reaper.SetProjExtState(0, extname, 'track_states', '')
end
function HasItemsInMeasure(track, measure)
local measure_start_pos = reaper.TimeMap_GetMeasureInfo(0, measure)
local measure_end_pos = reaper.TimeMap_GetMeasureInfo(0, measure + 1)
for i = 0, reaper.CountTrackMediaItems(track) - 1 do
local item = reaper.GetTrackMediaItem(track, i)
local length = reaper.GetMediaItemInfo_Value(item, 'D_LENGTH')
local start_pos = reaper.GetMediaItemInfo_Value(item, 'D_POSITION')
local end_pos = start_pos + length
if start_pos > measure_end_pos then break end
if start_pos <= measure_end_pos and end_pos >= measure_start_pos then
return true
end
end
end
local prev_measure = nil
local max_measure_peaks = {}
function Main()
local x, y = reaper.GetMousePosition()
local _, hover = reaper.GetThingFromPoint(x, y)
if hover == 'mcp.volume' then
reaper.defer(Main)
return
end
local cursor_pos = reaper.GetCursorPosition()
if reaper.GetPlayState() > 0 then cursor_pos = reaper.GetPlayPosition() end
local _, cursor_measure = reaper.TimeMap2_timeToBeats(0, cursor_pos + 0.001)
local is_update = false
if cursor_measure ~= prev_measure then
prev_measure = cursor_measure
-- Reset peaks when measure changes
max_measure_peaks = {}
for t = 0, reaper.CountTracks(0) - 1 do
local track = reaper.GetTrack(0, t)
-- Ensure showing tracks with items in measure (set threshold)
if HasItemsInMeasure(track, cursor_measure) then
max_measure_peaks[t + 1] = peak_threshold
end
end
is_update = true
end
for t = 0, reaper.CountTracks(0) - 1 do
local track = reaper.GetTrack(0, t)
local peak_l = reaper.Track_GetPeakInfo(track, 0)
local peak_r = reaper.Track_GetPeakInfo(track, 1)
local peak = math.max(peak_l, peak_r)
local prev_peak = max_measure_peaks[t + 1] or 0
local max_measure_peak = math.max(peak, prev_peak)
max_measure_peaks[t + 1] = max_measure_peak
local is_visible = max_measure_peak >= peak_threshold
is_update = is_update or (is_visible and prev_peak < peak_threshold)
SetTrackInfoValue(track, 'B_SHOWINMIXER', is_visible and 1 or 0)
end
if is_update then reaper.TrackList_AdjustWindows(false) end
reaper.defer(Main)
end
function Exit()
RestoreTracksVisibilityState()
reaper.TrackList_AdjustWindows(false)
end
SaveTracksVisibilityState()
reaper.atexit(Exit)
reaper.defer(Main)
Edit: I updated the code so that changes are temporarily stopped when the mouse is hoverered over any MCP volume fader. Edit2: Removed it again... The new GetThingFromPoint function makes the UI choppy. Edit3: Added it again lol, I just had to optimize it a bit.
Hey friend, will check it for sure. Let me get a coffee to enjoy this.
UPDATE: First test just working nicely. Thanks friend! I like how after "show all tracks" in the next measure MCP is cleaned up, but TCP still showing all tracks. Nice.
Background: The performance based mixing I am doing anyway via hardwware controllers, thus, having a nicely updating MCP just in front of me is great. Now Reaper only needs free jsfx + vst fx docking, so the empty space in mixer (on the right, in my case) can be used for docked MvMeter or Saike Spectral analysis jsfx.
Thanks again FeedTheCat!
I had some thoughts if certain tracks should be always visible, like tracks containing the string "BUS". I have usually 8 such buss tracks (stems) where all the rest of the tracks flow into. But again, why showing any busses when there is no signal? Just another variation idea for other users interesting maybe?
For sure I like the minimal MCP. It can be also a nice indicator if there is too much going on in the song, for optimizing "arrangement failures". (I know in art there are no failures, but human hearing capacity has certain limitations.)
UPDATE2: I like how the auto-hiding happens slowly, but auto-unhiding immediately! Great! Wise fine tunements you built in there! Great friend!
UPDATE3: With this script you probably opened a wormhole, an entire new category of scripts, working based on "signal availability". Let the community think what else can be useful if there is any signal or not anywhere. My other idea I had before is after saving a project as a new project, cleaning it up, deleting tracks which contain no items, or routings to and from, and now maybe also if there is no signal. Keeping the projects cleaner and minimal.
UPDATE4: Your folder magic is on my list of testing, but still did not test it yet. From your writings it had great impact with its unexpected usability. Thus wanted to test it. This would attack the TCP optimization, rather than MCP like in this thread.
UPDATE5: I like how cleaning up MCP helps you keeping an overview of the project, no matter how big, as anything playing is in front of you, in a compact form. You can concentrate on if any channel is contributing to the overall sound positively, if not, mute/delete.
Hey friend, will check it for sure. Let me get a coffee to enjoy this.
I just completely reworked it again, haha The whole thing with measures and items makes more sense for the TCP (My script was originally only showing tracks in the TCP that have items in the current measure).
The whole thing is now timer based, which makes a lot more sense for MCP. When the peak threshold is crossed, the track will be visible for a configurable amount of time.
Is there any way of triggering .lua scripts from outside of the usual Reaper actions bindings window (because it seems I reached the maximum number of allowed actions for Reaper) thus I can not add there or define key bindings. I can only use from the menu "Run script" then selecting the lua. It could be useful, if I could do this via a hotkey binding (using any set of tools, outside of Reaper, because Reaper can not).
I just completely reworked it again, haha The whole thing with measures and items makes more sense for the TCP (My script was originally only showing tracks in the TCP that have items in the current measure).
The whole thing is now timer based, which makes a lot more sense for MCP. When the peak threshold is crossed, the track will be visible for a configurable amount of time.
Just added it to my ReaPack
Ok, having version numbers could help. Whatever version I have, that one 15 minutes ago or so, just works nicely so far. I will do a diff to your latest official variant. Cool.
Ok, having version numbers could help. Whatever version I have, that one 15 minutes ago or so, just works nicely so far. I will do a diff to your latest official variant. Cool.
Don't think I changed the version you tried after you went to get coffee
I also added the TCP version to ReaPack:
Auto-hide tracks in TCP that have no items in current measure
Ok, having version numbers could help. Whatever version I have, that one 15 minutes ago or so, just works nicely so far. I will do a diff to your latest official variant. Cool.
The ReaPack version shows all tracks again when paused. Let me know if you prefer that. I think it might also be useful to let everything stay in place when paused.
Is there any way of triggering .lua scripts from outside of the usual Reaper actions bindings window (because it seems I reached the maximum number of allowed actions for Reaper) thus I can not add there or define key bindings. I can only use from the menu "Run script" then selecting the lua. It could be useful, if I could do this via a hotkey binding (using any set of tools, outside of Reaper, because Reaper can not).
Lol, how many scripts do you have?
Don't know... you could maybe use AddRemoveReaScript to dynamically swap out scripts, but that sounds complicated and overkill.
Regarding all the variants, TCP, MCP and in different forms, I would just rename each wisely, and keeping them all. The target user can decide later which fits bestly to their situation. It can be good, having many variants, in parallel, no need to decide for a specific single design.
Don't know... you could maybe use AddRemoveReaScript to dynamically swap out scripts, but that sounds complicated and overkill.
It seems this wall was hit by other as well. Just install all the stuff in Reapack (need to add more repositories, around 60 repos were on my list), then probably you will hit that wall as well.
see https://forum.cockos.com/showthread.php?t=260067
In the hope of cleaning my actions list, I deleted all the scripts with Chinese alphabet, because I can not read or understand them, scripts by zaibuyidao I guess, thanks zaibuyidao from here, but after next Reapack update, they all came back, haha. Now we need to get action managers, hehe.
Sure, it's actually simpler than for MCP. Didn't test it much, but it's up on github/reapack.
Fantastic, thanks! Seems to work great but I'll let you know if any glitches.
Sorry to ask even more but would it be possible to a TCP version for the auto-hide loop script?
Ideally for me the TCP/MCP would enable in a single script but it's no hassle to set them separately. I usually want their visibility to mirror and the only way I could see do this in Reaper was by disabling/re-enabling the mirroring in Track Manager to force an update or mess about with track selections.
Hmm, you mean a MCP version for "Auto-hide tracks in TCP that have no items in time selection"?
I guess I could make TCP,MCP and TCP+MCP versions for all scripts.
Sorry yes that's what I meant
Having them all available in TCP is working nicely for me atm as I can mirror them using a custom action selecting visible tracks but it'd be great if MCP/TCP could both be set using the same script.
Having them all available in TCP is working nicely for me atm as I can mirror them using a custom action selecting visible tracks but it'd be great if MCP/TCP could both be set using the same script.
Just pushed an update to all auto-hide scripts. There's various additions and optimizations, so please report back if I broke something. There's also 3 new versions that work on both TCP and MCP.
Just pushed an update to all auto-hide scripts. There's various additions and optimizations, so please report back if I broke something. There's also 3 new versions that work on both TCP and MCP.
Fantastic!
I'll give them a try and let you know if any issues.
I did encounter one bug with the hide silent MCP script that's still occurring in the latest update. Creating a new track with it enabled produced the error:
...-Hide\Auto-hide silent tracks in MCP during playback.lua:101: attempt to compare number with nil
I did encounter one bug with the hide silent MCP script that's still occurring in the latest update. Creating a new track with it enabled produced the error: