Go Back   Cockos Incorporated Forums > REAPER Forums > ReaScript, JSFX, REAPER Plug-in Extensions, Developer Forum

Reply
 
Thread Tools Display Modes
Old 10-19-2021, 02:05 AM   #1
zaibuyidao
Human being with feelings
 
Join Date: Jan 2020
Location: Amoy
Posts: 182
Default Is there any way to get all the fx windows that are open now?

reaper.TakeFX_GetOpen( take, fx )
reaper.TrackFX_GetOpen( track, fx )

They can only get the status of a single take/track, there seems to be no official API to get all the FX windows that have been opened. Is there a way to do this?
__________________
Hi, the pronunciation of my English name is "TSAI PU YI TAO".
SFX Tag Searcher | New Articulation Map | Chinese Language Pack
zaibuyidao ReaScripts | ReaPack Repository (right-click and copy index URL)

Last edited by zaibuyidao; 10-19-2021 at 07:56 AM.
zaibuyidao is offline   Reply With Quote
Old 10-19-2021, 05:02 AM   #2
FeedTheCat
Human being with feelings
 
FeedTheCat's Avatar
 
Join Date: May 2019
Location: Berlin
Posts: 2,197
Default

Quote:
Originally Posted by zaibuyidao View Post
reaper.TakeFX_GetOpen( take, fx )
reaper.TrackFX_GetOpen( track, fx )

They can only get the status of a single take/track, there seems to be no official API to get all the FX windows that have been opened. Is there a way to do this?
You'll have to iterate over all tracks and items and check using the functions you mentioned above. Here's the function I used recently in a script:
Code:
function GetOpenProjects()
    local projects = {}
    local p = 0
    repeat
        local proj = reaper.EnumProjects(p)
        if reaper.ValidatePtr(proj, 'ReaProject*') then
            projects[#projects + 1] = proj
        end
        p = p + 1
    until not proj
    return projects
end

function GetAllFloatingFXWindows()
    local hwnds = {}
    local projects = GetOpenProjects()

    local TrackFX_GetFloatingWindow = reaper.TrackFX_GetFloatingWindow
    local TakeFX_GetFloatingWindow = reaper.TakeFX_GetFloatingWindow

    for _, proj in ipairs(projects) do
        local master_track = reaper.GetMasterTrack(proj)
        for fx = 0, reaper.TrackFX_GetCount(master_track) - 1 do
            local hwnd = TrackFX_GetFloatingWindow(master_track, fx)
            if hwnd then hwnds[#hwnds + 1] = hwnd end
        end
        for t = 0, reaper.CountTracks(proj) - 1 do
            local track = reaper.GetTrack(proj, t)
            for fx = 0, reaper.TrackFX_GetCount(track) - 1 do
                local hwnd = TrackFX_GetFloatingWindow(track, fx)
                if hwnd then hwnds[#hwnds + 1] = hwnd end
            end
            for fx = 0, reaper.TrackFX_GetRecCount(track) - 1 do
                local fx_in = fx + 0x1000000
                local hwnd = TrackFX_GetFloatingWindow(track, fx_in)
                if hwnd then hwnds[#hwnds + 1] = hwnd end
            end

            for i = 0, reaper.CountTrackMediaItems(track) - 1 do
                local item = reaper.GetTrackMediaItem(track, i)
                for tk = 0, reaper.GetMediaItemNumTakes(item) - 1 do
                    local take = reaper.GetMediaItemTake(item, tk)
                    if reaper.ValidatePtr(take, 'MediaItem_Take*') then
                        for fx = 0, reaper.TakeFX_GetCount(take) - 1 do
                            local hwnd = TakeFX_GetFloatingWindow(take, fx)
                            if hwnd then
                                hwnds[#hwnds + 1] = hwnd
                            end
                        end
                    end
                end
            end
        end
    end
    return hwnds
end
__________________
Featured scripts: REAPER Update UtilityLil ChordboxGridbox/Adaptive gridMX TunerRS5K LinkMIDI Editor Magic Donate💝: PayPal|ko-fi
FeedTheCat is offline   Reply With Quote
Old 10-19-2021, 07:46 AM   #3
zaibuyidao
Human being with feelings
 
Join Date: Jan 2020
Location: Amoy
Posts: 182
Default

Quote:
Originally Posted by FeedTheCat View Post
You'll have to iterate over all tracks and items and check using the functions you mentioned above. Here's the function I used recently in a script:
Thanks, that's the method I use too. I'm working on the script [Show FX Chain For Selected Track-Item] and when there are 1000+ items to process, traversing all the items makes the script run very slowly.

Also, my script only works in LOOP and the problem is even worse.

Is there a way to fix the slow running problem?

Attached is the script and project for [Show FX Chain For Selected Track-Item].

Code:
item_keep = false
track_keep = false

function Msg(string) reaper.ShowConsoleMsg(tostring(string) .. '\n') end

function updateTracksFx()
  local track_count = reaper.CountTracks(0)
  for track_idx = 0, track_count - 1 do
    value = reaper.CF_EnumSelectedFX(reaper.CF_GetTrackFXChain(reaper.GetTrack(0, track_idx)), -1)
    if value >= 0 then
      tracks_fx[track_idx] = value
    end
  end
end

function updateItemsFx()
  local item_count = reaper.CountMediaItems(0)
  for item_idx = 0, item_count - 1 do
    local item = reaper.GetMediaItem(0, item_idx)
    local take = reaper.GetTake(item, 0)
    local chain = reaper.CF_GetTakeFXChain(take)
    value = reaper.CF_EnumSelectedFX(chain, -1)
    if value >= 0 then
      items_fx[item_idx] = value
    end
  end
end

function hasTakeFxOpen(take)
  local cnt = reaper.TakeFX_GetCount(take)
  for i = 0, cnt - 1 do
    if reaper.TakeFX_GetOpen(take, i) then
      return true
    end
  end
  return false
end

function hasTrackFxOpen(track)
  local cnt = reaper.TrackFX_GetCount(track)
  for i = 0, cnt - 1 do
    if reaper.TrackFX_GetOpen(track, i) then
      return true
    end
  end
  return false
end

tracks_fx = {}
items_fx = {}

function main()
  
  updateTracksFx()
  updateItemsFx()

  local item_processed = false
  local track_processed = false

  -- item
  local item_count = reaper.CountMediaItems(0)
  for item_idx = 0, item_count - 1 do
    local item = reaper.GetMediaItem(0, item_idx)
    local take = reaper.GetTake(item, 0)
    take_fx_count = reaper.TakeFX_GetCount(take)
     -- if reaper.IsMediaItemSelected(item) and take_fx_count > 0 then
    if reaper.IsMediaItemSelected(item) then
      item_processed = true
    end
  end

  for item_idx = 0, item_count - 1 do
    local item = reaper.GetMediaItem(0, item_idx)
    local take = reaper.GetTake(item, 0)
    take_fx_count = reaper.TakeFX_GetCount(take)
    fx = reaper.TakeFX_GetChainVisible(take)
    if not reaper.IsMediaItemSelected(item) or take_fx_count <= 0 then
      reaper.PreventUIRefresh(1)
      -- if not item_keep or item_processed then
      if not item_keep then
        reaper.TakeFX_SetOpen(take, fx, false)
      end
    else
      if not hasTakeFxOpen(take) then
        reaper.TakeFX_SetOpen(take, items_fx[item_idx] or fx, true)
      end
      reaper.UpdateArrange()
      reaper.PreventUIRefresh(-1)
    end
  end

  -- track
  local track_count = reaper.CountTracks(0)

  for track_idx = 0, track_count - 1 do
    local track = reaper.GetTrack(0, track_idx)
    local track_fx_count = reaper.TrackFX_GetCount(track)
    local fx = reaper.TrackFX_GetChainVisible(track)
    -- if not item_processed and reaper.IsTrackSelected(track) and track_fx_count > 0 then
    if not item_processed and reaper.IsTrackSelected(track) then
      track_processed = true
    end
  end

  for track_idx = 0, track_count - 1 do
    local track = reaper.GetTrack(0, track_idx)
    local track_fx_count = reaper.TrackFX_GetCount(track)
    local fx = reaper.TrackFX_GetChainVisible(track)
    if item_processed or not reaper.IsTrackSelected(track) or track_fx_count <= 0 then
      reaper.PreventUIRefresh(1)
      -- if not track_keep or track_processed then
      if not track_keep then
        reaper.TrackFX_SetOpen(track, fx, false)
      end
    else
      if not hasTrackFxOpen(track) then
        reaper.TrackFX_SetOpen(track, tracks_fx[track_idx] or fx, true)
      end
    end
    reaper.UpdateArrange()
    reaper.PreventUIRefresh(-1)
  end

  reaper.defer(main)
  
end

main()
Attached Files
File Type: zip Show FX Chain For Selected Track-Item.zip (115.0 KB, 73 views)
__________________
Hi, the pronunciation of my English name is "TSAI PU YI TAO".
SFX Tag Searcher | New Articulation Map | Chinese Language Pack
zaibuyidao ReaScripts | ReaPack Repository (right-click and copy index URL)

Last edited by zaibuyidao; 10-19-2021 at 07:55 AM.
zaibuyidao is offline   Reply With Quote
Old 10-19-2021, 08:26 AM   #4
FeedTheCat
Human being with feelings
 
FeedTheCat's Avatar
 
Join Date: May 2019
Location: Berlin
Posts: 2,197
Default

One thing you can do is to change your main function to first check if the item/track selection has changed since the last defer run. These checks are generally very lightweight and can be run on every defer cycle without straining the CPU. When the condition you set was met (e.g. selected track changed), then you run the cpu-intensive stuff.

The code could look like this (Depending on your use case you might also want to check number of selected tracks etc):

Code:
local prev_sel_track
local prev_sel_item

function Main()

    local sel_track = reaper.GetSelectedTrack(0, 0)
    local sel_item = reaper.GetSelectedMediaItem(0, 0)

    local has_sel_track_changed = sel_track ~= prev_sel_track
    local has_sel_item_changed = sel_item ~= prev_sel_item

    if has_sel_track_changed or has_sel_item_changed then
        prev_sel_track = sel_track
        prev_sel_item = sel_item

        -- DO CPU-INTENSIVE STUFF
    end

    reaper.defer(Main)
end
__________________
Featured scripts: REAPER Update UtilityLil ChordboxGridbox/Adaptive gridMX TunerRS5K LinkMIDI Editor Magic Donate💝: PayPal|ko-fi
FeedTheCat is offline   Reply With Quote
Old 10-19-2021, 09:08 AM   #5
Fabian
Human being with feelings
 
Fabian's Avatar
 
Join Date: Sep 2008
Location: Sweden
Posts: 7,431
Default

Quote:
Originally Posted by zaibuyidao View Post
when there are 1000+ items to process, traversing all the items makes the script run very slowly.
Is it not enough to traverse only the visible ones? You can find out which tracks are currently visible, and then only check for those and their items. You could also avoid checking for off-screen items I guess.
__________________
// MVHMF
I never always did the right thing, but all I did wasn't wrong...
Fabian is offline   Reply With Quote
Old 10-20-2021, 07:30 AM   #6
zaibuyidao
Human being with feelings
 
Join Date: Jan 2020
Location: Amoy
Posts: 182
Default

Quote:
Originally Posted by FeedTheCat View Post
One thing you can do is to change your main function to first check if the item/track selection has changed since the last defer run. These checks are generally very lightweight and can be run on every defer cycle without straining the CPU. When the condition you set was met (e.g. selected track changed), then you run the cpu-intensive stuff.
Thank you very much, this solution will solve the problem.
__________________
Hi, the pronunciation of my English name is "TSAI PU YI TAO".
SFX Tag Searcher | New Articulation Map | Chinese Language Pack
zaibuyidao ReaScripts | ReaPack Repository (right-click and copy index URL)

Last edited by zaibuyidao; 10-20-2021 at 08:22 AM. Reason: Solved
zaibuyidao 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 10:27 PM.


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