|
|
|
03-27-2023, 02:35 AM
|
#1
|
Human being with feelings
Join Date: Jan 2007
Location: mcr:uk
Posts: 3,891
|
Script: Link and automate chain bypass to last touched FX (CPU saver)
EDIT: This script is largely redundant thanks to the new "Force auto-bypass on silence" options. Hurrah!
This script automatically bypasses all FX on a track when there are no items active on that track. It links the bypass of the last touched plugin to the bypass of all other plugins in the chain and adds automation, leaving a second of breathing space to avoid problems with plugins waking up slowly.
I call it "Link and automate chain bypass to last touched FX.lua". Catchy title no?
This is by far the most useful script I've ever made.
Code:
function pairsByKeys (t, f)
local a = {}
for n in pairs(t) do table.insert(a, n) end
table.sort(a, f)
local i = 0 -- iterator variable
local iter = function () -- iterator function
i = i + 1
if a[i] == nil then return nil
else return a[i], t[a[i]]
end
end
return iter
end
function sortpoints(a,b)
return a.pos < b.pos
end
pProj = 0
-- Toggling plugin bypass at item edges can sometimes cause glitches
-- so envelope points are offset by dOffset seconds for wriggle room
dOffset = 1
-- Get info on last touched FX. We don't care about param number.
retval, tracknumber, fxnumber, paramnumber = reaper.GetLastTouchedFX()
if retval == false then
reaper.ReaScriptError("!No last touched FX.") -- Terminate
end
iTrack = tracknumber & 0x0000FFFF -- low word is track index -- 0 = master track, 1 = track 1, etc.
iItem = tracknumber & 0xFFFF0000 -- high word is item index -- 1 = first item on track, etc
if iItem > 0 then
-- TakeFX
-- Probably not much point handling these since they're only active in the scope of the item
reaper.ReaScriptError("!This script does not work with Item FX.") -- Terminate
iPlugin = fxnumber & 0x0000FFFF -- low word == FX index
iTake = fxnumber & 0xFFFF0000 -- high word == take number
else
-- TrackFX
iPlugin = fxnumber & 0x00000FFF -- low 24 bits of fxnumber == FX index
bExtFX = fxnumber & 0x0000F000 > 0 -- if next 8 bits are 01, FX is record FX
end
-- Get track of last touched FX
if iTrack == 0 then
pTrack = reaper.GetMasterTrack()
else
pTrack = reaper.GetTrack(0, iTrack - 1)
end
nItems = reaper.CountTrackMediaItems(pTrack)
if nItems == 0 then
reaper.ReaScriptError("!No items on track.") -- Terminate
end
nPlugins = reaper.TrackFX_GetCount(pTrack)
if nPlugins < 1 then
reaper.ReaScriptError("!Script requires one or more Track FX to work.") -- Terminate
end
-- Find index of bypass on last touched FX
nParams = reaper.TrackFX_GetNumParams(pTrack, iPlugin)
iLeader = nParams - 3;
for ip = 0, nPlugins-1, 1 do
if ip ~= iPlugin then
nParams = reaper.TrackFX_GetNumParams(pTrack, ip)
iFollower = nParams - 3;
sParam = string.format('param.%s.plink.active', iFollower)
bResult = reaper.TrackFX_SetNamedConfigParm(pTrack, ip, sParam, "1")
sParam = string.format('param.%s.plink.effect', iFollower)
bResult = reaper.TrackFX_SetNamedConfigParm(pTrack, ip, sParam, tostring(iPlugin))
sParam = string.format('param.%s.plink.param', iFollower)
bResult = reaper.TrackFX_SetNamedConfigParm(pTrack, ip, sParam, tostring(iLeader))
end
end
-- Calculate envelope points
tPoints = {}
nItems = reaper.CountTrackMediaItems(pTrack)
for idx = 0, nItems-1, 1 do
pItem = reaper.GetMediaItem(pProj, idx)
-- Ignore muted items
bMuted = reaper.GetMediaItemInfo_Value(pItem, 'B_MUTE_ACTUAL')
if bMuted == 1.0 then
goto skip
end
dStart = reaper.GetMediaItemInfo_Value(pItem, 'D_POSITION')
dEnd = dStart + reaper.GetMediaItemInfo_Value(pItem, 'D_LENGTH')
-- Offset start but don't go below zero
if dStart > dOffset then
dStart = dStart - dOffset
else
dStart = 0
end
dEnd = dEnd + dOffset
-- Multiple item edges may occur at the same point in time, so sum the edge occurences.
-- Left edges add one, right edges subtract one.
-- Left edge
vs = tPoints[dStart]
if vs == nil then
tPoints[dStart] = 1
else
tPoints[dStart] = vs + 1
end
-- Right edge
ve = tPoints[dEnd]
if ve == nil then
tPoints[dEnd] = -1
else
tPoints[dEnd] = ve - 1
end
::skip::
end
tSortedPoints = {}
for k, v in pairsByKeys(tPoints) do
table.insert(tSortedPoints, {pos = k, val = v})
end
table.sort(tSortedPoints, sortpoints)
tFinalPoints = {}
prevDepth = 0
depth = 0
action = 1 -- 1 = open, 0 = close
count = 0
for k, v in ipairs(tSortedPoints) do
keep = false
count = count + 1
-- Insert point at start of envelope if necessary
if count == 1 and v.pos > 0 then
table.insert(tFinalPoints, {pos = 0, val = 0})
end
depth = depth + v.val
if count == 1 or depth == action then
keep = true
end
if keep == true then
table.insert(tFinalPoints, {pos = v.pos, val = action})
action = action ~ 1
end
end
-- Populate envelope
reaper.Undo_BeginBlock2(pProj)
-- Get the envelope and clear existing points
pEnv = reaper.GetFXEnvelope(pTrack, iPlugin, iLeader, 0)
if reaper.ValidatePtr2(pProj, pEnv, "TrackEnvelope*") then --Clear envelope
state = ""
ret, state = reaper.GetEnvelopeStateChunk(pEnv, state, false)
state = string.gsub(state, "PT[^>]+>", "PT 0 1 1>")
reaper.SetEnvelopeStateChunk(pEnv, state, false)
else
pEnv = reaper.GetFXEnvelope(pTrack, iPlugin, iLeader, 1) -- Create envelope
end
reaper.TrackList_AdjustWindows(false)
-- Now insert the envelope points
for k, v in pairs(tFinalPoints) do
value = v.val ~ 1 -- values are backwards for bypass so invert
reaper.InsertEnvelopePointEx(pEnv, -1, v.pos, value, 1, 0, false, true)
end
reaper.Envelope_SortPoints(pEnv)
reaper.TrackList_AdjustWindows(false)
reaper.UpdateArrange()
reaper.Undo_EndBlock2(pProj, "Link and automate chain bypass to last touched FX", 1|2)
Last edited by IXix; 04-29-2023 at 03:47 AM.
|
|
|
03-28-2023, 02:52 PM
|
#2
|
Human being with feelings
Join Date: Jul 2022
Location: Japan
Posts: 814
|
Oh this looks useful! Thanks for sharing it
Could you add it to your ReaPack?
|
|
|
03-29-2023, 03:13 AM
|
#3
|
Human being with feelings
Join Date: Jan 2007
Location: mcr:uk
Posts: 3,891
|
Quote:
Originally Posted by Suzuki
Could you add it to your ReaPack?
|
Er, maybe. I don't do much scripting so my repo is all JSFX. I'll have to look at how to structure it to incorporate scripts, or maybe just add it to the ReaTeam stuff.
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 06:05 AM.
|