Михаил, не обычный синтаксис.Поскольку TrackFX_GetInstrument() возвращает индекс первого инструмента, а инструментов может быть несколько, то можно использовать что-то в духе
PHP:function IsInstrument(track, fx) return ({reaper.TrackFX_GetFXName( track, fx, '' )})[2]:match('[%u]+i%:')~= nil end tr = reaper.GetSelectedTrack(0,0) is_FX_instrument = IsInstrument(tr,0)
({reaper.TrackFX_GetFXName( track, fx, '' )})[2]
local types = {"WAVE", "MIDI", "MP3", "FLAC", "VIDEO", "VORBIS", "WMA", "OPUS", "APE", "CLICK", "REX", "RPP"}
local track = reaper.GetSelectedTrack(0, 0)
local track_chunk, source, wave
local exist = {}
local input_msg = 'Specify the number of channels:'
local err_msg = 'Something went wrong'
local nf_msg = 'One or more source file(s) was not found. Do you want unfreeze the track anyway?'
local unfrz_msg = [[
Unfreeze track and delete freezed files from disc?
(Press "No" if you want to freeze track once more)
]]
---------------------------------------------------
function eugen27771_GetTrackStateChunk(track)
local fast_str = reaper.SNM_CreateFastString("")
if reaper.SNM_GetSetObjectState(track, fast_str, false, false) then
track_chunk = reaper.SNM_GetFastString(fast_str)
end
reaper.SNM_DeleteFastString(fast_str)
return track_chunk
end
---------------------------------------------------
function get_sources()
local t = {}
track_chunk = eugen27771_GetTrackStateChunk(track)
local ch_open, ch_cnt, it_id = false, 0, 0
for line in track_chunk:gmatch('[^\n\r]+') do
if line:match('<FREEZE') then ch_open = true end
if ch_open and line:match('<ITEM') then it_id = it_id + 1 end
if ch_cnt > 0 then
if not t[it_id] then t[it_id] = {} end
t[it_id][#t[it_id]+1] = line
end
if ch_open and line:match('<') then ch_cnt = ch_cnt + 1 end
if ch_open and line:match('>') then ch_cnt = ch_cnt - 1 end
if ch_open and ch_cnt < 1 then break end
end
local sources = t
for key in pairs(sources) do
local ch = table.concat(sources[key], '\n')
source = tostring(ch:match('<SOURCE %w+')):sub(9)
if source == "" then source = "EMPTY" end
if source ~= "MIDI" and source ~= "LTC" and source ~= "EMPTY" then
local filename = tostring(ch:match('FILE %C+')):sub(7)
filename = filename:gsub('"%s*%d*', "")
local file_exists = reaper.file_exists(filename)
if source == "CLICK" then file_exists = true end
table.insert(exist, tostring(file_exists))
wave = 1
end
if source == "MIDI" then wave = 1 end
end
end
---------------------------------------------------
function frz()
local t = {}
for i = 0, reaper.CountTrackMediaItems(track) - 1 do
local item = reaper.GetTrackMediaItem(track, i)
local take = reaper.GetActiveTake(item)
if take then
local src = reaper.GetMediaItemTake_Source(take)
source = reaper.GetMediaSourceType(src, "")
if source == "RPP_PROJECT" then source = "RPP" end
else
source = "EMPTY"
end
table.insert(t, source)
end
local c = table.concat(types)
for key, val in pairs(t) do
local finds = c:find(val)
if finds then wave = 1 break end
end
if not wave then return end
local retval, chan = reaper.GetUserInputs("Channels", 1, input_msg, '')
chan = tonumber(chan)
if chan == 1 then
reaper.Main_OnCommand(40901, 0) -- freeze to mono
elseif chan == 2 then
reaper.Main_OnCommand(41223, 0) -- freeze to stereo
elseif chan == 3 then
reaper.Main_OnCommand(40877, 0) -- freeze to multichannel
else
return
end
end
---------------------------------------------------
function Ident(bool)
local t = {}
local ident
for line in track_chunk:gmatch('[^\n\r]+') do
fr = line:match('FREEZE %d.+')
if fr then table.insert(t, fr) end
end
local item_count = reaper.CountTrackMediaItems(track)
for k = #t - item_count, #t - 1 do
local pos_len = t[k+1]:match('%d.+%s'):gsub(" ", "$")
pos_len = pos_len:sub(1, #pos_len - 1)
local pos = pos_len:match('(.*($))')
pos = ('%.4f'):format(pos:sub(1, #pos - 1))
local len = pos_len:match('(($).*)')
len = ('%.4f'):format(len:sub(2))
local item = reaper.GetTrackMediaItem(track, k - #t + item_count)
local it_pos = ('%.4f'):format(reaper.GetMediaItemInfo_Value(item, "D_POSITION"))
local it_len = ('%.4f'):format(reaper.GetMediaItemInfo_Value(item, "D_LENGTH"))
if tonumber(pos) == tonumber(it_pos) and tonumber(len) == tonumber(it_len) then
ident = true
else
ident = false
reaper.MB(err_msg, "Error", 0)
return
end
end
return ident
end
function unfrz()
reaper.PreventUIRefresh(-1)
reaper.SelectAllMediaItems(0, 0)
for i = 0, reaper.CountTrackMediaItems(track) - 1 do
local item = reaper.GetTrackMediaItem(track, i)
reaper.SetMediaItemSelected(item, 1)
reaper.Main_OnCommand(40440, 0) -- set offline
end
local con = table.concat(exist)
local not_found = tostring(con):find("false")
if not_found and source ~= "RPP" then
local dialog = reaper.MB(nf_msg, "Warning", 4)
if dialog == 6 then
reaper.Main_OnCommand(reaper.NamedCommandLookup("_S&M_DELTAKEANDFILE2"), 0)
reaper.Main_OnCommand(41644, 0) -- unfreeze
else
reaper.SelectAllMediaItems(0, 0)
end
else
reaper.Main_OnCommand(reaper.NamedCommandLookup("_S&M_DELTAKEANDFILE2"), 0)
reaper.Main_OnCommand(41644, 0) -- unfreeze
end
reaper.PreventUIRefresh(1)
end
---------------------------------------------------
function Main()
local sel_track = reaper.CountSelectedTracks(0)
if sel_track ~= 1 then return end
local freeze = reaper.BR_GetMediaTrackFreezeCount(track)
if freeze ~= 0 then
get_sources()
if wave == 1 then
local dialog = reaper.MB(unfrz_msg, "Unfreeze", 3)
if dialog == 6 then
Ident(bool)
unfrz()
elseif dialog == 7 then
frz()
end
else
reaper.Main_OnCommand(41644, 0) -- unfreeze
end
else
frz()
end
end
Main()
Сделаю отдельную версию. Лично я частенько фрижу в моно определённые треки.Мое видение, лучше убрать все всплывающие запросы сделать три варианта моно/стерео/multi (редко фризиться в моно, в основном Vsti в стерео).
Это, конечно, многое упрощает. Но многократная заморозка - это одна из главных фишек риперовского фриза и может быть очень полезной на слабых машинах. Поэтому я предусмотрел и такой вариант. В принципе, чем он мешает? Захотели расфризить - жмите "да", если передумали - "отмена". Конечно, кнопка "нет" может ввести в заблуждение, особенно если работать в спешке и не читать сообщение в диалоге.На выход из фриза убрать запрос на повторный фриз он незачем. (Проще нажал скрипт, если трек не зафризен - то зафризеть его, а если зафризен разфризеть)
Они при разморозке же вроде бы и так никуда не деваются.Операции с зафризеным треком, лучше не производить кроме как добавления в FX нового плагина и то в исключительных мерах).При разморозке копировать добавленные Fxсы, и добавлять их в цепочку размороженного.
Да протупилОни при разморозке же вроде бы и так никуда не деваются.
Да протестил и действительно прикольно. Но все же ходелось бы резные варианты МultiFreeze (с запросами) и SingleFreez (робота в два клика) А так Браво!!!!!!!!!!Но многократная заморозка - это одна из главных фишек риперовского фриза и может быть очень полезной на слабых машинах
action: Go to end of time selectionИщу скрипт, который поместит Edit cursor в конец Time Selection или в конец лупа.
script by me2beats: Move cursor to nearest grid divisionэкшн, который притянет Edit Cursor к ближайшей Grid Line
С Folder треками не работает@CerberPic, Спасибо Замечательно. Я сделал себе 4 варианта
Вот еще бы к Вашей коллекции smart freez-unfreez Vsti Instrument (only)...........
action: Go to end of time selection
action: Go to end of loop
Я скрипты в рипер изучаю недавно, мало понимаю, но предыдущий опыт подсказывает, что должно быть какое-то простое и оригинальное решение. Например, в lua вроде есть возможность выполнять внешние приложения, точно не знаю работает-ли это в окружении рипера. Если да, т с файлами можно делать все что угодно посредством командной строки. Но важно понимать на каком этапе возникают проблемы с кириллицей. Если есть возможность запустить например внешний батник, то ему можно передать имена в бинарном виде, а там преобразовать их и произвести необходимые операции. Ну в общем ход мыслей ясен...работает, но не выполняет главную функцию - удаление фризов с диска.
Так, пресеты-таки. По крайней мере для обучения - вещь невероятная.
Сами настройки очень близки к ReaComp, поэтому я прикинул, что их можно на ReaComp и выставить спец. кнопочкой.
Мне нравится.
Посмотреть вложение 139744
Да, фолдеры-то я не учёл. Теперь всё должно работать (обе версии во вложении).С Folder треками не работает
Ну, значит, первая, оригинальная версия делает следующее:Опишите детально пожалуйста, что делает ваш скрипт, в чем его особенность?
Я говорил на эту тему с Михаилом. Он сказал, что удалять при помощи экшна от SWS предпочтительнее, чем командной строкой. Хотя бы потому что там учтены все варианты - вывод в оффлайн, удаление в корзину... Я пробовал оба метода, проблемы с кириллицей возникают в обоих случаях, SWS при этом ещё выдаёт уведомление о том, что файл не был удалён. Вообще работа с консолью посредством lua в рипере организована как-то кривовато, как мне показалось.Я скрипты в рипер изучаю недавно, мало понимаю, но предыдущий опыт подсказывает, что должно быть какое-то простое и оригинальное решение. Например, в lua вроде есть возможность выполнять внешние приложения, точно не знаю работает-ли это в окружении рипера. Если да, т с файлами можно делать все что угодно посредством командной строки.
Внешний батник - отдельный исполняемый процесс, отдельный файл, который нужно будет скачивать пользователю для того, чтобы опробовать скрипт, класть в определённую директорию... И неизвестно, к каким дополнительным траблам может привести такой метод. Вопрос: зачем всё это, если можно просто избегать кириллицы в путях?Если есть возможность запустить например внешний батник, то ему можно передать имена в бинарном виде, а там преобразовать их и произвести необходимые операции
Я себе сделал все три версииВторая версия (та, что no dialog, stereo only) сделана по просьбе @Maestro Sound и работает попеременно - фриз/анфриз
В разумных пределах все может вмещаться в одну командную строку. При необходимости все дополнительные файлы генерируются скриптом и им-же удаляются.Внешний батник - отдельный исполняемый процесс, отдельный файл, который нужно будет скачивать пользователю для того, чтобы опробовать скрипт, класть в определенную директорию...
Как минимум работать будет только на Windows, а это уже немаленькое ограничение.И неизвестно, к каким дополнительным траблам может привести такой метод.
Еще со времен MS-DOS привык избегать пробелов и кириллицы)Вопрос: зачем всё это, если можно просто избегать кириллицы в путях?
Спасибо! Уже начал осваивать потихоньку. Закончил эксперименты с курсором, перехожу к маркерам.Начинайте, помогу.
Приехали!!!....... а говорили что скриптом все можноНа перемещение треков, FX-ов нет ни API ни Экшинов ни стандартных команд.
Можно. Вы же не об этом спросили, а об API.Приехали!!!....... а говорили что скриптом все можно
Я выше приводил пример какие экшены мне нужно заменить скриптом. Подробно, сам пока не понимаю до конца алгоритма. прежде чем составлять алгоритм, нужно знать возможности среды в которой предполагается реализация. В моем случае изучение данной среды происходит параллельно с разработкой алгоритма. Учусь на предмете, так-сказать.опишите подробнее что должен скрипт делать.
Про дефер интересно.В общих чертах есть два типпа скриптов - разово срабатывающих и с дефером.
Как происходит механизм остановки скрипта пользователем? Как это событие определяется в скрипте? Скрипт-же не принимает параметры, что-бы создавать разные кнопки с командами запуска-остановки например. Предполагаю, что останавливать можно по событию повторного запуска. Или есть механизм принудительной остановки скрипта из вне в рипере?С дефером - работает либо пока его не остановит пользователь
Очень просто - ещё раз "запускаете" скрипт или нажимаете его кнопку на тулбаре.Как происходит механизм остановки скрипта пользователем?
Так это не работает - нужно менять условия - т.е. синтаксис.в строке
reaper.TrackFX_SetEnabled(track, i-1, 1 ) -- Unbypass FX
reaper.TrackFX_SetEnabled(track, i-1, 0 ) -- Bypass FX
мне нужно поменять что бы удалял Vsti какой сюда Api вставить?