ReaScripts (скрипты для Reaper) - делимся (3 онлайн)

EUGEN27771

Well-Known Member
23 Апр 2010
2.293
1.995
113
Скрипт сохраняет текущие настройки последнего редактируемого эффекта как новый пользовательский пресет
Save VST Preset Demo.gif Save FX Preset Demo.gif
====
Save_FX_Preset
Поддерживаются VST и JS - эффекты.
 
Последнее редактирование:

Aleksandr Oleynik

Well-Known Member
16 Янв 2007
26.360
20.063
113
62
Киев
Ура!!!! Допилил! Очень круто...
Женя, а как с JSFX?
 
Последнее редактирование:

Aleksandr Oleynik

Well-Known Member
16 Янв 2007
26.360
20.063
113
62
Киев
@EUGEN27771, а в чем PROFIT? Что не так с обычным сохранением пресетов?
Женя скромничает!!!!!
С обычным сохранением пресетов не так то, что его не возможно сделать внешней командой или экшином или скриптом - НИ КАК. Нет в API Рипера такой функции, не дали нам её разработчики.
А Женя её написал.
Она будет полезна больще тем, кто пишет комплексные скрипты в которых очень нужна подобная функция.
Ну вот простой пример приведу -
Вы отстраиваете какой-то типичный проект и вам нужно чтоб для каждой его новой версии в куче плагинах сразу, которые вы крутили при настройке, были сохранены Пресеты с этой версией проекта. А потом, чтоб их одной кнопкой вызвать все разом можно было (эту функцию, кстати дали разрабы).
Те кто пишут скрипты знают, что сделать это можно через сохранение чанка треков - но там сохраняется всё подряд, а не то, что нужно.
И я хорошо знаю какой объём работы Женя для этого проделал.....
 
  • Like
Реакции: Oliver_Cray

EUGEN27771

Well-Known Member
23 Апр 2010
2.293
1.995
113
Рендер айтема до последнего VSTi(все, что после него перед рендером мьютируется, а потом восстанавливается).
Render selected item as new take, up to last VSTi - рендерит, как новый тейк.
Render selected item on new track, up to last VSTi - рендерит, на новый трек, делает посыл на оригинальный и убирает посыл на мастер трек.
Первый вариант мне все равно кажется более полезным.
 
  • Like
Реакции: Buyan, sve и LilColt

Aleksandr Oleynik

Well-Known Member
16 Янв 2007
26.360
20.063
113
62
Киев
Скрипт сохраняет текущие настройки последнего редактируемого эффекта как новый пользовательский пресет
Женя, я под свои нужды чуть переделал скрипт: теперь он сохраняет новый Пресет у любого, в данный момент открытого FX-а, даже если параметры его не трогали (как вариант может добавишь?) -
PHP:
--[[
   * ReaScript Name: Save_FX_Preset
   * Lua script for Cockos REAPER
   * Author: EUGEN27771
   * Author URI: http://forum.cockos.com/member.php?u=50462
   * Licence: GPL v3
   * Version: 1.02
  ]]

  --------------------------------------------------------------------------------
  local msg = function(M) reaper.ShowConsoleMsg(tostring(M).."\n") end
  --------------------------------------------------------------------------------

--------------------------------------------------------------------------------
-- Base64_to_Hex(modded from lua.org functions)  -------------------------------
--------------------------------------------------------------------------------
-- decryption table --
local base64bytes = {['A']=0, ['B']=1, ['C']=2, ['D']=3, ['E']=4, ['F']=5, ['G']=6, ['H']=7, ['I']=8, ['J']=9, ['K']=10,['L']=11,['M']=12,
                     ['N']=13,['O']=14,['P']=15,['Q']=16,['R']=17,['S']=18,['T']=19,['U']=20,['V']=21,['W']=22,['X']=23,['Y']=24,['Z']=25,
                     ['a']=26,['b']=27,['c']=28,['d']=29,['e']=30,['f']=31,['g']=32,['h']=33,['i']=34,['j']=35,['k']=36,['l']=37,['m']=38,
                     ['n']=39,['o']=40,['p']=41,['q']=42,['r']=43,['s']=44,['t']=45,['u']=46,['v']=47,['w']=48,['x']=49,['y']=50,['z']=51,
                     ['0']=52,['1']=53,['2']=54,['3']=55,['4']=56,['5']=57,['6']=58,['7']=59,['8']=60,['9']=61,['+']=62,['/']=63,['=']=nil}
--------------------------------------------
-- Decode Base64 to HEX --------------------
--------------------------------------------
function B64_to_HEX(data)
  local chars  = {}
  local result = {}
  local hex
    for dpos=0, #data-1, 4 do
        -- Get chars -------------------
        for char=1,4 do chars[char] = base64bytes[(string.sub(data,(dpos+char), (dpos+char)) or "=")] end -- Get chars
        -- To hex ----------------------
        if chars[3] and chars[4] then
            hex = string.format('%02X%02X%02X',                                  -- if 1,2,3,4 chars
                                   (chars[1]<<2)       + ((chars[2]&0x30)>>4),   -- 1
                                   ((chars[2]&0xf)<<4) + (chars[3]>>2),          -- 2
                                   ((chars[3]&0x3)<<6) + chars[4]              ) -- 3
          elseif  chars[3] then
            hex = string.format('%02X%02X',                                      -- if 1,2,3 chars
                                   (chars[1]<<2)       + ((chars[2]&0x30)>>4),   -- 1
                                   ((chars[2]&0xf)<<4) + (chars[3]>>2),          -- 2
                                   ((chars[3]&0x3)<<6)                         )
          else
            hex = string.format('%02X',                                          -- if 1,2 chars
                                   (chars[1]<<2)       + ((chars[2]&0x30)>>4)  ) -- 1
        end
       ---------------------------------
       table.insert(result,hex)
    end
  return table.concat(result)
end

----------------------------------------
-- String_to_HEX  ----------------------
----------------------------------------
function String_to_HEX(Preset_Name)
  local VAL  = {Preset_Name:byte(1,-1)} -- to bytes, values
  local Pfmt = string.rep("%02X", #VAL)
  return string.format(Pfmt, table.unpack(VAL))
end

--------------------------------------------------------------------------------
-- FX_Chunk_to_HEX -------------------------------------------------------------
--------------------------------------------------------------------------------
-- Variant 1 ---------------------------
function FX_Chunk_to_HEX(FX_Type, FX_Chunk, Preset_Name)
  local Preset_Chunk = FX_Chunk:match("\n.*\n")        -- extract preset(simple var)

    ---------------------------------------
    -- For JS -----------------------------
    ---------------------------------------
    if FX_Type=="JS" then
       Preset_Chunk = Preset_Chunk:gsub("\n", "")      -- del "\n"
       --reaper.ShowConsoleMsg(Preset_Chunk..'\n')
       return String_to_HEX(Preset_Chunk..Preset_Name)
    end

    ---------------------------------------
    -- For VST ----------------------------
    ---------------------------------------
    local Hex_TB = {}
    local init = 1
    ---------------------
    for i=1, math.huge do
          line = Preset_Chunk:match("\n.-\n", init)    -- extract line from preset(simple var)
          if not line then
             --reaper.ShowConsoleMsg(Hex_TB[i-1].."\n")
             Hex_TB[i-1] = "00"..String_to_HEX(Preset_Name).."0010000000" -- Preset_Name to Hex(replace name from chunk)
             --reaper.ShowConsoleMsg(Hex_TB[i-1].."\n")
             break
          end
          ---------------
          init = init + #line - 1                      -- for next line
          line = line:gsub("\n","")                    -- del "\n"
          --reaper.ShowConsoleMsg(line.."\n")
          Hex_TB[i] = B64_to_HEX(line)
    end
    ---------------------
    return table.concat(Hex_TB)
end

-- Variant 2(without Name to Hex, simple var) ------
--[[
function FX_Chunk_to_HEX(FX_Type, FX_Chunk, Preset_Name)
  local Preset_Chunk = FX_Chunk:match("\n.*\n")   -- extract preset(simple var)
  ----------------------------------------
  Preset_Chunk = Preset_Chunk:gsub("\n","")       -- del "\n"
  if FX_Type=="JS" then return String_to_HEX(Preset_Chunk..Preset_Name)
     else return B64_to_HEX(Preset_Chunk)
  end
end
--]]

--------------------------------------------------------------------------------
-- Get_CtrlSum -----------------------------------------------------------------
--------------------------------------------------------------------------------
function Get_CtrlSum(HEX)
  local Sum = 0
  for i=1, #HEX, 2 do  Sum = Sum + tonumber( HEX:sub(i,i+1), 16) end
  return string.sub( string.format("%X", Sum), -2, -1 )
end

--------------------------------------------------------------------------------
-- Write preset to PresetFile --------------------------------------------------
--------------------------------------------------------------------------------
function Write_to_File(PresetFile, Preset_HEX, Preset_Name)
  local file, Presets_ini, Nprsts
  ----------------------------------------------------------
  -- Rewrite header(or create) -----------------------------
  ----------------------------------------------------------
    local ret_r, ret_w
    if reaper.file_exists(PresetFile) then
        -- BR function works faster than lua r,w --
        ret_r, Nprsts =  reaper.BR_Win32_GetPrivateProfileString("General", "NbPresets", "", PresetFile)
        Nprsts = math.tointeger(Nprsts)
        ------------------
        ret_w = reaper.BR_Win32_WritePrivateProfileString("General", "NbPresets", math.tointeger(Nprsts+1), PresetFile)
    else Nprsts = 0
         Presets_ini = "[General]\nNbPresets="..Nprsts+1
         file = io.open(PresetFile, "w")
         file:write(Presets_ini)
         file:close()
    end
  ----------------------------------------------------------
  -- Write preset data to file -----------------------------
  ----------------------------------------------------------
  file = io.open(PresetFile, "r+")
  file:seek("end")                        -- to end of file
  ------------------
  file:write("\n[Preset"..Nprsts.."]")    -- preset number(0-based)
  --------------------------------------
  --------------------------------------
  local Len = #Preset_HEX                 -- Data Lenght
  local s = 1
  local Ndata = 0
  for i=1, math.ceil(Len/32768) do
      if i==1 then Ndata = "\nData=" else Ndata = "\nData_".. i-1 .."=" end
      local Data = Preset_HEX:sub(s, s+32767)
      local Sum = Get_CtrlSum(Data)
      file:write(Ndata, Data, Sum)
      s = s+32768
  end
  --------------------------------------
  --- Preset_Name, Data Lenght ---------
  --------------------------------------
  file:write("\nName=".. Preset_Name .."\nLen=".. Len//2 .."\n")
  -------------------
  file:close()
end

--------------------------------------------------------------------------------
-- Get FX_Chunk and PresetFile  ------------------------------------------------
--------------------------------------------------------------------------------
function Get_FX_Data(track, fxnum)
  local fx_cnt = reaper.TrackFX_GetCount(track)
  if fx_cnt==0 or fxnum>fx_cnt-1 then return end       -- if fxnum not valid
  local ret, Track_Chunk =  reaper.GetTrackStateChunk(track,"",false)
  --reaper.ShowConsoleMsg(Track_Chunk)

  ------------------------------------
  -- Find FX_Chunk(use fxnum) --------
  ------------------------------------
  local s, e = Track_Chunk:find("<FXCHAIN")            -- find FXCHAIN section
  -- find VST(or JS) chunk
  for i=1, fxnum+1 do
      s, e = Track_Chunk:find("<%u+%s.->", e)
  end
    ----------------------------------
    -- FX_Type -----------------------
    local FX_Type = string.match(Track_Chunk:sub(s+1,s+3), "%u+")   -- FX Type
    if not(FX_Type=="VST" or FX_Type=="JS") then return end         -- Only VST and JS supported
    ----------------------------------
    -- extract FX_Chunk --------------
    local FX_Chunk = Track_Chunk:match("%b<>", s)      -- FX_Chunk(simple var)
    ----------------------------------
    --reaper.ShowConsoleMsg(FX_Chunk.."\n")

  ------------------------------------
  -- Get UserPresetFile --------------
  ------------------------------------
  local PresetFile = reaper.TrackFX_GetUserPresetFilename(track, fxnum, "")
  ------------------------------------
  return FX_Type, FX_Chunk, PresetFile
end

--------------------------------------------------------------------------------
-- Main function  --------------------------------------------------------------
--------------------------------------------------------------------------------
function Save_VST_Preset(track, fxnum, Preset_Name)
  if not (track and fxnum and Preset_Name) then return end       -- Need track, fxnum, Preset_Name
  local FX_Type, FX_Chunk, PresetFile = Get_FX_Data(track, fxnum)
  --reaper.ShowConsoleMsg(FX_Chunk..'\n')
  -----------
  if FX_Chunk and PresetFile then
     local start_time = reaper.time_precise()
     local Preset_HEX = FX_Chunk_to_HEX(FX_Type, FX_Chunk, Preset_Name)
     --reaper.ShowConsoleMsg("Processing time = ".. reaper.time_precise()-start_time ..'\n') -- time test
     local start_time = reaper.time_precise()
     Write_to_File(PresetFile, Preset_HEX, Preset_Name)
     --reaper.ShowConsoleMsg("Write time = ".. reaper.time_precise()-start_time ..'\n') -- time test
     reaper.TrackFX_SetPreset(track, fxnum, Preset_Name) -- For "update", but this is optional
  end
end

----------------------------------------------------------------------------------------------------
-- GetLastTouchedFX  -------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
function Get_LastTouch_FX()
  local retval, tracknum, fxnum = reaper.GetLastTouchedFX()           -- fxnum
  if not retval then return end
  local track = reaper.GetTrack(0, tracknum-1)                        -- track(trackID)
  local Pidx, Npt = reaper.TrackFX_GetPresetIndex(track, fxnum)
  local  Preset_Name = "New "..Npt+1                                  -- New Preset_Name
  return track, fxnum, Preset_Name
end
----------------------------------------------------------------------------------------------------
-- GetOpenFX ---------------------------------------------------------------------------------------
function GetOpenFX ()
  local counttracks = reaper.CountTracks(0)
  if counttracks == nil then return end
  for i=1, counttracks do
    local tr = reaper.GetTrack(0,i-1)
    if tr ~= nil then
      local CountFX = reaper.TrackFX_GetCount( tr )
      for i=1, CountFX do
        local tt = reaper.TrackFX_GetFloatingWindow(tr, i-1)
        if tt then
          local track = tr
          local fxnum = i-1
          local Pidx, Npt = reaper.TrackFX_GetPresetIndex(tr, i-1)
          local Preset_Name = "New "..Npt+1                                  -- New Preset_Name
          return track, fxnum, Preset_Name
        end
      end
    end
  end

end
-- Start  ------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
-- local track, fxnum, Preset_Name = Get_LastTouch_FX()                  -- any function can be used
-- Save_VST_Preset(track, fxnum, Preset_Name)                            -- RUN
local track, fxnum, Preset_Name = GetOpenFX ()
Save_VST_Preset(track, fxnum, Preset_Name)

PS: И ещё -
Использовать PresetIndex для номерации очередного пресета - не совсем хорошо.
Куча плагинов, которые передают свои Пресеты в оболочку Рипера и индекс очередной (Npt+1) может быть и 101 и 209 и т.д.. Но это не самое страшное, хотя и сбивает с толку - страшно когда Плагин передаёт очередной, выбранный, блок пресетов, а его кол-во формирует тот-же индекс, с которым Пресет уже сохранён.
Предлагаю использовать Nprsts (кол-во Пользовательских пресетов из ini файла), который уже вычесляется чуть позже у тебя в коде для того чтобы править "NbPresets".
Я подправил свой раздел кода -
PHP:
--[[
   * ReaScript Name: Save_FX_Preset
   * Lua script for Cockos REAPER
   * Author: EUGEN27771
   * Author URI: http://forum.cockos.com/member.php?u=50462
   * Licence: GPL v3
   * Version: 1.02
  ]]

  --------------------------------------------------------------------------------
  local msg = function(M) reaper.ShowConsoleMsg(tostring(M).."\n") end
  --------------------------------------------------------------------------------

--------------------------------------------------------------------------------
-- Base64_to_Hex(modded from lua.org functions)  -------------------------------
--------------------------------------------------------------------------------
-- decryption table --
local base64bytes = {['A']=0, ['B']=1, ['C']=2, ['D']=3, ['E']=4, ['F']=5, ['G']=6, ['H']=7, ['I']=8, ['J']=9, ['K']=10,['L']=11,['M']=12,
                     ['N']=13,['O']=14,['P']=15,['Q']=16,['R']=17,['S']=18,['T']=19,['U']=20,['V']=21,['W']=22,['X']=23,['Y']=24,['Z']=25,
                     ['a']=26,['b']=27,['c']=28,['d']=29,['e']=30,['f']=31,['g']=32,['h']=33,['i']=34,['j']=35,['k']=36,['l']=37,['m']=38,
                     ['n']=39,['o']=40,['p']=41,['q']=42,['r']=43,['s']=44,['t']=45,['u']=46,['v']=47,['w']=48,['x']=49,['y']=50,['z']=51,
                     ['0']=52,['1']=53,['2']=54,['3']=55,['4']=56,['5']=57,['6']=58,['7']=59,['8']=60,['9']=61,['+']=62,['/']=63,['=']=nil}
--------------------------------------------
-- Decode Base64 to HEX --------------------
--------------------------------------------
function B64_to_HEX(data)
  local chars  = {}
  local result = {}
  local hex
    for dpos=0, #data-1, 4 do
        -- Get chars -------------------
        for char=1,4 do chars[char] = base64bytes[(string.sub(data,(dpos+char), (dpos+char)) or "=")] end -- Get chars
        -- To hex ----------------------
        if chars[3] and chars[4] then
            hex = string.format('%02X%02X%02X',                                  -- if 1,2,3,4 chars
                                   (chars[1]<<2)       + ((chars[2]&0x30)>>4),   -- 1
                                   ((chars[2]&0xf)<<4) + (chars[3]>>2),          -- 2
                                   ((chars[3]&0x3)<<6) + chars[4]              ) -- 3
          elseif  chars[3] then
            hex = string.format('%02X%02X',                                      -- if 1,2,3 chars
                                   (chars[1]<<2)       + ((chars[2]&0x30)>>4),   -- 1
                                   ((chars[2]&0xf)<<4) + (chars[3]>>2),          -- 2
                                   ((chars[3]&0x3)<<6)                         )
          else
            hex = string.format('%02X',                                          -- if 1,2 chars
                                   (chars[1]<<2)       + ((chars[2]&0x30)>>4)  ) -- 1
        end
       ---------------------------------
       table.insert(result,hex)
    end
  return table.concat(result)
end

----------------------------------------
-- String_to_HEX  ----------------------
----------------------------------------
function String_to_HEX(Preset_Name)
  local VAL  = {Preset_Name:byte(1,-1)} -- to bytes, values
  local Pfmt = string.rep("%02X", #VAL)
  return string.format(Pfmt, table.unpack(VAL))
end

--------------------------------------------------------------------------------
-- FX_Chunk_to_HEX -------------------------------------------------------------
--------------------------------------------------------------------------------
-- Variant 1 ---------------------------
function FX_Chunk_to_HEX(FX_Type, FX_Chunk, Preset_Name)
  local Preset_Chunk = FX_Chunk:match("\n.*\n")        -- extract preset(simple var)

    ---------------------------------------
    -- For JS -----------------------------
    ---------------------------------------
    if FX_Type=="JS" then
       Preset_Chunk = Preset_Chunk:gsub("\n", "")      -- del "\n"
       --reaper.ShowConsoleMsg(Preset_Chunk..'\n')
       return String_to_HEX(Preset_Chunk..Preset_Name)
    end

    ---------------------------------------
    -- For VST ----------------------------
    ---------------------------------------
    local Hex_TB = {}
    local init = 1
    ---------------------
    for i=1, math.huge do
          line = Preset_Chunk:match("\n.-\n", init)    -- extract line from preset(simple var)
          if not line then
             --reaper.ShowConsoleMsg(Hex_TB[i-1].."\n")
             Hex_TB[i-1] = "00"..String_to_HEX(Preset_Name).."0010000000" -- Preset_Name to Hex(replace name from chunk)
             --reaper.ShowConsoleMsg(Hex_TB[i-1].."\n")
             break
          end
          ---------------
          init = init + #line - 1                      -- for next line
          line = line:gsub("\n","")                    -- del "\n"
          --reaper.ShowConsoleMsg(line.."\n")
          Hex_TB[i] = B64_to_HEX(line)
    end
    ---------------------
    return table.concat(Hex_TB)
end

-- Variant 2(without Name to Hex, simple var) ------
--[[
function FX_Chunk_to_HEX(FX_Type, FX_Chunk, Preset_Name)
  local Preset_Chunk = FX_Chunk:match("\n.*\n")   -- extract preset(simple var)
  ----------------------------------------
  Preset_Chunk = Preset_Chunk:gsub("\n","")       -- del "\n"
  if FX_Type=="JS" then return String_to_HEX(Preset_Chunk..Preset_Name)
     else return B64_to_HEX(Preset_Chunk)
  end
end
--]]

--------------------------------------------------------------------------------
-- Get_CtrlSum -----------------------------------------------------------------
--------------------------------------------------------------------------------
function Get_CtrlSum(HEX)
  local Sum = 0
  for i=1, #HEX, 2 do  Sum = Sum + tonumber( HEX:sub(i,i+1), 16) end
  return string.sub( string.format("%X", Sum), -2, -1 )
end

--------------------------------------------------------------------------------
-- Write preset to PresetFile --------------------------------------------------
--------------------------------------------------------------------------------
function Write_to_File(PresetFile, Preset_HEX, Preset_Name)
  local file, Presets_ini, Nprsts
  ----------------------------------------------------------
  -- Rewrite header(or create) -----------------------------
  ----------------------------------------------------------
    local ret_r, ret_w
    if reaper.file_exists(PresetFile) then
        -- BR function works faster than lua r,w --
        ret_r, Nprsts =  reaper.BR_Win32_GetPrivateProfileString("General", "NbPresets", "", PresetFile)
        Nprsts = math.tointeger(Nprsts)
        ------------------
        ret_w = reaper.BR_Win32_WritePrivateProfileString("General", "NbPresets", math.tointeger(Nprsts+1), PresetFile)
    else Nprsts = 0
         Presets_ini = "[General]\nNbPresets="..Nprsts+1
         file = io.open(PresetFile, "w")
         file:write(Presets_ini)
         file:close()
    end
  ----------------------------------------------------------
  -- Write preset data to file -----------------------------
  ----------------------------------------------------------
  file = io.open(PresetFile, "r+")
  file:seek("end")                        -- to end of file
  ------------------
  file:write("\n[Preset"..Nprsts.."]")    -- preset number(0-based)
  --------------------------------------
  --------------------------------------
  local Len = #Preset_HEX                 -- Data Lenght
  local s = 1
  local Ndata = 0
  for i=1, math.ceil(Len/32768) do
      if i==1 then Ndata = "\nData=" else Ndata = "\nData_".. i-1 .."=" end
      local Data = Preset_HEX:sub(s, s+32767)
      local Sum = Get_CtrlSum(Data)
      file:write(Ndata, Data, Sum)
      s = s+32768
  end
  --------------------------------------
  --- Preset_Name, Data Lenght ---------
  --------------------------------------
  file:write("\nName=".. Preset_Name .."\nLen=".. Len//2 .."\n")
  -------------------
  file:close()
end

--------------------------------------------------------------------------------
-- Get FX_Chunk and PresetFile  ------------------------------------------------
--------------------------------------------------------------------------------
function Get_FX_Data(track, fxnum)
  local fx_cnt = reaper.TrackFX_GetCount(track)
  if fx_cnt==0 or fxnum>fx_cnt-1 then return end       -- if fxnum not valid
  local ret, Track_Chunk =  reaper.GetTrackStateChunk(track,"",false)
  --reaper.ShowConsoleMsg(Track_Chunk)

  ------------------------------------
  -- Find FX_Chunk(use fxnum) --------
  ------------------------------------
  local s, e = Track_Chunk:find("<FXCHAIN")            -- find FXCHAIN section
  -- find VST(or JS) chunk
  for i=1, fxnum+1 do
      s, e = Track_Chunk:find("<%u+%s.->", e)
  end
    ----------------------------------
    -- FX_Type -----------------------
    local FX_Type = string.match(Track_Chunk:sub(s+1,s+3), "%u+")   -- FX Type
    if not(FX_Type=="VST" or FX_Type=="JS") then return end         -- Only VST and JS supported
    ----------------------------------
    -- extract FX_Chunk --------------
    local FX_Chunk = Track_Chunk:match("%b<>", s)      -- FX_Chunk(simple var)
    ----------------------------------
    --reaper.ShowConsoleMsg(FX_Chunk.."\n")

  ------------------------------------
  -- Get UserPresetFile --------------
  ------------------------------------
  local PresetFile = reaper.TrackFX_GetUserPresetFilename(track, fxnum, "")
  ------------------------------------
  return FX_Type, FX_Chunk, PresetFile
end

--------------------------------------------------------------------------------
-- Main function  --------------------------------------------------------------
--------------------------------------------------------------------------------
function Save_VST_Preset(track, fxnum, Preset_Name)
  if not (track and fxnum and Preset_Name) then return end       -- Need track, fxnum, Preset_Name
  local FX_Type, FX_Chunk, PresetFile = Get_FX_Data(track, fxnum)
  --reaper.ShowConsoleMsg(FX_Chunk..'\n')
  -----------
  if FX_Chunk and PresetFile then
     local start_time = reaper.time_precise()
     local Preset_HEX = FX_Chunk_to_HEX(FX_Type, FX_Chunk, Preset_Name)
     --reaper.ShowConsoleMsg("Processing time = ".. reaper.time_precise()-start_time ..'\n') -- time test
     local start_time = reaper.time_precise()
     Write_to_File(PresetFile, Preset_HEX, Preset_Name)
     --reaper.ShowConsoleMsg("Write time = ".. reaper.time_precise()-start_time ..'\n') -- time test
     reaper.TrackFX_SetPreset(track, fxnum, Preset_Name) -- For "update", but this is optional
  end
end

----------------------------------------------------------------------------------------------------
-- GetLastTouchedFX  -------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
function Get_LastTouch_FX()
  local retval, tracknum, fxnum = reaper.GetLastTouchedFX()           -- fxnum
  if not retval then return end
  local track = reaper.GetTrack(0, tracknum-1)                        -- track(trackID)
  local Pidx, Npt = reaper.TrackFX_GetPresetIndex(track, fxnum)
  local  Preset_Name = "New "..Npt+1                                  -- New Preset_Name
  return track, fxnum, Preset_Name
end
----------------------------------------------------------------------------------------------------
-- GetOpenFX ---------------------------------------------------------------------------------------
function GetOpenFX ()
  local counttracks = reaper.CountTracks(0)
  if counttracks == nil then return tracksX end
  for i=1, counttracks do
    local tr = reaper.GetTrack(0,i-1)
    if tr ~= nil then
      local CountFX = reaper.TrackFX_GetCount( tr )
      for i=1, CountFX do
        local tt = reaper.TrackFX_GetFloatingWindow(tr, i-1)
        if tt then
          local track = tr
          local fxnum = i-1
          local PresetFile = reaper.TrackFX_GetUserPresetFilename(track, fxnum, "")
          if reaper.file_exists(PresetFile) then
            ret_r, Nprsts =  reaper.BR_Win32_GetPrivateProfileString("General", "NbPresets", "", PresetFile)
            Nprsts = math.tointeger(Nprsts)
          else
            Nprsts = 0
          end
          local Pidx, Npt = reaper.TrackFX_GetPresetIndex(tr, i-1)
          local Preset_Name = "New "..Nprsts+1                                  -- New Preset_Name
          return track, fxnum, Preset_Name
        end
      end
    end
  end

end
-- Start  ------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
-- local track, fxnum, Preset_Name = Get_LastTouch_FX()                  -- any function can be used
-- Save_VST_Preset(track, fxnum, Preset_Name)                            -- RUN
local track, fxnum, Preset_Name = GetOpenFX ()
Save_VST_Preset(track, fxnum, Preset_Name)
 
Последнее редактирование:
  • Like
Реакции: lil-burn

lil-burn

Well-Known Member
15 Авг 2012
903
638
93
Екатеринбург
Au to Rea 0.5
скрипт переводит сессию Adobe Audition в текущий проект рипера.
в данной версии:
! - работает пока только с xml-файлами, сохраненными с помощью Audition 3
! - при переводе сохраняются пока только положения клипов в проекте
- каждый аудио-клип добавляется в рипер в качестве айтема на новый трек (пока так)
- скрипт должен работать с кириллицей в названиях папок и файлов (хотя не факт, что во всех случаях)

как работает скрипт:
1. в буфер обмена копируется путь к папке, которая (обязательно) содержит .xml файл сессии Au и все необходимые аудиофайлы
2. в рипере запускается скрипт Au to Rea 0.5, после чего появляется окно, куда вставляем содержимое буфера (путь к папке с xml файлом). Жмем "Ок"
3. Ждем несколько секунд и, собственно, все.
Au to Rea 0.5.gif
 

abrokadabra2

Member
2 Дек 2014
85
16
8
temirtau
прикольная тема такое жэ чтобы в кубе работешь надо раз и перепрыгнул в рипер и наоборот в куб было бы кайф
 

Levanter

New Member
21 Окт 2008
4
1
3
@EUGEN27771, спасибо за Render selected item as new take, up to last VSTi и
Render selected item on new track, up to last VSTi Делаю очередную попытку перейти с Logic на Reaper. Если можно добавьте, пожалуйста, к Render selected item as new take, up to last VSTi bypass fx 01 и сохранение в треке миди тейка в мют режиме. Еще, с Render selected item on new track, up to last VSTi можно убрать все инсерт плагины в новом треке?
 
Последнее редактирование:
  • Like
Реакции: stepperian

SKlogic

Well-Known Member
14 Май 2006
3.126
1.208
113
46
Moscow
sergeykuptsov.com
Он так и делает вроде. Сохрагяет айтем в мьют. А если нужен весь трек-посмотри старндартные фриз опции. И в новом треке никаких игсертов не. Вы точно эти скрипты запускаете???
 

Levanter

New Member
21 Окт 2008
4
1
3
@SKlogic, в Render selected item as new take, up to last VSTi миди айтом изчезает и все инсерты на треке активны. Может из за того, что я на маке скрипт юзаю?
Хотелось бы, чтобы миди аитом остался в мюте на том же треке а синт в первом слоте инсертов перешел в байпас.
 

Aleksandr Oleynik

Well-Known Member
16 Янв 2007
26.360
20.063
113
62
Киев
Скрипт, который создаёт трэк с именем Drum Bus (можно в скрипте поменять), если его ещё нет в проекте, и делает его Фолдером для всех треков в имени которых есть перечисленные в скрипте слоги (можно менять и/или добовлять). А также раскрашивает всё в первый кастомный цвет - нужно задать заранее через экшин SWS Open color management window>Set custom color.
Скрипт также добовляет в фолдер любой новый трек с именем отвечающим указанным слогам.
В начале кода скрипта есть раздел -
--- Блок параметров, которые задаются (можно менять) -----
В строке -
PHP:
local parent_name = "Drum Bus"
задаётся имя Трек-Фолдера
в строке -
PHP:
local patern_children = {"tom", "hat", "snare", "over" }
через запятую в кавычках задаются слоги, за которыми следим.

в строке -
PHP:
local mcpLayoutNameIn = "Big Meter"
задаётя лайаут в микшере для Трек Фолдера, брать из Темы в файле rtconfig.txt

в строке -
PHP:
local tcpLayoutNameIn = ""
задаётя лайаут в окне аранжа для Трек Фолдера, брать из Темы в файле rtconfig.txt, если указать пустые кавычки - будет выбран лайаут по умолчанию


Скрипт не рушит роутинг трэков, сохраняет на них все отстроенные плагины и не перемещает Трэк-Фолдер, если он уже создан.

PS: Добавил deffer версию скрипта. Запущенный один раз он постоянно следит за проектом, и если возникает в нём новый трек с именем, совпадающим со слогом отслеживаемым - он его сразу забрасывает в папку

PSS: Добавил возможность создания любого кол-ва пар - Парент - Чилдрен
задаются в той-же секции -
--- Блок параметров, которые задаются (можно менять) -----
В скрипте пример для двух пар -

PHP:
local parent_name_1 = "Drum Bus"
local patern_children_1 = {"tom", "hat", "snare", "over", "drum" }

local parent_name_2 = "Vox Bus"
local patern_children_2 = {"lead vox", "back vox", "vox" }

t = {}
t[parent_name_1] = patern_children_1
t[parent_name_2] = patern_children_2

Чтоб добавить формирование Трек Фолдера и чилдренов для, например, секции гитар, нужно написать так -
PHP:
local parent_name_1 = "Drum Bus"
local patern_children_1 = {"tom", "hat", "snare", "over", "drum" }

local parent_name_2 = "Vox Bus"
local patern_children_2 = {"lead vox", "back vox", "vox" }

local parent_name_3 = "GTR Bus"
local patern_children_3 = {"lead gtr", "back gtr", "gtr" }

t = {}
t[parent_name_1] = patern_children_1
t[parent_name_2] = patern_children_2
t[parent_name_3] = patern_children_3

В атаче архив с двумя скриптами - разового действия и с дефером (который висит в фоне и следит за проектом)

PSS: Очередная версия v3
Исправлена работа с регистром, исправлена работа с цветом, сделано так: что BUS-ы не создаются, если нет для них ни одного чилдрен трека в проекте.
Другие мелкие исправления.
PSSS: Сделаны исправления по работе с разгруженной папкой v4
 

Вложения

Последнее редактирование:

Aleksandr Oleynik

Well-Known Member
16 Янв 2007
26.360
20.063
113
62
Киев
Два скрипта, которые вешаются на хот кеи и отвечают за -
(для миди) - SWS/FNG: Transpose selected MIDI items up/down octave,
(для аудио) Xenakios/SWS: Nudge item pitch up/down.
При этом скрипт понимает миди ли это айтем или аудио и применяет верный транспоуз
 

Вложения

Последнее редактирование:

convex

без понтов
25 Фев 2011
4.578
4.208
113
42
Красноярский край
Обратите внимание, пользователь заблокирован на форуме.
этак мы и скрипт, пишущий хиты и сводящий на грэмми, скоро затребуем :D
 
  • Like
Реакции: Ivan_k26

Aleksandr Oleynik

Well-Known Member
16 Янв 2007
26.360
20.063
113
62
Киев
Не забыл, цвет каждой папки соответсвует ячейке кастом колора SWS - до 16.
PS: подправил описание.
 
Последнее редактирование:
  • Like
Реакции: stepperian

Martin111

Member
18 Фев 2015
482
20
18
53
@Aleksandr Oleynik, а как тогда горячие клавиши на раскраску делать ?
[DOUBLEPOST=1468231487][/DOUBLEPOST]У меня не все 16 заняты, просто интересно, вдруг со временем папок будет становиться больше.
 

Aleksandr Oleynik

Well-Known Member
16 Янв 2007
26.360
20.063
113
62
Киев
@Martin111, Я не до конца понимаю чего вы хотите.
Жёстко в скрипте прописать ОДИН цвет для всех папок и их чилдренов?
 

Martin111

Member
18 Фев 2015
482
20
18
53
Хочется чтобы не было привязки к ячейкам, что бы покрасить папку в один цвет, а уходящие в неё оставались дефолтными. Тоесть чтобы была возможность работать с палитрой как с обычными папками.
 

Aleksandr Oleynik

Well-Known Member
16 Янв 2007
26.360
20.063
113
62
Киев
Хочется чтобы не было привязки к ячейкам, что бы покрасить папку в один цвет
все папки и Drum BUS и VOX BUS и GTR BUS - одним заданным в скрите цветом?

а уходящие в неё оставались дефолтными
что такое дефолтными? т.е. чилдрены оставались серыми, не красились в цет папки?

Тоесть чтобы была возможность работать с палитрой как с обычными папками.
Это вообще не понял. :(
 

Martin111

Member
18 Фев 2015
482
20
18
53
Да, чтобы чилдрены оставались серыми !
[DOUBLEPOST=1468238022][/DOUBLEPOST]Сейчас когда все уходит в Bus все становится одного цвета, допустим если bus папку хочу сделать яркой, чилдрены автоматически становятся такими же, а я хочу чтобы чилдрены оставались серыми.
 

stepperian

Active Member
20 Окт 2005
184
34
28
Au to Rea 0.5
скрипт переводит сессию Adobe Audition в текущий проект рипера.
в данной версии:
! - работает пока только с xml-файлами, сохраненными с помощью Audition 3
! - при переводе сохраняются пока только положения клипов в проекте
- каждый аудио-клип добавляется в рипер в качестве айтема на новый трек (пока так)
- скрипт должен работать с кириллицей в названиях папок и файлов (хотя не факт, что во всех случаях)

как работает скрипт:
1. в буфер обмена копируется путь к папке, которая (обязательно) содержит .xml файл сессии Au и все необходимые аудиофайлы
2. в рипере запускается скрипт Au to Rea 0.5, после чего появляется окно, куда вставляем содержимое буфера (путь к папке с xml файлом). Жмем "Ок"
3. Ждем несколько секунд и, собственно, все.
Посмотреть вложение 117584
Это дает уже первые шаги к колобрации проекта , думаю можно сделать так что бы было 2 участника работающие над одним проектом с двух компьютеров. как бы фишка в том что бы подгружать семплы или миди в проект не выходя их него ) обмен можно сделать в виде файла , а может еще проще )
 

Сейчас онлайн (Пользователей: 0, Гостей: 3)