local clearPreviousSelection = false -- 'true' deselects previously selected notes, 'false' keeps them selected
local maxLengthTolerance = 0.01 -- Given in quarter notes, this value determines how much longer the individual notes can be than the grid division
local undoDesc = "Select notes of the same length as current grid division (add to selection)" -- The description of the created undo point

local function countSelectedNotes(take)
  local noteCount = 0
  local i = reaper.MIDI_EnumSelNotes(take, -1)
  while i ~= -1 do
    noteCount = noteCount + 1
    i = reaper.MIDI_EnumSelNotes(take, i)
  end
  return noteCount
end

local function sayMessage(message)
  if reaper.APIExists("osara_outputMessage") then
    reaper.osara_outputMessage(message)
  end
end

local editor = reaper.MIDIEditor_GetActive()
if not editor then return(0) end
local take = reaper.MIDIEditor_GetTake(editor)
if not take then return(0) end
local _, noteCount = reaper.MIDI_CountEvts(take)
if noteCount == 0 then return(0) end

reaper.Undo_BeginBlock()

local gridQN = reaper.MIDI_GetGrid(take) or 1.0
local i = 0
local lengthQN = 0
local maxToleratedQN = gridQN + maxLengthTolerance

if clearPreviousSelection then
  reaper.MIDI_SelectAll(take, false)
end

for i = 0, noteCount-1 do
  local OK, selected, muted, startPPQ, endPPQ, channel, pitch, velocity = reaper.MIDI_GetNote(take, i)
  if OK then
    startQN = reaper.MIDI_GetProjQNFromPPQPos(take, startPPQ)
    endQN = reaper.MIDI_GetProjQNFromPPQPos(take, endPPQ)
    lengthQN = endQN - startQN
    if lengthQN >= gridQN and lengthQN <= maxToleratedQN then
      reaper.MIDI_SetNote(take, i, true, muted, startPPQ, endPPQ, channel, pitch, velocity, true)
    end
  end
end

reaper.Undo_EndBlock(undoDesc, -1)

selectedCount = countSelectedNotes(take)

if clearPreviousSelection then
  if selectedCount == 0 then
    sayMessage("Cleared previous selection, no notes selected")
    elseif selectedCount == 1 then
    sayMessage("Cleared previous selection, 1 note selected")
    else
    sayMessage("Cleared previous selection, " .. selectedCount .. " notes selected")
  end
  else
  if selectedCount == 0 then
    sayMessage("No notes selected")
    elseif selectedCount == 1 then
    sayMessage("1 note selected")
    else
    sayMessage(selectedCount .. " notes selected")
  end
end
