Archie-reascript: обсуждение, пожелания, сообщения об ошибках. (2 онлайн)

Нет, не правильно. Было две ноты, а должно стать три?
Как по мне, то да - должно стать три, если с этим экшеном заморочились, то должны были учесть и вставить ноту, т.к. экшен должен перекрывающей нотой вырезать кусок, а так как он работает я вообще не вижу в нем смысла никакого.
Посмотреть вложение 167034
Мод для дублирования к месту под курсором с учётом сетки
JavaScript:
-- @description Smart duplicate events
-- @version 1.01
-- @author MPL
-- @website http://forum.cockos.com/showthread.php?t=188335
-- @changelog
--    # fix maxppq var miss

-----------------------------------------------------------------------------------------
  function SmartDuplicateNotes(pos)
    local  ME = MIDIEditor_GetActive()
    if not ME then return end
    local take = MIDIEditor_GetTake(ME)
    if not take then return end
    local data = ParseRAWMIDI(take)
    local item = GetMediaItemTake_Item( take )
    local item_pos =  GetMediaItemInfo_Value( item, 'D_POSITION')
    local ret, ppq_shift = CalcShift(item, item_pos, take, data, pos)
    if not ret then return end
     extendMIDI, noteoff_ppq = AddShiftedSelectedEvents(take, data, ppq_shift )
    if extendMIDI then
      local start_qn =  TimeMap2_timeToQN( 0, item_pos )
      local end_qn =  reaper.MIDI_GetProjQNFromPPQPos( take, noteoff_ppq )
      MIDI_SetItemExtents(item, start_qn, end_qn)
    end
  end
-----------------------------------------------------------------------------------------
  function ParseRAWMIDI(take)
      local data = {}
      local gotAllOK, MIDIstring = MIDI_GetAllEvts(take, "")
      if not gotAllOK then return end
      local s_unpack = string.unpack
      local s_pack   = string.pack
      local MIDIlen = MIDIstring:len()
      local idx = 0
      local offset, flags, msg1
      local ppq_pos = 0
      local nextPos, prevPos = 1, 1
      while nextPos <= MIDIlen do
       
          prevPos = nextPos
          offset, flags, msg1, nextPos = s_unpack("i4Bs4", MIDIstring, prevPos)
          idx = idx + 1
          ppq_pos = ppq_pos + offset
          data[idx] = {rawevt = s_pack("i4Bs4", offset, flags , msg1),
                            offset=offset,
                            flags=flags,
                            selected =flags&1==1,
                            muted =flags&2==2,
                            msg1=msg1,
                            ppq_pos = ppq_pos,
                            isNoteOn =msg1:byte(1)>>4 == 0x9,
                            isNoteOff =msg1:byte(1)>>4 == 0x8,
                            isCC = msg1:byte(1)>>4 == 0xB,
                            chan = 1+(msg1:byte(1)&0xF),
                            vel=vel}


      end
      return data
  end
-----------------------------------------------------------------------------------------
  function CalcShift(item, item_pos, take, data, pos)
    local min_ppq, max_ppq
    ppq_pos = reaper.MIDI_GetPPQPosFromProjTime( take, pos )
    for i =1, #data do
      if data[i].selected and not min_ppq then min_ppq = data[i].ppq_pos end
      if data[i].selected                 then max_ppq = data[i].ppq_pos end  
    end
    if not max_ppq or not min_ppq then return end
    local ppq_dif = ppq_pos-max_ppq--max_ppq - min_ppq
    local time_dif = MIDI_GetProjTimeFromPPQPos(take, ppq_dif) - item_pos
    local retval, measures, cml = TimeMap2_timeToBeats(0, time_dif)
    local time_of_measure = TimeMap2_beatsToTime(0, 0, 1)
    local measure_ppq = MIDI_GetPPQPosFromProjTime(take, time_of_measure+ item_pos)
    local ppq_shift = measure_ppq * (measures+1)
    return true, math.floor(ppq_shift)
  end
-----------------------------------------------------------------------------------------
  function AddShiftedSelectedEvents(take, data, ppq_shift )
    local str = ''
    local last_ppq
    for i = 1, #data-1 do  
      local flag
      if data[i].flags&1==1 then flag = data[i].flags-1 else flag = data[i].flags end
      local str_per_msg = string.pack("i4Bs4", data[i].offset, flag , data[i].msg1)
      str = str..str_per_msg
      last_ppq = data[i].ppq_pos
    end
 
    for i = 1, #data-1 do
      if data[i].selected then
        local new_ppq = data[i].ppq_pos + ppq_shift
        local str_per_msg = string.pack("i4Bs4", new_ppq-last_ppq, data[i].flags , data[i].msg1)
        str = str..str_per_msg
        last_ppq = new_ppq
      end
    end
 
    local noteoffoffs = data[#data].ppq_pos -last_ppq
    if data[#data].ppq_pos < last_ppq then noteoffoffs = 1 end
    str = str.. string.pack("i4Bs4", noteoffoffs, data[#data].flags , data[#data].msg1)
    MIDI_SetAllEvts(take, str)
 
    if data[#data].ppq_pos < last_ppq then return true, noteoffoffs + last_ppq  end
  end

-----------------------------------------------------------------------------------------
    function CheckFunctions(str_func)
      local SEfunc_path = reaper.GetResourcePath()..'/Scripts/MPL Scripts/Functions/mpl_Various_functions.lua'
      local f = io.open(SEfunc_path, 'r')
      if f then
        f:close()
        dofile(SEfunc_path)
     
        if not _G[str_func] then
          reaper.MB('Update '..SEfunc_path:gsub('%\\', '/')..' to newer version', '', 0)
         else
          --
          BR_GetMouseCursorContext()
          pos = BR_GetMouseCursorContext_Position()
          if pos > 0 then
            Undo_BeginBlock2( 0 )
            SmartDuplicateNotes(pos)
            Undo_EndBlock( 'Smart duplicate notes', -1)
          end
        end    
       else
        reaper.MB(SEfunc_path:gsub('%\\', '/')..' missing', '', 0)
      end
    end
  --------------------------------------------------------------------
  CheckFunctions('SetFXName')

Что то он сильно промахивается мимо мыши, особенно когда дублируешь в лево.
Да и зачем ? Я же сделал.

осле второго пункта рипер не понимает какую ноту закрывать, для предупреждения таких ситуаций и придумали режим, который убивает overlapped notes и делает следующее:
Это в рипере так придумали. В не одной другой же daw нету таких глюков с миди как в рипере.
 
Последнее редактирование:
должны были учесть и вставить ноту
Это уже ты придумываешь на ходу. Режим придуман по факту для исправления имеющегося миди стрима, а не добавления инфы в него. Для какой-нибудь железки не нужна лишняя нота, железке важнее, чтоб в неё скормили корректное миди. Особенно это актуально для всякой полифонии.

Это в рипере так придумали. В не одной другой же daw нету таких глюков с миди как в рипере.

Потому что в %других_DAW% используют модифицированный протокол MIDI, который обходит ограничения стандартного с разных сторон.
 
@AlexLazer, Привет!
167121
 
  • Like
Реакции: smrz1 и AlexLazer
Обновил сегодня перед записью скрипты и чуть не посидел во время работы. думал что-то сломалось)
@Archchie,
Script: Archie_Track; Zoom tracks in TCP to fit screen (Ctrl + Click save restore)Smart(`).lua удалён? Теперь - Script: Archie_View; Zoom TCP to fit screen.lua этот вместо смарта?
 
Script: Archie_Track; Zoom tracks in TCP to fit screen (Ctrl + Click save restore)Smart(`).lua удалён?
Да.
Теперь - Script: Archie_View; Zoom TCP to fit screen.lua этот вместо смарта?
Нет, он и был при смарте, я его только немного обновил, что бы автоматизация тоже учитывалась.
---------------
Вместо смарта посмотри этот скрипт: Arc_View; Zoom height full project - recover back.lua
Если не понравится, то смарт можешь скачать от сюда
 
  • Like
Реакции: YuriOl
smrz1 написал(а):
@Archchie, интересно, а вот есть такой скрипт - типа запрет на действие?
Просто бывает так, что в какой то последовательности действий происходит конфликт и было бы не плохо иметь возможность не позволяющую срабатывать экшену или скрипту в определённой ситуации...

Моя, твоя не понимать)).
В каком смысле запрет на действие ?
В рипере нету искусственного интеллекта и скрипту надо четко и подробно объяснять, что ему делать.

У меня назначено два скринсета - Screenset: Load window set #01 - (на F7) и Screenset: Load window set #05 - (на F6).

В скринсете на F7 я использую два кастома:
Custom: Mixer Big (Вкл/выкл большого, плавающего микшера в главном окне) - назначен на F3
Mixer: Toggle master track in docked window
Mixer: Toggle docking in docker
и
Custom: Toggle Mixer/Master track (Вкл/выкл Микшер+Мастер трек) - назначен на F1
Mixer: Toggle master track in docked window
View: Toggle mixer visible

Их поочерёдное включение:
Рис 1 исходное состояние скринсета на F7
Захват1.png


Рис 2 кастом на F3
Захват2.png


Рис 3 кастом на F1 (без микшера и мастер трека)
Захват3.png
Но если я, при включённом кастоме на F3, включу кастом на F1 - получается вот так:
Рис 4 Захват4.png
А если после этого нажать кастом на F3, то получается ещё хуже:
Рис 5 Захват5.png
Исправляется это только нажатием Screenset: Load window set #01 - (на F7)

В скринсете на F6 эти кастомы работают так же, но положение бывает ещё более не предсказуемым
Рис 6
Захват6.png
Как запретить использование любого из этих двух кастомов (на F1 или на F3), если хотя бы один из них уже включен?
 
Последнее редактирование:
Как запретить использование любого из этих двух кастомов (на F1 или на F3), если хотя бы один из них уже включен?
Кастом конечно остановить не как не получится, но если его засунуть в скрипт, то вот как то так.:Dle54:
Для кастомов F1 и F3 - Создаешь два новых скрипта с именами этих кастомов (имена любые) и вставляешь вот этот код
В строке "ACTION_ID" вставляешь id кастома или id всех экшенов которые в кастоме через запятую.
Для кастома:
Mixer: Toggle master track in docked window -- 41610
View: Toggle mixer visible -- 40078

строка будет выглядеть так
JavaScript:
    local ACTION_ID = {"41610","40078"};
JavaScript:
    local ACTION_ID = {"id","id","id"};
  
  
  
    --------------------------------------------
    local ExtState = tonumber(reaper.GetExtState("smrz1_Block_1","Block_smrz1"));
  
    if ExtState ~= 1 then;
        reaper.Undo_BeginBlock();
        for i = 1, #ACTION_ID do;
            reaper.Main_OnCommand(reaper.NamedCommandLookup(ACTION_ID[i]),0);
        end;
        local title = ({reaper.get_action_context()})[2]:match(".+[/\\](.+)");
        reaper.Undo_EndBlock(title,-1);
        reaper.SetExtState("smrz1_Block_1","Block_smrz1",1,true);
    end;
   
    --------------------------------------------

Для F7 создаешь скрипт с любым именем и вставляешь этот код и так же в первой строке вставляешь id экшена F7
Например для "Screenset: Load window set #01" строка будет выглядеть так
JavaScript:
    local ACTION_ID = {"40454"};
JavaScript:
    local ACTION_ID = {"id","id","id"};
  
  
    --------------------------------------------
    local HasExtState = reaper.HasExtState("smrz1_Block_1","Block_smrz1");
    if HasExtState then;
        reaper.DeleteExtState("smrz1_Block_1","Block_smrz1",true);
    end;
  
    reaper.Undo_BeginBlock();
  
    for i = 1, #ACTION_ID do;
        reaper.Main_OnCommand(reaper.NamedCommandLookup(ACTION_ID[i]),0);
    end;
    local title = ({reaper.get_action_context()})[2]:match(".+[/\\](.+)");
    reaper.Undo_EndBlock(title,-1);
    --------------------------------------------
Все - эти скрипты назначаешь вместо назначенных экшенов/кастомов и получится следующее
При нажатии на скрипты "F1 или F3" будет срабатывать блок и эти скрипты больше не будут запускаться до того момента, пока ты не запустишь скрипт F7, а при запуске скрипта F7 блок будет сниматься с тех скриптов.
 
Последнее редактирование:
@Archchie, Ого!:Dle79:Сейчас сделаю... А скрипт должен быть lua или eel?:Dle47:
Скрипты в автозагрузке должны быть?
 
@Archchie, всё получилось, но вышла другая штука (чем то похожая на первичную проблему):
Изначально, нажимая F3, у меня открывался и закрывался "Большой микшер" - это удобно и привычно, как в других DAW.
Нажимая F1, у меня скрывались мастер-трек и микшер. В главном окне - только треки на весь экран (ТСР) - это тоже удобно, повторное нажатие - исходное положение.
Бардак начинался только если при одном включённом экшене - запустить второй...

Теперь бардака нет, но появилась заморочка: "Большой микшер" открывается через F3, а закрывается через F7. Так же с F1. То есть, что бы просто "глянуть и закрыть" микшер надо использовать уже две клавиши... Раньше я замедлялся при случайном запуске двух экшенов (решением было запуск F7) - теперь это не ошибка, а правило!

Что то не то... Похоже, идея о запрете одновременного использования двух экшенов F1 и F3 не работает как хотелось.

Получается, что надо, при использовании (к примеру) экшена F3, закрывался, от этого, сначала экшен F1 - если он открыт. Или наоборот - F1 закрывает открытый F3 и открывается сам, при этом каждый из экшенов должны быть Toggle... Такое возможно?

п. с. Как то всё запутанно у меня формулируется эта, с виду простая задача. Только просто её решить - не получается пока...:Dle13::Dle87:
 
Последнее редактирование:
@smrz1, Попробуй так
JavaScript:
    -- F1
    local mixerVisible = reaper.GetToggleCommandStateEx(0,40078);
    if mixerVisible == 1 then;
        local DockingInDocker = reaper.GetToggleCommandStateEx(0,40083);
        if DockingInDocker == 0 then;
            reaper.Main_OnCommand(40083,0);
            local masterDocked = reaper.GetToggleCommandStateEx(0,41610);
            if masterDocked == 0 then;
                reaper.Main_OnCommand(41610,0);
            end;
            return;
        end;
        reaper.Main_OnCommand(40078,0);
        local masterDocked = reaper.GetToggleCommandStateEx(0,41610);
        if masterDocked == 1 then;
            reaper.Main_OnCommand(41610,0);
        end;
    else;
        reaper.Main_OnCommand(40078,0);
        local masterDocked = reaper.GetToggleCommandStateEx(0,41610);
        if masterDocked == 0 then;
            reaper.Main_OnCommand(41610,0);
        end;
    end;
JavaScript:
    local DockingInDocker = reaper.GetToggleCommandStateEx(0,40083);
    if DockingInDocker == 0  then;
        reaper.Main_OnCommand(40083,0);
        local masterDocked = reaper.GetToggleCommandStateEx(0,41610);
        if masterDocked == 0 then;
            reaper.Main_OnCommand(41610,0);
        end;
    else;
        reaper.Main_OnCommand(40083,0);
        local masterDocked = reaper.GetToggleCommandStateEx(0,41610);
        if masterDocked == 1 then;
            reaper.Main_OnCommand(41610,0);
        end;
    end;
 
Последнее редактирование:
  • Like
Реакции: smrz1
@Archchie, идеально! СУПЕР:Dle4::Dle8::Dle11:
Доделываю маленький (по вознаграждению) проект - про донаты в пользу твоего полезного и важного дела не забуду.
 
  • Like
Реакции: Archie's
@Archchie, а можно сделать скрипт, чтобы можно было кнопку в пиано ролл сделать скрипта типа этого - Script: amagalma_Snap MIDI item(s) edges to grid without changing content position.lua. Хороший скрипт, он ровняет концы миди айтема не затрагивая миди ноты, но он работает только в окне аранжировки, а в миди редакторе только как горячая клавиша, а хочется и кнопку в миди редакторе сделать для удобства? Может у тебя есть что-то подобное?
 
Что то не то... Похоже, идея о запрете одновременного использования двух экшенов F1 и F3 не работает как хотелось.
при этом каждый из экшенов должны быть Toggle...
И не будет работать как хотелось, потому как сам представь, как может быть скрипт тоггле и что бы у него был запрет?
Когда нужно срабатывать запрету, если скрипту нужно всегда работать???
с виду простая задача.
Порой с виду простая задача, на деле оказывается совсем не такой простой, как кажется.
Иногда бывает что скрипт в 200-300 строк проще чем скрипт в 20 строк, бывает что скрипт в 200-300 строк пишется за пару часов, а на скрипт в 20 строк уходит пару вечеров- а то и больше.


а можно сделать скрипт, чтобы можно было кнопку в пиано ролл сделать
В экшен листе ставишь галку показать путь скрин 1. Далее смотришь путь, где находится скрипт скрин 2. Далее выбираешь в экшен листе секцию midi Editor и жмешь load скрин 3. Находишь скрипт и жмешь открыть. Все этот же скрипт добавился в миди секцию скрин 4 и теперь из миди секции добавляй его в тулбар в пиано ролл.


скрин 1
167353





скрин 2

167354




скрин 3

167355





скрин 4


167356
 
Последнее редактирование:
  • Like
Реакции: YuriOl и Krikets
"Порой с виду простая задача, на деле оказывается совсем не такой простой, как кажется.
Иногда бывает что скрипт в 200-300 строк проще чем скрипт в 20 строк, бывает что скрипт в 200-300 строк пишется за пару часов, а на скрипт в 20 строк уходит пару вечеров- а то и больше
."

@Archchie, да, всё это, со скриптами, как кубик рубика (которым балуюсь иногда, но только для того, что бы отдохнуть - то есть, крайне медленно).

Ночью поработал используя новые скрипты на F1 и F3. Всё великолепно, но пару вопросов есть.
Из первичной позиции жму F1
До F1
Захват1.png

С F1
Захват2.png


Потом нажимаю F3, открывается окно микшера, всё как надо, Захват3.png но после повторного F3 и закрытия микшера, окно становится первичным (как до нажатия F1)Захват1.png
А можно сделать, что бы микшер закрывался и окно оставалось тем же в котором открывался? (после нажатия F1Захват2.png или до).

п. с. Заметил одну необычность: если микшер открываю F3, то окно микшера на мгновение становиться белым!
А если микшер открывать из окна после F1 - с F3 - микшер открывается без всякого мигания. Видео карта не самая худшая, с кастомом открывалось без мигания, хоть и чуть медленней... Что это может быть?
 
Последнее редактирование:
А можно сделать, что бы микшер закрывался и окно оставалось тем же в котором открывался? (после нажатия F1Захват2.png или до).
Вроде удалось сделать.
JavaScript:
    -- F3
    
    -------------------------------------------------------
    local function no_undo()reaper.defer(function()end)end;
    -------------------------------------------------------
    
    
    local DockingInDocker = reaper.GetToggleCommandStateEx(0,40083);
    if DockingInDocker == 0  then;
       
       reaper.Main_OnCommand(40083,0);
       
       local ExtState1 = tonumber(reaper.GetExtState("mixerVisible_smrz1","smrz1mixerVisible_"));
       if ExtState1 and ExtState1 == 1 then;
          local mixerVisible_ = reaper.GetToggleCommandStateEx(0,40078);
          local masterDocked = reaper.GetToggleCommandStateEx(0,41610);
          if mixerVisible_ ~= 1 then;
             reaper.Main_OnCommand(40078,0);
          end;
          if masterDocked ~= 1 then;
             reaper.Main_OnCommand(41610,0);
          end;
       elseif ExtState1 and ExtState1 == 0 then;
          
          local mixerVisible_ = reaper.GetToggleCommandStateEx(0,40078);
          local masterDocked = reaper.GetToggleCommandStateEx(0,41610);
          if mixerVisible_ ~= 0 then;
             reaper.Main_OnCommand(40078,0);
          end;
          if masterDocked ~= 0 then;
             reaper.Main_OnCommand(41610,0);
          end;
       else;
          local masterDocked = reaper.GetToggleCommandStateEx(0,41610);
          if masterDocked == 0 then; 
             reaper.Main_OnCommand(41610,0);
          end;
       end; 
        
    else;
       ----
       local mixerVisible_ = reaper.GetToggleCommandStateEx(0,40078);
       reaper.SetExtState("mixerVisible_smrz1","smrz1mixerVisible_",mixerVisible_,false);
       
       local masterDocked = reaper.GetToggleCommandStateEx(0,41610);
       if masterDocked == 1 then;
          reaper.Main_OnCommand(41610,0);
       end;
       reaper.Main_OnCommand(40083,0);
    end;
    
    no_undo();

п. с. Заметил одну необычность: если микшер открываю F3, то окно микшера на мгновение становиться белым!
Окно становиться белым потому что это так экшены работают в такой последовательности, сейчас вроде не так мерцает или по моему вообще не мерцает.
с кастомом открывалось без мигания, хоть и чуть медленней...
В скрипте используются те же самые экшены, что и в кастоме, просто в скрипте ими можно более гибче управлять (хотя в цикл экшенах можно также гибко ими управлять), так что в скорости наврятли скрипт быстрее чем кастом.

В F1 вставь в начало скрипта
JavaScript:
    -------------------------------------------------------
    local function no_undo()reaper.defer(function()end)end;
    -------------------------------------------------------
и в конец скрипта
JavaScript:
    no_undo();
Это для того, что бы не выскакивало вот эта надпись ReaScript
167364
 
  • Like
Реакции: smrz1
@Archchie, не люблю повторяться, но не в такой ситуации - @Archchie, - ты ВЫСШИЙ!

Всё просто так как и должно быть! Микшер открывается-закрывается откуда и куда надо (и с F1 и без неё), надписи от F1 - нет (я и не заметил эту надпись ReaScript - на другое смотрел), и самое, что реально бросалось в глаза - мгновение "белого микшера" - исчезло в никуда!:Dle47::Dle92:
Ещё раз огромное спасибо!!! :Dle79:
 
@Archchie, спасибо за микшер.
А как можно сделать что бы окно микшера сразу открывалось на весь экран?
 
@Archchie, спасибо за микшер.
А как можно сделать что бы окно микшера сразу открывалось на весь экран?
А разве оно не на весь экран? Точнее, если ты его расширил на весь экран, потом закрыл, потом опять откроешь - оно и будет на весь экран... У меня так - как расширил - так оно и будет открываться. Только что специально проверил - расширение задаёшь сам и оно таким остаётся.
 
  • Like
Реакции: Archie's
А разве оно не на весь экран? Точнее, если ты его расширил на весь экран, потом закрыл, потом опять откроешь - оно и будет на весь экран...
Оно на весь экран на время сессии.
В новом проекте его опять надо настраивать.
 
А как можно сделать что бы окно микшера сразу открывалось на весь экран?
Попробуй добавить в самый конец.
Требуется расширение: reaper_js_ReaScriptAPI
JavaScript:
    local Window_Mixer = reaper.JS_Window_Find("Mixer",true);
    if Window_Mixer then;
       local _,_, scr_x, scr_y = reaper.my_getViewport(0,0,0,0,0,0,0,0,1);
       reaper.JS_Window_SetPosition(Window_Mixer,0,0,scr_x, scr_y);
    end;
 
Последнее редактирование:
  • Like
Реакции: Shico
Попробуй добавить в самый конец.
Спасибо, всё работает.

И вот ещё: у вас в начале скрипта стоит F3, это что-то принципиальное?
Потому как F3 это назначение микшера у камрада @smrz1, у меня по-другому (сейчас попробовал F6), но и так, и так всё работает.
Так есть ли смысл вписывать моё значение или это всё равно и пусть как по-умолчанию?
 
в начале скрипта стоит F3, это что-то принципиальное?
Нет, это не принципиально, это так называемый тег для того, что бы визуально понимать где какой код.
Можешь назначать на что угодно.
 
Последнее редактирование:
@Shico,
это в начало кода для регулировки ( 0 лево / 1 право)
PHP:
  local POSITION = 1   -- 0 left / 1 right
это в конец кода
PHP:
  if reaper.GetToggleCommandState(40389)~=POSITION then;reaper.Main_OnCommand(40389,0)end;
 
  • Like
Реакции: Shico

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