Go Back   Cockos Incorporated Forums > REAPER Forums > ReaScript, JSFX, REAPER Plug-in Extensions, Developer Forum

Reply
 
Thread Tools Display Modes
Old 08-07-2016, 12:15 PM   #1
juliansader
Human being with feelings
 
Join Date: Jul 2009
Posts: 3,714
Default Weird behavior when using calling notation action directly after MIDI_SetNote [FIXED]

[EDIT: Fixed in v5.23]

I have encountered a strange problem:

There appears to be a discoordination between:
* ReaScript functions that de/select notes, such as MIDI_SetNote and MIDI_SelectAll, and
* Notation actions that are called through MIDIEditor_OnCommand, such as "Beam selected notes together" or "Nudge length display offset".

If the notation action is called too soon after the ReaScript function, the action is sometimes skipped or applied to the wrong note. My impression is that scripts are executed faster than the MIDI editor can update after a ReaScript function.

If a pause step is inserted in-between, using for example "reaper.GetUserInputs", the notation actions are applied correctly.

As an example, here is a script that I am working on. It is intended to change the displayed length of notes in the notation editor to a user-specified length. (EDIT: This is an old version of the script - it has since been rewritten to write directly to notation text events, which works much better than trying to use OnCommand to call actions.)

Code:
editor = reaper.MIDIEditor_GetActive()
if editor ~= nil then
    take = reaper.MIDIEditor_GetTake(editor)
    if reaper.ValidatePtr2(0, take, "MediaItem_Take*") then    
        
        -- Get user-specified displayed note length
        repeat
            retval, input = reaper.GetUserInputs("Set displayed note length", 
                                                      1,
                                                      "Note length (4=quarter note)",
                                                      "8") 
            input = tonumber(input)
        until retval == false or (type(input) == "number" and input>0)
        
        if retval == false then 
            return(0)
        else
    
            reaper.Undo_BeginBlock2(0)
            
            reaper.MIDI_Sort(take)
            
            -- It seems that the "Notation: Nudge note display length" actions work in
            --    steps of 1/64 notes.
            -- Weird, sometimes REAPER's PPQ is not 960.  So first get PPQ of take.
            local QNstart = reaper.MIDI_GetProjQNFromPPQPos(take, 0)
            PPQ = reaper.MIDI_GetPPQPosFromProjQN(take, QNstart + 1) - QNstart
            PP64 = PPQ/16
            
            userLength = (4.0/input)*PPQ -- Desired length of displayed notes in ticks
            
            reaper.MIDIEditor_OnCommand(editor, 41759) -- Notation: Clear display offset
            
            -- Store indices of selected notes so that they can be reselected after deselection
            tableSelIndices = {}
            i = -1
            repeat
                i = reaper.MIDI_EnumSelNotes(take, i)
                if i >= 0 then table.insert(tableSelIndices, i) end
            until i == -1
            
            -- The notes will now all be deselected, and then REselected one by one 
            --    so that the notation actions can be applied to each note separately.
            reaper.MIDI_SelectAll(take, false)
            reaper.GetUserInputs("Pause step...",1,"","")
            
            for _, index in ipairs(tableSelIndices) do
            
                local noteOK, _, _, startppq, endppq, _, _, _ = reaper.MIDI_GetNote(take, index)
                
                if noteOK then
                    local noteLength = endppq-startppq
                    reaper.MIDI_SetNote(take, index, true, nil, nil, nil, nil, nil, nil, false)
                    reaper.GetUserInputs("Pause step...",1,"","")
                    
                    if noteLength < userLength then
                        -- In REAPER v5.22, can only increase or decrease display length by up to eight 64th notes
                        local numSteps = math.min(8, math.floor(0.5 + (userLength-noteLength)/PP64)) -- PP64 = length of nudge = 64th note)
                        for i = 1, numSteps do
                            reaper.MIDIEditor_OnCommand(editor, 41763) -- Notation: Nudge length display offset RIGHT
                        end
                    elseif noteLength > userLength then
                        local numSteps = math.min(8, math.floor(0.5 + (noteLength-userLength)/PP64)) -- PP64 = length of nudge = 64th note
                        for i = 1, numSteps do
                            reaper.MIDIEditor_OnCommand(editor, 41762) -- Notation: Nudge length display offset LEFT
                        end
                    end
                end

                -- Deselect note again, so that next note can be reselected
                reaper.MIDI_SetNote(take, index, false, nil, nil, nil, nil, nil, nil, false)
                reaper.GetUserInputs("Pause step...",1,"","")
                                                    
            end
            
            -- Reselect all the notes that were originally selected
            for _, index in ipairs(tableSelIndices) do
                reaper.MIDI_SetNote(take, index, true, nil, nil, nil, nil, nil, nil, false)
            end
            
            reaper.Undo_EndBlock2(0, "Notation: Set displayed note length", -1)
        end
    end
end
I have inserted several pause steps using "reaper.GetUserInputs("Pause step...",1,"","")".

By removing these pause steps one at a time and running the script with several notes selected, one can see the different effects.

So... Has anyone else encountered this strange behavior? Is this a bug that I have discovered, or am I overlooking my own coding error?

Last edited by juliansader; 07-02-2017 at 02:20 PM.
juliansader 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 11:27 AM.


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