Script tweak FR - MPL Export items to RS5k on sel track
currently this script renders each selected item and puts it into its own RS5k instance. this is awesome.
it would be handy if a tweak of this script could be made that, rather than rendering, creating multiple instances of RS5k containing the original sample but with edited start/end points containing the audio item's contents.
i don't know how to do this but would learn a lot from comparing it to MPL's original version.
__________________ mccrabney scripts: MIDI edits from the Arrange screen ala jjos/MPC sequencer
|sis - - - anacru| isn't what we performed: pls no extra noteons in loop recording
| - - - - - anacru|sis <==this is what we actually performed.
It's nice that MPL has done this in a script, but honestly, the sampling side of Reaper has much to be desired, period.
We see other daws developing evolved workflows in sound design, sampling, and arranging. Reaper, however, has become a powerhouse when it comes to recording and routing.
I for one am at the same time excited, yet a small sense of jealousy due to other daws' sampling and arrangement features. I am one of those who really do not like working with multiple daws and saving multiple projects for one session (the main reason I also stopped using Reason).
We'll have to wait and see what's in the near future when it comes to the sampling features of Reaper.
what i would probably do is further tweak the script to, instead of glue, simply create incrementally shorter selection lengths. let's pretend that this symbol "12345678" is a wav that we will slice and apply to rs5k.
ideally you would result with the following instances of RS5k, with the different selection:
12345678
2345678
345678
45678
5678
678
78
8
one would apply a voice limit/monophonic assignment to these samples so that they would cut each other off...
thinking out loud. thanks for your script, anyway -- it is really good, i just wish RS5k was better with envelopes/midi control (see this bug report: http://forum.cockos.com/showthread.php?t=192930)
__________________ mccrabney scripts: MIDI edits from the Arrange screen ala jjos/MPC sequencer
|sis - - - anacru| isn't what we performed: pls no extra noteons in loop recording
| - - - - - anacru|sis <==this is what we actually performed.
rather than rendering, creating multiple instances of RS5k containing the original sample but with edited start/end points containing the audio item's contents.
Try this video-->
It works the same way as harmor does(kinda) by mapping sample offsets.
If your accurate with the envelope shaping,you may/will get what you want.
MPL might also consider these options for any new tweaks to existing scripts.
Have you ever tried the mpl isomorphic keyboard to go with it yet?
Note it will be buggy if items/takes:
- are looped
- have rate other than 1.0x
- have stretch markers
- ...something else I could forgot about
Code:
local script_title = 'Export selected items to RS5k instances on selected track (drum mode)'
-------------------------------------------------------------------------------
function F_SetFXName(track, fx, new_name)
local edited_line,edited_line_id,segm
-- get ref guid
if not track or not tonumber(fx) then return end
local FX_GUID = reaper.TrackFX_GetFXGUID( track, fx )
if not FX_GUID then return else FX_GUID = FX_GUID:gsub('-',''):sub(2,-2) end
local plug_type = reaper.TrackFX_GetIOSize( track, fx )
-- get chunk t
local _, chunk = reaper.GetTrackStateChunk( track, '', false )
local t = {} for line in chunk:gmatch("[^\r\n]+") do t[#t+1] = line end
-- find edit line
local search
for i = #t, 1, -1 do
local t_check = t[i]:gsub('-','')
if t_check:find(FX_GUID) then search = true end
if t[i]:find('<') and search and not t[i]:find('JS_SER') then
edited_line = t[i]:sub(2)
edited_line_id = i
break
end
end
-- parse line
if not edited_line then return end
local t1 = {}
for word in edited_line:gmatch('[%S]+') do t1[#t1+1] = word end
local t2 = {}
for i = 1, #t1 do
segm = t1[i]
if not q then t2[#t2+1] = segm else t2[#t2] = t2[#t2]..' '..segm end
if segm:find('"') and not segm:find('""') then if not q then q = true else q = nil end end
end
if plug_type == 2 then t2[3] = '"'..new_name..'"' end -- if JS
if plug_type == 3 then t2[5] = '"'..new_name..'"' end -- if VST
local out_line = table.concat(t2,' ')
t[edited_line_id] = '<'..out_line
local out_chunk = table.concat(t,'\n')
--msg(out_chunk)
reaper.SetTrackStateChunk( track, out_chunk, false )
reaper.UpdateArrange()
end
-------------------------------------------------------------------------------
function ExportSelItemsToRs5k(track, base_pitch)
for i = 1, reaper.CountSelectedMediaItems(0) do
local item = reaper.GetSelectedMediaItem(0,i-1)
local take = reaper.GetActiveTake(item)
if not take or reaper.TakeIsMIDI(take) then goto skip_to_next_item end
local tk_src = reaper.GetMediaItemTake_Source( take )
local filename = reaper.GetMediaSourceFileName( tk_src, '' )
it_len = reaper.GetMediaItemInfo_Value( item, 'D_LENGTH' )
src_len = reaper.GetMediaSourceLength( tk_src )
st_offs = reaper.GetMediaItemTakeInfo_Value( take, 'D_STARTOFFS')
rs5k_offs0 = st_offs / src_len
rs5k_offs1 = (st_offs+it_len)/ src_len
local rs5k_pos = reaper.TrackFX_AddByName( track, 'ReaSamplOmatic5000 (Cockos)', false, -1 )
reaper.TrackFX_SetParamNormalized( track, rs5k_pos, 2, 0) -- gain for min vel
reaper.TrackFX_SetParamNormalized( track, rs5k_pos, 3, base_pitch/127 ) -- note range start
reaper.TrackFX_SetParamNormalized( track, rs5k_pos, 4, base_pitch/127 ) -- note range end
reaper.TrackFX_SetParamNormalized( track, rs5k_pos, 5, 0.5 ) -- pitch for start
reaper.TrackFX_SetParamNormalized( track, rs5k_pos, 6, 0.5 ) -- pitch for end
reaper.TrackFX_SetParamNormalized( track, rs5k_pos, 8, 0 ) -- max voices = 0
reaper.TrackFX_SetParamNormalized( track, rs5k_pos, 9, 0 ) -- attack
reaper.TrackFX_SetParamNormalized( track, rs5k_pos, 11, 0 ) -- obey note offs
reaper.TrackFX_SetParamNormalized( track, rs5k_pos, 13, rs5k_offs0 ) -- start offset
reaper.TrackFX_SetParamNormalized( track, rs5k_pos, 14, rs5k_offs1 ) -- end offset
local new_name = F_extract_filename(filename)
F_SetFXName(track, rs5k_pos, 'RS5K '..new_name)
reaper.TrackFX_SetNamedConfigParm(track, rs5k_pos, "FILE0", filename)
reaper.TrackFX_SetNamedConfigParm(track, rs5k_pos, "DONE","")
base_pitch = base_pitch + 1
::skip_to_next_item::
end
end
-------------------------------------------------------------------------------
function vrs_check()
local appvrs = reaper.GetAppVersion()
appvrs = appvrs:match('[%d%p]+'):gsub('/','')
if not appvrs then return end
appvrs = tonumber(appvrs)
if not appvrs or appvrs <= 5.29 then return end
if not reaper.APIExists('TrackFX_SetNamedConfigParm') then return end
return true
end
-------------------------------------------------------------------------------
function FormMIDItake_data()
local MIDI = {}
-- check for same track/get items info
local item = reaper.GetSelectedMediaItem(0,0)
if not item then return end
MIDI.it_pos = reaper.GetMediaItemInfo_Value( item, 'D_POSITION' )
MIDI.it_end_pos = MIDI.it_pos + 0.1
local proceed_MIDI = true
local it_tr0 = reaper.GetMediaItemTrack( item )
for i = 1, reaper.CountSelectedMediaItems(0) do
local item = reaper.GetSelectedMediaItem(0,i-1)
local it_pos = reaper.GetMediaItemInfo_Value( item, 'D_POSITION' )
local it_len = reaper.GetMediaItemInfo_Value( item, 'D_LENGTH' )
MIDI[#MIDI+1] = {pos=it_pos, end_pos = it_pos+it_len}
MIDI.it_end_pos = it_pos + it_len
local it_tr = reaper.GetMediaItemTrack( item )
if it_tr ~= it_tr0 then proceed_MIDI = false break end
end
return proceed_MIDI, MIDI
end
-------------------------------------------------------------------------------
function F_extract_filename(orig_name)
local reduced_name_slash = orig_name:reverse():find('[%/%\\]')
local reduced_name = orig_name:sub(-reduced_name_slash+1)
reduced_name = reduced_name:sub(0,-1-reduced_name:reverse():find('%.'))
return reduced_name
end
-------------------------------------------------------------------------------
function AddMIDI(track, MIDI,base_pitch)
if not MIDI then return end
local new_it = reaper.CreateNewMIDIItemInProj( track, MIDI.it_pos, MIDI.it_end_pos )
local new_tk = reaper.GetActiveTake( new_it )
for i = 1, #MIDI do
local startppqpos = reaper.MIDI_GetPPQPosFromProjTime( new_tk, MIDI[i].pos )
local endppqpos = reaper.MIDI_GetPPQPosFromProjTime( new_tk, MIDI[i].end_pos )
local ret = reaper.MIDI_InsertNote( new_tk,
false, --selected,
false, --muted,
startppqpos,
endppqpos,
0,
base_pitch+i-1,
100,
true)--noSortInOptional )
--if ret then reaper.ShowConsoleMsg('done') end
end
reaper.MIDI_Sort( new_tk )
reaper.GetSetMediaItemTakeInfo_String( new_tk, 'P_NAME', 'sliced loop', 1 )
reaper.UpdateArrange()
end
-------------------------------------------------------------------------------
function main(track)
-- track check
local track = reaper.GetSelectedTrack(0,0)
if not track then return end
-- item check
local item = reaper.GetSelectedMediaItem(0,0)
if not item then return true end
-- get base pitch
local ret, base_pitch = reaper.GetUserInputs( script_title, 1, 'Set base pitch', 60 )
if not ret
or not tonumber(base_pitch)
or tonumber(base_pitch) < 0
or tonumber(base_pitch) > 127 then
return
end
base_pitch = math.floor(tonumber(base_pitch))
-- get info for new midi take
local proceed_MIDI, MIDI = FormMIDItake_data()
-- export to RS5k
ExportSelItemsToRs5k(track, base_pitch)
reaper.Main_OnCommand(40006,0)--Item: Remove items
-- add MIDI
if proceed_MIDI then AddMIDI(track, MIDI,base_pitch) end
MIDI_prepare(track)
end
-------------------------------------------------------------------------------
function MIDI_prepare(tr)
local bits_set=tonumber('111111'..'00000',2)
reaper.SetMediaTrackInfo_Value( tr, 'I_RECINPUT', 4096+bits_set ) -- set input to all MIDI
reaper.SetMediaTrackInfo_Value( tr, 'I_RECMON', 1) -- monitor input
reaper.SetMediaTrackInfo_Value( tr, 'I_RECARM', 1) -- arm track
reaper.SetMediaTrackInfo_Value( tr, 'I_RECMODE',0) -- record MIDI out
end
-------------------------------------------------------------------------------
if not vrs_check() then reaper.MB('Script works with REAPER 5.40 and upper. Script also need SWS extension.','Error',0) end
reaper.Undo_BeginBlock()
-- reaper.PreventUIRefresh( -1 )
main()
-- reaper.PreventUIRefresh( 1 )
reaper.Undo_EndBlock(script_title, 1)
Can those things be checked and if they turn up being different from the default, then render/glue them to like the the script currently does?
So glue/render new file if..
- Looped
- Have rate other than 1.0x
- Have stretch markers
- Any of these settings do not match a previously imported sample (buffering the settings of each sample during the import session, to be used in comparison with subsequently imported samples)
Is it possible for the script to Export Selected Items to ONE instance of RS5K? Was trying to work it out using the script that MPL created, but can't seem to load all of the media items into a singular RS5K instance. What would that look like? Thanks in advance
It will looks like if you load samples to list. And they will be played depending on incoming velocity, not on MIDI note, because RS5k designed this way.
How do i modify your script to export the selected media items to an RS5K List? I don't want each media item to play from its own RS5K. I would like to round robin using velocity (Midi Tool V2). Any help would be much obliged!
How do i modify your script to export the selected media items to an RS5K List? I don't want each media item to play from its own RS5K. I would like to round robin using velocity (Midi Tool V2). Any help would be much obliged!