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

Reply
 
Thread Tools Display Modes
Old 04-13-2021, 07:41 PM   #1
en5ca
Human being with feelings
 
Join Date: Dec 2018
Posts: 394
Default A simple iterative / strength quantize to grid script (Lua)

Iteratively (or by strength) quantizes selected items and/or MIDI events inside items (notes, CC, SysEx) to current grid; by each iteration (run) items and events are quantized by strength value closer to grid. If item / MIDI event difference to grid is lesser than hard limit value, then script hard quantizes the item / MIDI event.



Paste into ReaScript editor, save and close, and assign a keyboard shortcut or run from actions list. Strength and hard limit values (or the entire script for that matter) can be modified to work better, in case it causes terrible horror and misery.

Code:
-- between 0 and 1
local strenght = 0.62
-- hard limit in seconds
local hard_limit = 0.003

--

local floor = math.floor
local abs = math.abs

local function GetNewPosition(old_pos)
  local pos
  local snap = reaper.SnapToGrid(0, old_pos)
  if abs(snap - old_pos) > hard_limit then
    pos = (snap - old_pos) * strenght + old_pos
  else
    pos = snap
  end
  return pos
end

local function QuantizeMIDI(take)
  local orig_pos, new_pos, new_pos_ppq, new_end_ppq
  local evtcnt, notecnt, ccevtcnt, textsyxevtcnt = reaper.MIDI_CountEvts(take)
  for noteidx=0, notecnt -1 do
    local _, _, _, startppqpos, endppqpos, _, _, _ = reaper.MIDI_GetNote(take, noteidx)
    orig_pos =  reaper.MIDI_GetProjTimeFromPPQPos(take, startppqpos)
    new_pos = GetNewPosition(orig_pos)
    new_pos_ppq = reaper.MIDI_GetPPQPosFromProjTime(take, new_pos)
    new_end_ppq = endppqpos + (new_pos_ppq - startppqpos)
    reaper.MIDI_SetNote(take, noteidx, nil, nil, floor(new_pos_ppq+0.5), floor(new_end_ppq+0.5))
  end
  for ccidx=0, ccevtcnt -1 do
    local _, _, _, ppqpos, _, _, _, _ = reaper.MIDI_GetCC(take, ccidx)
    orig_pos =  reaper.MIDI_GetProjTimeFromPPQPos(take, ppqpos)
    new_pos = GetNewPosition(orig_pos)
    new_pos_ppq = reaper.MIDI_GetPPQPosFromProjTime(take, new_pos)
    reaper.MIDI_SetCC(take, ccidx, nil, nil, floor(new_pos_ppq+0.5))
  end
  for textsyxevtidx=0, textsyxevtcnt -1 do
    local _, _, _, ppqpos, _, _, _, _ = reaper.MIDI_GetTextSysexEvt(take, textsyxevtidx)
    orig_pos =  reaper.MIDI_GetProjTimeFromPPQPos(take, ppqpos)
    new_pos = GetNewPosition(orig_pos)
    new_pos_ppq = reaper.MIDI_GetPPQPosFromProjTime(take, new_pos)
    reaper.MIDI_SetTextSysexEvt(take, textsyxevtidx, nil, nil, floor(new_pos_ppq+0.5))
  end
end

local typebuf = ""
local count = reaper.CountSelectedMediaItems(0)
if count > 0 then
  reaper.Undo_BeginBlock()
  for i=0, count -1 do
    local item = reaper.GetSelectedMediaItem(0, i)
    local pos = reaper.GetMediaItemInfo_Value(item, "D_POSITION")
  
    local take = reaper.GetMediaItemTake(item, 0)
    local source = reaper.GetMediaItemTake_Source(take)
    typebuf = reaper.GetMediaSourceType(source, typebuf)
    if typebuf ~= "MIDI" then
      reaper.SetMediaItemPosition(item, GetNewPosition(pos), false)
    else
      reaper.MarkTrackItemsDirty(reaper.GetMediaItem_Track(item), item)
      QuantizeMIDI(take)
    end
  end
  reaper.Undo_EndBlock("Quantize", -1)
  reaper.UpdateArrange()
end

Last edited by en5ca; 04-14-2021 at 03:28 PM.
en5ca 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 01:08 AM.


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