Go Back   Cockos Incorporated Forums > REAPER Forums > JSFX and ReaScript Discussion

Reply
 
Thread Tools Display Modes
Old 06-17-2017, 04:22 PM   #1
mccrabney
Human being with feelings
 
mccrabney's Avatar
 
Join Date: Aug 2015
Location: Slackjaw, North Carolina
Posts: 923
Default 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.
__________________
MidiEditor: select last-recorded notes FR || QuantizSwing CC: Positive val only option
input quantize: OSC values for on/off state (for hardware LED) || control strength CC
automation items that behave as such.
mccrabney is offline   Reply With Quote
Old 06-17-2017, 09:22 PM   #2
Neutronic
Human being with feelings
 
Neutronic's Avatar
 
Join Date: Sep 2013
Posts: 195
Default

I think it'd be useful to create alternative versions that don't perform gluing and simply mention that in their titles.

Last edited by Neutronic; 06-17-2017 at 09:28 PM.
Neutronic is offline   Reply With Quote
Old 06-20-2017, 12:48 PM   #3
Ozman
Human being with feelings
 
Join Date: Feb 2015
Posts: 295
Default

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.
Ozman is offline   Reply With Quote
Old 06-21-2017, 01:30 PM   #4
mccrabney
Human being with feelings
 
mccrabney's Avatar
 
Join Date: Aug 2015
Location: Slackjaw, North Carolina
Posts: 923
Default

Quote:
Originally Posted by mpl View Post
What if takes to import:
  • have playrate other than 1
  • have stretch markers
  • looped
?

In this case gluing them is the only option to put them as they are in arrange.
agreed, in that case gluing is the only option. my request refers to other case uses.

it would be great for MLR style sample playback (see example of MLR here https://www.youtube.com/watch?v=zFbkIdV2nF8)

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)
__________________
MidiEditor: select last-recorded notes FR || QuantizSwing CC: Positive val only option
input quantize: OSC values for on/off state (for hardware LED) || control strength CC
automation items that behave as such.
mccrabney is offline   Reply With Quote
Old 06-22-2017, 02:00 AM   #5
Bri1
Human being with feelings
 
Bri1's Avatar
 
Join Date: Dec 2016
Posts: 556
Default

Quote:
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?
Bri1 is offline   Reply With Quote
Old 06-23-2017, 11:08 AM   #6
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 1,309
Default

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)
__________________
SoundCloud | MPL Scripts / ReaPack | Donate

Last edited by mpl; 06-23-2017 at 11:49 PM.
mpl is online now   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:52 AM.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.