function Main( take )
retval, notes, ccs, sysex = reaper.MIDI_CountEvts( take )
-- GET SELECTED NOTES (from 0 index)
for k = 0, notes - 1 do
local retval, sel, muted, startppq, endppq, chan, pitch, vel = reaper.MIDI_GetNote( take, k )
if sel then
reaper.ShowConsoleMsg("note selected")
-- ACTION HERE
end
end
end
-------------------------------
-- INIT
-------------------------------
take = reaper.MIDIEditor_GetTake( reaper.MIDIEditor_GetActive() )
if take then
Main( take ) -- Execute your main function
reaper.UpdateArrange() -- Update the arrangement (often needed)
end -- ENDIF Take is MIDI
function Main( take )
retval, notes, ccs, sysex = reaper.MIDI_CountEvts( take )
-- GET SELECTED NOTES (from 0 index)
for k = 0, notes - 1 do
local retval, sel, muted, startppq, endppq, chan, pitch, vel = reaper.MIDI_GetNote( take, k )
if sel then
reaper.ShowConsoleMsg("selected_notes".."\n")
-- ACTION HERE
else
reaper.ShowConsoleMsg("not_selected_notes".."\n")
end
end
end
-------------------------------
-- INIT
-------------------------------
take = reaper.MIDIEditor_GetTake( reaper.MIDIEditor_GetActive() )
if take then
Main( take ) -- Execute your main function
reaper.UpdateArrange() -- Update the arrangement (often needed)
end -- ENDIF Take is MIDI
---------------------------------------------------------------------------------------------------------
local msg = function(M) reaper.ShowConsoleMsg(tostring(M).."\n") end
---------------------------------------------------------------------------------------------------------
function Main (take)
retval, notes, ccs, sysex = reaper.MIDI_CountEvts( take )
-- GET SELECTED NOTES (from 0 index)
for k = 0, notes - 1 do
local retval, sel, muted, startppq, endppq, chan, pitch, vel = reaper.MIDI_GetNote( take, k )
if sel then
msg((k+1).." selected_notes".."\n")
-- IF SELECTED - ACTION HERE
break
else
if (notes - 1) == k then
msg((k+1).." not_selected_notes".."\n")
-- IF NOT SELECTED - ACTION HERE
end
end
end
end
-- INIT
take = reaper.MIDIEditor_GetTake( reaper.MIDIEditor_GetActive() )
if take then
Main (take) -- Execute your main function
reaper.UpdateArrange() -- Update the arrangement (often needed)
end
@Aleksandr Oleynik, А как получить количество сработанных циклов?если кол-во циклов совпало с кол-вом нот
А вот выше код написал.@Aleksandr Oleynik, А как получить количество сработанных циклов?
---------------------------------------------------------------------------------------------------------
local msg = function(M) reaper.ShowConsoleMsg(tostring(M).."\n") end --Переменная для последующего сокращения функции
---------------------------------------------------------------------------------------------------------
function Main (take) -- Начало описания главной функции
retval, notes, ccs, sysex = reaper.MIDI_CountEvts( take ) --Поддсчет количества нот
for k = 0, notes - 1 do --Задаем переменные для к и notes
local retval, sel, muted, startppq, endppq, chan, pitch, vel = reaper.MIDI_GetNote( take, k ) --Берем выделеные ноты
if sel then --Если есть выделеные ноты (проходит все ноты если есть выделеные выдает одно сообщение и прерываеться
msg((k+1).." selected_notes".."\n") --Выводим сообщение ноты выделены
-- IF SELECTED - ACTION HERE
break --прерываемся
else --или же
if (notes - 1) == k then -- смотрим выше если notes(количество нот равно нулю)
msg((k+1).." not_selected_notes".."\n") ---То выводим сообщение что ничего не выделено
-- IF NOT SELECTED - ACTION HERE
end
end
end
end
-- INIT
take = reaper.MIDIEditor_GetTake( reaper.MIDIEditor_GetActive() ) --Проверяет активен ли миди редактор
if take then --Если есть значение выполняем основную функцию
Main (take) -- Выполнение функции
reaper.UpdateArrange() -- Update the arrangement (often needed) --Обновление аражировки для отображения действий
end
----------------------------------------------------------------
local msg = function(param)reaper.ShowConsoleMsg(param.."\n")end
----------------------------------------------------------------
take = reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive()) --Получить миди редактор активного тейка
if take == nil then return end --если миди редактор закрыт то дальше не продолжать
retval,count_notes,ccs,sysex = reaper.MIDI_CountEvts(take) --Получить количество нот
for i = 1,count_notes do --Создаем цикл опроса по каждой ноте
local retval, sel, muted, startppq, endppq, chan, pitch, vel = reaper.MIDI_GetNote(take,i-1)--Получаем ноту и её состояние
if sel then msg(i.."notes_selection") break --Если нота выделенна то (msg)("notes_selection")и сломать цикл опроса
elseif count_notes == i then msg(i.."not_selected_notes") --Если количество нот == количеству цикла опроса то (msg)("not_selected_notes")
end
end
Нет. Способ записи кода ни как не влияет на производительнось. Код либо работает - либо нет.Кстати заметил что например скрипты kawa с удаленными пробелами все в одну строку как бы. Добавляет ли это проиводительности в реальности?
Почти всегда можно сделать лучше и проще, но на это ни какой жизни не хватит, по этому - первое найденное работающее решение и есть самым вернымИ возможно ли было это сделать проще? Получить значение из фунции reaper.MIDI_GetNote и использовать как то его через true и false?
isSet = reaper.GetSet_LoopTimeRange( 0, 0, 0, 0, 0 ) -- Даем переменную "Time selection"
focus = reaper.GetCursorContext() -- Даем переменную значения где сейчас фокус?
if focus == 0 then
reaper.Main_OnCommand(40697, 0) --если фокус на треках то даем команду стереть трек
elseif isSet == 0 and focus == 1 then
reaper.Main_OnCommand(40697, 0) -- если нет "Time selection" и фокус на "Items" стираем выделеные "Items"
elseif isSet == 0 and focus == 2 then
reaper.Main_OnCommand(40697, 0) -- если нет "Time selection" и фокус на "Envelope" стираем выделенную точку
elseif isSet > 0 and focus == 1 then
reaper.Main_OnCommand(reaper.NamedCommandLookup('_XENAKIOS_TSADEL'),0 ) --Если есть "Time selection" и фокус на "Items" стираем у выделенныйх "Items" только то что в "Time selection"
elseif isSet > 0 and focus == 2 then
reaper.Main_OnCommand(40089, 0) --Если есть "Time selection" и фокус на "Envelopes стираем группу точек в "Time selection""
end
isSet = reaper.GetSet_LoopTimeRange( 0, 0, 0, 0, 0 ) -- Берём переменную "Time selection"
focus = reaper.GetCursorContext() -- Берём переменную значения где сейчас фокус?
if isSet == 0 then
reaper.Main_OnCommand(40697, 0)
else
if focus == 1 then
reaper.Main_OnCommand(reaper.NamedCommandLookup('_XENAKIOS_TSADEL'), 0)
elseif focus == 2 then
reaper.Main_OnCommand(40089, 0)
end
end
isSet = reaper.GetSet_LoopTimeRange( 0, 0, 0, 0, 0 ) -- Берём переменную "Time selection"
focus = reaper.GetCursorContext() -- Берём переменную значения где сейчас фокус?
midieditor = reaper.MIDIEditor_GetActive()
if midieditor then
if isSet == 0 then
reaper.MIDIEditor_OnCommand(midieditor, 40002)
else
reaper.MIDIEditor_OnCommand(midieditor, 40214)
reaper.MIDIEditor_OnCommand(midieditor, 40746)
reaper.MIDIEditor_OnCommand(midieditor, 40002)
end
else
if isSet == 0 then
reaper.Main_OnCommand(40697, 0)
else
if focus == 1 then
reaper.Main_OnCommand(reaper.NamedCommandLookup('_XENAKIOS_TSADEL'), 0)
elseif focus == 2 then
reaper.Main_OnCommand(40089, 0)
end
end
end
isSet = reaper.GetSet_LoopTimeRange( 0, 0, 0, 0, 0 ) -- Берём переменную "Time selection"
focus = reaper.GetCursorContext() -- Берём переменную значения где сейчас фокус?
midieditor = reaper.MIDIEditor_GetActive()
if isSet == 0 then
if midieditor then
reaper.MIDIEditor_OnCommand(midieditor, 40002)
else
reaper.Main_OnCommand(40697, 0)
end
else
if midieditor then
reaper.MIDIEditor_OnCommand(midieditor, 40214)
reaper.MIDIEditor_OnCommand(midieditor, 40746)
reaper.MIDIEditor_OnCommand(midieditor, 40002)
else
if focus == 1 then
reaper.Main_OnCommand(reaper.NamedCommandLookup('_XENAKIOS_TSADEL'), 0)
elseif focus == 2 then
reaper.Main_OnCommand(40089, 0)
end
end
end
Да очень увлекательное это занятие, Рипер рано или поздно склонит тебя писать скрипты)Поздравляю!
В нашем полку прибыло?
Красивенько!И удобно! Надо будет себе поставить что бы глаза не разбегались)Вот на примере этого скрипта покажу как форматирует код Atom (поставили в него модуль LUA, и по нажатию шотката Shift+Control+I получаем верно отформатированный код) -
И сразу видно, где начинается и где заканчивается выражение (начинается в строке 8 с if и заканчивается end-ом в строке 18).
Ошибся, прошу прощения но я только начинаю многие вещи пока наугад.Функции с Get дают переменную, но в коментах наверное логичней писать - берём переменную.
Да точно это я не учел,- так намного компактней и красивей!) Первый скрипт слегка комом)Теперь, что касается оптимизации кода -
Экшин 40697 уже контекстно зависим от фокуса и ему не нужны доп условия зависящие от фокуса, он их и так понимает, а значит можно сильно упростить код -
PHP:isSet = reaper.GetSet_LoopTimeRange( 0, 0, 0, 0, 0 ) -- Берём переменную "Time selection" focus = reaper.GetCursorContext() -- Берём переменную значения где сейчас фокус? if isSet == 0 then reaper.Main_OnCommand(40697, 0) else if focus == 1 then reaper.Main_OnCommand(reaper.NamedCommandLookup('_XENAKIOS_TSADEL'), 0) elseif focus == 2 then reaper.Main_OnCommand(40089, 0) end end
Отличная идея! Вы уже две модификации сделали и продумали наперед Миди редактор. Я его как то упустил что в "Time Selection" нужно будет тоже ноты стирать.Ну и наверное стоит развить данный скрипт в область работы с тем-же миди эдитором.
Мы ведь можем отслеживать открыт или нет миди эдитор и точно так-же удалять по каким-то условиям ноты, контролеры....
Ну вот пока только для нот -
PHP:isSet = reaper.GetSet_LoopTimeRange( 0, 0, 0, 0, 0 ) -- Берём переменную "Time selection" focus = reaper.GetCursorContext() -- Берём переменную значения где сейчас фокус? midieditor = reaper.MIDIEditor_GetActive() if midieditor then if isSet == 0 then reaper.MIDIEditor_OnCommand(midieditor, 40002) else reaper.MIDIEditor_OnCommand(midieditor, 40214) reaper.MIDIEditor_OnCommand(midieditor, 40746) reaper.MIDIEditor_OnCommand(midieditor, 40002) end else if isSet == 0 then reaper.Main_OnCommand(40697, 0) else if focus == 1 then reaper.Main_OnCommand(reaper.NamedCommandLookup('_XENAKIOS_TSADEL'), 0) elseif focus == 2 then reaper.Main_OnCommand(40089, 0) end end end
Тот же код можно записать несколько иначе, используя другой путь выполнения условий -
PHP:isSet = reaper.GetSet_LoopTimeRange( 0, 0, 0, 0, 0 ) -- Берём переменную "Time selection" focus = reaper.GetCursorContext() -- Берём переменную значения где сейчас фокус? midieditor = reaper.MIDIEditor_GetActive() if isSet == 0 then if midieditor then reaper.MIDIEditor_OnCommand(midieditor, 40002) else reaper.Main_OnCommand(40697, 0) end else if midieditor then reaper.MIDIEditor_OnCommand(midieditor, 40214) reaper.MIDIEditor_OnCommand(midieditor, 40746) reaper.MIDIEditor_OnCommand(midieditor, 40002) else if focus == 1 then reaper.Main_OnCommand(reaper.NamedCommandLookup('_XENAKIOS_TSADEL'), 0) elseif focus == 2 then reaper.Main_OnCommand(40089, 0) end end end
Какой вариант лучше - зависит от того, какое условие является более главным.
В данном случаи - и тайм селекшин и открытый миди эдитор - равнозначны, но если вы дальше начнёте развивать код, и например захотите что-то удалять на энвелопах айтемов, а не треков - тайм селекшин станет более главным и тогда второй вариант кода будет удобнее! Хотя с энвелопами айтемов пример не удачный, так как с ними то как раз всё и так работать будет - с этим кодом.
Кстати, мне скрипт нравится, я бы им обычную функцию делита заменил, помониторив ещё другие возможные варианты, когда делит нужен и контекстная его работа удобнее.
Но нужно внимательнее посмотреть штатные экшины -
есть ведь 40307, 40312 для айтемов
local start_time, end_time = reaper.GetSet_LoopTimeRange(0, 0, 0, 0, 0)
if start_time == end_time then return end
---
local count_track = reaper.CountTracks(0)
for i = 1, count_track do
local track = reaper.GetTrack(0, i - 1 )
local count_env = reaper.CountTrackEnvelopes(track)
for i = 1, count_env do
local env = reaper.GetTrackEnvelope(track, i - 1 )
reaper.InsertEnvelopePoint( env, start_time, 0, 0, 0, 0, 0 )--?????????????????
reaper.InsertEnvelopePoint( env, end_time, 0, 0, 0, 0, 0 )--?????????????????
end
end
reaper.UpdateArrange()
Про экшен знаю,но ручками выделить кривую не как-так как это для всех кривых.если есть возможность ручками выделить кривую и переместить в эту точку плэй курсор - есть экшин такой, поставить поинт на кривую
Envelope_Evaluate()как поставить точки автоматизации в тех местах где находится автоматизация в данный момент.Как получить эту высоту?
Потому как нет в API этого, или опять в не очевидной форме.Что бы выделить кривую, тоже не могу найти в API
Envelope_SortPoints() после всех манипуляций с точками.А вот смотрите какой глюк я споймал -
Посмотреть вложение 142479
Чуть мозги себе не сломал - как такое возможно, чтоб было на айтеме две разных кривых громкости, при том, что в перечне она естественно одна.
focus = reaper.GetCursorContext() -- Берём переменную значения где сейчас фокус?
function movetrackdown()
function Is_Valid_Track(track)
valid_track = reaper.ValidatePtr(track, "MediaTrack*")
return valid_track
end
function ReverseTable(t)
local reversedTable = {}
local itemCount = #t
for k, v in ipairs(t) do
reversedTable[itemCount + 1 - k] = v
end
return reversedTable
end
function SaveSelectedTracks(table)
for i = 0, reaper.CountSelectedTracks(0)-1 do
table[i+1] = reaper.GetSelectedTrack(0, i)
end
end
function Main()
new_tracks = {}
sel_tracks = ReverseTable( sel_tracks )
for i, track in ipairs( sel_tracks ) do
reaper.SetOnlyTrackSelected( track )
reaper.Main_OnCommand(reaper.NamedCommandLookup("_S&M_COPYSNDRCV1"),0) -- copy track with routing
reaper.Main_OnCommand(reaper.NamedCommandLookup("_XENAKIOS_SELNEXTTRACK"),0) -- Select Next Track
local track_copy = reaper.GetSelectedTrack(0, 0)
if track_copy == track then
table.insert( new_tracks, track )
break
end
reaper.Main_OnCommand(40914, 0) -- set as last touch
reaper.Main_OnCommand(reaper.NamedCommandLookup("_S&M_PASTSNDRCV1"),0) -- paste track with routing
local track_copy = reaper.GetSelectedTrack(0, 0)
-- ADD SENDS ENVELOPE
for category = -1, 1 do
local sends_count = reaper.GetTrackNumSends( track, category )
for sendidx = 0, sends_count -1 do
for envelopeType = 0, 2 do
local env = reaper.BR_GetMediaTrackSendInfo_Envelope( track, category, sendidx, envelopeType )
local retval, xml = reaper.GetEnvelopeStateChunk( env, "", false )
local env_copy = reaper.BR_GetMediaTrackSendInfo_Envelope( track_copy, category, sendidx, envelopeType )
reaper.SetEnvelopeStateChunk( env_copy, xml, false )
end
end
end
reaper.DeleteTrack( track ) -- Delete Source Track
table.insert( new_tracks, track_copy )
end
return new_tracks
end
-- INIT
local reaper = reaper
count_selected_track = reaper.CountSelectedTracks( 0 )
if count_selected_track > 0 then
-- Avoid complex selection with Child and their Parents
reaper.Main_OnCommand(reaper.NamedCommandLookup("_SWS_UNSELPARENTS"),0) -- Unselect parent track
-- Save Tracks
sel_tracks = {}
SaveSelectedTracks( sel_tracks )
Main()
-- Select New Tracks
if new_tracks then
for i, track in ipairs( new_tracks ) do
reaper.SetTrackSelected( track, true )
end
end
-- Select Source Tracks if they still exist
for i, track in ipairs( sel_tracks ) do
if Is_Valid_Track( track ) then
reaper.SetTrackSelected( track, true )
end
end
reaper.TrackList_AdjustWindows(0)
reaper.Undo_EndBlock("Move selected tracks down on visible track list", -1)
reaper.SetCursorContext(0, fx_env)
end
end
if focus == 0 then movetrackdown()
elseif focus == 1 or 2 or -1 then reaper.Main_OnCommand(40118, 0) end
-----------------------------------------------------------------------------
local function No_Undo()end; local function no_undo()reaper.defer(No_Undo)end
-----------------------------------------------------------------------------
local focus = reaper.GetCursorContext2(true)-- Берём переменную значения где сейчас фокус?
local r = reaper.Main_OnCommand
local sws = reaper.NamedCommandLookup
--=====================================
kolichestvo_sel_tr = reaper.CountSelectedTracks( 0 ) --получаем кол-ва выделенных треков (кроме Мастера)
if kolichestvo_sel_tr == 0 then --если выделенных треков нет то
reaper.MB('No Select Track','Track',0) --окно с предупреждением
no_undo() return -- (no undo); остановить скрипт
end
--=================================================
function next_track()
for i = kolichestvo_sel_tr-1,0,-1 do --создаём цикл опроса по каждому выделенному треку (кроме Мастера)
local track = reaper.GetSelectedTrack(0,i+1) --Получаем выделенный трек из проекта кроме первого
if track then --если трек то
reaper.SetMediaTrackInfo_Value(track,'I_SELECTED',0) --снять выделение
end
end
reaper.SelectAllMediaItems(0, 0) --Снять выделения со всех айтамов
r(40914,0) --Track: Set first selected track as last touched track
r(sws("_S&M_CUTSNDRCV1"),0) --Cut selected tracks (with routing)
r(sws("_S&M_PASTSNDRCV1"),0) --paste track with routing
end
---==============================================================================
reaper.PreventUIRefresh(1); reaper.Undo_BeginBlock()
if focus == 0 then
next_track()
elseif focus == 1 then
--?????????????? (item)
elseif focus == 2 then--
--???????????????? (envelop)
end
reaper.Undo_EndBlock("Move the selected track down one track",1); reaper.PreventUIRefresh(-1)
focus = reaper.GetCursorContext2(true) -- Берём переменную значения где сейчас фокус?
function movetrackdown()
function Is_Valid_Track(track)
valid_track = reaper.ValidatePtr(track, "MediaTrack*")
return valid_track
end
function ReverseTable(t)
local reversedTable = {}
local itemCount = #t
for k, v in ipairs(t) do
reversedTable[itemCount + 1 - k] = v
end
return reversedTable
end
function SaveSelectedTracks(table)
for i = 0, reaper.CountSelectedTracks(0)-1 do
table[i+1] = reaper.GetSelectedTrack(0, i)
end
end
function Main()
new_tracks = {}
sel_tracks = ReverseTable( sel_tracks )
for i, track in ipairs( sel_tracks ) do
reaper.SetOnlyTrackSelected( track )
reaper.Main_OnCommand(reaper.NamedCommandLookup("_S&M_COPYSNDRCV1"),0) -- copy track with routing
reaper.Main_OnCommand(reaper.NamedCommandLookup("_XENAKIOS_SELNEXTTRACK"),0) -- Select Next Track
local track_copy = reaper.GetSelectedTrack(0, 0)
if track_copy == track then
table.insert( new_tracks, track )
break
end
reaper.Main_OnCommand(40914, 0) -- set as last touch
reaper.Main_OnCommand(reaper.NamedCommandLookup("_S&M_PASTSNDRCV1"),0) -- paste track with routing
local track_copy = reaper.GetSelectedTrack(0, 0)
-- ADD SENDS ENVELOPE
for category = -1, 1 do
local sends_count = reaper.GetTrackNumSends( track, category )
for sendidx = 0, sends_count -1 do
for envelopeType = 0, 2 do
local env = reaper.BR_GetMediaTrackSendInfo_Envelope( track, category, sendidx, envelopeType )
local retval, xml = reaper.GetEnvelopeStateChunk( env, "", false )
local env_copy = reaper.BR_GetMediaTrackSendInfo_Envelope( track_copy, category, sendidx, envelopeType )
reaper.SetEnvelopeStateChunk( env_copy, xml, false )
end
end
end
reaper.DeleteTrack( track ) -- Delete Source Track
table.insert( new_tracks, track_copy )
end
return new_tracks
end
-- INIT
local reaper = reaper
count_selected_track = reaper.CountSelectedTracks( 0 )
if count_selected_track > 0 then
-- Avoid complex selection with Child and their Parents
reaper.Main_OnCommand(reaper.NamedCommandLookup("_SWS_UNSELPARENTS"),0) -- Unselect parent track
-- Save Tracks
sel_tracks = {}
SaveSelectedTracks( sel_tracks )
Main()
-- Select New Tracks
if new_tracks then
for i, track in ipairs( new_tracks ) do
reaper.SetTrackSelected( track, true )
end
end
-- Select Source Tracks if they still exist
for i, track in ipairs( sel_tracks ) do
if Is_Valid_Track( track ) then
reaper.SetTrackSelected( track, true )
end
end
reaper.TrackList_AdjustWindows(0)
reaper.Undo_EndBlock("Move selected tracks down on visible track list", -1)
reaper.SetCursorContext(0, fx_env)
end
end
if focus == 0 then movetrackdown()
elseif focus == 1 or 2 or -1 then reaper.Main_OnCommand(40118, 0) end
Исправил!А второй код вы как то исправили? Я не могу найти отличий, но он работает)Как так?