Old 05-11-2015, 05:24 AM   #881
heda
Human being with feelings
 
heda's Avatar
 
Join Date: Jun 2012
Location: Spain
Posts: 7,239
Default

it looks great spk77
Maybe we could put all the tracks inside a folder instead of being always at the end, so you could put the folder collapsed anywhere you want, and the script should find the folder track by the name, for example "UNTUNED tracks" and then move the tracks to that folder. Just an idea.
heda is offline   Reply With Quote
Old 05-11-2015, 05:33 AM   #882
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by heda View Post
it looks great spk77
Maybe we could put all the tracks inside a folder instead of being always at the end, so you could put the folder collapsed anywhere you want, and the script should find the folder track by the name, for example "UNTUNED tracks" and then move the tracks to that folder. Just an idea.
Nice idea!
spk77 is offline   Reply With Quote
Old 05-11-2015, 06:03 AM   #883
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Two things I noticed while making the "duplicate script":
  • Track routing is not preserved when cut/pasting tracks - that's why there's "SWS: Cut selected tracks (with routing)"
  • It's a nice day outside.
spk77 is offline   Reply With Quote
Old 05-11-2015, 07:11 AM   #884
plamuk
Human being with feelings
 
Join Date: Feb 2007
Posts: 3,221
Default

Quote:
Originally Posted by X-Raym View Post
@nym
Getting media item under mouse involves REAPER v5 pre and SWS pre too.
There is BR_ functions for this, you will find them in the ReaScript doc.
X-Raym, i'm looking for something that checks for an item on a track under the EDIT cursor, not the mouse cursor. i saw the BR functions you mentioned -- close but not quite what i need.

thanks for your website, though, i spent a long time on it last night

Last edited by plamuk; 05-11-2015 at 07:17 AM.
plamuk is offline   Reply With Quote
Old 05-11-2015, 08:08 AM   #885
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@nym
Oh sorry I misread !

So under Edit cursor... of selected tracks, I presume ?

You can:

— Get edit cursor position
— Loop on selected tracks
—— Loop on items on this tracks
——— For each items, check if edit cursor is inside item start and item end (item end is item start+ item duration)
——— Do your action

All of this functions are in the API documenation.

You can also
— Save item selection (optionnal)
— Use Xenakios/SWS action "_XENAKIOS_SELITEMSUNDEDCURSELTX" (aka: select items under edit cursor on selected tracks)
— Loop through selected items
—— Do your action

Quote:
thanks for your website, though, i spent a long time on it last night
I'm glad to hear it

happy coding!

@spk77
Quote:
It's a nice day outside.
Time to take a sunbath :P
X-Raym is offline   Reply With Quote
Old 05-11-2015, 10:21 AM   #886
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by X-Raym View Post
Time to take a sunbath :P
It was sunny, but still too cold
spk77 is offline   Reply With Quote
Old 05-11-2015, 10:54 AM   #887
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
Default

Hi guys.
Today I have a strange problem.
I try to send changed formatted #string back to plugin

PHP Code:
function set_parameter()
(
Undo_BeginBlock();
0;
trackcount CountTracks(0);
loop(trackcount,
  
track GetTrack(0i);
  
GetSetMediaTrackInfo_String(track"P_NAME"#cur_track, 0);
  
match("KEY01_P1"#cur_track) ? 
    
(
    
fx TrackFX_GetByName(track"ReaEQ1"0);
    
0;
    
params  TrackFX_GetNumParams(trackfx);
      
loop (params,
      
TrackFX_GetParamName(trackfxj#par_name);
       
match("Gain-Band 3"#par_name) ? 
       
(


/* Here it is */
        
TrackFX_GetFormattedParamValue(track,fx,j,#Form_Par_Val); // get string
        
match ("%f"#Form_Par_Val, form_par_val); // convert to float
        
form_par_val form_par_val 1// add 1 db float
        
sprintf(#Form_Par_Val, "%{form_par_val}f"); // convert back to string
/* so now I want convert #Form_Par_Val back to value for TrackFX_SetParam - how to do that?*/
           
        
);
      
+= 1;
    );
    );
  
+= 1;
);
TrackList_AdjustWindows(0);
Undo_EndBlock("set parameter"0);
);
set_parameter();
UpdateArrange(); 
mpl is offline   Reply With Quote
Old 05-11-2015, 01:47 PM   #888
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Hi mpl,

There are functions to get/set ReaEQ params directly (f.ex. TrackFX_SetEQParam). I haven't tested them yet.

If you want to, for example, add/subtract x decibels to/from the current dB value, this might work:

Code:
function set_parameter() 
( 
Undo_BeginBlock(); 
dB_val = -1; // subtract 1 dB
i = 0;
trackcount = CountTracks(0); 
loop(trackcount, 
  track = GetTrack(0, i);
  GetSetMediaTrackInfo_String(track, "P_NAME", #cur_track, 0);
  match("KEY01_P1", #cur_track) ? ( 
    fx_index = TrackFX_GetByName(track, "ReaEQ", 0); 
    j = 0; 
    param_count = TrackFX_GetNumParams(track, fx_index); 
    loop(param_count, 
      TrackFX_GetParamName(track, fx_index, j, #par_name); 
      match("Gain-Band 3", #par_name) ? (
        trim = pow(10, dB_val / 20.0);
        val = trim * TrackFX_GetParam(track, fx_index, j, minval, maxval);
        val > maxval ? val = maxval
        :
        val < minval ? val = minval;
        TrackFX_SetParam(track, fx_index, j, val);
      );
      j += 1; 
    ); 
  ); 
  i += 1; 
); 

TrackList_AdjustWindows(0); 
Undo_EndBlock("set parameter", 0); 
); 
set_parameter(); 
UpdateArrange();

I have 3 tracks (named KEY01_P1) and ReaEQ is the first FX on each track.


(There might be better ways to do it, I don't know )

EDIT. Hmm...I don't know how to convert a formatted value back to normalized value
spk77 is offline   Reply With Quote
Old 05-11-2015, 03:14 PM   #889
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
Default

Thanks spk77, I thought about power and log functions for amp and frequency, but even this simple math little bit difficult for me.

If this feature not realized yet(=no one knows how to do that), I will post a FR. And also my opinion is every get/set_something should be inside one function with boolean=1 for set.
mpl is offline   Reply With Quote
Old 05-11-2015, 03:43 PM   #890
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Quote:
And also my opinion is every get/set_something should be inside one function with boolean=1 for set.
Some functions are already like that already, they start with GetSet.

I don't feel the need for all functions to be like that, but sure it is convenient in some cases.
X-Raym is offline   Reply With Quote
Old 05-11-2015, 05:41 PM   #891
plamuk
Human being with feelings
 
Join Date: Feb 2007
Posts: 3,221
Default

ok i made something that makes me love lua. it checks the selected track for an item under the edit cursor, and if it finds NONE, it creates a midi item.

this is my first reascript, borrowed heavily from "X-Raym_Add all items on selected track into item selection" since it was a starting point. please critique it on format and functional content.

now i'm going to learn how to make a tempo-dependent item endpoint with CreateNewMIDIItemInProj so that it's always a measure or so

question -- when looking for functions from x-raym's scripts, it looks in reaper/lua. how can i change this directory to the more appropriate /users/appdata/reaper/scripts ??

todo:
make a tempo-friendly endpoint
prevent midi item from overlapping next midi item?
create a followup script that deletes midi items if they are left empty

Code:
--[[
////////////// draft ///////////////////////
if item under edit cursor, create midi item.
please critique both formatting and content.
////////////////////////////////////////////
--]]

function get_script_path()
  if reaper.GetOS() == "Win32" or reaper.GetOS() == "Win64" then
    return debug.getinfo(1,'S').source:match("(.*".."\\"..")"):sub(2) -- remove "@"
  end
    return debug.getinfo(1,'S').source:match("(.*".."/"..")"):sub(2)
end

package.path = package.path .. ";" .. get_script_path() .. "?.lua"
require("X-Raym_Functions - console debug messages")

debug = 1 -- 0 => No console. 1 => Display console messages for debugging.
clean = 1 -- 0 => No console cleaning before every script execution. 1 => Console cleaning before every script execution.

msg_clean()

function is_edit_cursor_on_item() -- local (i, j, item, take, track)
reaper.Undo_BeginBlock() -- Begining of the undo block.

  selected_tracks_count = reaper.CountSelectedTracks(0)
  cursor_pos = reaper.GetCursorPosition()
  reaper.ShowConsoleMsg("cursor position - ")
  reaper.ShowConsoleMsg(cursor_pos)
  no_edit_cursor = 0
  
  -- LOOP TRHOUGH SELECTED TRACKS
  
  for i = 0, selected_tracks_count-1  do
    track_sel = reaper.GetSelectedTrack(0, i)
    item_num = reaper.CountTrackMediaItems(track_sel)

    for j = 0, item_num-1 do
      item = reaper.GetTrackMediaItem(track_sel, j)
      start_pos = reaper.GetMediaItemInfo_Value(item, "D_POSITION");
      end_pos = start_pos + reaper.GetMediaItemInfo_Value(item, "D_LENGTH");
      reaper.ShowConsoleMsg("\n item start --")
      reaper.ShowConsoleMsg(start_pos)
      reaper.ShowConsoleMsg(" ... item end --")
      reaper.ShowConsoleMsg(end_pos)
          if cursor_pos >= start_pos and cursor_pos <= end_pos
          then reaper.ShowConsoleMsg("\n item contains edit cursor \n")
               reaper.ShowConsoleMsg(no_edit_cursor)          
          else no_edit_cursor = no_edit_cursor + 1
               reaper.ShowConsoleMsg("\n item doesn't contain edit cursor \n")
               reaper.ShowConsoleMsg(no_edit_cursor)
          end
    end
  end -- ENDLOOP through selected tracks
  if no_edit_cursor == item_num
    then reaper.CreateNewMIDIItemInProj(track_sel, cursor_pos, cursor_pos+10)
  end
  
  reaper.Undo_EndBlock("create midi item under mouse cursor if none exists", 0) -- End of the undo block. Leave it at the bottom of your main function.
  reaper.ShowConsoleMsg("\n")
end

msg_start() -- Display characters in the console to show you the begining of the script execution.

is_edit_cursor_on_item() -- Execute your main function

reaper.UpdateArrange() -- Update the arrangement (often needed)

msg_end() -- Display characters in the console to show you the end of the script execution.
i made a licecap, but the display resolution is all screwy on this computer (yoga2 pro, some things appear TINY, others HUGE, and licecap was recording its own border somehow.


Last edited by plamuk; 05-11-2015 at 06:17 PM.
plamuk is offline   Reply With Quote
Old 05-11-2015, 11:08 PM   #892
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@nym
Quote:
borrowed heavily from "X-Raym_Add all items on selected track into item selection"
Oh, I made that ? I didn't remember ^^
Quote:
when looking for functions from x-raym's scripts, it looks in reaper/lua. how can i change this directory to the more appropriate /users/appdata/reaper/scripts ??
If you are talking about the link to my functions console messages scripts, it already looks in the user /users/appdata/reaper/scripts (/Functions) folder. It does this in a all-os-compatible way, it is not written in absolute, but it is what it does for windows users. So I don't suggest you to modify it. :P

What I suggest you to do is to put inside comment all dependencies and all functions related to this development scripts, so that you can share your script without telling to other to download my pack.The functions related to this file start by "msg".Note: dependency to my console debug message script is not useful to you if you use reaper.ShowConsoleMsg.

That said, your script work.

Welcome aboard ! :P


EDIT: a screen capture of LiceCap itself... this is pretty unique.

Last edited by X-Raym; 05-12-2015 at 05:31 AM.
X-Raym is offline   Reply With Quote
Old 05-12-2015, 07:37 AM   #893
plamuk
Human being with feelings
 
Join Date: Feb 2007
Posts: 3,221
Default

thanks, and thanks again for making this possible for me via your website.

this little script may help those of us who want to work with a more "track based midi" approach.

i can't believe that all it took was a head cold and an afternoon of forced bed rest / experimentation
plamuk is offline   Reply With Quote
Old 05-12-2015, 07:46 AM   #894
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@nym
It starts like that, but if you enjoyed it, be sure you will have a lot more afternoon to enhance your scripts :P
Don't worry, your to do list seems feasible.

@all
Do you think we can make a defer script that offset and fix the play cursor position, no matter what is the zoom position, using the new BR_ set arrange view function ? (in continuous scrolling it is straight in the middle of the screen, I want something like this but another place of the screen).

Won't it be too "jumpy" ?
X-Raym is offline   Reply With Quote
Old 05-13-2015, 07:07 PM   #895
daxliniere
Human being with feelings
 
daxliniere's Avatar
 
Join Date: Nov 2008
Location: London, UK
Posts: 2,581
Default

Quote:
Originally Posted by spk77 View Post
I hope this works:
Download from the stash...
Thankyou spk77, that's really awesome. Thanks for your time and expertise!!

All the best,
Dax.
__________________
Puzzle Factory Sound Studios, London [Website] [Instagram]
[AMD 5800X, 32Gb RAM, Win10x64, NVidia GTX1080ti, UAD2-OCTO, FireFaceUCX, REAPER x64]
[Feature request: More details in Undo History]
daxliniere is offline   Reply With Quote
Old 05-16-2015, 03:04 AM   #896
syntetic
Human being with feelings
 
syntetic's Avatar
 
Join Date: May 2014
Posts: 160
Default

another noob question from me:
how can i convert value for examle 1.023756 to float;
i use match("%f", #stringname, newfloat) but i get 1.024 only.
I tried to automate rate by plugin but I hear crackles,probably because I can't change rate to small values.

Last edited by syntetic; 05-16-2015 at 04:13 AM.
syntetic is offline   Reply With Quote
Old 05-16-2015, 04:14 AM   #897
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by syntetic View Post
another noob question from me:
how can i convert value for examle 1.023756 to float;
i tried to use match("%f", #stringname, newfloat) but i get 1.024 only.

EDIT: Tested - didn't work.

Didn't test, but this should work:

Code:
#stringname = "1.023756";

match("%0.10f", #stringname, newfloat); // show 10 digits after decimal point

Last edited by spk77; 05-16-2015 at 04:28 AM.
spk77 is offline   Reply With Quote
Old 05-16-2015, 04:17 AM   #898
heda
Human being with feelings
 
heda's Avatar
 
Join Date: Jun 2012
Location: Spain
Posts: 7,239
Default

Quote:
Originally Posted by syntetic View Post
I tried to automate rate by plugin but I hear crackles,probably because I can't change rate to small values.
Are you trying to automate the rate while playing an item? Or just at the beginning of the item as a more convenient way to change the rate of the items?
heda is offline   Reply With Quote
Old 05-16-2015, 04:33 AM   #899
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

The editor shows rounded values.


Test: Convert str-> float-> str
Code:
#stringname = "1.02375612354";
match("%f", #stringname, newfloat);
#val = sprintf(#, "%0.20f",newfloat);
The editor shows:
Code:
#stringname: 1.02375612354
newfloat: 1.024
#val: 1.02375612353999990000
spk77 is offline   Reply With Quote
Old 05-16-2015, 05:25 AM   #900
syntetic
Human being with feelings
 
syntetic's Avatar
 
Join Date: May 2014
Posts: 160
Default

spk77
when i change
Code:
#val = sprintf(#, "%0.20f",newfloat)
to
Code:
#val = sprintf(#, "%0.6f",newfloat)
editor shows not rounded values , but when i try change rate from val:
SetMediaItemTakeInfo_Value(take, "D_PLAYRATE",#val) - item rate sets to 90001.000000

Last edited by syntetic; 05-16-2015 at 05:33 AM.
syntetic is offline   Reply With Quote
Old 05-16-2015, 06:21 AM   #901
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Short answer:
You don't have to worry about the conversion - just use "%f" :

Code:
match("%f", #stringname, newfloat);
SetMediaItemTakeInfo_Value(take, "D_PLAYRATE",newfloat)

Longer answer:
#val is a string variable (that's why the rate is set to 90001.000000. EEL editor shows strings in that "format")

You have to use floats in SetMediaItemTakeInfo_Value function:
Code:
SetMediaItemTakeInfo_Value(take, "D_PLAYRATE", somefloatvalue)
newfloat value is rounded to 1.024 in the editor, but the newfloat variable holds the correct value "internally":

Testing...(the correct value is stored to the project file):
Code:
take = GetActiveTake(GetSelectedMediaItem(0,0));
#stringname = "1.023756";
match("%f", #stringname, newfloat);
SetMediaItemTakeInfo_Value(take, "D_PLAYRATE",newfloat);
UpdateArrange();
spk77 is offline   Reply With Quote
Old 05-16-2015, 01:41 PM   #902
plamuk
Human being with feelings
 
Join Date: Feb 2007
Posts: 3,221
Default

i've been thinking about my request "select most recently recorded midi"

this would be highly useful for selectively quantizing the most recent recorded midi without having to manually select it.

i wondered...what if we made a script that replaces the record behavior in which, upon "ctrl R" or whatever, it checks to see if the item is midi, selects all notes/events, records, and upon record stop it inverts the selection? this would in theory select only new events/notes.

thoughts?
plamuk is offline   Reply With Quote
Old 05-16-2015, 05:49 PM   #903
vanhaze
Human being with feelings
 
vanhaze's Avatar
 
Join Date: Jul 2012
Location: Netherlands
Posts: 5,247
Default New Script request: delete notes randomly in Midi Item.

Let's say i have a Midi Item, full of Notes.

Now i want to have a slider.
The slider opens at value zero : no notes are deleted from Midi Item.
The further i drag the slider to to the right, the more notes in the midi Item get DELETED, at RANDOM places in the item.

Scriptable ?

Why oh why this script request ??

I often user arpeggiation midi patterns.
I often vind these are "too busy", so i want to delete notes out of such patterns, to "let it breath more"

With my script wish, this could be done, leading to unpredictable, random, and possible awesome, note sequence patterns.

Thx in advance !!
vanhaze is offline   Reply With Quote
Old 05-17-2015, 11:56 PM   #904
syntetic
Human being with feelings
 
syntetic's Avatar
 
Join Date: May 2014
Posts: 160
Default

thanks spk,
Anybody know whether is it possible somehow to hide border of gfx window?

Last edited by syntetic; 05-18-2015 at 06:17 AM.
syntetic is offline   Reply With Quote
Old 05-18-2015, 07:40 AM   #905
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@vanhaze
I have done a script that may satisfied your need !

It is not exactly as you intend it to be first (because of some "limitations" - It is not real limitations, it is more because of "how things are designed"), but you may find it useful

It works with a user input.
It detects the number of notes there is in the item and then let you choose one number.

It then randomly select and mute a certain amount of notes accordingly.
It doesn't delete them: so you can re-execute the script several times !
But because it select the muted notes, you can then delete them if needed.

I'm finishing it.
X-Raym is offline   Reply With Quote
Old 05-24-2015, 06:56 AM   #906
Alex Ortega
Human being with feelings
 
Join Date: Oct 2013
Posts: 105
Default help me )

Quote:
Originally Posted by spk77 View Post
Tod, I thought this might be useful:

Split selected item(s) to equal length items:




Code:
# Split selected item(s) to equal length items
# (from item start to item end -> last "piece" might be shorter than a given value)

from reaper_python import *
from contextlib import contextmanager

@contextmanager
def undoable(message):
    RPR_Undo_BeginBlock2(0)
    try:
        yield
    finally:
        RPR_Undo_EndBlock2(0, message, -1)

def msg(m):
    RPR_ShowConsoleMsg(str(m) + "\n")

def dialog():
    default = "0.250"
    d = RPR_GetUserInputs("Split item(s) to equal length items", 1, "Length (seconds)", default, 30)
    return d

def split():
    selItemCount = RPR_CountSelectedMediaItems(0)
    if selItemCount == 0:
        msg("Select items")
        return

    d = dialog()
    if not d[0]:
        return

    newItemLength = float(d[4])
    selItemIdL = []
    newItem = ""

    for i in range(selItemCount):
        selItemIdL.append(RPR_GetSelectedMediaItem(0, i))

    for item in selItemIdL:
        length = RPR_GetMediaItemInfo_Value(item, "D_LENGTH")
        pos = RPR_GetMediaItemInfo_Value(item, "D_POSITION")
        currLength = pos

        while currLength < pos + length - newItemLength:
            newItem = RPR_SplitMediaItem(item, currLength + newItemLength)
            item = newItem
            currLength += newItemLength

    RPR_UpdateArrange()

with undoable("Split item(s) to equal length items"):
    split()
Hi spk77! I want to ask you a favor to help me write a script but rather alter your script
rewrite your script

# Split selected item (s) to equal length items

I would like that I could fix the Split item (s) to equal legth items (Length (second) 0.0000250)
and that the plate is not displayed and immediately pressed (s) and if possible what after this action was another effect (normalization). thanks

# Split selected item(s) to equal length items
Alex Ortega is offline   Reply With Quote
Old 05-27-2015, 11:44 AM   #907
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Alex Ortega View Post
Hi spk77! I want to ask you a favor to help me write a script but rather alter your script
rewrite your script

# Split selected item (s) to equal length items

I would like that I could fix the Split item (s) to equal legth items (Length (second) 0.0000250)
and that the plate is not displayed and immediately pressed (s) and if possible what after this action was another effect (normalization). thanks

# Split selected item(s) to equal length items
Hi Alex! I don't have Python installed on my computer, but if I understood correctly, this might work:

Code:
# Split selected item(s) to equal length items

from reaper_python import *
from contextlib import contextmanager

@contextmanager
def undoable(message):
    RPR_Undo_BeginBlock2(0)
    try:
        yield
    finally:
        RPR_Undo_EndBlock2(0, message, -1)

def msg(m):
    RPR_ShowConsoleMsg(str(m) + "\n")

def split():
    selItemCount = RPR_CountSelectedMediaItems(0)
    if selItemCount == 0:
        msg("Select items")
        return

    newItemLength = 0.0000250
    selItemIdL = []
    newItem = ""

    for i in range(selItemCount):
        selItemIdL.append(RPR_GetSelectedMediaItem(0, i))

    for item in selItemIdL:
        length = RPR_GetMediaItemInfo_Value(item, "D_LENGTH")
        pos = RPR_GetMediaItemInfo_Value(item, "D_POSITION")
        currLength = pos

        while currLength < pos + length - newItemLength:
            newItem = RPR_SplitMediaItem(item, currLength + newItemLength)
            item = newItem
            currLength += newItemLength

    RPR_Main_OnCommand(40108, 0)  # 40108: Normalize items
    RPR_UpdateArrange()
    

with undoable("Split item(s) to equal length items"):
    split()
spk77 is offline   Reply With Quote
Old 05-27-2015, 04:12 PM   #908
Alex Ortega
Human being with feelings
 
Join Date: Oct 2013
Posts: 105
Default

Quote:
Originally Posted by spk77 View Post
Hi Alex! I don't have Python installed on my computer, but if I understood correctly, this might work:

Code:
# Split selected item(s) to equal length items

from reaper_python import *
from contextlib import contextmanager

@contextmanager
def undoable(message):
    RPR_Undo_BeginBlock2(0)
    try:
        yield
    finally:
        RPR_Undo_EndBlock2(0, message, -1)

def msg(m):
    RPR_ShowConsoleMsg(str(m) + "\n")

def split():
    selItemCount = RPR_CountSelectedMediaItems(0)
    if selItemCount == 0:
        msg("Select items")
        return

    newItemLength = 0.0000250
    selItemIdL = []
    newItem = ""

    for i in range(selItemCount):
        selItemIdL.append(RPR_GetSelectedMediaItem(0, i))

    for item in selItemIdL:
        length = RPR_GetMediaItemInfo_Value(item, "D_LENGTH")
        pos = RPR_GetMediaItemInfo_Value(item, "D_POSITION")
        currLength = pos

        while currLength < pos + length - newItemLength:
            newItem = RPR_SplitMediaItem(item, currLength + newItemLength)
            item = newItem
            currLength += newItemLength

    RPR_Main_OnCommand(40108, 0)  # 40108: Normalize items
    RPR_UpdateArrange()
    

with undoable("Split item(s) to equal length items"):
    split()
Yes, it works thank you
Why then 4 Reapers works and does not work 5 Reapers an error "Script execution error"
And you can do this in .eel?

Last edited by Alex Ortega; 05-28-2015 at 01:54 AM.
Alex Ortega is offline   Reply With Quote
Old 05-28-2015, 04:08 AM   #909
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Alex Ortega View Post
Yes, it works thank you
Why then 4 Reapers works and does not work 5 Reapers an error "Script execution error"
And you can do this in .eel?
Hmm..it should work in REAPER 5.

This is a Lua version for REAPER Pre5 (save as *.lua).

NOTE: It takes very long time to execute this script when "slice_len" is set to "0.0000250":

For 1 second item, 40001 new items would be created (it took ~15 seconds here).




(Change the red value - now it's set to 0.250)
Code:
-- Split selected item(s) to equal length parts

local r = reaper

function msg(m)
  r.ShowConsoleMsg(tostring(m) .. "\n")
end

function split()
  local sel_item_count = r.CountSelectedMediaItems(0)
  if sel_item_count == 0 then
    msg("Select items")
    return
  end
   
  reaper.Undo_BeginBlock()
  local slice_len = 0.250 -- slice length in seconds

  local sel_item_t = {}
  for i=1, sel_item_count do
    sel_item_t[i] = r.GetSelectedMediaItem(0, i-1)
  end

  for i=1, #sel_item_t do
    local item = sel_item_t[i] 
    local length = r.GetMediaItemInfo_Value(item, "D_LENGTH")
    local pos = r.GetMediaItemInfo_Value(item, "D_POSITION")
    local curr_len = pos

    while (curr_len < pos + length - slice_len) do
      local new_item = r.SplitMediaItem(item, curr_len + slice_len)
      item = new_item
      curr_len = curr_len + slice_len
    end
    --]]
  end

  r.Main_OnCommand(40108, 0)  -- 40108: Normalize items
  r.UpdateArrange()
  r.Undo_EndBlock("Split to equal length parts", -1)
end
    

r.defer(split)
spk77 is offline   Reply With Quote
Old 05-28-2015, 01:09 PM   #910
Alex Ortega
Human being with feelings
 
Join Date: Oct 2013
Posts: 105
Default

Quote:
Originally Posted by spk77 View Post
Hmm..it should work in REAPER 5.

This is a Lua version for REAPER Pre5 (save as *.lua).

NOTE: It takes very long time to execute this script when "slice_len" is set to "0.0000250":

For 1 second item, 40001 new items would be created (it took ~15 seconds here).




(Change the red value - now it's set to 0.250)
Code:
-- Split selected item(s) to equal length parts

local r = reaper

function msg(m)
  r.ShowConsoleMsg(tostring(m) .. "\n")
end

function split()
  local sel_item_count = r.CountSelectedMediaItems(0)
  if sel_item_count == 0 then
    msg("Select items")
    return
  end
   
  reaper.Undo_BeginBlock()
  local slice_len = 0.250 -- slice length in seconds

  local sel_item_t = {}
  for i=1, sel_item_count do
    sel_item_t[i] = r.GetSelectedMediaItem(0, i-1)
  end

  for i=1, #sel_item_t do
    local item = sel_item_t[i] 
    local length = r.GetMediaItemInfo_Value(item, "D_LENGTH")
    local pos = r.GetMediaItemInfo_Value(item, "D_POSITION")
    local curr_len = pos

    while (curr_len < pos + length - slice_len) do
      local new_item = r.SplitMediaItem(item, curr_len + slice_len)
      item = new_item
      curr_len = curr_len + slice_len
    end
    --]]
  end

  r.Main_OnCommand(40108, 0)  -- 40108: Normalize items
  r.UpdateArrange()
  r.Undo_EndBlock("Split to equal length parts", -1)
end
    

r.defer(split)
Thank you, thank you ,thank you ,thank you ,thank you, thank you!
Alex Ortega is offline   Reply With Quote
Old 05-28-2015, 01:19 PM   #911
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default A math problem

Hi guys !

I'm working on a script, it works fine BUT there is one math formula problem, and it seems I can't make it work.

  1. The script is simple.
  2. Edit cursor somewhere
  3. Mouse over item
  4. Run script with keyboard shortcuts
  5. the item is expanded (rate and length) to the edit cursor, keeping snap in place and relative content too, so both item edges are moving.

There is 4 cases:

  • cursor after snap offset, snap offset at 0 in item
  • cursor after snap offset, snap offset at X in item
  • cursor before snap offset, snap offset at 0 in item
  • cursor before snap offset, snap offset at X in item

First it compares cursor pos, then snap offset pos. There one formula for each cases, to define the new Length, from which will be calculated the new Rate. There is only one formula for the rate:
PHP Code:
src_length/new_length
where src length is the length of the item under mouse if it rate was 1 (it may not be the case). New length is calculated differently from each cases explained above.

I am stuck with one of them, cursor after snap offset, snap offset at X in item.

As reference, the formula for cursor after snap offset, snap offset at 0 in item is:
PHP Code:
new_length = (cursor_pos init_position); 
where init pos is the position of the item under mouse before any transformation

And the good one for cursor before snap offset, snap offset at X in item is:
PHP Code:
new_length = (init_position cursor_pos) * (src_length/src_snap) + init_length
where src_ variable are values of the item under mouse if it's rate was 1 (the source rate, source length etc...), with snap at same position in content item.

Note: the actual solution is to use formula for cursor after snap offset, snap offset at 0 in item, and perfom the action several time. The correct version of this formula most contain src_snap, obviously.

Here is a demo of this script at the actual state:
See how it works, and how it doesn't.


Any volunteer for this "nice" math problem ?

The source could be fine here. (ctrl +s or File/save to save it).
X-Raym is offline   Reply With Quote
Old 05-28-2015, 01:29 PM   #912
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
Default

X-Raym, sorry I may didn`t understood you right due to my bad english. but how exaclty you want to "stretch" item to edit cursor - from start or end of item (depends on cursor position) or from center (apply playrate for to stretch item end or item start to edit cursor while center of item will stay at same position)?
mpl is offline   Reply With Quote
Old 05-28-2015, 01:39 PM   #913
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@mpl
If edit cursor is after snap absolute position, then right edge will snap the edit cursor.
If edit cursor is before snap absolute position, then left edge will snap to edit cursor.
This is easy.

The hard part (and core of the concept) is this:
Content (original/source) sample at snap offset and snap offset (in absolute, compair to the project time) shouldn't move is snap != 0. This means that if I set my snap offset to be at any precise moment of my sound (a hit for example), I don't want to make this hit/transient move. But because rate change so that left/right edge snap to edit cursor, then length and pos of the item changes to (both edges, but not the snap).
If snap = 0, then of to move left edge if needed. (no difficulty with this last case).

Is that more clear ?
X-Raym is offline   Reply With Quote
Old 05-28-2015, 02:25 PM   #914
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
Default

I`ll take a look.
But still didn`t understand why do you speak about snap offsets and not about stretch markers. Context of your rate changes is 100% stretch marker on fixed position behaviour.
mpl is offline   Reply With Quote
Old 05-28-2015, 05:23 PM   #915
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

The idea is to to use Snap Offset because snap offset is perfect for snapping. Quantize items, align items, move items to grid, these are the usages of Snap Offset.
Stretch Markers are used to modify the rate of a section of an item.
In my case, I want to modify speed (aka Take Playback Rate) of my items, in a whole (not sections, as strech markers would do). Changing playback rate adjust envelopes, fades and content.
The idea to leave Snap Offset in absolute time location, and audio content at snap offset pos is to keep items that have to be synched (a sonic hit at an event for exemple) in synchronization, while changing their duration, without adding or removing any other audio samples to the items.

Actually, except my random take playback rate script, all actions and mouse modifiers involving take playback rate aren't centered arround snap offset but arround items position. You have to resynch your items every time you change their playback rate.
This script is a solution to that, but I have one cases that still don't work perfectly (it works when executing the script several time..... Not very nice behavior, but it could be worse)

Last edited by X-Raym; 05-28-2015 at 05:29 PM.
X-Raym is offline   Reply With Quote
Old 05-28-2015, 09:22 PM   #916
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
Default

Check it out. Is this you want to do?

PHP Code:
mouse_item extension_api("BR_ItemAtMouseCursor"mouse_pos);
mouse_take GetActiveTake(mouse_item);
rate GetMediaItemTakeInfo_Value(mouse_take"D_PLAYRATE");
pos GetMediaItemInfo_Value(mouse_item"D_POSITION");
length GetMediaItemInfo_Value(mouse_item"D_LENGTH");
snapoffset GetMediaItemInfo_Value(mouse_item"D_SNAPOFFSET");

invsnapoffset length snapoffset;
snapoffset_pos pos snapoffset;
item_end pos length;
editcur GetCursorPosition();
abs_beetween abs(snapoffset_pos editcur);
itemcenter pos length/2;
1;

snapoffset !== ? (
  
editcur snapoffset_pos ? (
    
abs_beetween snapoffset;
    
newlength length k;
    
newpos editcur;
    
newsnapoffset snapoffset k
    );
  
editcur snapoffset_pos ? (
    
abs_beetween invsnapoffset;
    
newlength length k;
    
newpos editcur newlength;
    
newsnapoffset snapoffset k
    );
  
editcur == snapoffset_pos ? (
    
newlength length;
    
newpos pos;
    
newsnapoffset snapoffset;
    );
  );
  
snapoffset == ? (
  
editcur itemcenter ? (
    
fut_lenght item_end editcur;
    
fut_lenght length;
    
newlength length k;
    
newpos editcur;
    );
  
editcur itemcenter ? (
    
fut_length editcur pos;
    
fut_length length;
    
newlength length k;
    
newpos editcur newlength;
    );
  
editcur == itemcenter ? (
    
newlength length;
    
newpos pos;
    );
  );
    
newrate rate k;
  
SetMediaItemTakeInfo_Value(mouse_take"D_PLAYRATE"newrate);
SetMediaItemInfo_Value(mouse_item"D_POSITION"newpos);
SetMediaItemInfo_Value(mouse_item"D_LENGTH"newlength);
SetMediaItemInfo_Value(mouse_item"D_SNAPOFFSET"newsnapoffset); 

Last edited by mpl; 05-29-2015 at 12:38 AM.
mpl is offline   Reply With Quote
Old 05-28-2015, 10:18 PM   #917
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@mpl
Oh man, according to your screenshot, it works perfectly !!
And more, I saw you rewrite all the script to make this work, and it is even simpler than what I've so far ! I had the feeling it could be more simple but definitely, I get lost in the way somewhere
Thank you a lot for this !

I will continue this and make the 'propagate transformation rate ratio' I was working on, before the release.
As it is a total rewrite, I will credit you in script name itself and put you as contributors on my github

Side note: it seems that you made a of progress since you started reascript, congratulations
X-Raym is offline   Reply With Quote
Old 05-28-2015, 10:34 PM   #918
mpl
Human being with feelings
 
mpl's Avatar
 
Join Date: Oct 2013
Location: Moscow, Russia
Posts: 3,960
Default

Glad it works. And yes, I always try to make everything I work with as simplier as possible.

Not so progress like you, spk77 and other cool guys, coding is completely new for me, but I try to learn step-by-step

(I also find small error in my code and fixed it)

Last edited by mpl; 05-28-2015 at 11:06 PM.
mpl is offline   Reply With Quote
Old 05-29-2015, 12:41 AM   #919
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@mpl
Don't be so humble, in few hours you had more success than me in days :P
That's the beauty of the thing, every one can contribute, no matter it's level

Can you make a special case for item were snap offset is set to 0 if cursor is place before them ?
It would keep content at item right edge and adjust rate accordingly (as seen in my previous screenshot).
For the moment, if just put the item at edit cursor (this is good), keep the same length and make rate to 0 (this is not good :P)
The idea is that it would keep right edges in place, and adjust rate accordingly, so that the item fit in the duration edit cursor to right edges.

In code words,
what should be K value if item snap is 0 ?
PHP Code:
        cursor_pos item_snap_absolute ? (
            
abs_beetween item_snap;
            
new_length item_length k;
            
new_pos cursor_pos;
        ); 
(as you can see, it will make division by 0).

Last edited by X-Raym; 05-29-2015 at 12:47 AM.
X-Raym is offline   Reply With Quote
Old 05-29-2015, 12:54 AM   #920
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@mpl
Don't worry, based on the previous version of my script, I just did it

PHP Code:
        cursor_pos item_snap_absolute ? (
            
item_snap == ? (
                
new_length = (item_position cursor_pos) + item_length;
                
new_length item_length;
            ):(
                
abs_beetween item_snap;
                
new_length item_length k;
            );
            
new_pos cursor_pos;
        ); 
X-Raym 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 02:02 AM.


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