Old 09-02-2019, 01:42 PM   #1
Thonex
Human being with feelings
 
Join Date: May 2018
Location: Los Angeles
Posts: 684
Default New Script: Smart Auto x-fades across multiple comped tracks

Hey guys,

I wrote a script that may be useful to those who comp takes on many tracks (like orchestral) and then need to x-fade between takes. Since Reaper doesn't have a pre-record feature (aside from pre-roll), live punch-ins have no audio data (pre-recorded material) before the start of an item... (again... UNLESS you are using a pre-roll with "Record during pre-roll" option ON). So, when creating auto-crossfades, it can be very tedious to zoom into each take and see if there is pre-roll before the take so there can be a proper crossfade. As you know, Reaper will extend the item's edge beyond where there is any audio and execute an x-fade where there is no audio -- resulting in a bad x-fade. You have to tediously drag item's edges (that you know has audio padding) on top of items that don't so that they x-fade properly.


Below you can see where I dragged the items' edges to the left showing the Items were punched in (the notches in the red circles) and to the left of the notches there is no audio (loop items is off)



What does this script do?
  • This script looks at every item and sees if there is audio to the let and right of the item’s edges. It then x-fades accordingly.
  • It will not try to push an item's edge beyond the actual audio file's range.
  • It does not touch the left edge of the first item or the right edge of the last item.
  • You can set your x-fade amount in the script. I set it to 50ms. If you need 100… just hit the action twice.
    Code:
    x_fade = .050 -- put your x-fade time here.
  • Part of doing comps across multiple track is keeping your vertical edits identical. If you inadvertently select a range that doesn't line up vertically, your will get get a pop-up notifying you if you want to continue anyway.



In the video below, I have 8 tracks of material that have multiple takes. When I hit CMD+L you can see all the takes. Many of them have no audio to the left to right of the take’s edge (meaning the source audio does not extend past the take). The black area is where the are empty lanes. You’ll be able to select all the items you want and simply let the script determine in what direction the x-fade should take place.

Enjoy. (let me know if you find any bugs — I’m sure you will )





Here is the code:

Code:
--[[
  Script: AK X-Fade Comps.lua
  Written by Thonex
  v1.0
  Since Reaper doesn't have pre-record feature (aside from pre-roll), live punch-ins have no audio data (pre-recorded material)
  before the start of an item... UNLESS you are using a pre-roll with "Record during pre-roll" option ON. So, when creating
  auto-crossfades, it can be very tedious zoom into each take and see if there is pre-roll before the take so there can be
  a proper crossfade.
  
  This script looks at all the items/takes and determines if there is audio preceding or after the edges of the items/takes.
  It then processes a crossfade making sure it doesn't push the boundaries of the item beyond it's audio content so that there
  will be a real crossfade as opposed to a fade-in or fade-out.   


--]]



function Msg (param)
  reaper.ShowConsoleMsg(tostring (param).."\n")
end

function isint(n) -- function to test if a number is whole
  return n==math.floor(n)
end

function main()

  reaper.PreventUIRefresh(1)
  reaper.ClearConsole() 
  reaper.Undo_BeginBlock()
  
  x_fade = .050 -- put your x-fade time here.
  
  
---------- this is where we calcualte how may items on each track  ----------
  count_sel_items =  reaper.CountSelectedMediaItems( 0 )
  
  prev_track      = 0
  num_tracks      = 0
 -- items_per_track = 0
  
  i=0
  for i=0, count_sel_items-1 do
  
    item = reaper.GetSelectedMediaItem(0, i)
    track =  reaper.GetMediaItem_Track( item )
    
    if track ~= prev_track then
 
        num_tracks = num_tracks + 1
        prev_track = track
    end
    
  i=i+1
  end
  
  items_per_track = count_sel_items/num_tracks
  
  if not isint(items_per_track) then
    cont = reaper.ShowMessageBox( "There is an uneven number of items on the tracks. Continue anyway?", "NOTICE", 1 )
  end
  
  if cont == 2 then return end 
--[[  
  Msg(num_tracks)
  Msg(count_sel_items)
  Msg(items_per_track)
  Msg(cont)
--]]  
---------- END OF this is where we calcualte how may items on each track  ----------


  i=0
  for i=0, count_sel_items-1 do
  

    item = reaper.GetSelectedMediaItem(0, i)
    take = reaper.GetActiveTake(item)

    item_pos = reaper.GetMediaItemInfo_Value(item,"D_POSITION")
    item_len = reaper.GetMediaItemInfo_Value(item,"D_LENGTH")
    item_end = item_pos + item_len
    item_snap = reaper.GetMediaItemInfo_Value(item,"D_SNAPOFFSET")

    source = reaper.GetMediaItemTake_Source( take )
    source_len, lengthIsQN = reaper.GetMediaSourceLength( source )
  
    take_off = reaper.GetMediaItemTakeInfo_Value(take, "D_STARTOFFS")
    take_rate = reaper.GetMediaItemTakeInfo_Value(take,"D_PLAYRATE")

    take_off_comp = take_off * (1/take_rate)
    
    r_edge_pad = tonumber(string.format("%." .. (6 or 0) .. "f",source_len - take_off_comp - item_len))
    l_edge_pad = tonumber(string.format("%." .. (6 or 0) .. "f",take_off_comp))

    
    item_snap = reaper.GetMediaItemInfo_Value(item,"D_SNAPOFFSET")
    
--[[
    Msg(reaper.GetMediaSourceFileName(source, ""))
    Msg("source len: ".. source_len)
    Msg("item len: "..item_len)

    Msg("left edge pad: ".. l_edge_pad)
    Msg("Right Edge space: "..r_edge_pad )
--]]
    
    if not ((i%items_per_track == 0) or (i%items_per_track == items_per_track-1))  then  -- check that it is not the first or last item on track
      
      -- if there is space to the left of the item... start x ms earlier
      if take_off_comp > x_fade then
        item_left = item_pos - x_fade
        else
        item_left = item_pos - l_edge_pad
      end  
      -- if there is space to the right of the item... end x ms later
      if r_edge_pad > x_fade then
        item_right = item_end + x_fade
        else
        item_right = item_end + r_edge_pad
      end  
      
        reaper.BR_SetItemEdges( item,item_left, item_right )
    end
    
    if (i%items_per_track == 0)then  -- check that it is first item on track
         
      -- if there is space to the right of the item... end x ms later
      if r_edge_pad > x_fade then
        item_right = item_end + x_fade
        else
        item_right = item_end + r_edge_pad
      end  
      
        reaper.BR_SetItemEdges( item,item_pos, item_right )
    end
    
    if (i%items_per_track == items_per_track-1)  then  -- check that it is the last item on track
          
      -- if there is space to the left of the item... start x ms earlier
      if take_off_comp > x_fade then
        item_left = item_pos - x_fade
        else
        item_left = item_pos - l_edge_pad
      end  

 
   reaper.BR_SetItemEdges( item,item_left, item_end )
    end
        

    -- Msg(i%items_per_track)

    i=i+1

  end

  reaper.PreventUIRefresh(-1)
  reaper.UpdateArrange()
  reaper.Undo_EndBlock("crossfade items based on their audio boundaries", -1)

end

main()
__________________
Cheers,
Andrew K
v5.982/64 Mac 10.12.+, i7 Quad 2.9GHz, 24GB

Last edited by Thonex; 09-14-2019 at 11:33 PM.
Thonex is online now   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 05:57 PM.


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