Reaper: Interesting Tips, Tricks & Actions.

Discussion in 'Reaper' started by justsomerandomdude, Feb 9, 2023.

  1. typical-love

    typical-love Platinum Record

    Joined:
    May 9, 2020
    Messages:
    328
    Likes Received:
    151
    Yeah, this rules. Been meaning to set this up to where I can do editing/menial tasks on my laptop and finish on my PC and go back and forth etc, just so I'm not sitting in a chair all day long.
     
  2. justsomerandomdude

    justsomerandomdude Rock Star

    Joined:
    Aug 24, 2020
    Messages:
    533
    Likes Received:
    360
  3. justsomerandomdude

    justsomerandomdude Rock Star

    Joined:
    Aug 24, 2020
    Messages:
    533
    Likes Received:
    360
    Toggle Bertom EQ Curve Analyzer above and below floating FX
    (requires bertom Eq Curve analyzer plugin: https://bertomaudio.com/eq-curve-analyzer.html)

    Script made with Chat Gpt:

    This does what it says above, adds bertom analyzer on the top and bottom of the floating fx in your plugin chain.
    Its a pain in ass to add this when needed and to remove it.

    This just adds two instances, which u already know if u r using bertom analyzer, and just floats the analyzer (the bottom one). Running it again acts like toggle and removes the instances.
    I use an old version of bertom i guess its 1.2.0, if u r using latest version 2 u might want to change the fx name in the script from this
    Code:
    local FX_NAME = "EQ Curve Analyzer (Bertom)"
    to
    Code:
    local FX_NAME = "EQ Curve Analyzer 2 (Bertom)"
    Here is the Script
    Code:
    -- @description Toggle EQ Curve Analyzer (Bertom) above and below floating FX
    -- @version 1.9
    -- @author ChatGPT
    
    local FX_NAME = "EQ Curve Analyzer (Bertom)"
    local FLAG_PARAM_VALUE = 0.123456789  -- unique magic value to mark inserted FX (param 0)
    
    function isTaggedFX(track, fx_index)
      local param_val = reaper.TrackFX_GetParam(track, fx_index, 0)
      return math.abs(param_val - FLAG_PARAM_VALUE) < 0.000001
    end
    
    function findTaggedFX(track)
      local tagged = {}
      local count = reaper.TrackFX_GetCount(track)
      for i = 0, count - 1 do
        if isTaggedFX(track, i) then
          table.insert(tagged, i)
        end
      end
      return tagged
    end
    
    function removeTaggedFX(track)
      local tagged = findTaggedFX(track)
      -- Delete from highest index to lowest to avoid reindexing issues
      table.sort(tagged, function(a,b) return a > b end)
      for _, i in ipairs(tagged) do
        reaper.TrackFX_Delete(track, i)
      end
    end
    
    function tagFX(track, fx_index)
      -- Mark param 0 with magic value to identify inserted FX
      reaper.TrackFX_SetParam(track, fx_index, 0, FLAG_PARAM_VALUE)
    end
    
    function insertAnalyzerAt(track, insert_pos)
      local fx_index = reaper.TrackFX_AddByName(track, FX_NAME, false, -1)
      if fx_index == -1 then return -1 end
    
      tagFX(track, fx_index)
    
      if fx_index ~= insert_pos then
        reaper.TrackFX_CopyToTrack(track, fx_index, track, insert_pos, true)
      end
    
      return insert_pos
    end
    
    function getFirstFloatingFX()
      local track_count = reaper.CountTracks(0)
      for i = 0, track_count - 1 do
        local track = reaper.GetTrack(0, i)
        local fx_count = reaper.TrackFX_GetCount(track)
        for fx = 0, fx_count - 1 do
          if reaper.TrackFX_GetFloatingWindow(track, fx) then
            return track, fx
          end
        end
      end
      return nil, nil
    end
    
    local function floatFX(track, fx_index)
      reaper.TrackFX_Show(track, fx_index, 3) -- 3 = floating and focused
    end
    
    function toggleAnalyzers()
      local track, fx_index = getFirstFloatingFX()
      if not track then
        reaper.MB("No floating FX window found.\nOpen and float a plugin window first.", "Error", 0)
        return
      end
    
      local tagged = findTaggedFX(track)
      if #tagged > 0 then
        reaper.Undo_BeginBlock()
        removeTaggedFX(track)
        reaper.Undo_EndBlock("Removed EQ Curve Analyzers", -1)
        return
      end
    
      reaper.Undo_BeginBlock()
      -- Insert top (signal generator)
      insertAnalyzerAt(track, fx_index)
      -- Insert bottom (analyzer)
      local bottom_fx_index = insertAnalyzerAt(track, fx_index + 2)
    
      -- Close floating window of top FX (signal generator) if open
      reaper.TrackFX_Show(track, fx_index, 2)
    
      -- Float only the bottom analyzer FX window
      if bottom_fx_index and bottom_fx_index >= 0 then
        floatFX(track, bottom_fx_index)
      end
    
      reaper.Undo_EndBlock("Inserted EQ Curve Analyzers with floating analyzer only", -1)
    end
    
    reaper.PreventUIRefresh(1)
    toggleAnalyzers()
    reaper.PreventUIRefresh(-1)
    reaper.UpdateArrange()
    

    Edit:
    Code:
    -- @description Toggle EQ Curve Analyzer (Bertom) above and below floating FX
    -- @version 1.9
    -- @author ChatGPT
    
    local FX_NAME = "EQ Curve Analyzer 2 (Bertom)"
    local FLAG_PARAM_VALUE = 0.123456789  -- unique magic value to mark inserted FX (param 0)
    
    function isTaggedFX(track, fx_index)
      local param_val = reaper.TrackFX_GetParam(track, fx_index, 0)
      return math.abs(param_val - FLAG_PARAM_VALUE) < 0.000001
    end
    
    function findTaggedFX(track)
      local tagged = {}
      local count = reaper.TrackFX_GetCount(track)
      for i = 0, count - 1 do
        if isTaggedFX(track, i) then
          table.insert(tagged, i)
        end
      end
      return tagged
    end
    
    function removeTaggedFX(track)
      local tagged = findTaggedFX(track)
      -- Delete from highest index to lowest to avoid reindexing issues
      table.sort(tagged, function(a,b) return a > b end)
      for _, i in ipairs(tagged) do
        reaper.TrackFX_Delete(track, i)
      end
    end
    
    function tagFX(track, fx_index)
      -- Mark param 0 with magic value to identify inserted FX
      reaper.TrackFX_SetParam(track, fx_index, 0, FLAG_PARAM_VALUE)
    end
    
    function insertAnalyzerAt(track, insert_pos)
      local fx_index = reaper.TrackFX_AddByName(track, FX_NAME, false, -1)
      if fx_index == -1 then return -1 end
    
      tagFX(track, fx_index)
    
      if fx_index ~= insert_pos then
        reaper.TrackFX_CopyToTrack(track, fx_index, track, insert_pos, true)
      end
    
      return insert_pos
    end
    
    function getFirstFloatingFX()
      local track_count = reaper.CountTracks(0)
      for i = 0, track_count - 1 do
        local track = reaper.GetTrack(0, i)
        local fx_count = reaper.TrackFX_GetCount(track)
        for fx = 0, fx_count - 1 do
          if reaper.TrackFX_GetFloatingWindow(track, fx) then
            return track, fx
          end
        end
      end
      return nil, nil
    end
    
    local function floatFX(track, fx_index)
      reaper.TrackFX_Show(track, fx_index, 3) -- 3 = floating and focused
    end
    
    function toggleAnalyzers()
      local track, fx_index = getFirstFloatingFX()
      if not track then
        reaper.MB("No floating FX window found.\nOpen and float a plugin window first.", "Error", 0)
        return
      end
    
      local tagged = findTaggedFX(track)
      if #tagged > 0 then
        reaper.Undo_BeginBlock()
        removeTaggedFX(track)
        reaper.Undo_EndBlock("Removed EQ Curve Analyzers", -1)
        return
      end
    
      reaper.Undo_BeginBlock()
      -- Insert top (signal generator)
      insertAnalyzerAt(track, fx_index)
      -- Insert bottom (analyzer)
      local bottom_fx_index = insertAnalyzerAt(track, fx_index + 2)
    
      -- Close floating window of top FX (signal generator) if open
      reaper.TrackFX_Show(track, fx_index, 2)
    
      -- Float only the bottom analyzer FX window
      if bottom_fx_index and bottom_fx_index >= 0 then
        floatFX(track, bottom_fx_index)
      end
    
      reaper.Undo_EndBlock("Inserted EQ Curve Analyzers with floating analyzer only", -1)
    end
    
    reaper.PreventUIRefresh(1)
    toggleAnalyzers()
    reaper.PreventUIRefresh(-1)
    reaper.UpdateArrange()
    

    Note* This works only for 64-bit plugins vst and vst3 plugins, didn't work with 32-bit bridged plugins. Any one with a workaround can modify this and share it if u wish to.
     
    Last edited: Jun 25, 2025 at 1:22 AM
  4. xorome

    xorome Audiosexual

    Joined:
    Sep 28, 2021
    Messages:
    1,413
    Likes Received:
    1,060
    Interesting idea. I don't need the exact same thing, but here's what I came up with for my own needs:

    Code:
    local fx_pre = "BertEQA"
    local fx_pos = "BertEQA"
    
    local function sammich()
        retval, trackidx, itemidx, takeidx, fxidx, parm = reaper.GetTouchedOrFocusedFX(1);
    
        if retval == false then
            retval, trackidx, itemidx, takeidx, fxidx, parm = reaper.GetTouchedOrFocusedFX(0);
        end
    
        if retval == false then return end
    
        track = reaper.GetTrack(0, trackidx);
    
        if track then
            reaper.TrackFX_AddByName(track, fx_pre, 0, -1000 - fxidx);
            reaper.TrackFX_AddByName(track, fx_pos, 0, -1002 - fxidx);
        end
    end
    
    reaper.PreventUIRefresh(1)
    reaper.defer(sammich)
    reaper.UpdateArrange()
    reaper.PreventUIRefresh(-1)
    
    This sandwiches the currently selected or last touched plugin between two other plugins.
    The plugin that is inserted before is assigned in local fx_pre = "BertEQA"
    The plugin that is inserted after in local fx_pos = "BertEQA"

    BertEQA is what I renamed Bertom EQ Analyzer to in my case.

    You could change this to other combinations, like fx_pre = "AutoGainMatchBefore", fx_pos = "AutoGainMatchAfter" if you had two such plugins, or a M/S encoder/decoder pair and so on.

    Just save a copy under a different file name if needed.

    I have no idea how reliable this is, seems to work for me. Would need changes to work for containers I think.

    E: A word
     
    Last edited: Jun 25, 2025 at 5:30 PM
  5. justsomerandomdude

    justsomerandomdude Rock Star

    Joined:
    Aug 24, 2020
    Messages:
    533
    Likes Received:
    360
    I knew u would hop in to help, thanks @xorome, at first that was what i came up with using Chat gpt, but i usually use it for a short while and remove it from the chain. Just for a quick reference and to make sure im going the right way.
    So, i need only the Analyzer window open, because both would flood my screen.

    So, our dear Chat gpt made a script that i assigned to a shortcut,
    when enabled it
    1. sandwiches the floating fx
    2. opens only the analyzer while the generator does not float,
    and after use
    3. with the same shortcut/script removes the analyzer and generator from the chain. :)
     
Loading...
Similar Threads - Reaper Interesting Tips Forum Date
[SOLVED] HoRNet HATEFISh RhyGenerator: Reaper MIDI routing? Software Apr 21, 2025
Melodyne copy/paste in Reaper Software Reviews and Tutorials Apr 3, 2025
What do other DAWs have that REAPER doesn't? (songwriting, composition, music production) DAW Jan 25, 2025
How to configure Remidi4 in Reaper (tired) :) Mixing and Mastering Jan 23, 2025
Question about Cockos Reaper Mixing and Mastering Jan 14, 2025
Loading...