Go Back   Cockos Incorporated Forums > REAPER Forums > REAPER Feature Requests

Reply
 
Thread Tools Display Modes
Old 06-07-2012, 04:21 AM   #1
timlloyd
Human being with feelings
 
Join Date: Mar 2010
Posts: 4,713
Default Copy and Paste ReaScript functions

Currently to copy/paste items in a script we have to chain built-in actions.

Could we have something like the following:

Code:
void CopyMediaItem(MediaItem* item, double starttime, double endtime)

void PasteMediaItem(MediaTrack* tr, double starttime)
... and have these not update the arrange view when called (as the "SplitMediaItem" function is now).

This way, we could make scripts which feel more like actions and less like macros, and could be faster as well. We wouldn't need to select a track first, move the edit cursor or worry about the edit cursor moving on paste (depending on user's preferences)
timlloyd is offline   Reply With Quote
Old 06-18-2012, 02:51 AM   #2
timlloyd
Human being with feelings
 
Join Date: Mar 2010
Posts: 4,713
Default

Nobody?
timlloyd is offline   Reply With Quote
Old 03-21-2019, 04:28 AM   #3
nikolalkc
Human being with feelings
 
nikolalkc's Avatar
 
Join Date: Feb 2017
Location: Belgrade, Serbia
Posts: 338
Default

Is this really still unavailable?
nikolalkc is offline   Reply With Quote
Old 03-21-2019, 09:03 AM   #4
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,984
Default

Create new item with API and apply source item chunk to it.
mpl is offline   Reply With Quote
Old 03-21-2019, 09:41 AM   #5
nikolalkc
Human being with feelings
 
nikolalkc's Avatar
 
Join Date: Feb 2017
Location: Belgrade, Serbia
Posts: 338
Default

That's exactly what I did.
Thanks anyway.
Here's a LUA reascript function for everyone else.

Code:
function CopyMediaItem (itemToCopy,destinationTrack,position)
	reaper.PreventUIRefresh( 1 )
	local original_position =  reaper.GetMediaItemInfo_Value( itemToCopy, "D_POSITION" )
	reaper.SetMediaItemInfo_Value( itemToCopy, "D_POSITION" , position )
	local retval, chunk = reaper.GetItemStateChunk( itemToCopy, "", false )
	local temp_item = reaper.CreateNewMIDIItemInProj( destinationTrack, 3, 0.1, false )
	reaper.SetMediaItemInfo_Value( itemToCopy, "D_POSITION" , original_position )
	
	reaper.SetItemStateChunk( temp_item, chunk, false )
	reaper.PreventUIRefresh( -1 )
end
And this is how you use it:

Code:
CopyMediaItem(myItem,myTrack,1.5)
nikolalkc is offline   Reply With Quote
Old 03-21-2019, 10:46 AM   #6
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,628
Default

Is it ok, if I add that function to my Ultraschall-API?
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 03-21-2019, 10:55 AM   #7
nikolalkc
Human being with feelings
 
nikolalkc's Avatar
 
Join Date: Feb 2017
Location: Belgrade, Serbia
Posts: 338
Default

Yes of course.
nikolalkc is offline   Reply With Quote
Old 03-21-2019, 01:15 PM   #8
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,984
Default

Quote:
Originally Posted by nikolalkc View Post
That's exactly what I did.
Thanks anyway.
Here's a LUA reascript function for everyone else.

Code:
function CopyMediaItem (itemToCopy,destinationTrack,position)
	reaper.PreventUIRefresh( 1 )
	local original_position =  reaper.GetMediaItemInfo_Value( itemToCopy, "D_POSITION" )
	reaper.SetMediaItemInfo_Value( itemToCopy, "D_POSITION" , position )
	local retval, chunk = reaper.GetItemStateChunk( itemToCopy, "", false )
	local temp_item = reaper.CreateNewMIDIItemInProj( destinationTrack, 3, 0.1, false )
	reaper.SetMediaItemInfo_Value( itemToCopy, "D_POSITION" , original_position )
	
	reaper.SetItemStateChunk( temp_item, chunk, false )
	reaper.PreventUIRefresh( -1 )
end
And this is how you use it:

Code:
CopyMediaItem(myItem,myTrack,1.5)
I would also recommend to replace GUID in new item chunk by generated one.
mpl is offline   Reply With Quote
Old 03-21-2019, 01:39 PM   #9
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,900
Default

You should take a lok at our ReaTeam Template repo,


I put similar functions years ago,

https://github.com/ReaTeam/ReaScript...dia%20item.lua



It also took care of the GUID generation.



But it could go further using native actions within the script,

to have goodies like "Track envelopes points follow selection", "Auto crossfade", "ripple editing" etc..

EDIT: here it was: https://github.com/ReaTeam/ReaScript...20position.lua
X-Raym is offline   Reply With Quote
Old 03-22-2019, 01:05 AM   #10
nikolalkc
Human being with feelings
 
nikolalkc's Avatar
 
Join Date: Feb 2017
Location: Belgrade, Serbia
Posts: 338
Default

Quote:
Originally Posted by mpl View Post
I would also recommend to replace GUID in new item chunk by generated one.
Does this mean that in my case original item and copied item have the same GUID?
What's the danger of not changing it in item chunk?
nikolalkc is offline   Reply With Quote
Old 03-22-2019, 02:31 AM   #11
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,900
Default

@niko
Imcompatibility with all other actions / scripts which need unique GUID to work.
X-Raym is offline   Reply With Quote
Old 03-22-2019, 05:54 AM   #12
Meo-Ada Mespotine
Human being with feelings
 
Meo-Ada Mespotine's Avatar
 
Join Date: May 2017
Location: Leipzig
Posts: 6,628
Default

Quote:
Originally Posted by nikolalkc View Post
Does this mean that in my case original item and copied item have the same GUID?
What's the danger of not changing it in item chunk?
The GUID and the IGUID are unique identifiers, that help Reaper and extensions/scripts to differentiate between two MediaItems, who share otherwise the same attributes/characteristics.

So changing them both is a very good idea. Helps Reaper as well, when saving and reloading a project.
__________________
Use you/she/her.Ultraschall-Api Lua Api4Reaper - Donate, if you wish

On vacation for the time being...
Meo-Ada Mespotine is offline   Reply With Quote
Old 12-13-2020, 12:43 AM   #13
daniellumertz
Human being with feelings
 
daniellumertz's Avatar
 
Join Date: Dec 2017
Location: Brazil
Posts: 2,008
Default

Trying to use Nikola function to MIDI copy, and have independent IGUID. So tried to join with X-Raym function to gsub inside the chunk of the item. But the chunk that is getting back for some reason is lacking info.
Code:
function CopyMediaItem(item, track, position)
    reaper.SetMediaItemInfo_Value( item, "D_POSITION" , position )
    local retval, chunk = reaper.GetItemStateChunk( item, "", false )


    local new_item = reaper.CreateNewMIDIItemInProj( track, 3, 0.1 )
    local new_item_guid = reaper.BR_GetMediaItemGUID(new_item)


    new_item_chunk = chunk:gsub('IGUID ({.+})', 'IGUID ' .. new_item_guid)
    reaper.SetItemStateChunk( new_item, new_item_chunk , false )
end
Do I need to change that 'IGUID ({.+})'? I think it is altering all the chunk after IGUID instead of just that part
daniellumertz is offline   Reply With Quote
Old 12-13-2020, 01:22 AM   #14
tufb
Human being with feelings
 
Join Date: Dec 2017
Posts: 152
Default

https://github.com/bfut/ReaScripts/b...ted%20item.lua

bfut_GetSetItemChunkValue() (GPLv3)
bfut_ResetAllChunkGuids()(GPLv3)

Perhaps this is relevant. Note, these assume that there are no conflicts.

If you end up using these, I'd be interested how it works out and which OS you use.

edit: I'd love if either reaper or sws would implement string split for Lua.

Last edited by tufb; 12-13-2020 at 08:21 AM.
tufb is offline   Reply With Quote
Old 12-13-2020, 05:01 PM   #15
daniellumertz
Human being with feelings
 
daniellumertz's Avatar
 
Join Date: Dec 2017
Location: Brazil
Posts: 2,008
Default

hmm this is usefull, trying to understand how could I add this, I more or less solved my problem using the code this:

Code:
 
function CopyMediaItem(item, track, position)
    reaper.SetMediaItemInfo_Value( item, "D_POSITION" , position )
    local retval, chunk = reaper.GetItemStateChunk( item, "", false )

    local new_item = reaper.CreateNewMIDIItemInProj( track, 3, 0.1 )
    local new_item_guid = reaper.BR_GetMediaItemGUID(new_item)

  
    reaper.SetItemStateChunk( new_item, chunk, false )
    reaper.Main_OnCommand(41613, 0) -- Item: Remove active take from MIDI source data pool (AKA un-pool, un-ghost, make unique)
end
but IDK if this can have not seen consequences
daniellumertz is offline   Reply With Quote
Old 12-13-2020, 05:50 PM   #16
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,900
Default

@daniellumertz
Better use the native copy and paste funciton inside your script,


So that you are sure it will behave as intented (generating new GUIS for items, takes and everything which need GUID, also taking care of several other things like auto cross fades, items follow envelope, ripple editing state...)
X-Raym is offline   Reply With Quote
Old 12-13-2020, 06:46 PM   #17
daniellumertz
Human being with feelings
 
daniellumertz's Avatar
 
Join Date: Dec 2017
Location: Brazil
Posts: 2,008
Default

Quote:
Originally Posted by X-Raym View Post
@daniellumertz
Better use the native copy and paste funciton inside your script,


So that you are sure it will behave as intented (generating new GUIS for items, takes and everything which need GUID, also taking care of several other things like auto cross fades, items follow envelope, ripple editing state...)
The problem is that It must not copy envelopes ( independent if the user have items follow envelopes on ) and because of ripple editing, independent if it is on the paste should not trigger it, is a very specific case hehe. Thanks
daniellumertz is offline   Reply With Quote
Old 12-14-2020, 02:42 AM   #18
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,900
Default

@daniellumertz
The trick is just to toggle off these off within the script,
and then toggle it back.


Then your copy paste will be transparent :P
X-Raym is offline   Reply With Quote
Old 12-14-2020, 11:01 AM   #19
daniellumertz
Human being with feelings
 
daniellumertz's Avatar
 
Join Date: Dec 2017
Location: Brazil
Posts: 2,008
Default

this is a way also! heheh thanks! time to think which way should I took with the script, not for only that but other things hahaha decisions decisions .....
daniellumertz is offline   Reply With Quote
Old 12-18-2020, 11:54 PM   #20
daniellumertz
Human being with feelings
 
daniellumertz's Avatar
 
Join Date: Dec 2017
Location: Brazil
Posts: 2,008
Default

Quote:
Originally Posted by tufb View Post
https://github.com/bfut/ReaScripts/b...ted%20item.lua

bfut_GetSetItemChunkValue() (GPLv3)
bfut_ResetAllChunkGuids()(GPLv3)

Perhaps this is relevant. Note, these assume that there are no conflicts.

If you end up using these, I'd be interested how it works out and which OS you use.

edit: I'd love if either reaper or sws would implement string split for Lua.
Tested bfut_ResetAllChunkGuids() and worked nice here for changing GUID and IGUID thankss! windows 10 here can test in a mac I have to see if it works too

just wondering why in the script exemple you use bfut_GetSetItemChunkValue() to change IGUID inseted of bfut_ResetAllChunkGuids()

edit: also why the while loop in the function?

Last edited by daniellumertz; 12-19-2020 at 12:16 AM.
daniellumertz is offline   Reply With Quote
Old 12-19-2020, 10:54 AM   #21
tufb
Human being with feelings
 
Join Date: Dec 2017
Posts: 152
Default

Cheers, that's good news. Thanks for testing. Mac would be interesting, as I can't test that. I never had a bug report related to my replacement scripts, but, you know.

IGUID is a unique field. All the other ID fields are related to FX, takes etc., and in general not unique fields in an item chunk, hence the while to replace all occurences. MIDI takes are a special case, where pooled/ghost sheets share a single ID across items.

Last edited by tufb; 12-19-2020 at 11:15 AM.
tufb is offline   Reply With Quote
Old 05-16-2021, 11:00 PM   #22
daniellumertz
Human being with feelings
 
daniellumertz's Avatar
 
Join Date: Dec 2017
Location: Brazil
Posts: 2,008
Default

Quote:
Originally Posted by X-Raym View Post
@daniellumertz
Better use the native copy and paste funciton inside your script,


So that you are sure it will behave as intented (generating new GUIS for items, takes and everything which need GUID, also taking care of several other things like auto cross fades, items follow envelope, ripple editing state...)
Ok I am considering doing a function to use the MainOnCommand and bypass all trim, ripple edit options that might be on. But meanwhile I did this function that might be helpfull,

Code:
function print(...)
    for k,v in ipairs({...}) do
        reaper.ShowConsoleMsg(tostring(v))
    end
    reaper.ShowConsoleMsg("\n")
end

function bfut_ResetAllChunkGuids(item_chunk, key) -- (I changed a little but it is from here: https://github.com/bfut/ReaScripts/blob/main/Items%20Editing/bfut_Replace%20item%20under%20mouse%20cursor%20with%20selected%20item.lua
    item_chunk = item_chunk:gsub('%s('..key..')%s+.-[\r]-[%\n]', "\ntemp%1 "..reaper.genGuid("").."\n", 1)
    return item_chunk:gsub('temp'..key, key), true
end

function ChangeChunkPosition(item_chunk, newpos)
    local new_chunk = item_chunk:gsub("POSITION [%d%.]+","POSITION "..tostring(newpos))
    return new_chunk
end

function LoadSelectedItems(list) -- Not used it is here in case you need
    reaper.Main_OnCommand(40289, 0)--Item: Unselect all items
    if #list ~= 0 then 
        for i = 1, #list do 
            local bol = reaper.ValidatePtr( list[i] ,"MediaItem*" )
            if bol then
                reaper.SetMediaItemSelected( list[i], true )
            end
        end 
    end
end

function SaveSelectedItems() -- Not used it is here in case you need
    local list = {}
    local num = reaper.CountSelectedMediaItems(0)
    if num ~= 0 then
        for i= 0, num-1 do
            list[i+1] =  reaper.GetSelectedMediaItem( 0, i )
        end
    end
    --reaper.Main_OnCommand(40289, 0)--Item: Unselect all items
    return list
end

function CopyTakeInfo(take_copy, take_paste) -- Copy every info you can with  reaper.SetMediaItemTakeInfo_Value()
    local names = [[
    D_STARTOFFS
    D_VOL
    D_PAN
    D_PANLAW
    D_PLAYRATE
    D_PITCH
    B_PPITCH
    I_CHANMODE
    I_PITCHMODE
    I_CUSTOMCOLOR
    IP_TAKENUMBER
    ]] -- You can add or remove items from this list to be copied or not. Here is all of them
    local info = {}
    for info in string.gmatch(names,"%S+") do
        local val = reaper.GetMediaItemTakeInfo_Value(take_copy, info)
        reaper.SetMediaItemTakeInfo_Value(take_paste, info, val)
    end
end

function CopyMediaNotMIDI(item, track, position) -- Fork From Xraym https://github.com/ReaTeam/ReaScripts-Templates/blob/master/Items%20Creations/X-Raym_Copy%20media%20item.lua
	local new_item = reaper.AddMediaItemToTrack(track)
	local new_item_guid = reaper.BR_GetMediaItemGUID(new_item)
	local retval, item_chunk =  reaper.GetItemStateChunk(item, '')
    local new_item_chunk = bfut_ResetAllChunkGuids(item_chunk, "IGUID")
    local new_item_chunk = bfut_ResetAllChunkGuids(new_item_chunk, "GUID")
	reaper.SetItemStateChunk(new_item, new_item_chunk)
    -- Set some extra info  PUT THIS BAC
    local vol = reaper.GetMediaItemInfo_Value(item, "D_VOL")
	reaper.SetMediaItemInfo_Value(new_item, "D_VOL", vol)
    local off = reaper.GetMediaItemInfo_Value(item, "D_SNAPOFFSET")
	reaper.SetMediaItemInfo_Value(new_item, "D_SNAPOFFSET", off)
    CopyTakeInfo(reaper.GetMediaItemTake(item, 0), reaper.GetMediaItemTake(new_item, 0)) 
	reaper.SetMediaItemInfo_Value(new_item, "D_POSITION", position)
	return new_item
end

function CopyMIDI(item, track, position)-- Copy an MIDI Item to Track at position. Be awere that it will change the item selection to the new item so use SaveSelectedItems() before calling it and then LoadSelectedItems(items_list)
    local retval, chunk = reaper.GetItemStateChunk( item, "", false )
    local chunk = bfut_ResetAllChunkGuids(chunk, "IGUID")
    local chunk = bfut_ResetAllChunkGuids(chunk, "GUID")
    local chunk = bfut_ResetAllChunkGuids(chunk, "POOLEDEVTS")
    local chunk = ChangeChunkPosition(chunk, position)

    local new_item = reaper.CreateNewMIDIItemInProj( track, 3, 0.1 )
    reaper.SetItemStateChunk( new_item, chunk, false )
    return new_item
end

function CopyMediaItem(item, track, position, selectcopy) -- It will change your item selection to the new item if you don't want this use You can put the SaveSelectedItems() and LoadSelectedItems().
    local selectcopy = selectcopy or false -- when selectcopy is true the copied item will be selected
    local ismidi = reaper.TakeIsMIDI(reaper.GetMediaItemTake(item, 0))
    local new_item = nil
    if ismidi == true then
        new_item = CopyMIDI(item, track, position) 
    else 
        new_item = CopyMediaNotMIDI(item, track, position)
    end
    reaper.UpdateItemInProject(new_item)
    if selectcopy then 
        reaper.Main_OnCommand(40289, 0)--Item: Unselect all items
        reaper.SetMediaItemSelected( new_item, true )
    end
    return new_item
end

--Exemple Copy Items to Selected Track  
local count_sel_items = reaper.CountSelectedMediaItems(0)
local count_sel_tracks = reaper.CountSelectedTracks(0)
if count_sel_tracks > 0 and count_sel_items > 0 then
    --Saves some info
    reaper.Undo_BeginBlock()
    reaper.PreventUIRefresh( 1 )
    --local items_list = SaveSelectedItems() 
    --The actual thing
    for items_i = 0,count_sel_items-1 do
        local item = reaper.GetSelectedMediaItem(0, items_i)
        local pos = reaper.GetMediaItemInfo_Value(item, "D_POSITION")
        for i = 0, count_sel_tracks-1 do
            local track_loop = reaper.GetSelectedTrack(0, i)
            CopyMediaItem(item, track_loop, pos)
            reaper.UpdateArrange()
        end
        --LoadSelectedItems(items_list)
    end
    --Load things up
    reaper.PreventUIRefresh( -1 )
    reaper.Undo_EndBlock('Copy Items to Selected Tracks', -1)
end
I use part of yours code in templates github and tufb to adjust the GUID and IGUID. I think it is working . at least in my tests.


Thanks
Edit: removed a bug converning FX and GUID, I think I should update to reapack right?

EDIT: One more change code is better now with some options to be reused

EDIT EDIT EDIT: I tired of editing code is in reapack https://github.com/daniellumertz/Dan...d%20Tracks.lua

Last edited by daniellumertz; 05-17-2021 at 01:05 AM.
daniellumertz is offline   Reply With Quote
Old 05-16-2021, 11:48 PM   #23
daniellumertz
Human being with feelings
 
daniellumertz's Avatar
 
Join Date: Dec 2017
Location: Brazil
Posts: 2,008
Default

hm what the effects of having two items with same FXID ?
daniellumertz is offline   Reply With Quote
Old 06-22-2021, 06:00 AM   #24
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,458
Default

I do not know but I think they should not.


Anyway, GUIDs are auto-generated by Reaper if they are missing. I made this function:
Code:
local function CopyMediaItemToTrack( item, track, position )
  local _, chunk = reaper.GetItemStateChunk( item, "", false )
  chunk = chunk:gsub("{.-}", "") -- Reaper auto-generates all GUIDs
  local new_item = reaper.AddMediaItemToTrack( track )
  reaper.PreventUIRefresh( 1 )
  reaper.SetItemStateChunk( new_item, chunk, false )
  reaper.SetMediaItemInfo_Value( new_item, "D_POSITION" , position )
  reaper.PreventUIRefresh( -1 )
  return new_item
end
It would be nice to have it as native API though:
Code:
MediaItem CopyMediaItemToTrack( MediaItem item, Track tr, number position )
__________________
Most of my scripts can be found in ReaPack.
If you find them useful, a donation would be greatly appreciated! Thank you! :)

Last edited by amagalma; 06-22-2021 at 06:09 AM.
amagalma is offline   Reply With Quote
Old 06-23-2021, 10:17 AM   #25
daniellumertz
Human being with feelings
 
daniellumertz's Avatar
 
Join Date: Dec 2017
Location: Brazil
Posts: 2,008
Default

LOL, much easier. Just some lines of code. I don't know Why it took me that giant piece of code. thanks Amagalma, will update some scripts of mine to use this
daniellumertz is offline   Reply With Quote
Old 02-15-2024, 03:32 PM   #26
daniellumertz
Human being with feelings
 
daniellumertz's Avatar
 
Join Date: Dec 2017
Location: Brazil
Posts: 2,008
Default

Just complemeting the explanation above, testing here removing all the guids characters will return {00000000-0000-0000-0000-000000000000} and removing all the guid with its brackets will return the current guid or in its absence, generate a new guid. Which is the case with applying a chunk missing guids to an empty item which only have IGUID identifier.

Just worries me that this part of amagalma snippet chunk:gsub("{.-}", "") can erase information from the user, less likely track names contaning {}. But also item ext states with serialized tables. Bellow is my proposal for CopyMediaItemToTrack:
Code:
function print(...) 
    local t = {}
    for i, v in ipairs( { ... } ) do
        t[i] = tostring( v )
    end
    reaper.ShowConsoleMsg( table.concat( t, " " ) .. "\n" )
end

-- Items
function enumSelectedItems(proj)
    local cnt = reaper.CountSelectedMediaItems(0)
    local i = -1
    return function ()
        i = i + 1
        local item = reaper.GetSelectedMediaItem(proj, i) -- get current selected item
        return item
    end
end
function literalize(str)
    return str:gsub(
        "[%(%)%.%%%+%-%*%?%[%]%^%$]",
        function(c)
        return "%" .. c
        end
    )
end

---Reset all `key` identifiers in a chunk 
---@param chunk string item/track/envelope chunk
---@param key string identifier key Items:(GUID, IGUID, POOLEDEVTS, FXID) Tracks:(TRACKID, FXID) Envelopes:(EGUID)
---@param new_guid string?  optional. Default value is reaper.genGuid(''). If just '' the guid will be the current guid or if no current guid for that Identifier it will generate one.  If just '{}' the guid will be {00000000-0000-0000-0000-000000000000}. 
---@return string chunk return chunk with new guids
function ResetChunkIndentifier(chunk, key, new_guid)
    local pattern = '\n'..key..'%s?{.-}\n'
    for sub in chunk:gmatch(pattern) do -- Need to run gsub in a loop for a new reaper.genGuid('') for every occurance. 
        local guid_line = '\n'..key..' '..(new_guid or reaper.genGuid(''))..'\n'
        local sub_pattern = literalize(sub)
        chunk = chunk:gsub(sub_pattern,guid_line, 1) -- Need to be sure gsub is working in the actual line matched at gmatch, just using a gsub with the current GUID could result changing stored information at extstates
    end
    return chunk
end


---comment
---@param item item* item to be copied
---@param track track* track to copy to
---@param position number position in seconds to copy to
---@param selected boolean? optional boolean if is selected or not, if nil copy with current state (selecter or not)
---@param pooled_copy boolean? optional if true will make a pooled copy if nil or false will make a independent copy
---@return item
local function CopyMediaItemToTrack(item, track, position, selected, pooled_copy)
    local _, chunk = reaper.GetItemStateChunk( item, "", false )
    chunk = ResetChunkIndentifier(chunk, 'GUID', '')
    chunk = ResetChunkIndentifier(chunk, 'IGUID', '')
    if not pooled_copy then
        chunk = ResetChunkIndentifier(chunk, 'POOLEDEVTS', '')
    end
    chunk = ResetChunkIndentifier(chunk, 'FXID', '')
    local new_item = reaper.AddMediaItemToTrack( track )
    reaper.SetItemStateChunk( new_item, chunk, false )
    reaper.SetMediaItemInfo_Value( new_item, "D_POSITION" , position )
    if selected ~= nil then
        reaper.SetMediaItemInfo_Value( new_item, "B_UISEL" , selected and 1 or 0 )
    end
    return new_item
end


local proj = 0
local sel_items = {}
for item in enumSelectedItems(proj) do
    sel_items[#sel_items+1] = item
end

for _, item in ipairs(sel_items) do
    local track = reaper.GetMediaItemTrack(item)
    CopyMediaItemToTrack(item, track, 1, false )
end

Last edited by daniellumertz; 02-18-2024 at 01:27 PM.
daniellumertz 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 10:37 PM.


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