ReaScripts (скрипты для Reaper) - Учимся создавать!!!

Тема в разделе "Reaper", создана пользователем Archchie, 29 дек 2017.

  1. Archchie

    Archchie Active Member

    Регистрация:
    24 окт 2017
    Сообщения:
    351
    Симпатии:
    174
    Пол:
    Мужской
    А можно немого объяснений для понимания или ссылочку где поучится можно???
     
  2. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    У Евгения есть скрипт-едитор для чанков ---- он очень удобен и для понимания и для учёбы. Поищите у него
     
  3. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    @Archchie, чем функция "свернуть" треки в выделенную папку отличается от скрыть её чайлды?
     
  4. Archchie

    Archchie Active Member

    Регистрация:
    24 окт 2017
    Сообщения:
    351
    Симпатии:
    174
    Пол:
    Мужской
    Тем, что они потом не разворачиваются
     
  5. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    Так делайте скрипт тогл.
    И в общем - нафига это сворачивать скриптом????
    Чтоб скрипт сработал вам фолдер трек нужно мышкой выделить. А не проще сразу на тот треугольник клацнуть и свернуть треки?
    Очень не люблю делать что-то бесполезное, не продуманное, а попросту - надуманное.
     
  6. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    Но я так и не понял что должен делать скрипт и чему он помогает.
    Вы же всё урывками делаете.
    --- добавлено 25 янв 2018 ---
    Так не делайте так, чтоб скрывал в Микшере.
    @Archchie, пишите развёрнутое тех задание, если это уже не учёба, и финалом есть работающий скрипт.
    Просто так писать вам функции я не стану, потому как на 99% уверен, что для задуманного функционала она не нужна или нужна в другом виде.
     
  7. @Michael

    @Michael Well-Known Member

    Регистрация:
    14 дек 2010
    Сообщения:
    840
    Симпатии:
    1.264
    Пол:
    Мужской
    Адрес:
    Орёл / Москва
    @Aleksandr Oleynik Наверно ему нужно чтобы был линк между состояниями папок в TCP и MCP при включенной функции Mixer: Clickable icon for folder tracks to show/hide children. Но видимо на двух страницах бессмысленного флуда это было сложно написать, хочется пожрать кактус, чем написать таки тех задание.
     
    Aleksandr Oleynik нравится это.
  8. @Michael

    @Michael Well-Known Member

    Регистрация:
    14 дек 2010
    Сообщения:
    840
    Симпатии:
    1.264
    Пол:
    Мужской
    Адрес:
    Орёл / Москва
    Развернул папку в микшере - развернулась в аранже и наоборот. И куда скрипту смотреть в первую очередь - в статус папки в микшере или в аранже? Можно тыкать по прежнему тыкать пальцем в небо, или дать тех задание, получить решение, затем по готовому решению задавать вопросы.
     
  9. @Michael

    @Michael Well-Known Member

    Регистрация:
    14 дек 2010
    Сообщения:
    840
    Симпатии:
    1.264
    Пол:
    Мужской
    Адрес:
    Орёл / Москва
    Папка свернута в аранже. Как ты развернёшь её в микшере, если скрипт смотрит в аранж?
     
  10. @Michael

    @Michael Well-Known Member

    Регистрация:
    14 дек 2010
    Сообщения:
    840
    Симпатии:
    1.264
    Пол:
    Мужской
    Адрес:
    Орёл / Москва
    PHP:
    function ShowChildrenInMCP(tris_show)
      
    local _,tr_chunk reaper.GetTrackStateChunk(tr,'',true)
      
    local BUSCOMP_var1 tr_chunk:match('BUSCOMP (%d+)')
      
    local tr_chunk_out tr_chunk:gsub('BUSCOMP '..BUSCOMP_var1..' %d+''BUSCOMP '..BUSCOMP_var1..' '..(is_show and or 1))
      
    reaper.SetTrackStateChunk(trtr_chunk_out,true)
    end

    tr 
    reaper.GetTrack(0,0)
    ShowChildrenInMCP(trtrue)

    Я то пожру, только ты быстрее забьёшь, чем что-то готовое получишь с таким подходом.
     
    Archchie нравится это.
  11. @Michael

    @Michael Well-Known Member

    Регистрация:
    14 дек 2010
    Сообщения:
    840
    Симпатии:
    1.264
    Пол:
    Мужской
    Адрес:
    Орёл / Москва
    Получится. Просто ты не знаешь как. Потому что... (третий раз повторять пожалуй будет лишним).
     
  12. @Michael

    @Michael Well-Known Member

    Регистрация:
    14 дек 2010
    Сообщения:
    840
    Симпатии:
    1.264
    Пол:
    Мужской
    Адрес:
    Орёл / Москва
    Так как ты, я никогда не учился ни в одной из областей. Касаемо рипера - это 1) изучение чужих готовых решений 2) формирование собственных грамотных тех заданий и дальнейшее изучение решений 3)более конкретные вопросы после понимания и изучения механизмов большинства существующих API.
     
    Archchie и Aleksandr Oleynik нравится это.
  13. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    Вот решение подобных "загвоздочек" - и делается на этапе написания Тех Задания, о котором вас просят уже какую страницу.
    --- добавлено 25 янв 2018 ---
    Не, не на дебила, а на упрямца, который решил, что знает лучше как нужно учиться :)
    Рано или поздно ты поймёшь, что после того как ты более-менее освоиш синтаксис LUA и разберёшься с API Рипера - 80% твоего времени при написании законченного и работающего скрипта, будет занимать написание грамотного тех задания самому себе, а если понадобится помощь - то тем более - в твоих скриптах ни кто разбиратся без ТЗ не станет.
    Так что процесс обучения этот этап должен содержать...

    Пока мы тут поняли ТОЛЬКО какой-то отрывок ТЗ, причём с взаимоисключающими условиями.
     
    Последнее редактирование: 25 янв 2018
    Archchie нравится это.
  14. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    Сделать можно, но это скрипт не его пока уровня - нужно ведь запоминать состояние и сравнивать при его изменении. Значит нужно в таблицы нырять. А тут ещё и в чанки нужно нырять, так как ни Экшина ни API на закрытие/открытие папки в Микшере нет, только через чанки.
    В общем - в данном конкретном случаи, написанная функция ни чего в голове не прояснит и в обучении не даст!

    В общем я пас, в том числе и с целью правильного обучения...
     
  15. Archchie

    Archchie Active Member

    Регистрация:
    24 окт 2017
    Сообщения:
    351
    Симпатии:
    174
    Пол:
    Мужской
    Да просто для работы нужен .Полезный скрипт .
    Учится будем на других скриптах
     
  16. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    Так напишите до конца что он должен делать, ну ей богу - Михаил одно предложение написал с интерпритацией (перводом) того, что вы пишите уже десяток постов - мне оно понятно, а то, что пишите вы - нет.
    Вам нужно чтоб если вы в окне аранжа TCP закрыли папку до минимального размера чайлдов, в окне Микшера MCP она тоже закрылась?
    А если откроете в аранже эту папку в Микшере она тоже должна открыться?
    А если в Аранже папка закрыта, а вы её в Микшере ручками откроете, что скрипт должен делать с окном Аранжа?

    Ну напишите вы ВСЕ случаи работы с папкой, ну в чём же проблема?
    если вы не можете сформулировать чётко и ясно условия для простейшего скрипта, то как же вы будете писать эти скрипты???? Вы на пол пути запутаетесь и ни чегно работать не будет.
     
  17. Archchie

    Archchie Active Member

    Регистрация:
    24 окт 2017
    Сообщения:
    351
    Симпатии:
    174
    Пол:
    Мужской
    @@Michael СПАСИБО!!!
    Именно оно.Только можно чуть чуть подправить что бы папки в микшере сворачивались когда в аранже папка крошечная,а не маленькая(средняя)?
     
  18. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    @Archchie, строку -
    PHP:
    ShowChildrenInMCP(trackTCP_state==0)
    измените на -
    PHP:
    ShowChildrenInMCP(trackTCP_state==or TCP_state==1)
    Хотя, если бы разобрались сами - было бы лучше....
    --- добавлено 26 янв 2018 ---
    @@Michael, не очень удобен такой функционал по "зажиганию" кнопки - чтоб выключить, нужно два раза на кнопку клацать.
     
  19. @Michael

    @Michael Well-Known Member

    Регистрация:
    14 дек 2010
    Сообщения:
    840
    Симпатии:
    1.264
    Пол:
    Мужской
    Адрес:
    Орёл / Москва
    Производительность. Твой комп сдохнет раньше, чем перелопатит все папки в больших проектах.

    Тулбар:
    ReaPack/mpl_Link TCP MCP folder collapsed state (background).lua
     
    Последнее редактирование: 27 янв 2018
  20. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    Не....., тут ты не прав - это всего лишь стартовая проверка проекта и приведение его в правильное состояние для работы скрипта в фоне, до дефера.
    Ни чего не сдохнет сколько бы там треков в проекте не было, просто будет какая-то задержка перед нормальной работой.
     
    Archchie нравится это.
  21. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    @@Michael, как получить Grid division в MIDI Editor-е, если линковка гридов в миди эдиторе и аранж окне отключена?
    Всё перелопатил - не могу найти, нашёл только грид для нот.
    Я конечно "через задницу" эту задачу решил, но хотелось бы прямое решение найти, помоги.
     
  22. incubator

    incubator Active Member

    Регистрация:
    24 янв 2007
    Сообщения:
    363
    Симпатии:
    143
    Адрес:
    Spb
    Привет друзья!Очень нубский вопрос!)Хотел как то образоваться в направлении написании скриптов хотя бы элементарных. Посмотрел весь курс x-raym и стрим Михаила Пилявского кое-что стал понимать, но поскольку в математике и програмировании совсем плох, сам разобраться во всем не смог. Все настолько по-разному пишут коды.Все с чего то начинают. Решил начать с шаблонов. Нашел шаблон x-raym выполнение функции для выделенных нот. И хотел прикрутить к нему действие если ноты не выделены. Иже как пару дней не могу добиться результата куда вставить второе условие что бы когда ноты были "не выделены" совершалось другое действие. Пока просто вывожу reaper.ShowConsoleMsg("note selected") Подскажите пожалуйста как это можно сделать?
    Код:
    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
     
  23. Archchie

    Archchie Active Member

    Регистрация:
    24 окт 2017
    Сообщения:
    351
    Симпатии:
    174
    Пол:
    Мужской
    @incubator,
    PHP:
    function Maintake )
       
      
    retvalnotesccssysex reaper.MIDI_CountEvtstake )
      -- 
    GET SELECTED NOTES (from 0 index)
      for 
    0notes do
      
    local retvalselmutedstartppqendppqchanpitchvel reaper.MIDI_GetNotetake)
     
        if 
    sel then
          reaper
    .ShowConsoleMsg("selected_notes".."\n")
          -- 
    ACTION HERE
        
    else
          
    reaper.ShowConsoleMsg("not_selected_notes".."\n")
        
    end

      end

    end

    -------------------------------
    -- 
    INIT
    -------------------------------

    take reaper.MIDIEditor_GetTakereaper.MIDIEditor_GetActive() )

    if 
    take then



      Main
    take ) -- Execute your main function



      
    reaper.UpdateArrange() -- Update the arrangement (often needed)

    end -- ENDIF Take is MIDI
     
    Последнее редактирование: 3 фев 2018
    incubator нравится это.
  24. incubator

    incubator Active Member

    Регистрация:
    24 янв 2007
    Сообщения:
    363
    Симпатии:
    143
    Адрес:
    Spb
    @Archchie, Спасибо вроде бы просто все было) Но единственно он, выдает количество выделенных нот и количество не выделеных.Я хотел впоследствии назначить экшны для выполнения с реакцией на выделение.Возможно ли что бы код делал при любом количестве одно сообщение "selected_notes" если хоть одна нота выделена и если не выделена одно сообщение "not_selected_notes" Я теоретически понимаю что нужна математика с reaper.MIDI_CountEvts но как это на практике сделать?Там какой то цикл получаеться который ноты считает или reaper.MIDI_CountEvts сразу дает количество? Простите за дилетантский лепет!

    P.S Спасибо за материалы буду изучать
     
  25. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    @incubator, в первом условии, в конце его, перед else -
    ставиш break и цикл завершится как только попадётся первая выделенная нота.
    А вот чтоб что-то сработало если ни одна не выделена - можно сделать ещё одно условие -
    если кол-во циклов совпало с кол-вом нот, тогда делать что-то.
    Если пройдя все циклы не обнаружится ни одной выделенной ноты и break не оборвет цикл, значит циклов и будет столько же, сколько нот.
    И, да - MIDI_CountEvts сразу даёт кол-во нот и контролеров.

    PS: В общем вот так -
    PHP:
    ---------------------------------------------------------------------------------------------------------
    local msg = function(Mreaper.ShowConsoleMsg(tostring(M).."\n"end
    ---------------------------------------------------------------------------------------------------------

    function 
    Main (take)
      
    retvalnotesccssysex reaper.MIDI_CountEvtstake )
      -- 
    GET SELECTED NOTES (from 0 index)
      for 
    0notes do
        
    local retvalselmutedstartppqendppqchanpitchvel reaper.MIDI_GetNotetake)

        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_GetTakereaper.MIDIEditor_GetActive() )

    if 
    take then
      Main 
    (take) -- Execute your main function
      
    reaper.UpdateArrange() -- Update the arrangement (often needed)
    end
     
    Последнее редактирование: 3 фев 2018
    Archchie и incubator нравится это.
  26. Archchie

    Archchie Active Member

    Регистрация:
    24 окт 2017
    Сообщения:
    351
    Симпатии:
    174
    Пол:
    Мужской
    @Aleksandr Oleynik, А как получить количество сработанных циклов?
     
  27. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    А вот выше код написал.
    Если ни одна из нот не выделена, то кол-во циклов в любом случаи будет равно кол-ву нот, а значит для того чтобы инициировать какое-то действе по этому условию (что ни одна нота не выделена), нужно сделать очередное условие if кол-во нот == кол-ву циклов
    ну а цикл ведь у нас переменная k
     
    Archchie и incubator нравится это.
  28. incubator

    incubator Active Member

    Регистрация:
    24 янв 2007
    Сообщения:
    363
    Симпатии:
    143
    Адрес:
    Spb
    @Aleksandr Oleynik, Спасибо все разжевали даже, я сейчас подпишу комментарии для лучшего понимания.

    Кстати заметил что например скрипты kawa с удаленными пробелами все в одну строку как бы. Добавляет ли это проиводительности в реальности?
    Код:
    ---------------------------------------------------------------------------------------------------------
    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
    



    И возможно ли было это сделать проще? Получить значение из фунции reaper.MIDI_GetNote и использовать как то его через true и false?
     
    Последнее редактирование: 3 фев 2018
  29. Archchie

    Archchie Active Member

    Регистрация:
    24 окт 2017
    Сообщения:
    351
    Симпатии:
    174
    Пол:
    Мужской
    PHP:
    ----------------------------------------------------------------
    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 1,count_notes do                                                                --Создаем цикл опроса по каждой ноте
      local retval
    selmutedstartppqendppqchanpitchvel 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



     
    Последнее редактирование: 3 фев 2018
    incubator нравится это.
  30. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    Нет. Способ записи кода ни как не влияет на производительнось. Код либо работает - либо нет.
    Я для написания скриптов использую редактор Atom с модулем для LUA -
    он автоматом по шоткату мне форматирует и табулирует верно код.
    Когда код скрипта разрастается, используют (ну кроме коментов) для лучшего потом понимания своего же скрипта, несколько приёмов.
    Я наверняка все и не знаю, но -
    - делают правильное форматирование и табуляцию, чтоб каждое условие, каждая функция читались сразу;
    - разбивают всё на простые функции - это порой увеличивает код, но очень способствет его пониманию;
    - разбивают скрипт на неколько модулей, по сути на отдельные скрипты.
    --- добавлено 3 фев 2018 ---
    Почти всегда можно сделать лучше и проще, но на это ни какой жизни не хватит, по этому - первое найденное работающее решение и есть самым верным :)
     
    Последнее редактирование: 3 фев 2018
    Archchie и incubator нравится это.
  31. incubator

    incubator Active Member

    Регистрация:
    24 янв 2007
    Сообщения:
    363
    Симпатии:
    143
    Адрес:
    Spb
    @Archchie, Спасибо! У вас компактно и понятно)))

    @Aleksandr Oleynik, Поздравте меня я написал свой первый скрип с нуля!!! Я очень люблю умные кнопки которые действуют на все в зависимости от фокуса.Я сделал умный Delete который работает в зависимости от фокуса и "Time selection".Код элементарный, но я думаю даже может пригодится кому то))
    Код:
     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

    Посмотрите пожалуйста укажите на ошибки!)
     
    Kokarev Maxim нравится это.
  32. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    Поздравляю! :)
    В нашем полку прибыло?

    Вот на примере этого скрипта покажу как форматирует код Atom (поставили в него модуль LUA, и по нажатию шотката Shift+Control+I получаем верно отформатированный код) -
    2018-02-04_085632.png
    И сразу видно, где начинается и где заканчивается выражение (начинается в строке 8 с if и заканчивается end-ом в строке 18).

    Функции с Get дают переменную, но в коментах наверное логичней писать - берём переменную.

    Теперь, что касается оптимизации кода -
    Экшин 40697 уже контекстно зависим от фокуса и ему не нужны доп условия зависящие от фокуса, он их и так понимает, а значит можно сильно упростить код -
    PHP:
    isSet = reaper.GetSet_LoopTimeRange0000) --  Берём переменную "Time selection"
    focus reaper.GetCursorContext() --  Берём переменную значения где сейчас фокус?

    if isSet == 
    0 then
      reaper
    .Main_OnCommand(406970)
    else
      if 
    focus == 1 then
        reaper
    .Main_OnCommand(reaper.NamedCommandLookup('_XENAKIOS_TSADEL'), 0)
      elseif 
    focus == 2 then
        reaper
    .Main_OnCommand(400890)
      
    end
    end

    Ну и наверное стоит развить данный скрипт в область работы с тем-же миди эдитором.
    Мы ведь можем отслеживать открыт или нет миди эдитор и точно так-же удалять по каким-то условиям ноты, контролеры....
    Ну вот пока только для нот -
    PHP:
    isSet = reaper.GetSet_LoopTimeRange0000) --  Берём переменную "Time selection"
    focus reaper.GetCursorContext() --  Берём переменную значения где сейчас фокус?
    midieditor reaper.MIDIEditor_GetActive()

    if 
    midieditor then
      
    if isSet == 0 then
        reaper
    .MIDIEditor_OnCommand(midieditor40002)
      else
        
    reaper.MIDIEditor_OnCommand(midieditor40214)
        
    reaper.MIDIEditor_OnCommand(midieditor40746)
        
    reaper.MIDIEditor_OnCommand(midieditor40002)
      
    end
    else
      if isSet == 
    0 then
        reaper
    .Main_OnCommand(406970)
      else
        if 
    focus == 1 then
          reaper
    .Main_OnCommand(reaper.NamedCommandLookup('_XENAKIOS_TSADEL'), 0)
        elseif 
    focus == 2 then
          reaper
    .Main_OnCommand(400890)
        
    end
      end
    end

    Тот же код можно записать несколько иначе, используя другой путь выполнения условий -
    PHP:
    isSet = reaper.GetSet_LoopTimeRange0000) --  Берём переменную "Time selection"
    focus reaper.GetCursorContext() --  Берём переменную значения где сейчас фокус?
    midieditor reaper.MIDIEditor_GetActive()

    if isSet == 
    0 then
      
    if midieditor then
        reaper
    .MIDIEditor_OnCommand(midieditor40002)
      else
        
    reaper.Main_OnCommand(406970)
      
    end
    else
      if 
    midieditor then
        reaper
    .MIDIEditor_OnCommand(midieditor40214)
        
    reaper.MIDIEditor_OnCommand(midieditor40746)
        
    reaper.MIDIEditor_OnCommand(midieditor40002)
      else
        if 
    focus == 1 then
          reaper
    .Main_OnCommand(reaper.NamedCommandLookup('_XENAKIOS_TSADEL'), 0)
        elseif 
    focus == 2 then
          reaper
    .Main_OnCommand(400890)
        
    end
      end
    end
    Какой вариант лучше - зависит от того, какое условие является более главным.
    В данном случаи - и тайм селекшин и открытый миди эдитор - равнозначны, но если вы дальше начнёте развивать код, и например захотите что-то удалять на энвелопах айтемов, а не треков - тайм селекшин станет более главным и тогда второй вариант кода будет удобнее! Хотя с энвелопами айтемов пример не удачный, так как с ними то как раз всё и так работать будет - с этим кодом.
    Кстати, мне скрипт нравится, я бы им обычную функцию делита заменил, помониторив ещё другие возможные варианты, когда делит нужен и контекстная его работа удобнее.
    Но нужно внимательнее посмотреть штатные экшины -
    есть ведь 40307, 40312 для айтемов
     
    Последнее редактирование: 4 фев 2018
    Kokarev Maxim и incubator нравится это.
  33. Archchie

    Archchie Active Member

    Регистрация:
    24 окт 2017
    Сообщения:
    351
    Симпатии:
    174
    Пол:
    Мужской
    Такой вопрос! Как реализовать? Получаем выделенный трек и если выделенных треков нет то
    PHP:
        local sel_track reaper.GetSelectedTrack(0,0)
        if  
    sel_track == nil then
           
    return
        
    end
    и вот(в место return) если выделенных треков нет-то, что бы всплывало вот такое вот окно
    Снимо1к.PNG
     
    Последнее редактирование: 4 фев 2018
  34. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    @Archchie,
    PHP:
    local sel_track reaper.GetSelectedTrack(0,0)
    if  
    sel_track == nil then
      mesg 
    = [=[No tracks selected]=]
      
    reaper.MB(mesg ""0)
    end
     
    Archchie нравится это.
  35. incubator

    incubator Active Member

    Регистрация:
    24 янв 2007
    Сообщения:
    363
    Симпатии:
    143
    Адрес:
    Spb
    Да очень увлекательное это занятие, Рипер рано или поздно склонит тебя писать скрипты)
    Красивенько!И удобно! Надо будет себе поставить что бы глаза не разбегались)
    Ошибся, прошу прощения но я только начинаю многие вещи пока наугад.
    Да точно это я не учел,- так намного компактней и красивей!) Первый скрипт слегка комом)
    Отличная идея! Вы уже две модификации сделали и продумали наперед Миди редактор. Я его как то упустил что в "Time Selection" нужно будет тоже ноты стирать.
    А может все таки лучше разделить Delete для Основного окна и для Миди редактора?Это же вроде возможно? Потому что я нопример использую миди редактор в Доке и одновременно работаю в аранжировке и вместо кусочка клипов удаляються нотки))
    Если разделить на отдельные скрипты.Тогда вопрос можно ли получить фокус из Мидиредактора, на нотах он или на контроллерах?
    Ну 40307 там делает cut то есть забирает стираемое в буфер а в процессе работы могут возникнуть запутки с этим)
    Я потестирую тогда и попробую отдельный Delete для Миди редактора сделать)) Спасибо за участие! Очень интерестно так обучаться)
     
  36. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    Можно, и отформатировать в ручную можно пробелами -
    PHP:
    local sel_track reaper.GetSelectedTrack(0,0)
    if  
    sel_track == nil then
      mesg 
    = [=[        No Selected
                 Track
    ]=]
      
    reaper.MB(mesg ""0)
    end
     
    Archchie нравится это.
  37. Archchie

    Archchie Active Member

    Регистрация:
    24 окт 2017
    Сообщения:
    351
    Симпатии:
    174
    Пол:
    Мужской
    Подскажите пожалуйста, не могу ни как сообразить,
    как поставить точки автоматизации в тех местах где находится автоматизация в данный момент.
    Как получить эту высоту?
    Снимок.PNG
    PHP:
            local start_timeend_time reaper.GetSet_LoopTimeRange(00000)
            if 
    start_time == end_time then return end
            
    ---
            
    local count_track reaper.CountTracks(0)
            for 
    1count_track do
              
    local track reaper.GetTrack(0)
              
    local count_env reaper.CountTrackEnvelopes(track)
              for 
    1count_env do
                
    local env reaper.GetTrackEnvelope(track)


                
    reaper.InsertEnvelopePointenvstart_time0000)--?????????????????
                
    reaper.InsertEnvelopePointenvend_time0000)--?????????????????


              
    end
            end


            reaper
    .UpdateArrange()
              
     
    Последнее редактирование: 10 фев 2018
  38. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    @Archchie, удивительно, но я точно тем-же занимался вчера.
    Получить из уравнения треугольника.
    Ну или, если есть возможность ручками выделить кривую и переместить в эту точку плэй курсор - есть экшин такой, поставить поинт на кривую
     
  39. Archchie

    Archchie Active Member

    Регистрация:
    24 окт 2017
    Сообщения:
    351
    Симпатии:
    174
    Пол:
    Мужской
    Про экшен знаю,но ручками выделить кривую не как-так как это для всех кривых.
    Что бы выделить кривую, тоже не могу найти в API
     
  40. @Michael

    @Michael Well-Known Member

    Регистрация:
    14 дек 2010
    Сообщения:
    840
    Симпатии:
    1.264
    Пол:
    Мужской
    Адрес:
    Орёл / Москва
    Envelope_Evaluate()
     
    Archchie и Aleksandr Oleynik нравится это.
  41. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    @@Michael, спасибище!!!
    А я тут целый математический кружок развёл у себя в скрипте, чтоб её вычислить :)...
    PS: Но что приятно - вычисленная мной совсем иначе Value с точностью до 12-го знака совпала с значение value вычисляемого из функции Envelope_Evaluate.......

    Как же не хватает подробного описания API функций Рипера..., куча функций совершенно с не адекватными названиями и самой функции и переменных. Да ещё и переменные одни и те же в разных функциях называются почему то по разному...
    --- добавлено 11 фев 2018 ---
    Потому как нет в API этого, или опять в не очевидной форме.
    @@Michael, может и это есть, а мы не находим?
     
    Последнее редактирование: 11 фев 2018
    incubator и Archchie нравится это.
  42. gazzz

    gazzz Gazzuar (Goa-trance)

    Регистрация:
    17 янв 2008
    Сообщения:
    243
    Симпатии:
    84
    Адрес:
    Lyubertsy
    @Aleksandr Oleynik, это наверное если отрезок линейный, а если имеет эксп/лог характер (curve) ?
     
  43. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    @gazzz, Envelope_Evaluate() работает при любой кривой, мой метод вычисления через функции прямоугольного треуголиника работает ЕСТЕСТВЕННО только для линейных кривых, это очевидно....
    --- добавлено 11 фев 2018 ---
    А вот смотрите какой глюк я споймал -
    2018-02-11_132835.png
    Чуть мозги себе не сломал - как такое возможно, чтоб было на айтеме две разных кривых громкости, при том, что в перечне она естественно одна.
     
  44. @Michael

    @Michael Well-Known Member

    Регистрация:
    14 дек 2010
    Сообщения:
    840
    Симпатии:
    1.264
    Пол:
    Мужской
    Адрес:
    Орёл / Москва
    Envelope_SortPoints() после всех манипуляций с точками.
     
    Последнее редактирование: 11 фев 2018
    Aleksandr Oleynik нравится это.
  45. Aleksandr Oleynik

    Aleksandr Oleynik Well-Known Member

    Регистрация:
    16 янв 2007
    Сообщения:
    16.899
    Симпатии:
    9.158
    Пол:
    Мужской
    Адрес:
    Киев
    @@Michael, ещё один вопрос всплыл - как различить какая кривая Volume выделена, Трековая или Тэйковая?
    Имя у ни одно и то-же, а вот время позиций точек разное и нужно точно знать - какая.
    По выделенному айтему - не проходит, так как как ни странно, а можно выделить кривую айтема не выделяя сам айтем.

    PS: Сам спросил, сам ответил - Envelope_GetParentTake
     
  46. incubator

    incubator Active Member

    Регистрация:
    24 янв 2007
    Сообщения:
    363
    Симпатии:
    143
    Адрес:
    Spb
    Друзья пытался модифицировать сегодня скрипт x-raym который двигает выбранный трек ниже или выше (на самом деле он его заново создает и стирает) Так вот когда пытаешься ставить его как фунцию в условия он теряет фокус с треков после одного срабатывания и ничем его не вернуть не sws командой не API командой. Я хотел что бы он в зависимости от фокуса двигал или треки или контент. Подскажите пожалуйста как можно поставить его в условия грамотно? Или вернуть фокус?
    Код:
    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
     
  47. Archchie

    Archchie Active Member

    Регистрация:
    24 окт 2017
    Сообщения:
    351
    Симпатии:
    174
    Пол:
    Мужской
    @incubator,

    PHP:
        -----------------------------------------------------------------------------
        
    local function No_Undo()endlocal 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)     --получаем кол-ва выделенных треков (кроме Мастера)
        if 
    kolichestvo_sel_tr == 0 then                        --если выделенных треков нет то
           reaper
    .MB('No Select Track','Track',0)               --окно с предупреждением
          no_undo
    () return                                      --  (no undo); остановить скрипт
        end
        
    --=================================================

        function 
    next_track()
          for 
    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(00)  --Снять выделения со всех айтамов
          r
    (40914,0)                        --TrackSet 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)


    PHP:
    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 kv in ipairs(t) do
          
    reversedTable[itemCount k] = v
      end
      
    return reversedTable
    end

    function SaveSelectedTracks(table)
      for 
    0reaper.CountSelectedTracks(0)-do
        
    table[i+1] = reaper.GetSelectedTrack(0i)
      
    end
    end



    function Main()

      
    new_tracks = {}

      
    sel_tracks ReverseTablesel_tracks )

      for 
    itrack in ipairssel_tracks ) do

        
    reaper.SetOnlyTrackSelectedtrack )

        
    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(00)

        if 
    track_copy == track then
           table
    .insertnew_trackstrack )
          break
        
    end
        reaper
    .Main_OnCommand(409140) -- set as last touch
        reaper
    .Main_OnCommand(reaper.NamedCommandLookup("_S&M_PASTSNDRCV1"),0) -- paste track with routing

        local track_copy 
    reaper.GetSelectedTrack(00)

        -- 
    ADD SENDS ENVELOPE
        
    for category = -1do
          
    local sends_count reaper.GetTrackNumSendstrackcategory )
          for 
    sendidx 0sends_count -do
            for 
    envelopeType 0do
              
    local env reaper.BR_GetMediaTrackSendInfo_EnvelopetrackcategorysendidxenvelopeType )
              
    local retvalxml reaper.GetEnvelopeStateChunkenv""false )
              
    local env_copy reaper.BR_GetMediaTrackSendInfo_Envelopetrack_copycategorysendidxenvelopeType )
              
    reaper.SetEnvelopeStateChunkenv_copyxmlfalse )
            
    end
          end
        end

        reaper
    .DeleteTracktrack ) -- Delete Source Track

        table
    .insertnew_trackstrack_copy )

      
    end

      
    return new_tracks

    end

    -- INIT
    local reaper 
    reaper

    count_selected_track 
    reaper.CountSelectedTracks)

    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 
    = {}
      
    SaveSelectedTrackssel_tracks )

      
    Main()

      -- 
    Select New Tracks
      
    if new_tracks then
        
    for itrack in ipairsnew_tracks ) do
          
    reaper.SetTrackSelectedtracktrue )
        
    end
      end

      
    -- Select Source Tracks if they still exist
      
    for itrack in ipairssel_tracks ) do
        if 
    Is_Valid_Tracktrack then
          reaper
    .SetTrackSelectedtracktrue )
        
    end
      end
      reaper
    .TrackList_AdjustWindows(0)


      
    reaper.Undo_EndBlock("Move selected tracks down on visible track list", -1)



    reaper.SetCursorContext(0fx_env)
    end

    end



    if focus == 0 then movetrackdown()
    elseif 
    focus == or or -1 then  reaper.Main_OnCommand(401180end
     
    Последнее редактирование: 14 фев 2018
    incubator нравится это.
  48. incubator

    incubator Active Member

    Регистрация:
    24 янв 2007
    Сообщения:
    363
    Симпатии:
    143
    Адрес:
    Spb
    @Archchie, Спасибо большое! А второй код вы как то исправили? Я не могу найти отличий, но он работает)Как так?
     
  49. Archchie

    Archchie Active Member

    Регистрация:
    24 окт 2017
    Сообщения:
    351
    Симпатии:
    174
    Пол:
    Мужской
    Исправил!
    Первую строку.
     
    incubator нравится это.
  50. incubator

    incubator Active Member

    Регистрация:
    24 янв 2007
    Сообщения:
    363
    Симпатии:
    143
    Адрес:
    Spb
    @Archchie, А как вам удалось понять что из за нее скрипт не работал?)
     

Поделиться этой страницей