Go Back   Cockos Incorporated Forums > REAPER Forums > REAPER Q&A, Tips, Tricks and Howto

Reply
 
Thread Tools Display Modes
Old 12-10-2016, 05:41 AM   #1
Superpuman
Human being with feelings
 
Join Date: Mar 2016
Posts: 28
Default Deleting notes in Reascript using Lua interesting question...

Ok - let's say I have a lot of notes in my midi track.
I have 300 notes and now I have calculated that I want
to delete all notes from 150 to 175.

If I use reaper.MIDI_deleteNote(take,150)
this will delete note 150 - so far so good !

After that I write reaper.MIDI_deleteNote(take,151)
and that code will delete the wrong note and I understad
why - because I deleted note 150 before so the note that
I now want to delete - note 151 - has now index 150....

So....if I want to delete note 150 to 175 i would write
a loop that deletes note 150 25 times ( or 26 to be correct).

But...maybe I wanted to delete note 150,157,162,169,173....you get the picture....

So..finally....my question.....Is there a better way of handling
deleting notes at special positions in the grid ?

Kind Regards
Superpuman is offline   Reply With Quote
Old 12-10-2016, 06:29 AM   #2
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 15,823
Default

This is a standard programming idiom. Either decrement the loop variable every time you delete an item, or loop from back to front.

Code:
for i=0,cnt-1 do
  if WantDelete(i) then
    reaper.MIDI_DeleteNote(take,i)
    i=i-1
  end
end

... or ...

for i=cnt-1,0 do
  if WantDelete(i) then    
    reaper.MIDI_DeleteNote(take,i)  
  end
end
schwa is offline   Reply With Quote
Old 12-10-2016, 10:29 AM   #3
Superpuman
Human being with feelings
 
Join Date: Mar 2016
Posts: 28
Default

Quote:
Originally Posted by schwa View Post
This is a standard programming idiom. Either decrement the loop variable every time you delete an item, or loop from back to front.

Code:
for i=0,cnt-1 do
  if WantDelete(i) then
    reaper.MIDI_DeleteNote(take,i)
    i=i-1
  end
end

... or ...

for i=cnt-1,0 do
  if WantDelete(i) then    
    reaper.MIDI_DeleteNote(take,i)  
  end
end

From back to front -Thank you ! Nice soluton !
Superpuman is offline   Reply With Quote
Old 12-10-2016, 01:52 PM   #4
Lawrence
Human being with feelings
 
Join Date: Mar 2007
Posts: 21,551
Default

Quote:
Originally Posted by schwa View Post
This is a standard programming idiom.
It is.

The other option, depending on the collection or array or language methods, etc, etc, is to remove the range of items all at once. No idea if whatever he used there, Lua or JS or whatever allows that or not, making "selections" of multiple things in a collection, then deleting all "selected" items.
Lawrence is offline   Reply With Quote
Old 12-10-2017, 09:29 PM   #5
_Stevie_
Human being with feelings
 
_Stevie_'s Avatar
 
Join Date: Oct 2017
Location: Black Forest
Posts: 5,067
Default

I'm confronted with the same problem and I'm literally desperate. I tried pretty much everything, but my code just doesn't seem to work.

The script is supposed to delete all MIDI notes before the edit cursor. A version where all notes get selected already works.
The problems seem to happen in the undo block. I tried the "loop back to front" but nothing happens at all.

Code:
for i = 0, reaper.CountSelectedMediaItems(0)-1 do -- loop through all selected items
    item = reaper.GetSelectedMediaItem(0, i)
    if i > 0 then
        reaper.ShowMessageBox("Please select only one item", "Error" , 0) -- popup error message, if more than 1 item is selected
        return
    else
        for t = 0, reaper.CountTakes(item)-1 do -- Loop through all takes within each selected item
            take = reaper.GetTake(item, t)
            if reaper.TakeIsMIDI(take) then -- make sure, that take is MIDI
                cursor_position = reaper.GetCursorPosition()  -- get edit cursor position 
                cursor_position_ppq = reaper.MIDI_GetPPQPosFromProjTime(take, cursor_position) -- convert to PPQ
                notes = reaper.MIDI_CountEvts(take) -- count notes and save amount to "notes"
            end
        end
    end 
end

reaper.Undo_BeginBlock() reaper.PreventUIRefresh(1)

for n = notes-1, 0 do -- loop thru all notes
    _, sel, _, start_note, end_note, _, _, _ = reaper.MIDI_GetNote(take, n) -- get selection status, start and end position
    
    if start_note < cursor_position_ppq and end_note <= cursor_position_ppq then 
    reaper.MIDI_DeleteNote(take, n) -- delete note if condition above is true

    
    end
end


reaper.PreventUIRefresh(-1) reaper.Undo_EndBlock('Delete notes before cursor', 2)
_Stevie_ is offline   Reply With Quote
Old 12-11-2017, 04:18 AM   #6
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 3,714
Default

* To loop backwards, tell Lua to use "-1" steps:, for n = notes-1, 0, -1 do

* Move the "for n = notes-1, 0, -1 do" loop to within the "for t = 0, reaper.CountTakes(item)-1 do" loop, otherwise the script will only edit the last take in the item.
juliansader is offline   Reply With Quote
Old 12-11-2017, 05:39 AM   #7
_Stevie_
Human being with feelings
 
_Stevie_'s Avatar
 
Join Date: Oct 2017
Location: Black Forest
Posts: 5,067
Default

Ahhh thanks so much Julian! It works!
Actually the script should only work with one item selected,
would I still need to put the loop inside the CountTakes loop?
_Stevie_ is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 10:02 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.