Помогите создать экшн / кастом экшн / скрипт

  • Автор темы Автор темы @Michael
  • Дата начала Дата начала
@CerberPic, спасибо большое. Проверил работает хорошо. Добавьте пожалуйста в скрипт два исключения:
-Чтобы после первого запуска скрипта можно было также выбирать выделенный итем от первого запуска скрипта и повторно запускать скрипт дальше.
Сейчас скрипт на повторную активацию срабатывает если выбрать любые другие итемы в проекте, кроме того что был выделен от первого запуска.
- И второй момент в качестве исключения добавьте ситуацию если под концом выделенного итема стоит начало другого итема на нижнем треке, то в этой ситуации выделяется именно этот ниже стоящий итем.
 
Чтобы после первого запуска скрипта можно было также выбирать выделенный итем от первого запуска скрипта и повторно запускать скрипт дальше
Так если он выделен, на него и ориентируется скрипт, продолжать выполнение или остановиться. В таком случае при повторной активации будет продолжаться выполнение скрипта, а это вам изначально было не нужно.
если под концом выделенного итема стоит начало другого итема на нижнем треке, то в этой ситуации выделяется именно этот ниже стоящий итем
Так уже было в одном из ранних вариантов. Но вы сказали:
Между точкой отсчета(конец итема) и будущим выделенным итемом всегда есть какое-то расстояние.
Выражайтесь точнее.
 
В таком случае при повторной активации будет продолжаться выполнение скрипта, а это вам изначально было не нужно.
CerberPic, вы меня не поняли, я имел виду что после первичного запуска скрипта у нас выделился итем. Нужно чтобы скрипт понимал ситуацию, если я сразу после этого кликаю мышкой на этот же выделенный итем и после этого опять запускаю скрипт. Нужно чтобы скрипт понимал такую ситуацию и позволял и дальше активировать скрипт, даже если мы выбираем уже выделенный итем после предыдущей активации скрипта.
Сейчас этого нет и скрипт игнорирует такую ситуацию.
Все верно, вы правы я писал что между точкой отсчета(конец итема) и будущим выделенным итемом всегда есть какое-то расстояние.
Я поэтому и написал что это уже в дополнение ,как исключение. Может быть запросто такая ситуацию, что конец выделенного итема и начало нижестоящего итема под ним стоят встык встык, вот в этой ситуации будет полезно не пропускать нижестоящий итем а также его выделять. Это как исключение из общего правила.
Поправьте пожалуйста эти два момента.
 
@HDVulcan, второй пункт поправлю, в этом ничего сложного. С первым же всё не так просто.

Нужно чтобы скрипт понимал ситуацию, если я сразу после этого кликаю мышкой на этот же выделенный итем и после этого опять запускаю скрипт.
Как он может это понять? Скрипт же не будет постоянно висеть в фоне и следить за всеми вашими действиями.
В который раз вас прошу описать конкретную ситуацию, при которой скрипт должен вести себя подобным образом. Иначе я так и не буду понимать ваших задач. Если дальнейшее выделение всё же планируется, почему для этого необходим дополнительный клик по айтему?
Для понимания. На данный момент принцип работы скрипта такой:
При первой активации айтем выделяется и запоминается. При следующей активации скрипт проверяет: если выделенный айтем и тот айтем, что был выделен на предыдущем шаге - это один и тот же объект, то работа скрипта прерывается. В противном случае выделяется и запоминается следующий айтем. Пока это единственное, до чего я додумался в целях предотвращения дальнейшего выделения. И другого пути решения пока что не вижу.

UPD: Могу предложить вариант, при котором при вторичном запуске выделение производиться не будет, а на третий раз работа снова возобновится. То есть, вместо клика по айтему вам нужно будет дважды запустить скрипт.
 
Последнее редактирование:
Интересно, сколько ещё страниц взаимоисключающей писанины тут будет, пока станет известно, что и без скрипта этого можно обойтись.
 
@@Michael, как тримить айтем (левый, правый его край)?
Что то по простому только через экшины нашёл. Может есть и в API?
 
Нужна помощь при создании экшена/скрипта
Есть трек/В нем айтемы/в них тейки. Нужно чтоб по нажатию шортката становился активным тейк который находится под мышкой и тут же курсор перескакивал на выбранный тейк и начиналось воспроизведение. Опять навел мышку на тейк другой, нажал шорткат, тейк активировался и с его начала пошло воспроизведение.

@Erundolog, Посмотри ещё это

Взять элемент под курсором мыши,выбрать,засолировать,начать воспроизведение(восстановить состояние без звука)
PHP:
--[[
   * ВАЖНО:
   * ПРИ ПОВТОРНОМ  ЗАПУСКЕ СКРИПТА ПОЯВИТСЯ ОКНО (Reascript task control):
   * ДЛЯ КОРЕКТНОЙ РАБОТЫ СКРИПТА СТАВИМ ГАЛКУ
   * (Remember my answer for this script) НАЖИМАЕМ New instance
   -------------------
   * Category:    item
   * Description: take item under mouse cursor,select,solo take,start play
                                                              ( restore mute state )
   * Oписание:    взять элемент под курсором мыши,выбрать,засолировать,
                             начать воспроизведение(восстановить состояние без звука)
   * Author:      Archie
   * Version:     1.0
--==================================================================================]]


    --local function msg(param);reaper.ShowConsoleMsg(param.."\n")end
    -----------------------------------------------------------------------------
    local function No_Undo()end; local function no_undo()reaper.defer(No_Undo)end
    -----------------------------------------------------------------------------



    local function SaveMuteStateAll_Item()

        local guitem,mute,item = '',''
        --reaper.DeleteExtState( 'Archie_guit_cur_it䴎', 'Archie_guit_cur_it䴎', false )
        --reaper.DeleteExtState( 'Archie_mute_cur_it䵵', 'Archie_mute_cur_it䵵', false )
        for i = 1,  reaper.CountMediaItems( 0 ) do
            item = reaper.GetMediaItem(0, i - 1)
            guitem = guitem..reaper.BR_GetMediaItemGUID( item )
            mute = mute..'&'..reaper.GetMediaItemInfo_Value( item, 'B_MUTE')
        end
        reaper.SetExtState( 'Archie_guit_cur_it䴎', 'Archie_guit_cur_it䴎', guitem, false )
        reaper.SetExtState( 'Archie_mute_cur_it䵵', 'Archie_mute_cur_it䵵', mute, false )
    end
    ---

    local function RestoreMuteStateAll_Item()
       ----
        local resguitem = reaper.GetExtState('Archie_guit_cur_it䴎', 'Archie_guit_cur_it䴎')
        local restomute = reaper.GetExtState('Archie_mute_cur_it䵵', 'Archie_mute_cur_it䵵')

        local x, y = 0, 0

        for guid_i in string.gmatch(resguitem, '{..-}' ) do
            local it = reaper.BR_GetMediaItemByGUID( 0, guid_i )
            if it then
            -------
                for mute_i in string.gmatch(restomute, "[^&]+") do
                    if x == y then
                        reaper.SetMediaItemInfo_Value( it, 'B_MUTE', mute_i)
                      break
                    end
                    y = y + 1
                end
                y = 0
                x = x + 1
            -------------
            end
        end
        reaper.DeleteExtState( 'Archie_guit_cur_it䴎', 'Archie_guit_cur_it䴎', false )
        reaper.DeleteExtState( 'Archie_mute_cur_it䵵', 'Archie_mute_cur_it䵵', false )
    end



    local count_item = reaper.CountMediaItems( 0 )
    if count_item == 0 then
        no_undo()
       return
    end



    local window, segment, details = reaper.BR_GetMouseCursorContext()
    local item = reaper.BR_GetMouseCursorContext_Item()
    if not item then no_undo() return end


    local it_track = reaper.GetMediaItem_Track( item )
    local mute_tr = reaper.GetMediaTrackInfo_Value( it_track, 'B_MUTE')
    if mute_tr == 1 then no_undo() return end


    reaper.PreventUIRefresh(1)
    reaper.Undo_BeginBlock()

    local position = reaper.GetMediaItemInfo_Value( item, 'D_POSITION' )

    reaper.SelectAllMediaItems( 0, 0 )
    reaper.SetMediaItemSelected( item, 1 )

    local take = reaper.BR_GetMouseCursorContext_Take()
    reaper.SetActiveTake( take )

    reaper.SetEditCurPos( position, 0, 0 )


    RestoreMuteStateAll_Item()
    SaveMuteStateAll_Item()

    for i = 1,count_item  do

        local items = reaper.GetMediaItem(0, i - 1)
        local sel = reaper.GetMediaItemInfo_Value(items, 'B_UISEL')
        if sel == 0 then
            reaper.SetMediaItemInfo_Value(items, 'B_MUTE', 1)
        else
            reaper.SetMediaItemInfo_Value(items, 'B_MUTE', 0)
        end
    end

     reaper.OnPlayButton()
     reaper.UpdateArrange()


     reaper.Undo_EndBlock([[take item under mouse cursor,select,solo
                              take,start play(restore mute state )]],1)
     reaper.PreventUIRefresh(-1)


     function main()

        local cur = reaper.GetPlayState()
        local Selitem = reaper.GetSelectedMediaItem(0, 0)
        if cur == 0 or cur == 2 or not Selitem then
            def = 1
            reaper.OnStopButton()
            RestoreMuteStateAll_Item()
            reaper.UpdateArrange()
        end
        --if not tonumber(t)then t=0 else t=tonumber(t)end t=t+1 msg(t)
        if not def then reaper.defer(main) else reaper.atexit(main) end
     end

     main()

Взять элемент под курсором мыши,выбрать,засолировать,начать воспроизведение,смотреть элементы в фоновом режиме(восстановить состояние без звука)
обратить внимание на 15 строку
PHP:
--[[
   * ВАЖНО:
   * ПРИ ПОВТОРНОМ  ЗАПУСКЕ СКРИПТА ПОЯВИТСЯ ОКНО (Reascript task control):
   * ДЛЯ КОРЕКТНОЙ РАБОТЫ СКРИПТА СТАВИМ ГАЛКУ
   * (Remember my answer for this script) НАЖИМАЕМ New instance
   -------------------
   * Category:    item
   * Description: take item under mouse cursor,select,solo take,start play,
                                  watch items in background(restore mute state )
   * Oписание:    взять элемент под курсором мыши,выбрать,засолировать,начать
                                     воспроизведение,смотреть элементы в фоновом
                                         режиме(восстановить состояние без звука)
   * Author:      Archie
   * Version:     1.0
--================================================================================]]



    local ClickCursorItem = 1 --[[ Если 0 то не надо кликать по элементу,
                                  Если 1 то надо кликать по элементу ]]


    --local function msg(param);reaper.ShowConsoleMsg(param.."\n")end
    -----------------------------------------------------------------------------
    local function No_Undo()end; local function no_undo()reaper.defer(No_Undo)end
    -----------------------------------------------------------------------------


    local function SaveMuteStateAll_Item()

        local guitem,mute,item = '',''
        --reaper.DeleteExtState( 'Archie_guit_cur_it䴎', 'Archie_guit_cur_it䴎', false )
        --reaper.DeleteExtState( 'Archie_mute_cur_it䵵', 'Archie_mute_cur_it䵵', false )
        for i = 1,  reaper.CountMediaItems( 0 ) do
            item = reaper.GetMediaItem(0, i - 1)
            guitem = guitem..reaper.BR_GetMediaItemGUID( item )
            mute = mute..'&'..reaper.GetMediaItemInfo_Value( item, 'B_MUTE')
        end
        reaper.SetExtState( 'Archie_guit_cur_it䴎', 'Archie_guit_cur_it䴎', guitem, false )
        reaper.SetExtState( 'Archie_mute_cur_it䵵', 'Archie_mute_cur_it䵵', mute, false )
    end
    ---

    local function RestoreMuteStateAll_Item()
       ----
        local resguitem = reaper.GetExtState('Archie_guit_cur_it䴎', 'Archie_guit_cur_it䴎')
        local restomute = reaper.GetExtState('Archie_mute_cur_it䵵', 'Archie_mute_cur_it䵵')

        local x, y = 0, 0

        for guid_i in string.gmatch(resguitem, '{..-}' ) do
            local it = reaper.BR_GetMediaItemByGUID( 0, guid_i )
            if it then
            -------
                for mute_i in string.gmatch(restomute, "[^&]+") do
                    if x == y then
                        reaper.SetMediaItemInfo_Value( it, 'B_MUTE', mute_i)
                      break
                    end
                    y = y + 1
                end
                y = 0
                x = x + 1
            -------------
            end
        end
        reaper.DeleteExtState( 'Archie_guit_cur_it䴎', 'Archie_guit_cur_it䴎', false )
        reaper.DeleteExtState( 'Archie_mute_cur_it䵵', 'Archie_mute_cur_it䵵', false )
    end



    local count_item = reaper.CountMediaItems( 0 )
    if count_item == 0 then
        no_undo()
       return
    end


    local function PlaySoloActiveTake()

        local window, segment, details = reaper.BR_GetMouseCursorContext()
        local item = reaper.BR_GetMouseCursorContext_Item()
        if not item then no_undo() return end


        local it_track = reaper.GetMediaItem_Track( item )
        local mute_tr = reaper.GetMediaTrackInfo_Value( it_track, 'B_MUTE')
        if mute_tr == 1 then no_undo() return end


        reaper.PreventUIRefresh(1)
        reaper.Undo_BeginBlock()

        local position = reaper.GetMediaItemInfo_Value( item, 'D_POSITION' )

        reaper.SelectAllMediaItems( 0, 0 )
        reaper.SetMediaItemSelected( item, 1 )

        local take = reaper.BR_GetMouseCursorContext_Take()
        reaper.SetActiveTake( take )

        reaper.SetEditCurPos( position, 0, 0 )


        RestoreMuteStateAll_Item()
        SaveMuteStateAll_Item()


        local count_item = reaper.CountMediaItems( 0 )
        for i = 1,count_item  do

            local items = reaper.GetMediaItem(0, i - 1)
            local sel = reaper.GetMediaItemInfo_Value(items, 'B_UISEL')
            if sel == 0 then
                reaper.SetMediaItemInfo_Value(items, 'B_MUTE', 1)
            else
                reaper.SetMediaItemInfo_Value(items, 'B_MUTE', 0)
            end
        end

         reaper.OnPlayButton()
         reaper.UpdateArrange()


         reaper.Undo_EndBlock([=[take item under mouse cursor,select,
                                solo take,start play,watch items in
                                 background (restore mute state )]=],1)    
         reaper.PreventUIRefresh(-1)
    end

    PlaySoloActiveTake()


    local function main()

        if ClickCursorItem == 0 then
            local window, segment, details = reaper.BR_GetMouseCursorContext()
        end
        local Selitem = reaper.GetSelectedMediaItem(0, 0)
        if Selitem then
            local guitem = reaper.BR_GetMediaItemGUID( Selitem )
            local ItemMouseCur = reaper.BR_GetMouseCursorContext_Item()
            if ItemMouseCur  then
               local  GuItemCur = reaper.BR_GetMediaItemGUID( ItemMouseCur )
               if guitem ~= GuItemCur then
                   PlaySoloActiveTake()
               else
                   if ClickCursorItem == 0 then
                       local take = reaper.BR_GetMouseCursorContext_Take()
                       reaper.SetActiveTake( take )
                       reaper.UpdateArrange()
                   end
               end
            end
        end
        --local def
        local PlayState = reaper.GetPlayState()
        if PlayState == 0 or PlayState == 2 or not Selitem then
            def = 1
            reaper.OnStopButton()
            RestoreMuteStateAll_Item()
            reaper.UpdateArrange()
        end
        --if not tonumber(t)then t=0 else t=tonumber(t)end t=t+1 msg(t)
        if not def then reaper.defer(main)else reaper.atexit(main)end
     end

     main()
 
Последнее редактирование:
  • Like
Реакции: Erundolog
@Archchie, Спасибо, кину в копилку. А можно попросить вторую версию скрипта которым до этого меня так выручил, с возможностью воспроизведения не с начала тейка а с положения курсора мыши ?
Я их буду оба использовать но в разных ситуациях
 
@Erundolog,
Так ?

PHP:
   -----------------------------------------------------------------------------
    local function No_Undo()end; local function no_undo()reaper.defer(No_Undo)end
    -----------------------------------------------------------------------------
  
  
  
    local window, segment, details = reaper.BR_GetMouseCursorContext()
  
    local item = reaper.BR_GetMouseCursorContext_Item()
    if not item then no_undo() return end

  
    reaper.Undo_BeginBlock()
    
    reaper.SelectAllMediaItems( 0, 0 )
  
    reaper.SetMediaItemSelected( item, 1 )
  
    local take = reaper.BR_GetMouseCursorContext_Take()
  
    reaper.SetActiveTake( take )
  
    local window, segment, details = reaper.BR_GetMouseCursorContext()
    positioncur = reaper.BR_GetMouseCursorContext_Position()
  
    reaper.SetEditCurPos( positioncur, 0, 0 )
  
    reaper.OnPlayButton()
  
    reaper.UpdateArrange()
  
    reaper.Undo_EndBlock("take item under cursor mouse, select play from mouse cursor",1)
 
Последнее редактирование:
  • Like
Реакции: Erundolog
@Oliver_Cray, Script: me2beats_Select all tracks with name X (without input box).lua
Изначально там имя Buss вписано, в скрипте меняешь на свое, там где локал нейм вначале
 
  • Like
Реакции: Oliver_Cray
Как можно выбрать трек по имени (части имени)?

@Oliver_Cray, Script: me2beats_Select all tracks with name X (without input box).lua
Изначально там имя Buss вписано, в скрипте меняешь на свое, там где локал нейм вначале
данный скрипт не позволит выбрать треки по ЧАСТИ имени, а только по полному. К тому же не всегда удобно постоянно менять скрипт (сегодня нужно выделить все DRUM, завтра - все GUIT и т.д.), - чем менять постоянно скрипт, будет быстрее выбрать через Track Manager.

Было бы здорово заиметь скрипт по методу:
нажал на хоткей, всплыло окно, набрал туда к примеру GUIT, нажал ENTER, и все треки, где в названии есть данный набор символов, - выделились
 
@Supa75, лично мне удобнее без вопроса. Мне нужно выбирать одни и те же папки, месторасположение которых меняется.
 
нажал на хоткей, всплыло окно, набрал туда к примеру GUIT, нажал ENTER, и все треки, где в названии есть данный набор символов, - выделились

лично мне удобнее без вопроса. Мне нужно выбирать одни и те же папки, месторасположение которых меняется.
Проверяйте.

PHP:
--[[
   * Category:    Track
   * Description: Select a track by name (with an input field or keyword. instruction inside script)
   * Oписание:    Выберите трек по имени (с полем ввода или ключевым словом. инструкция внутри скрипта)
   * Author:      Archie
   * Version:     1.0
--===================================================================================================]]


    local Message_box_to_input_the_name = [[1]] 
                                   --  = [[1]] " Show message box to enter name.Otherwise, enter 
                                   --  keywords separated by commas without spaces.
                                   --  "Example: = [[drums,track,folder]] 
                                       ------------------------------------
                                   --  = [[1]] "Показать окно сообщения для ввода имени.В противном 
                                   --  случае, введите ключевые слова, разделенные запятыми без пробелов.
                                   --  "Пример: = [[барабаны,трек,папка]]
                                                               

    local Message_Unselect = (1)   --  Message_Unselect; = 1 show window with warning and choice, = 0 don't show a
                                   --  warning window and does not remove the selection, = -1 do not show
                                   --  the warning window,and unselect the previous tracks
                                   --   ---------------------------------------------------
                                   --  Отменить_Выбор_Сообщения; = 1 показать окно с предупреждением и выбором, 
                                   --  = 0 не показывать окно с предупреждением и не снимать выделение,  = -1
                                   --  не показывать окно с предупреждением и  снять выделение
                                   --  с предыдущих треков'
                 


    -----------------------------------------------------------------------------
    local function No_Undo()end; local function no_undo()reaper.defer(No_Undo)end
    -----------------------------------------------------------------------------


    local CountSelTr = reaper.CountSelectedTracks()
    if CountSelTr == 0 then Message_Unselect = 0 end
   
   
    local CountTr = reaper.CountTracks()
   
    local Message,Undo,retval,ret_csv
   
    if Message_box_to_input_the_name == '1' then
        retval, ret_csv = reaper.GetUserInputs( 'Select track by name', 1, 'Enter the name of the track', 'name')
        if retval == false then no_undo() return end
    else
        ret_csv = Message_box_to_input_the_name 
    end
   
   
    reaper.PreventUIRefresh(1)


    for i = 1,CountTr do
        local track = reaper.GetTrack(0,i-1)
        retval, _ = reaper.GetTrackState( track )
        for symbol in string.gmatch(retval, "[^%s]+") do
            for ret in string.gmatch(ret_csv, "[^,]+") do
                if symbol == ret then
                    Undo = 1
                    if Message_Unselect == 1 then
                        Message = reaper.ShowMessageBox( 'Unselected All track ?','Select track by name', 1 )
                        Message_Unselect = 0
                     elseif Message_Unselect == 0 then
                        Message = 0
                     elseif Message_Unselect == -1 then
                        Message = 1
                     end
                     if Message == 1 then
                        local tr = reaper.GetTrack(0, 0)
                        reaper.SetOnlyTrackSelected(tr)
                        reaper.SetTrackSelected(tr, 0)
                     end 
                     reaper.SetTrackSelected(track,1)
                end   
            end         
        end
    end
    reaper.PreventUIRefresh(-1) 


    if Undo ~= 1 then
       no_undo()
    else
       reaper.Undo_BeginBlock()
       reaper.Undo_EndBlock("Select track by name",1)
    end
 
Последнее редактирование:
не работает у меня чего-то
qwe.gif
 
не работает у меня чего-то
Так он по слогам не умеет работать ,введите одно любое слово от имени трека целиком и будет все работать.
Например: Имя трека "Трек 1" , введите либо Трек, либо 1
 
Последнее редактирование:
Как можно выбрать трек по имени (части имени)?
1. Использовать Track manager, вписывая в фильтр всё что угодно. Дополнительные квантификаторы:
vo NOT ka оставит треки с vo, но без ka
ka AND o оставит треки с ka и c o
vo OR ro оставит треки с vo или с ro
Далее достаточно кликнуть на нужный трек в нём и он выделится в TCP/MCP
2. Использовать ReaConsole. Можно запускать сразу с нужным параметром: SWS: Open console with 'S' to select track(s)
Этот метод не такой мощный, потому что не работают квантификаторы, зато можно выделять трек под нужным номером, вписывая s 1 для выделения первого трека. Ну и в консоли надо писать первые буквы трека, иначе не работает, в отличие от Track manager.
@borisuperful, @Supa75, @Archchie,
P.S. Совет на будущее: прежде чем работать со скриптами, надо разобраться со встроенным функционалом. :)
 
  • Like
Реакции: Aleksandr Oleynik
@Supa75, Лови проверяй,сейчас поправил , теперь выделяет треки по части имени - вплоть до одной буквы. Вводишь первую букву имени трека и скрипт поймет или несколько названий через запятую или пробел(можно так же сокращенно)
111.gif 222.gif
Обновленно. / 4.06.
Исправлена проблема с кирилецей. Если у трека было имя на русском языке то вылетала ошибка
PHP:
--[[
   * Category:    Track
   * Description: Select a track by name (with the"abbreviated input" input
                                                           field or keyword. instruction inside the script)
   * Oписание:    Выберите трек по имени (с полем ввода"сокращенный ввод" или
                                                            ключевым словом. инструкция внутри скрипта)
   * Author:      Archie
   * Version:     1.0
--===================================================================================================]]

     -- Enter keywords or a part of a word in the search field, separated by commas or spaces
     -- Введите ключевые слова или часть слова в поле поиска, разделенные запятыми или пробелами



    local Message_box_to_input_the_name = [[1]]
                                           --  = [[1]] " Show message box to enter name.Otherwise, enter
                                          --  keywords separated by commas.
                                         --  "Example: = [[drums,track, folder]]
                                        -----------------------------------------------
                                       --  = [[1]] "Показать окно сообщения для ввода имени.В противном
                                      --  случае, введите ключевые слова, разделенные запятыми
                                     --  "Пример: = [[барабаны,трек, папка]]


    local Message_Unselect = (2)  --  Message_Unselect;
                                 --  = 2 show window with warning and choice,
                                --  = 0 don't show a warning window and does not remove the selection,
                               --   = 1 do not show the warning window,and unselect the previous tracks
                              -----------------------------------------------
                             --  ОкноСообщенияОбОтменеВыбораПредыдущих;
                            --  = 2 показать окно с предупреждением и выбором,
                           --  = 0 не показывать окно с предупреждением и не снимать выделение,
                          --  = 1 не показывать окно с предупреждением и снять выделение
                         --  с предыдущих треков'
                        -------------------------------------------


    -----------------------------------------------------------------------------
    local function No_Undo()end; local function no_undo()reaper.defer(No_Undo)end
    -----------------------------------------------------------------------------



    local CountSelTr = reaper.CountSelectedTracks()
    if CountSelTr == 0 then Message_Unselect = 0 end


    local CountTr = reaper.CountTracks()

    local Message, Undo, retval, ret_csv

    if Message_box_to_input_the_name == '1' then
        retval, ret_csv = reaper.GetUserInputs( 'Select track by name', 1, 'Enter the name of the track ', 'name')
        if retval == false then
           no_undo()
           return
        end
    else
        ret_csv = Message_box_to_input_the_name
    end

    local CountString = string.len(ret_csv)
    if CountString == 0 then
        no_undo() return
    end
    local CountString = nil


    reaper.PreventUIRefresh(1)


    for i = 1, CountTr do
        local track = reaper.GetTrack(0, i - 1)
        local retval, _ = reaper.GetTrackState( track )
   
        for var in string.gmatch(ret_csv, "[^%s^,]+") do
                           -- http://marker.to/YWIbtQ
            local CountString = string.len(var)
                              -- http://marker.to/OB9uXO
            for symbol in string.gmatch(retval, "[^%s^,^-]+") do
         
                local Y, B, S = 0, '', symbol
                for var in string.gmatch(S,".") do
                    B = B..var
                    Y = Y + 1
                    if Y == CountString then break end
                end

                if B == var then
                    Undo = 1
                    if Message_Unselect == 2 then
                        Message = reaper.ShowMessageBox( 'Unselected All track ?', 'Select track by name', 1 )
                    elseif Message_Unselect == 1 then
                        Message = 1
                    elseif Message_Unselect == 0 then
                        Message = 2
                    end
                    Message_Unselect = 0
                    if Message == 1 then
                        local tr = reaper.GetTrack(0, 0)
                        reaper.SetOnlyTrackSelected(tr)
                        reaper.SetTrackSelected(tr, 0)
                    end
                    reaper.SetTrackSelected(track, 1)
                end
            end
        end
    end

    reaper.PreventUIRefresh(1*0)

    if Undo ~= 1 then
        no_undo()
    else
        reaper.Undo_BeginBlock()
        reaper.Undo_EndBlock("Select track by name", 1)
    end
 
Последнее редактирование:
P.S. Совет на будущее: прежде чем работать со скриптами, надо разобраться со встроенным функционалом.
Вот-Вот это точно!!!
Только теперь покажите мне как при помощи Track manager-a и одного нажатия выделить все треки в проекте с определенными именами ???
 
Последнее редактирование:
Довольно специфичная идея для создания скрипта, но при подборе динамики для нот может очень зайти. Фишка в стретчинге велосити в геометрической прогресии, не изменяя сами ноты. Методом кастомов смог сделать стретчинг "в одну сторону", а в другую уже сложно. На гифки перый стретч - это кастом, второй стретч - обыкновенный undo history.
2018-06-02_02-46-03.gif
Кастом такой:
Код:
SWS/BR: Save note selection from active item, slot 01
Script: mpl_Stretch selected MIDI notes positions by x0.5.lua
Script: me2beats_Select only odd notes.lua
Script: mpl_Copy selected notes velocities.lua
SWS/BR: Restore note selection to active item, slot 01
Script: mpl_Stretch selected MIDI notes positions by x2.lua
Script: mpl_Paste selected notes velocities.lua
 
Я ДАЛ 2 СПОСОБА - ЧЕРЕЗ КОНСОЛЬ ЭТО ДЕЛАЕТСЯ.
Через СВСовскую консоль не разу не чего не делал,сейчас попробовал-так то ничего ,если бы не одно но.
С сокращенными именами она не работает "то есть работает ,но не понятно как, из множества вариаций имен у меня сработала только с одним именем (один раз)"(см.gif 1).
И если имя состоит из цифр - например: 11 или 22 ,12 и т.д. ( у меня частенько например такое бывает на начальном этапе), то все приплыли, консоль не работает (см.gif 2)., то есть выбирает не по имени ,а по номеру,(а должна по идеи сначала просчитать все имена и если таковы не найдены ,то перейти к нумерации треков )
333.gif 3033.gif
 
Последнее редактирование:
Через СВСовскую консоль не разу не чего не делал,сейчас попробовал-так то ничего ,если бы не одно но.
С сокращенными именами она не работает
Я сначала тоже не понял, но потом разобрался - либо пишете номер трека, либо первые буквы, которые индивидуальны для одного трека.
То есть если у вас есть 4 трека: Admin, Administrator, Admiral, Admak, то первый выделить можно только по номеру или полному имени(как и все остальные), второй по admini, третий по admir, а четвёртый по adma. Если треки называются одинаково, то только по полному имени.
Кстати, консоль можно использовать в cycle/custom экшнах и скриптах.
О консоли написано тут: http://www.sws-extension.org/reaconsole.php

то есть выбирает не по имени ,а по номеру
Да, к сожалению, такие треки не выделить этим способом.
Зато можно использовать Track manager. Закрепляете его в докер и можно выделять.
mix.gif
 
Подскажите, есть скрипт Create stretch-markers at transients от Евгения, возможно ли как-то сделать, чтобы он в истории сохранялся? Закрываю скрипт и после первого редактирования маркеров нажимаю ctrl+z - у меня все маркеры стираются. Но только в том случае, если в скрипте начинаешь что-то редактировать. Где-то на этом этапе, когда вносишь изменения в скрипте, я так понимаю нужно вписать UndoBeginBlock и UndoEndBlock, но как именно?
UPD: Все, получилось, надо было Undo_BeginBlock и Undo_EndBlock вводить:)
 
Последнее редактирование:
Create stretch-markers at transients, с историей разобрался, тогда второй вопрос, как сделать, чтобы он понимал несколько выделенных айтемов?
Код:
/*
   * ReaScript Name:Create stretch-markers at transients
   * Lua script for Cockos REAPER
   * Author: EUGEN27771
   * Author URI: http://forum.cockos.com/member.php?u=50462
   * Licence: GPL v3
   * Version: 1.01
*/

// -- Script creates stretch-markers at transients
function slider_New(x,y,w,h, r,g,b,a, lbl, val,min_val,max_val)
(
  this.x = x; this.y = y; this.w = w; this.h = h; // coord
  this.r = r; this.g = g; this.b = b; this.a = a; // color
  this.lbl = lbl;
  this.min_val = min_val;
  this.max_val = max_val;
  this.val = val;
  this.norm_val = (val - min_val)/(max_val - min_val);; // norm value
);

//-- Get mouse ---------------
function pointIN(p_x, p_y)
( // if point in obj area
  p_x>=this.x && p_x <= this.x+this.w &&
  p_y>=this.y && p_y <= this.y+this.h;
);

function mouseIN()
( // if mouse in obj area
  mouse_cap&1==0 && this.pointIN(mouse_x, mouse_y);
);

function mouseDown()
( // if mouse will be pressed in obj area
  mouse_cap&1==1 && this.pointIN(mouse_ox,mouse_oy);
);

function mouseUp()
( // if mouse released(anywhere) and will be pressed in obj area
  mouse_cap&1==0 && this.pointIN(mouse_ox,mouse_oy);
);

//-- Set value ---------------
function set_value()
local(norm_val, K )
(
  K = 10; // K = coeff(when Ctrl pressed)
  Ctrl ? (
    norm_val = this.norm_val + ((mouse_x-last_x)/(this.w*K));
  ) : (
    norm_val = (mouse_x-this.x)/this.w;
  );
 
  this.norm_val = min( max(norm_val,0), 1 ); // verify and set value
  this.val = this.min_val + (this.max_val-this.min_val) * this.norm_val;
);

//-- Draw slider -------------
function slider_draw()
  local(x,y,w,h, r,g,b,a, lbl,lbl_w,lbl_h, val,val_w,val_h)
(
  x=this.x; y=this.y; w=this.w; h=this.h;
  r=this.r; g=this.g; b=this.b; a=this.a;
  lbl=this.lbl;
  this.mouseIN() ? a=a+0.1;
  this.mouseDown() ? (
    a=a+0.2;
    this.set_value();
    //this.onMove();
  );
  this.mouseUp() ? (
    //this.onUp();
    RunMain = 1;
    mouse_ox = mouse_oy = -1; // reset mouse
  );
  //-- draw body, frame ---
  gfx_set(r,g,b,a);
  gfx_rect(x,y,w,h, 0);
  gfx_rect(x,y,w*this.norm_val,h, 1);
  //-- draw label ---------
  gfx_set(0.9,0.8,0.5,1);
  gfx_measurestr(lbl, lbl_w, lbl_h);
  gfx_x = x+5; gfx_y = y+(h-lbl_h)/2;
  gfx_drawstr(lbl);
  //-- draw value ---------
  val = sprintf(#, "%.2f", this.val);
  gfx_measurestr(val, val_w, val_h);
  gfx_x = x+w-val_w-5; gfx_y = y+(h-val_h)/2;
  gfx_drawstr(val); // draw Slider Value

);

//==========================================================================================================//

//-- Create Sliders --------------------------
//-- args = (x,y,w,h, r,g,b,a, lbl, val,min_val,max_val)
Thresh.slider_New(10,10,260,18, 0.5,0.5,0.5,0.3, "Threshold dB",   -10, -60,   0 );
Sens.slider_New(10,30,260,18, 0.5,0.5,0.5,0.3, "Sensetivity dB",  4.5,   0,  18 );
Retrig.slider_New(10,50,260,18, 0.5,0.5,0.5,0.3, "Retrig ms",  20,  20, 450 );


//==========================================================================================================//

//--------------------------------------------------------------------------------
//---  Simple Detect Transients Function  ----------------------------------------
//--------------------------------------------------------------------------------
function DetectTransients(item, srate, Threshold_dB, Sensitivity_dB, Retrig_sec)
  local(Threshold, Sensitivity, Retrig,
        attTime1, relTime1, attTime2, relTime2, ga1, gr1, ga2, gr2, envOut1, envOut2
        take, item_len, item_len_smpls,
        AA, starttime_sec, samplebuffer, n_blocks, input, smpl, mrk_pos, retrig_cnt)
(   
  //-- Threshold, Sensitivity, Retrig to norm values ---
  Threshold   = 10^(Threshold_dB/20);    //-- Threshold_dB - to norm value
  Sensitivity = 10^(Sensitivity_dB/20);  //-- Sensitivity_dB - to norm value
  Retrig      = floor(Retrig_sec*srate); //-- Retrig_sec - to samples

  //-- Envelopes Attack, Release Time -----------------
  attTime1 = 0.001;           //-- Env1(fast) attack(sec)
  relTime1 = 0.010;           //-- Env1(fast) release(sec)
  attTime2 = 0.007;           //-- Env2(slow) attack(sec)
  relTime2 = 0.015;           //-- Env2(slow) release(sec)

  //-- Compute sample frequency related coeffs --------
  ga1 = exp(-1/(srate*attTime1));  //-- attack1 coeff
  gr1 = exp(-1/(srate*relTime1));  //-- release1 coeff
  ga2 = exp(-1/(srate*attTime2));  //-- attack2 coeff
  gr2 = exp(-1/(srate*relTime2));  //-- release2 coeff
  //---------------------------------------------------
  envOut1 = 0;
  envOut2 = 0;
    //-- item, take data ------------------------------
    take = GetActiveTake(item);
    playrate  = GetMediaItemTakeInfo_Value(take, "D_PLAYRATE"); // get orig playrate
    SetMediaItemTakeInfo_Value(take, "D_PLAYRATE", 1);          // set playrate = 1
    item_len  = GetMediaItemInfo_Value(item, "D_LENGTH");
    item_len_smpls = floor(item_len*srate);
    //-------------------------------------------------
    AA = CreateTakeAudioAccessor(take);
    starttime_sec = 0;
    samplebuffer = 0;
    n_blocks = ceil(item_len_smpls/65536);
 
    // -- Detect Transients --------------------------------
    loop(n_blocks,
        GetAudioAccessorSamples(AA, srate, 1, starttime_sec, 65536, samplebuffer);
        smpl=0;
        loop(65536,
            input = abs(samplebuffer[smpl]); // abs sample value(abs envelope)

            // -- Envelope1(fast) --------------------------
            envOut1 < input ? (
              envOut1 = input + ga1*(envOut1 - input);
            ) : (
              envOut1 = input + gr1*(envOut1 - input);
            );
         
            // -- Envelope2(slow) --------------------------
            envOut2 < input ? (
              envOut2 = input + ga2*(envOut2 - input);
            ) : (
              envOut2 = input + gr2*(envOut2 - input);
            );
         
            // -- Trigger ----------------------------------
            retrig_cnt > Retrig ? (
              envOut1 > Threshold && envOut1/envOut2 > Sensitivity ? (
                mrk_pos = starttime_sec + smpl/srate;    // Calc mrk pos
                SetTakeStretchMarker(take, -1, mrk_pos); // Insert marker
                retrig_cnt = 0;
              );             
            ) : (         
              envOut2 = envOut1; // уравнивает огибающие, пока триггер неактивен(здесь важно)
              retrig_cnt+=1;
            );               
            smpl+=1; 
        );
        starttime_sec+=65536/srate; // To next block
    );
  DestroyAudioAccessor(AA);
  SetMediaItemTakeInfo_Value(take, "D_PLAYRATE", playrate); // restore orig playrate         
  UpdateTimeline();       
);


//==========================================================================================================//
function MAIN()
local(item, srate, Threshold_dB, Sensitivity_dB, Retrig_sec)
(
  Undo_BeginBlock();
  item = GetSelectedMediaItem(0, 0);
 
    item ? (
    //-- Detection settings --
    srate = 44100;
    Threshold_dB   = Thresh.val;
    Sensitivity_dB = Sens.val;
    Retrig_sec     = Retrig.val/1000;
    Main_OnCommand(41844, 0);  // remove old str-marks(All)
    //------------------------
    start = time_precise();
    DetectTransients(item, srate, Threshold_dB, Sensitivity_dB, Retrig_sec);
    //ShowConsoleMsg(sprintf(#, "%f \n", time_precise()-start); );
  );
Undo_EndBlock("Add stretch markers at transients",-1)
);

//----------------------------
function Draw_Sliders()
(
  Thresh.slider_draw();
  Sens.slider_draw();
  Retrig.slider_draw();
);

//-- mainloop ----------------
function mainloop()
(
  //-- mouse and modkeys --
  mouse_cap&1==1 && last_mouse_cap&1==0  ||       //-- L mouse
  mouse_cap&2==2 && last_mouse_cap&2==0  ||       //-- R mouse
  mouse_cap&64==64 && last_mouse_cap&64==0 ? (    //-- M mouse
    mouse_ox = mouse_x; mouse_oy = mouse_y;
  );

  Ctrl  = mouse_cap&4==4;   //-- Ctrl  state
  Shift = mouse_cap&8==8;   //-- Shift state
  Alt   = mouse_cap&16==16; //-- Shift state
  //-- Main functions etc --
  Draw_Sliders();
  RunMain ? (MAIN(); RunMain = 0;);
  //------------------------
  last_mouse_cap = mouse_cap;
  last_x = mouse_x; last_y = mouse_y;
  char = gfx_getchar();
  char >= 0 ? defer("mainloop();");
  gfx_update();
);

//-- init --------------------
function init()
  local(width, height, dockstate, xpos, ypos)
( //-- window -----------
  width = 280; height = 80; dockstate = 0; xpos = 200; ypos = 300;
  gfx_init("Create stretch-markers at transients(eel)",width,height,dockstate,xpos,ypos);
  gfx_clear = 25 + 25*256 + 25*65536;
  //-- Init mouse -------
  last_mouse_cap = 0;
  last_x = last_y = 0;
  mouse_ox = mouse_oy = -1;
  gfx_setfont(1, "Arial", 15);
);

RunMain = 1;// for first run
init();
mainloop();
 
Последнее редактирование:

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