Удаление нот со сдвигом.

Iskander M

Member
6 Мар 2014
278
19
18
38
Москва
Привет. Какой экшн или скрипт позволит при удалении выделенных миди-нот сместить все, что справа, к началу диапазона выделенных нот. Короче, удаление со смещением всего справа налево к началу.
2023-03-27_20-23-44.png
 
Попробуй этот
Код:
function TimeSelOff()
  Editor=reaper.MIDIEditor_GetActive()
  local take=reaper.MIDIEditor_GetTake(Editor)
  local _,CountEvts=reaper.MIDI_CountEvts(take)
  if CountEvts>0 then
    
    s={}                     
    for nado=1,127 do
      s[nado]={}
      s[nado][0]={}
      s[nado][0].counter=0
    end
    index=0
    for i=0,CountEvts-1 do
      _,sel,muted,start,ending,chank,pitch,vel=reaper.MIDI_GetNote(take,i+index)
      if sel==true then       
        s[pitch][0].counter=s[pitch][0].counter+1                       
      end
      s[pitch][#s[pitch]+1]={}
      s[pitch][#s[pitch]].sel=sel
      s[pitch][#s[pitch]].muted=muted
      s[pitch][#s[pitch]].start=start
      s[pitch][#s[pitch]].ending=ending
      s[pitch][#s[pitch]].chank=chank
      s[pitch][#s[pitch]].pitch=pitch
      s[pitch][#s[pitch]].vel=vel
      reaper.MIDI_DeleteNote(take,i+index)
      index=index-1
    end

    for x=1,#s do
      offset=0
      if #s[x]>=1 then
        for y=1,#s[x] do
          if s[x][y].sel==true then
            offset=offset-(s[x][y].ending-s[x][y].start)
          else
            reaper.MIDI_InsertNote(
            take,
            s[x][y].sel,
            s[x][y].muted,
            s[x][y].start+offset,
            s[x][y].ending+offset,
            s[x][y].chank,
            s[x][y].pitch,
            s[x][y].vel)
          end
        end
      end
    end
  end
end


function TimeSelOn(TimeSelStart,TimeSelEnd)
  Editor=reaper.MIDIEditor_GetActive()
  local take=reaper.MIDIEditor_GetTake(Editor)
  local _,CountEvts=reaper.MIDI_CountEvts(take)
  reaper.MIDIEditor_OnCommand(Editor,40214)
  reaper.MIDIEditor_OnCommand(Editor,40746)
  if CountEvts>0 then
    
    s={}                     
    for nado=1,127 do
      s[nado]={}
      s[nado][0]={}
      s[nado][0].counter=0
    end
    index=0
    for i=0,CountEvts-1 do
      _,sel,muted,start,ending,chank,pitch,vel=reaper.MIDI_GetNote(take,i+index)
      if sel==true then         
        s[pitch][0].counter=s[pitch][0].counter+1                       
      end
      s[pitch][#s[pitch]+1]={}
      s[pitch][#s[pitch]].sel=sel
      s[pitch][#s[pitch]].muted=muted
      s[pitch][#s[pitch]].start=start
      s[pitch][#s[pitch]].ending=ending
      s[pitch][#s[pitch]].chank=chank
      s[pitch][#s[pitch]].pitch=pitch
      s[pitch][#s[pitch]].vel=vel
      reaper.MIDI_DeleteNote(take,i+index)
      index=index-1
    end
    offset=TimeSelStart-TimeSelEnd
    offset=reaper.MIDI_GetPPQPosFromProjTime(take,offset)
    for x=1,#s do
      if #s[x]>=1 then
        for y=1,#s[x] do
          if s[x][y].sel==false and s[x][y].start>=TimeSelEnd then
            reaper.MIDI_InsertNote(
            take,
            s[x][y].sel,
            s[x][y].muted,
            s[x][y].start+offset,
            s[x][y].ending+offset,
            s[x][y].chank,
            s[x][y].pitch,
            s[x][y].vel)
          elseif s[x][y].sel==false and s[x][y].ending<=TimeSelStart then
            reaper.MIDI_InsertNote(
            take,
            s[x][y].sel,
            s[x][y].muted,
            s[x][y].start,
            s[x][y].ending,
            s[x][y].chank,
            s[x][y].pitch,
            s[x][y].vel)
          end
        end
      end
    end
  end
end
 
reaper.Undo_BeginBlock()
TimeSelStart,TimeSelEnd=reaper.GetSet_LoopTimeRange2(0, false, false, 0, 0, false)
    if TimeSelStart>0 or TimeSelEnd>0 then
      TimeSelOn(TimeSelStart,TimeSelEnd)
    else
      TimeSelOff()
    end
reaper.Undo_EndBlock("Note ripple delete",0)
Если просто выделить конкретные ноты, то он удалит каждую выделенную ноту, а следующие за ней (и имеющие то же питч что и выделенная) сдвинутся влево
При выделении time selection удаляются все ноты в time selection, а все остальные (не зависимо от питча) сдвинутся влево на длину time selection

Пожалуйста напишите если скрипт будет вести себя плохо, я пока ничего плохого не нашел
 
  • Like
Реакции: Iskander M
@serpen, спасибо огромное! Все работает по описанию двух вариантов!
Работает адекватно, если ноты в ряд и они вплотную друг к другу примыкают, например.
Но если ноты сделать меньше в два раза, то они сдвигаются на полтакта, то есть четко в совокупности по длине всех нот:
Далее, если ноты в 4 раза меньше по длине, то соответственно на четверть такта происходит смещение итд.
 

Вложения

  • 2023-03-28_14-55-56.png
    2023-03-28_14-55-56.png
    21,7 KB · Просмотры: 41
  • 2023-03-28_14-58-40.png
    2023-03-28_14-58-40.png
    24 KB · Просмотры: 48
  • 2023-03-28_15-12-58.png
    2023-03-28_15-12-58.png
    20,3 KB · Просмотры: 47
Последнее редактирование:
@Iskander M, сместить все, что справа к началу выделенных нот поможет такой кастом экшен:
Ripple MIDI.jpg

Подсмотрел тут
Потребуется SWS и скрипт от X-Raym из его репозитория
Проверил - работает =)
Ripple MIDI.gif
 
  • Like
Реакции: Iskander M
@serpen но если ноты сделать меньше в два раза, то они сдвигаются на полтакта, то есть четко в совокупности по длине всех нот:
А вам нужно что бы сдвигалось к первой, я просто смотрел как работает ripple delete для item-ов и подстраивал под него.
Если хотите могу переписать, хотя верхний кастом экшн тоже весьма не плох.
 
  • Like
Реакции: Iskander M
@Iskander M, если будете пробовать этот кастом экшн - стоит отметить два момента, на которые автор обращает внимание тут:
- корректно работает только через шорткат (собственно, из-за экшена от X-Raym)
- работает только с выделенными нотами (т.е. может хорошо сработать с мелодией, но есть под мелодией есть какой-то невыделенный аккомпанемент - возможны нежелательные сдвиги, наслоения и т.п.)
Так что нужно учитывать эти ограничения
 
@Iskander M, если будете пробовать этот кастом экшн - стоит отметить два момента, на которые автор обращает внимание тут:
- корректно работает только через шорткат (собственно, из-за экшена от X-Raym)
- работает только с выделенными нотами (т.е. может хорошо сработать с мелодией, но есть под мелодией есть какой-то невыделенный аккомпанемент - возможны нежелательные сдвиги, наслоения и т.п.)
Так что нужно учитывать эти ограничения
Если считать за "референс" действия то как это реализовано с итемами (то есть при включение рипла двигаются либо все элементы на дорожке, либо еще под и над ним) то при втором случае это можно реализовать тайм селекшионом, но там удалится всё что есть в этой зоне
Поищите скрипт "select all midi notes right cursor" тогда если поставить edit cursor перед экшном то можно будет использовать и без шортката.
 
  • Like
Реакции: truemanofan
Поищите скрипт "select all midi notes right cursor" тогда если поставить edit cursor перед экшном то можно будет использовать и без шортката.
Да, с таким скриптом должно быть получше =) Но тут уже пусть топикстартер смотрит, как ему удобней =)
А я за что купил - за то продал =)
 
@truemanofan, отличный кастом, подходит, делает всё, что нужно!))
Но так как это последовательность команд, то при отмене всего этого хозяйства приходится каждую из этих команд удалять по очереди,
Это не особо удобно, хоть и применяться отмена часто не будет скорее всего.
Спасибо за подгон!) Взял.
 
  • Like
Реакции: truemanofan
А вам нужно что бы сдвигалось к первой, я просто смотрел как работает ripple delete для item-ов и подстраивал под него.
Если хотите могу переписать, хотя верхний кастом экшн тоже весьма не плох.
Да, кастом хорош. Но как написал выше предложившему этот кастом - при отмене нужно отменять каждую команду из последовательности команд. Конечно же, в идеале было бы иметь миру такой скрипт, при котором одно нажатие отмены.)))
Если будет скрипт, то я, конечно же, воспользуюсь скриптом!

То что при принципу ripple для айтемов - да, я это заметил, пользуюсь этим для айтемов часто.
 
Последнее редактирование:
Если считать за "референс" действия то как это реализовано с итемами (то есть при включение рипла двигаются либо все элементы на дорожке, либо еще под и над ним) то при втором случае это можно реализовать тайм селекшионом, но там удалится всё что есть в этой зоне
Поищите скрипт "select all midi notes right cursor" тогда если поставить edit cursor перед экшном то можно будет использовать и без шортката.
Эмммм, ну вообщем горячими клавишами удобнее, назначил через шорткат. Спасибо)
 
Но так как это последовательность команд, то при отмене всего этого хозяйства приходится каждую из этих команд удалять по очереди
Да, когда проверял тоже на это обратил внимание =) Согласен, неудобненько =) как вариант можно сделать отдельный undo-кастом для отмены в таком случае =)) Посчитать сколько действий отменяется- вроде, 5, чтоб оставить выделение нот и 6, чтоб убрать =) и просто накидать пять-шесть раз подряд Edit: Undo, назначить шорткат на соседнюю с риппл эдитом кнопку =)
Например:
применать риппл едит - "ctrl"+"_"
отмена - "ctrl"+"+"
undo.jpg

Работает =))
undo.gif
 
  • Like
Реакции: Iskander M
А это что такое? В экшен листе не нашёл.
в окне создания кастом экшена в низу правой части окна есть несколько пунктов, consolidate позволяет сделать действия как одно, то есть undo-иться будет полностью
 
  • Like
Реакции: Iskander M
в окне создания кастом экшена в низу правой части окна есть несколько пунктов, consolidate позволяет сделать действия как одно, то есть undo-иться будет полностью
Ого, не знал о такой фиче! Работает, спасибо!))))

@truemanofan, Consolidate undo points - это решение с undo, о котором мы не знали! Выше подсказали.)
 
Последнее редактирование:
  • Like
Реакции: truemanofan

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