 |
|
|
08-26-2020, 06:54 AM
|
#1
|
Human being with feelings
Join Date: Mar 2019
Posts: 235
|
Razor Edit Scripts
While the other threads are busy discussing features and implementation details I thought it would be nice to have a thread for experimenting with scripts now that we have access to API.
Here are some wrapper functions around the "basic API" that are hopefully a bit more approachable. (Lua)
This stuff will likely break in the future, but it is nice to have something that makes it easier to play around with razor edits in the meanwhile. Place this at the top of your code:
Code:
function literalize(str)
return str:gsub("[%(%)%.%%%+%-%*%?%[%]%^%$]", function(c) return "%" .. c end)
end
function GetGUIDFromEnvelope(envelope)
local ret2, envelopeChunk = reaper.GetEnvelopeStateChunk(envelope, "")
local GUID = "{" .. string.match(envelopeChunk, "GUID {(%S+)}") .. "}"
return GUID
end
function GetItemsInRange(track, areaStart, areaEnd)
local items = {}
local itemCount = reaper.CountTrackMediaItems(track)
for k = 0, itemCount - 1 do
local item = reaper.GetTrackMediaItem(track, k)
local pos = reaper.GetMediaItemInfo_Value(item, "D_POSITION")
local length = reaper.GetMediaItemInfo_Value(item, "D_LENGTH")
local itemEndPos = pos+length
--check if item is in area bounds
if (itemEndPos > areaStart and itemEndPos <= areaEnd) or
(pos >= areaStart and pos < areaEnd) or
(pos <= areaStart and itemEndPos >= areaEnd) then
table.insert(items,item)
end
end
return items
end
function GetEnvelopePointsInRange(envelopeTrack, areaStart, areaEnd)
local envelopePoints = {}
for i = 1, reaper.CountEnvelopePoints(envelopeTrack) do
local retval, time, value, shape, tension, selected = reaper.GetEnvelopePoint(envelopeTrack, i - 1)
if time >= areaStart and time <= areaEnd then --point is in range
envelopePoints[#envelopePoints + 1] = {
id = i-1 ,
time = time,
value = value,
shape = shape,
tension = tension,
selected = selected
}
end
end
return envelopePoints
end
function SetTrackRazorEdit(track, areaStart, areaEnd, clearSelection)
if clearSelection == nil then clearSelection = false end
if clearSelection then
local ret, area = reaper.GetSetMediaTrackInfo_String(track, 'P_RAZOREDITS', '', false)
--parse string, all this string stuff could probably be written better
local str = {}
for j in string.gmatch(area, "%S+") do
table.insert(str, j)
end
--strip existing selections across the track
local j = 1
while j <= #str do
local GUID = str[j+2]
if GUID == '""' then
str[j] = ''
str[j+1] = ''
str[j+2] = ''
end
j = j + 3
end
--insert razor edit
local REstr = tostring(areaStart) .. ' ' .. tostring(areaEnd) .. ' ""'
table.insert(str, REstr)
local finalStr = ''
for i = 1, #str do
local space = i == 1 and '' or ' '
finalStr = finalStr .. space .. str[i]
end
local ret, area = reaper.GetSetMediaTrackInfo_String(track, 'P_RAZOREDITS', finalStr, true)
return ret
else
local ret, area = reaper.GetSetMediaTrackInfo_String(track, 'P_RAZOREDITS', '', false)
local str = area ~= nil and area .. ' ' or ''
str = str .. tostring(areaStart) .. ' ' .. tostring(areaEnd) .. ' ""'
local ret, area = reaper.GetSetMediaTrackInfo_String(track, 'P_RAZOREDITS', str, true)
return ret
end
end
function SetEnvelopeRazorEdit(envelope, areaStart, areaEnd, clearSelection, GUID)
local GUID = GUID == nil and GetGUIDFromEnvelope(envelope) or GUID
local track = reaper.Envelope_GetParentTrack(envelope)
if clearSelection then
local ret, area = reaper.GetSetMediaTrackInfo_String(track, 'P_RAZOREDITS', '', false)
--parse string
local str = {}
for j in string.gmatch(area, "%S+") do
table.insert(str, j)
end
--strip existing selections across the envelope
local j = 1
while j <= #str do
local envGUID = str[j+2]
if GUID ~= '""' and envGUID:sub(2,-2) == GUID then
str[j] = ''
str[j+1] = ''
str[j+2] = ''
end
j = j + 3
end
--insert razor edit
local REstr = tostring(areaStart) .. ' ' .. tostring(areaEnd) .. ' ' .. GUID
table.insert(str, REstr)
local finalStr = ''
for i = 1, #str do
local space = i == 1 and '' or ' '
finalStr = finalStr .. space .. str[i]
end
local ret, area = reaper.GetSetMediaTrackInfo_String(track, 'P_RAZOREDITS', finalStr, true)
return ret
else
local ret, area = reaper.GetSetMediaTrackInfo_String(track, 'P_RAZOREDITS', '', false)
local str = area ~= nil and area .. ' ' or ''
str = str .. tostring(areaStart) .. ' ' .. tostring(areaEnd) .. ' ' .. GUID
local ret, area = reaper.GetSetMediaTrackInfo_String(track, 'P_RAZOREDITS', str, true)
return ret
end
end
function GetRazorEdits()
local trackCount = reaper.CountTracks(0)
local areaMap = {}
for i = 0, trackCount - 1 do
local track = reaper.GetTrack(0, i)
local ret, area = reaper.GetSetMediaTrackInfo_String(track, 'P_RAZOREDITS', '', false)
if area ~= '' then
--PARSE STRING
local str = {}
for j in string.gmatch(area, "%S+") do
table.insert(str, j)
end
--FILL AREA DATA
local j = 1
while j <= #str do
--area data
local areaStart = tonumber(str[j])
local areaEnd = tonumber(str[j+1])
local GUID = str[j+2]
local isEnvelope = GUID ~= '""'
--get item/envelope data
local items = {}
local envelopeName, envelope
local envelopePoints
if not isEnvelope then
items = GetItemsInRange(track, areaStart, areaEnd)
else
envelope = reaper.GetTrackEnvelopeByChunkName(track, GUID:sub(2, -2))
local ret, envName = reaper.GetEnvelopeName(envelope)
envelopeName = envName
envelopePoints = GetEnvelopePointsInRange(envelope, areaStart, areaEnd)
end
local areaData = {
areaStart = areaStart,
areaEnd = areaEnd,
track = track,
items = items,
--envelope data
isEnvelope = isEnvelope,
envelope = envelope,
envelopeName = envelopeName,
envelopePoints = envelopePoints,
GUID = GUID:sub(2, -2)
}
table.insert(areaMap, areaData)
j = j + 3
end
end
end
return areaMap
end
function SplitRazorEdits(razorEdits)
local areaItems = {}
local tracks = {}
reaper.PreventUIRefresh(1)
for i = 1, #razorEdits do
local areaData = razorEdits[i]
if not areaData.isEnvelope then
local items = areaData.items
--recalculate item data for tracks with previous splits
if tracks[areaData.track] ~= nil then
items = GetItemsInRange(areaData.track, areaData.areaStart, areaData.areaEnd)
end
for j = 1, #items do
local item = items[j]
--split items
local newItem = reaper.SplitMediaItem(item, areaData.areaStart)
if newItem == nil then
reaper.SplitMediaItem(item, areaData.areaEnd)
table.insert(areaItems, item)
else
reaper.SplitMediaItem(newItem, areaData.areaEnd)
table.insert(areaItems, newItem)
end
end
tracks[areaData.track] = 1
end
end
reaper.PreventUIRefresh(-1)
return areaItems
end
Moved the explanations/examples over to this post as they no longer fit here: https://forum.cockos.com/showpost.ph...9&postcount=73
Last edited by BirdBird; 09-01-2020 at 04:03 PM.
|
|
|
08-26-2020, 02:47 PM
|
#2
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 7,210
|
meo-mespotine will like this code snippets for sure :P
Thanks for sharing !
|
|
|
08-27-2020, 12:55 AM
|
#3
|
Human being with feelings
Join Date: Feb 2020
Location: Los Angeles
Posts: 353
|
I just wrote a very simple one that returns true or false if a Razor Edit exists anywhere in your session....... I don't know how you get those cool code snippet windows. Fortunately my script is short....
Code:
function RazorEditSelectionExists()
for i=0, reaper.CountTracks(0)-1 do
local retval, x = reaper.GetSetMediaTrackInfo_String(reaper.GetTrack(0,i), "P_RAZOREDITS", "string", false)
if x ~= "" then return true end
end--for
return false
end--RazorEditSelectionExists()
Last edited by sonictim; 10-30-2020 at 09:12 AM.
Reason: code brackets
|
|
|
08-27-2020, 02:03 AM
|
#4
|
Human being with feelings
Join Date: Feb 2020
Location: Los Angeles
Posts: 353
|
Link Razor Edit with Item Selection
BirdBird! Thank you...
Using your code, and the code I just posted, I just wrote a quick defer function that will link area selection with item selection. Now I'm using my Razor Edit also as a Marquee Selection! I'm a novice coder (was my first time using defer) so if anyone notices any problems with it, please let me know
Code:
function Main()
if RazorEditSelectionExists() then
local selections = GetRazorEdits()
for i = 1, #selections do
local areaData = selections[i]
local items = areaData.items
for j = 1, #items do reaper.SetMediaItemSelected(items[j], true) end
end
end--if
reaper.defer(Main)
end--Main()
Main()
Last edited by sonictim; 08-27-2020 at 02:36 PM.
Reason: updating code
|
|
|
08-27-2020, 06:47 AM
|
#5
|
Human being with feelings
Join Date: Apr 2013
Location: France
Posts: 7,210
|
@sonictim
to emebed mua code on fprum post use [ code][ /code] syntax without spaces. :P
|
|
|
08-27-2020, 09:03 AM
|
#6
|
Human being with feelings
Join Date: Dec 2009
Location: Oblivion
Posts: 7,870
|
I can't find other threads discussing the feature...what is razor edit?
|
|
|
08-27-2020, 06:47 AM
|
#7
|
Human being with feelings
Join Date: Apr 2020
Location: Leipzig
Posts: 2,117
|
Quote:
Originally Posted by X-Raym
meo-mespotine will like this code snippets for sure :P
Thanks for sharing !
|
How did you know that?
@sonictim
please put [CODE] brackets arounds your code. Just select the code and hit the #-button in the editor. Otherwise, the forum's layouting could break things.
And it's better readable that way.
|
|
|
Thread Tools |
|
Display Modes |
Hybrid Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 08:41 AM.
|