Объединение нескольких треков (каналов) в многоканальный трек (рендер)

borisuperful

Well-Known Member
31 Янв 2013
2.017
1.158
113
Т.к. планирую эту идею развивать (возможно в виде новых скриптов), создам топик. Скрипт достаточно навороченный для моего текущего уровня, но вроде все получилось :) Итак - объединение нескольких треков или каналов в мультиканальную вав. С помощью рендера. В том числе - можно из двух моно сложить стерео, но т.к. принцип посылов (на которых собственно и построен скрипт) выглядит как 1 на 1 канал, 1 на 2 канал, то, соответственно, это будет то же самое, что выставить панорамники 100R и 100L в моно-паре. Скрипты рендерят сигнал постфейдерно (пост ФХ), но и вынимают его из инсерт-треков, то есть все ваши посылы не будут рендерятся! Для этого у меня есть другой свой скрипт - "Mixdown selection".
Данный скрипт отобразит в окне ввода столько треков, сколько выделено. Ограничение 16 шт на уровне API. Также он отобразит название треков - если оно более 16 символов, сократит название по центру, а если имени у трека нет, напишет "Track untitled" с порядковым номером.
Ставим напротив трека 1 - значит моно, 2 - значит стерео. Другие данные скрипт не принимает. Если выбрать для трека моно, но у него стерео источник, то просто возьмется первый левый канал. Скрипт учитывает TS если он есть (если нет - рендерит весь трек). Ошибки буду исправлять, если что, с виду исправно. Последнее, что сейчас добавлю - скрипт использует одну функцию от SWS API, так что без SWS никак
В общем-то и все! Гифку и сам скрипт прикреплю в виде файла и исходного кода.

tY62s5YBUj.gif

JavaScript:
  function bla() end function nothing() reaper.defer(bla) end

  ---Test---How many selected tracks?---------------------------------------------------
  local count_sel_tracks = reaper.CountSelectedTracks(0)
  if count_sel_tracks == 0 then
    reaper.MB('No tracks. Please select tracks', 'Error', 0) nothing() return
  elseif count_sel_tracks > 16 then
    reaper.MB('More than 16 tracks are not supported :(', 'Error', 0) nothing() return
  end
  --------------------------------------------------------------------------------------

  ---Create userinput default values----------------------------------
  local num_inputs = string.rep('1,',count_sel_tracks)
  num_inputs = string.sub(num_inputs, 0, string.len(num_inputs)-1)
  --------------------------------------------------------------------

  local t = {}

  ---Get selected tracks count and tracks names for userinput and contraction the track name, if it's long---
  for i=0, count_sel_tracks-1 do
    local track_for_name = reaper.GetSelectedTrack(0,i)
    local _, name_of_sel_track = reaper.GetSetMediaTrackInfo_String( track_for_name, 'P_NAME', 0, false)
    string_track_length = string.len(name_of_sel_track)
    if string_track_length > 16 then
      name_of_sel_track = string.format(string.sub(name_of_sel_track, 0, 8) .. "%s",
      '...'..string.sub(name_of_sel_track, string_track_length-6, string_track_length))
    elseif string_track_length == 0 then
      name_of_sel_track = "Track untitled "..i+1 ---Named track, even if no name
    end
    name_of_sel_track = string.format(name_of_sel_track .. "%s",'  (chan):,')
    table.insert(t,name_of_sel_track)
  end
  -----------------------------------------------------------------------------------------------------------

  local inputs_names = table.concat(t) ---String from tracks and tracks names table

  ::START::
  ---User input for entering values----------------------------------------------------------------------------
  local retval, retvals_csv =
  reaper.GetUserInputs('Create multichannel track from sel tracks', count_sel_tracks, inputs_names, num_inputs)
  -------------------------------------------------------------------------------------------------------------

  if retval then

      local t_val = {}
      ---Test---"You can only enter mono(1) or stereo(2) channels"-------------------
      for s in string.gmatch(retvals_csv, "%d+") do
        table.insert(t_val,tonumber(s))
        if tonumber(s) ~= 1 and tonumber(s) ~= 2 then
          reaper.MB('You can only enter mono(1) or stereo(2) channels', 'Error', 0)
          goto START
        end
      end
      -------------------------------------------------------------------------------

      ---Test---"You can only enter mono(1) or stereo(2) channels" and get table count of new values---
      local length_table = 0
      local count_table = 0
      for i=1, #t_val do
        length_table = length_table + 1
        count_table = count_table + t_val[i]
      end
      if length_table ~= count_sel_tracks then
        reaper.MB('You can only enter mono(1) or stereo(2) channels', 'Error', 0)
        goto START
      end
      --------------------------------------------------------------------------------------------------

      reaper.Undo_BeginBlock()
      reaper.PreventUIRefresh(1)

      ---Insert track for render at top of selected tracks and set track channel count from table--
      local tra = reaper.GetSelectedTrack(0,0)
      local number_tra = reaper.GetMediaTrackInfo_Value(tra,'IP_TRACKNUMBER')
      reaper.InsertTrackAtIndex(number_tra-1,true)
      reaper.SetMediaTrackInfo_Value(reaper.GetTrack(0,number_tra-1), "I_NCHAN", count_table)
      ---------------------------------------------------------------------------------------------
 
      local t_tracks = {}
      local num_ch = 0 ---unit for channel cycle
      for i=1, count_sel_tracks do
        t_tracks[i] = reaper.GetSelectedTrack(0,i-1) ---save tracks selection
        local get_track = reaper.GetSelectedTrack(0,i-1)
        if t_val[i] == 1 then
          reaper.CreateTrackSend( get_track, reaper.GetTrack(0,number_tra-1))
          for j=0, reaper.GetTrackNumSends(get_track,0)-1 do
            local send_track = reaper.BR_GetMediaTrackSendInfo_Track(get_track, 0, j, 1)
            if send_track == reaper.GetTrack(0,number_tra-1) then ---searching send track if sends are already exist
              ---Insert 1-1, 1-2, 1-3, 1-4 etc. sends for mono tracks-------------------
              reaper.SetTrackSendInfo_Value( get_track, 0, j, 'I_SRCCHAN', 1024)
              reaper.SetTrackSendInfo_Value( get_track, 0, j, 'I_DSTCHAN', 1024+num_ch)
              num_ch = num_ch + 1
              --------------------------------------------------------------------------
            end
          end
        elseif t_val[i] == 2 then
          local num_send = 0 ---unit for searching send track if sends are already exist
          reaper.CreateTrackSend( get_track, reaper.GetTrack(0,number_tra-1))
          reaper.CreateTrackSend( get_track, reaper.GetTrack(0,number_tra-1))
          for j=0, reaper.GetTrackNumSends(get_track,0)-1 do
            local send_track = reaper.BR_GetMediaTrackSendInfo_Track(get_track, 0, j, 1)
            if send_track == reaper.GetTrack(0,number_tra-1) and num_send == 0 then
            ---Insert 1-1, 2-2, 1-3, 2-4, 1-5, 2-6 etc. sends for stereo tracks---------
              reaper.SetTrackSendInfo_Value( get_track, 0, j, 'I_SRCCHAN', 1024)  
              reaper.SetTrackSendInfo_Value( get_track, 0, j, 'I_DSTCHAN', 1024+num_ch)
              num_send = 1
            elseif send_track == reaper.GetTrack(0,number_tra-1) and num_send == 1 then
              reaper.SetTrackSendInfo_Value( get_track, 0, j, 'I_SRCCHAN', 1025)
              reaper.SetTrackSendInfo_Value( get_track, 0, j, 'I_DSTCHAN', 1025+num_ch)
              num_ch = num_ch + 2
              num_send = 0
            ----------------------------------------------------------------------------
            end
          end
        end
      end

      reaper.SetOnlyTrackSelected(reaper.GetTrack(0,number_tra-1),true) ---select only global folder track for render

      local count_tr_br = reaper.CountTracks(0) ---count tracks before render
      reaper.Main_OnCommand(41720, 0) -- Render multichannel
      local count_tr_ar = reaper.CountTracks(0) ---count tracks after render

      if count_tr_ar > count_tr_br then ---if render is not canceled
        reaper.DeleteTrack(reaper.GetTrack(0,number_tra))
        for i=1, #t_tracks do
          reaper.SetMediaTrackInfo_Value(t_tracks[i],'B_MUTE',1) ---set source tracks mute
        end
      elseif count_tr_br == count_tr_ar then ---if render is canceled
        reaper.DeleteTrack(reaper.GetTrack(0,number_tra-1))
        for i=1, #t_tracks do
          reaper.SetTrackSelected(t_tracks[i],true) ---restore source tracks selection
        end
      end
  else nothing() return end ---end script if cancel in user input


  reaper.Undo_EndBlock('Create multichannel track from selected tracks (render)',-1)
  reaper.PreventUIRefresh(-1)
 

Вложения

Последнее редактирование:
@Antonio, для любой ситуации, если понадобится создать многоканальную вав :) Ну или стерео.
Просто рипер отлично умеет распаковывать, поэтому логично, если бы точно также работало, но обратно.
 
  • Like
Реакции: Antonio
Чуть-чуть обновил (только мелкие исправления)

JavaScript:
  function bla() end function nothing() reaper.defer(bla) end

  ---Test---How many selected tracks?---------------------------------------------------
  local count_sel_tracks = reaper.CountSelectedTracks(0)
  if count_sel_tracks == 0 then
    reaper.MB('No tracks. Please select tracks', 'Error', 0) nothing() return
  elseif count_sel_tracks > 16 then
    reaper.MB('More than 16 tracks are not supported :(', 'Error', 0) nothing() return
  end
  --------------------------------------------------------------------------------------

  ---Create userinput default values----------------------------------
  local num_inputs = string.rep('1,',count_sel_tracks)
  num_inputs = string.sub(num_inputs, 0, string.len(num_inputs)-1)
  --------------------------------------------------------------------

  local t = {}

  ---Get selected tracks count and tracks names for userinput and contraction the track name, if it's long---
  for i=0, count_sel_tracks-1 do
    local track_for_name = reaper.GetSelectedTrack(0,i)
    local _, name_of_sel_track = reaper.GetSetMediaTrackInfo_String( track_for_name, 'P_NAME', 0, false)
    string_track_length = string.len(name_of_sel_track)
    if string_track_length > 16 then
      name_of_sel_track = string.format(string.sub(name_of_sel_track, 0, 8) .. "%s",
      '...'..string.sub(name_of_sel_track, string_track_length-6, string_track_length))
    elseif string_track_length == 0 then
      name_of_sel_track = "Track untitled "..i+1 ---Named track, even if no name
    end
    name_of_sel_track = string.format(name_of_sel_track .. "%s",'  (chan):,')
    table.insert(t,name_of_sel_track)
  end
  -----------------------------------------------------------------------------------------------------------

  local inputs_names = table.concat(t) ---String from tracks and tracks names table

  ::START::
  ---User input for entering values----------------------------------------------------------------------------
  local retval, retvals_csv =
  reaper.GetUserInputs('Create multichannel track from sel tracks', count_sel_tracks, inputs_names, num_inputs)
  -------------------------------------------------------------------------------------------------------------

  if retval then

      local t_val = {}
      ---Test---"You can only enter mono(1) or stereo(2) channels"-------------------
      for s in string.gmatch(retvals_csv, "[^,]*") do
        table.insert(t_val,tonumber(s))
        if (tonumber(s) ~= 1 and tonumber(s) ~= 2) or not tonumber(s) then
          reaper.MB('You can only enter mono(1) or stereo(2) channels', 'Error', 0)
          goto START
        end
      end
      -------------------------------------------------------------------------------
     
 
      ---Get table count of new values---------------------
      local count_table = 0
      for i=1, #t_val do
        count_table = count_table + t_val[i]
      end
     
      if (count_table % 2 == 0) then
        count_table = count_table ---even integer
      else
        count_table = count_table+1 ---odd integer + 1
      end
      ---------------------------------------------------------

      reaper.Undo_BeginBlock()
      reaper.PreventUIRefresh(1)
 
      ---Insert track for render at top of selected tracks and set track channel count from table--
      local tra = reaper.GetSelectedTrack(0,0)
      local number_tra = reaper.GetMediaTrackInfo_Value(tra,'IP_TRACKNUMBER')
      reaper.InsertTrackAtIndex(number_tra-1,true)
      reaper.SetMediaTrackInfo_Value(reaper.GetTrack(0,number_tra-1), "I_NCHAN", count_table)
      ---------------------------------------------------------------------------------------------
   
      local t_tracks = {}
      local num_ch = 0 ---unit for channel cycle
      local num_send = 0 ---unit for searching send track if sends are already exist
      for i=1, count_sel_tracks do
        t_tracks[i] = reaper.GetSelectedTrack(0,i-1) ---save tracks selection
        local get_track = reaper.GetSelectedTrack(0,i-1)
        if t_val[i] == 1 then
          reaper.CreateTrackSend( get_track, reaper.GetTrack(0,number_tra-1))
          for j=0, reaper.GetTrackNumSends(get_track,0)-1 do
            local send_track = reaper.BR_GetMediaTrackSendInfo_Track(get_track, 0, j, 1)
            if send_track == reaper.GetTrack(0,number_tra-1) then ---searching send track if sends are already exist
              ---Insert 1-1, 1-2, 1-3, 1-4 etc. sends for mono tracks-------------------
              reaper.SetTrackSendInfo_Value( get_track, 0, j, 'I_SRCCHAN', 1024)
              reaper.SetTrackSendInfo_Value( get_track, 0, j, 'I_DSTCHAN', 1024+num_ch)
              num_ch = num_ch + 1
              --------------------------------------------------------------------------
            end
          end
        elseif t_val[i] == 2 then
          reaper.CreateTrackSend( get_track, reaper.GetTrack(0,number_tra-1))
          reaper.CreateTrackSend( get_track, reaper.GetTrack(0,number_tra-1))
          for j=0, reaper.GetTrackNumSends(get_track,0)-1 do
            local send_track = reaper.BR_GetMediaTrackSendInfo_Track(get_track, 0, j, 1)
            if send_track == reaper.GetTrack(0,number_tra-1) and num_send == 0 then
            ---Insert 1-1, 2-2, 1-3, 2-4, 1-5, 2-6 etc. sends for stereo tracks---------
              reaper.SetTrackSendInfo_Value( get_track, 0, j, 'I_SRCCHAN', 1024)    
              reaper.SetTrackSendInfo_Value( get_track, 0, j, 'I_DSTCHAN', 1024+num_ch)
              num_send = 1
            elseif send_track == reaper.GetTrack(0,number_tra-1) and num_send == 1 then
              reaper.SetTrackSendInfo_Value( get_track, 0, j, 'I_SRCCHAN', 1025)
              reaper.SetTrackSendInfo_Value( get_track, 0, j, 'I_DSTCHAN', 1025+num_ch)
              num_ch = num_ch + 2
              num_send = 0
            ----------------------------------------------------------------------------
            end
          end  
        end
      end
 
      reaper.SetOnlyTrackSelected(reaper.GetTrack(0,number_tra-1),true) ---select only global folder track for render
 
      local count_tr_br = reaper.CountTracks(0) ---count tracks before render
      reaper.Main_OnCommand(41720, 0) -- Render multichannel
      local count_tr_ar = reaper.CountTracks(0) ---count tracks after render
 
      if count_tr_ar > count_tr_br then ---if render is not canceled
        reaper.DeleteTrack(reaper.GetTrack(0,number_tra))
        for i=1, #t_tracks do
          reaper.SetMediaTrackInfo_Value(t_tracks[i],'B_MUTE',1) ---set source tracks mute
        end
      elseif count_tr_br == count_tr_ar then ---if render is canceled
        reaper.DeleteTrack(reaper.GetTrack(0,number_tra-1))
        for i=1, #t_tracks do
          reaper.SetTrackSelected(t_tracks[i],true) ---restore source tracks selection
        end
      end
  else nothing() return end ---end script if cancel in user input


  reaper.Undo_EndBlock('Create multichannel track from selected tracks (render)',-1)
  reaper.PreventUIRefresh(-1)
 

Вложения

Последнее редактирование:
  • Like
Реакции: Mr_Tsonts и Antonio
Тестирую щас новый вариант, который складывает любое кол-во каналов с одного трека. То есть, например, можно 4 канальный + 4 канальный + 6 канальный. Но до 64 каналов в сумме. Завтра выложу скорее всего
 
Вот новый вариант - теперь можно вводить любое кол-во каналов на дорожку, однако в сумме не более 64. Данная версия по сути лучше первой и может сложить, к примеру, 4 канала с одного трека + стерео канал с другого и т.п. Кол-во дорожек все также ограничено 16 штуками. Выложу просто код, кому нужно, скопирует.

JavaScript:
  function bla() end function nothing() reaper.defer(bla) end

  ---Test---How many selected tracks?---------------------------------------------------
  local count_sel_tracks = reaper.CountSelectedTracks(0)
  if count_sel_tracks == 0 then
    reaper.MB('No tracks. Please select tracks', 'Error', 0) nothing() return
  elseif count_sel_tracks > 16 then
    reaper.MB('More than 16 tracks are not supported :(', 'Error', 0) nothing() return
  end
  --------------------------------------------------------------------------------------

  ---Create userinput default values----------------------------------
  local num_inputs = string.rep('1,',count_sel_tracks)
  num_inputs = string.sub(num_inputs, 0, string.len(num_inputs)-1)
  --------------------------------------------------------------------

  local t = {}

  ---Get selected tracks count and tracks names for userinput and contraction the track name, if it's long---
  for i=0, count_sel_tracks-1 do
    local track_for_name = reaper.GetSelectedTrack(0,i)
    local _, name_of_sel_track = reaper.GetSetMediaTrackInfo_String( track_for_name, 'P_NAME', 0, false)
    string_track_length = string.len(name_of_sel_track)
    if string_track_length > 16 then
      name_of_sel_track = string.format(string.sub(name_of_sel_track, 0, 8) .. "%s",
      '...'..string.sub(name_of_sel_track, string_track_length-6, string_track_length))
    elseif string_track_length == 0 then
      name_of_sel_track = "Track untitled "..i+1 ---Named track, even if no name
    end
    name_of_sel_track = string.format(name_of_sel_track .. "%s",'  (chan):,')
    table.insert(t,name_of_sel_track)
  end
  -----------------------------------------------------------------------------------------------------------

  local inputs_names = table.concat(t) ---String from tracks and tracks names table

  ::START::
  ---User input for entering values----------------------------------------------------------------------------
  local retval, retvals_csv =
  reaper.GetUserInputs('Create multichannel track from sel tracks', count_sel_tracks, inputs_names, num_inputs)
  -------------------------------------------------------------------------------------------------------------

  if retval then
     
    function Round_To_Integer(x, n)
      n = n or 1
      return math.floor(x / n + 0.5) * n
    end

    local t_val = {}
   
    ---Test---"You can only enter an integer"-------------------------------------------------------
    for s in string.gmatch(retvals_csv, "[^,]*") do
      if not tonumber(s) or Round_To_Integer(tonumber(s), 1) ~= tonumber(s) or tonumber(s) <= 0 then
        reaper.MB('You can only enter an integer', 'Error', 0)
        goto START
      end
      table.insert(t_val,tonumber(s))
    end
    ------------------------------------------------------------------------------------------------

    ---Get table count of new values--------
    local count_table = 0
    local length_table = 0
    for i=1, #t_val do
      count_table = count_table + t_val[i]
      length_table = length_table + 1
    end
    ----------------------------------------
   
    ---Test---"You cannot enter not an integer and cannot do more than 64 channels on one track"----
    if length_table ~= count_sel_tracks then
      reaper.MB('You can only enter an integer', 'Error', 0)
      goto START
    elseif count_table > 64 then
      reaper.MB('You cannot do more than 64 channels on one track :(', 'Error', 0)
      goto START
    end
    ------------------------------------------------------------------------------------------------
   
    reaper.Undo_BeginBlock()
    reaper.PreventUIRefresh(1)
   
    ---Round odd number to event number (up)-------------
    function Round_To_Even(number_round)
      if (number_round % 2 ~= 0) then
        number_round = number_round+1 ---odd integer + 1
      end
      return number_round
    end
    -----------------------------------------------------

    ---Insert track for render at top of selected tracks and set track channel count from table------------
    local tra = reaper.GetSelectedTrack(0,0)
    local number_tra = reaper.GetMediaTrackInfo_Value(tra,'IP_TRACKNUMBER')
    reaper.InsertTrackAtIndex(number_tra-1,true)
    reaper.SetMediaTrackInfo_Value(reaper.GetTrack(0,number_tra-1), "I_NCHAN", Round_To_Even(count_table))
    -------------------------------------------------------------------------------------------------------

    local t_tracks = {}
    local num_src_send = 0 ---unit for source sends cycle
    local num_dst_send = 0 ---unit for destination sends cycle
    for i=1, count_sel_tracks do
      t_tracks[i] = reaper.GetSelectedTrack(0,i-1) ---save tracks selection
      local get_track = reaper.GetSelectedTrack(0,i-1)
      reaper.SetMediaTrackInfo_Value(get_track, "I_NCHAN", Round_To_Even(t_val[i])) ---set channel count for track if multichannel source
      ---Insert sends for selected track (count sends from table)----------
      for h=1, t_val[i] do
        reaper.CreateTrackSend(get_track, reaper.GetTrack(0,number_tra-1))
      end
      ---------------------------------------------------------------------
      for j=0, reaper.GetTrackNumSends(get_track,0)-1 do
        local send_track = reaper.BR_GetMediaTrackSendInfo_Track(get_track, 0, j, 1)
        if send_track == reaper.GetTrack(0,number_tra-1) then ---searching send track if sends are already exist
          reaper.SetTrackSendInfo_Value(get_track, 0, j, 'I_SRCCHAN', 1024+num_src_send) ---set source send channel
          reaper.SetTrackSendInfo_Value(get_track, 0, j, 'I_DSTCHAN', 1024+num_src_send+num_dst_send) ---set dest send channel
          reaper.BR_GetSetTrackSendInfo(get_track, 0, j, 'I_MIDI_SRCCHAN', true, -1) ---disable default midi send
          num_src_send = num_src_send + 1
        end
      end
      num_dst_send = num_dst_send + t_val[i]
      num_src_send = 0
    end

    reaper.SetOnlyTrackSelected(reaper.GetTrack(0,number_tra-1),true) ---select only global folder track for render

    local count_tr_br = reaper.CountTracks(0) ---count tracks before render
    reaper.Main_OnCommand(41720, 0) -- Render multichannel
    local count_tr_ar = reaper.CountTracks(0) ---count tracks after render

    if count_tr_ar > count_tr_br then ---if render is not canceled
      reaper.DeleteTrack(reaper.GetTrack(0,number_tra))
      for i=1, #t_tracks do
        reaper.SetMediaTrackInfo_Value(t_tracks[i],'B_MUTE',1) ---set source tracks mute
      end
    elseif count_tr_br == count_tr_ar then ---if render is canceled
      reaper.DeleteTrack(reaper.GetTrack(0,number_tra-1))
      for i=1, #t_tracks do
        reaper.SetTrackSelected(t_tracks[i],true) ---restore source tracks selection
      end
    end
   
    reaper.Undo_EndBlock('Create multichannel track from selected tracks (render)',-1)
    reaper.PreventUIRefresh(-1)
     
  else nothing() return end ---end script if cancel in user input
 
  • Like
Реакции: N0-body и Antonio
@borisuperful, слушай, а я вот не помню, есть ли у тебя скрипт для рендера, желательно айтема, или по тайм селекшн, например, миди (или аудио) на два (правый и левый) моно?
 

Сейчас просматривают