03-30-2016, 03:00 AM | #1 |
Banned
Join Date: Sep 2015
Posts: 1,650
|
Issue setting note end pos to following note start pos
So I was putting together a quick script for a thread in General Discussion, but noticed that setting the end position of a note to the start position of the next note of equal pitch sometimes results in a note length of zero. I can subtract one PPQ from the length of course, but if we draw adjoining notes with the MIDI editor, the List View displays the start and end being equal. If you run this on a selected note a couple of times you should see the issue... Code:
--get the take active in the MIDI editor local take=reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive()) local cnt=0 --counter for notes, we access notes by their index number local notes_to_insert={} -- create a table of notes we want to insert -- because inserting whilst getting them -- messes with getting them all in the right order --try and get the first note, ok=true if we get one local ok, selected, muted, sppq, eppq, chan, pitch, vel=reaper.MIDI_GetNote(take, 0) --this bit only runs if we have a note (ok = true) while ok do if selected then -- only do this if the note we just got is selected length=eppq-sppq -- end position (in ppq) minus start = length new_length=math.floor(length/2) -- always round after dividing -- for stuff that needs a whole number eppq=sppq+new_length reaper.MIDI_SetNote(take,cnt,selected,muted,sppq,eppq,chan,pitch,vel,false) --false=don't sort -- we want to insert a new note of the same length at the end of the one -- we just halved, so we'll store the details to insert later notes_to_insert[#notes_to_insert+1]={ take=take,selected=selected,muted=muted,sppq=eppq, eppq=eppq+new_length, chan=chan, pitch=pitch, vel=vel} end -- increase the counter and try to get the next note, this -- "while loop" we are in will repeat if we get one cnt=cnt+1 ok, selected, muted, sppq, eppq, chan, pitch, vel=reaper.MIDI_GetNote(take, cnt) end -- now we go through the table of new notes we stored, inserting them into take for i=1,#notes_to_insert,1 do local n=notes_to_insert[i] reaper.MIDI_InsertNote(n.take,n.selected,n.muted,n.sppq,n.eppq,n.chan,n.pitch,n.vel,false) end reaper.MIDI_Sort(take) --make sure everything is back in order |
04-01-2016, 02:01 PM | #2 |
Human being with feelings
Join Date: Jun 2012
Posts: 2,173
|
Ran into something like that here:
http://forum.cockos.com/showthread.php?t=143366 Some note division scripts here: http://forum.cockos.com/showthread.php?t=174008 In short, I guess I would say: Delete the notes, then replace them with both (or more.) |
04-01-2016, 05:44 PM | #3 |
Banned
Join Date: Sep 2015
Posts: 1,650
|
Yes, deleting all notes then re-adding them works.
It turns out that it's the sorting that Reaper does that causes the issue. If I pass true for noSort and do not sort the take with MIDI_Sort then everything is fine. It looks like the sorting can put the note-off of a previous note after a note-on of a current note or something. Which explains why deleting and re-adding them sequentially works too. I think it's approaching a definable bug. |
04-01-2016, 06:56 PM | #4 |
Human being with feelings
Join Date: Jun 2012
Posts: 2,173
|
The trickiness is discouraging. I should have added in the join notes thread that spk77s eel script was apparently working fine for a while, then something went bad. Some "definition" would help!
|
04-02-2016, 03:37 AM | #5 |
Banned
Join Date: Sep 2015
Posts: 1,650
|
I don't know, it looks encouraging because it seems as though there's a three stage process:
1. Insert Events -> events go after rest of events 2. Sort Events -> events put in time order 3. Stuff to prevent broken MIDI existing in items And it's only #2 that's putting note-offs after note-ons for proceeding events, making #3 tidy stuff that shouldn't need tidied. So only #2 needs tweaked. At least that's what I gather from looking at the raw MIDI. |
04-02-2016, 04:51 AM | #6 |
Administrator
Join Date: Mar 2007
Location: NY
Posts: 16,501
|
It looks like that script is "split notes in half" rather than what you said?
Regardless, if you are iterating over notes to edit them, and re-sorting them as you go, you can run into trouble (besides being inefficient). |
04-02-2016, 05:15 AM | #7 |
Banned
Join Date: Sep 2015
Posts: 1,650
|
Thanks for the reply.. yes, it just splits notes.
The issue still arises when I pass noSort to MIDI_InsertNote when MIDI_Sort is run once at the end of the script. So this works (running multiple times)... Code:
--get the take active in the MIDI editor local take=reaper.MIDIEditor_GetTake(reaper.MIDIEditor_GetActive()) local cnt=0 --counter for notes, we access notes by their index number local notes_to_insert={} -- create a table of notes we want to insert -- because inserting whilst getting them -- messes with getting them all in the right order --try and get the first note, ok=true if we get one local ok, selected, muted, sppq, eppq, chan, pitch, vel=reaper.MIDI_GetNote(take, 0) --this bit only runs if we have a note (ok = true) while ok do if selected then -- only do this if the note we just got is selected length=eppq-sppq -- end position (in ppq) minus start = length new_length=math.floor(length/2) -- always round after dividing -- for stuff that needs a whole number eppq=sppq+new_length reaper.MIDI_SetNote(take,cnt,selected,muted,sppq,eppq,chan,pitch,vel,false) --false=don't sort -- we want to insert a new note of the same length at the end of the one -- we just halved, so we'll store the details to insert later notes_to_insert[#notes_to_insert+1]={ take=take,selected=selected,muted=muted,sppq=eppq, eppq=eppq+new_length, chan=chan, pitch=pitch, vel=vel} end -- increase the counter and try to get the next note, this -- "while loop" we are in will repeat if we get one cnt=cnt+1 ok, selected, muted, sppq, eppq, chan, pitch, vel=reaper.MIDI_GetNote(take, cnt) end -- now we go through the table of new notes we stored, inserting them into take for i=1,#notes_to_insert,1 do local n=notes_to_insert[i] reaper.MIDI_InsertNote(n.take,n.selected,n.muted,n.sppq,n.eppq,n.chan,n.pitch,n.vel,true) end --reaper.MIDI_Sort(take) --make sure everything is back in order So at least here it doesn't appear to be repeated sorting that is the issue, but any call to MIDI_Sort. It looks like the sort that happens in the MIDI editor is different from MIDI_Sort in some way because if I leave MIDI_Sort commented out, the MIDI is sorted without issues in the MIDI editor when I click in it (viewing raw MIDI). |
04-02-2016, 05:27 AM | #8 |
Banned
Join Date: Sep 2015
Posts: 1,650
|
Here's the raw MIDI after a sort that produces a zero length note....
Code:
+0 0: 90 3C 60 +1680 1680: 80 3C 00 +0 1680: 90 3C 60 +1680 3360: 90 3C 60 +0 3360: 80 3C 00 +1680 5040: 80 3C 00 +0 5040: 90 3C 60 +1680 6720: 80 3C 00 +20160 26880: B0 7B 00 Code:
+0 0: 90 3C 60 +1680 1680: 80 3C 00 +1680 3360: 90 3C 60 +1680 5040: 80 3C 00 +21840 26880: B0 7B 00 +-25200 1680: 90 3C 60 +1680 3360: 80 3C 00 +1680 5040: 90 3C 60 +1680 6720: 80 3C 00 Code:
+0 0: 90 3C 60 +1680 1680: 80 3C 00 +0 1680: 90 3C 60 +1680 3360: 80 3C 00 +0 3360: 90 3C 60 +1680 5040: 80 3C 00 +0 5040: 90 3C 60 +1680 6720: 80 3C 00 +20160 26880: B0 7B 00 |
04-02-2016, 05:43 AM | #9 |
Administrator
Join Date: Mar 2007
Location: NY
Posts: 16,501
|
Hm, this is somewhat technical. I'll see if there is a simple way to fix the problem.
|
04-02-2016, 05:43 AM | #10 |
Banned
Join Date: Sep 2015
Posts: 1,650
|
Whoops, I'm sorting with SetNote while getting them too, I'll just check with that off.... phew, still doesn't work.
@schwa: thanks for looking into this! Last edited by snooks; 04-02-2016 at 05:49 AM. |
Thread Tools | |
Display Modes | |
|
|