Old 08-01-2013, 08:23 PM   #161
James HE
Human being with feelings
 
James HE's Avatar
 
Join Date: Mar 2007
Location: I'm in a barn
Posts: 4,467
Default

If there is an action for this, I'm not seeing it.

I need something to select the track of the last touched FX parameter.

adjusting a FX parameter does not set the track as last touched, bummer.

there are actions to effect the last touched FX parameter in many ways, so some sort of script to then select that track should be possible.

For what I'm doing here, this parent channel script is pretty cool. I'm using Jeffos ReaControlPath to trigger the script via a JS plugin (sending MIDI cc's. (you see this near the end of the gif) Watch the meters of the "Router" track - as I add the tracks and also when moving the "channel" knob.

The track needing to be selected is fine when adding VCA Masters to the VCA folder. the parent channel increments each one that you add. I should add another mode however that will select the track if you move the channel parameter of an existing track - so that people don;t get their routing all tangled up.

Progress. I was doing the auto-routing by using multi-channel tracks for all the masters, but this method of changing the parent is much much much more cpu efficient. I'm now onto working out near-automatic communication between the masters and slave VCA's.


Last edited by James HE; 08-01-2013 at 08:51 PM.
James HE is offline   Reply With Quote
Old 08-01-2013, 09:40 PM   #162
FnA
Human being with feelings
 
FnA's Avatar
 
Join Date: Jun 2012
Posts: 2,173
Default

Quote:
Originally Posted by semiquaver View Post
Hey folks! here is a script I could really use:

I would like an action to set midi items to ignore project tempo and use instead the tempo at the time position they start at!

straighforward enough except for the dreaded chunk parsing...

TIA
EDIT- No longer needed. SWS now has actions specifically for this.

Hi semiquaver. I suppose you want something you can use on existing items full of events? Not sure about that, but I have a macro which works OK for making new items locked to tempo. No script, just SWS cycle/regular actions.

1. Actions to set timebase to time, color, whatever.

More essential part...

2. An action to open item in MIDI Editor.

3. Single cycle action in MIDI Editor section consisting of MIDI Editor action "Toggle locking MIDI to project tempo at media item start time."

4. Single cycle action in MIDI Editor section consisting of MIDI Editor action "File: Close window"

Maybe 3 and 4 could be combined, but I use them seperately for other things so...




Hey, James. Maybe this could be the ticket? Haven't tried it in anything yet myself. Just popped it in a script with a MSG box to see. Appears to give the track number, etc. Have to go now....(copied from html list in Help menu) vvvvvv

Returns true if the last touched FX parameter is valid, false otherwise. tracknumber==0 means the master track, 1 means track 1, etc. fxnumber and paramnumber are zero-based. See GetFocusedFX.

bool GetLastTouchedFX(int* tracknumber, int* fxnumber, int* paramnumber)

Last edited by FnA; 09-02-2013 at 06:13 AM.
FnA is offline   Reply With Quote
Old 08-02-2013, 07:44 AM   #163
semiquaver
Human being with feelings
 
Join Date: Jun 2008
Posts: 4,923
Default

thanks fna! I was unaware of that action.
semiquaver is offline   Reply With Quote
Old 08-02-2013, 06:13 PM   #164
FnA
Human being with feelings
 
FnA's Avatar
 
Join Date: Jun 2012
Posts: 2,173
Default

No prob semi, I was surprised myself to find it in the MIDI Editor actions, with the source properties window and all.

James, will this work? Some parameters don't show up as last touched. (Ones not available for automation?)

Code:
###Select track with last touched FX parameter###
from reaper_python import *

ltfx = RPR_GetLastTouchedFX(0, 0, 0)
trk = RPR_GetTrack(0, ltfx[1] - 1)
RPR_SetMediaTrackInfo_Value(trk, "I_SELECTED", 1)
FnA is offline   Reply With Quote
Old 08-02-2013, 06:19 PM   #165
James HE
Human being with feelings
 
James HE's Avatar
 
Join Date: Mar 2007
Location: I'm in a barn
Posts: 4,467
Default

Quote:
Originally Posted by FnA View Post

James, will this work? Some parameters don't show up as last touched. (Ones not available for automation?)

Code:
###Select track with last touched FX parameter###
from reaper_python import *

ltfx = RPR_GetLastTouchedFX(0, 0, 0)
trk = RPR_GetTrack(0, ltfx[1] - 1)
RPR_SetMediaTrackInfo_Value(trk, "I_SELECTED", 1)

I'll try it out thanks.

*edit.. not working at all.

Last edited by James HE; 08-03-2013 at 11:57 PM.
James HE is offline   Reply With Quote
Old 08-06-2013, 03:57 AM   #166
FnA
Human being with feelings
 
FnA's Avatar
 
Join Date: Jun 2012
Posts: 2,173
Default

Hmm. That blows. Seemed to be working here in a simple test...
1)Move parameter (one that shows up when you click the param button). Used mouse.
2) Run script from action window
3) Track is set selected. Other selections unaffected. Figured you could macro that part yourself. That part could be scripted too I guess. I'm a python noob. Maybe someone else can help.

I'm using Windows 7, Python 3.2, Reaper 4.402x64.

edit. Script continues to work for me. Don't know what the difference could be between our setups. However, I noticed something...Some of Reapers "last touched" actions include MIDI controller activity, some don't. Show/hide envelope(and the similar TCP control action) for last touched FX parameter does. My little script does not. It only detects moving the TCP control or the FX window knob/slider. I don't know what ReaScript function might access that other kind of data. Your project is kind of complicated, so I don't know exactly what you are going for here. I guess if an error was displayed, you would have said so. I'm NIFOR but I think I can find a script in here that has a MSG box code you could paste at the end of the script that might help determine why the script doesn't work for you...

Code:
type = 0
title = "wtf"
msg = ltfx, trk

result = RPR_MB( msg, title, type )
What does it say?

Last edited by FnA; 08-07-2013 at 04:08 AM.
FnA is offline   Reply With Quote
Old 08-07-2013, 07:39 PM   #167
James HE
Human being with feelings
 
James HE's Avatar
 
Join Date: Mar 2007
Location: I'm in a barn
Posts: 4,467
Default

Quote:
Originally Posted by FnA View Post
Hmm....
No worries! Working!

I have no idea what was going on before when I was testing it earlier. I may have just needed to close and re-open REAPER or something.

A lot of what I'm doing with the VCA setup can be broken up into different useful bits of code, that trigger, via Midi and Jeffos' MIDItoReacontrol path, different macros.

I'll try to bang out a test case for this and make a JS that will let you change a tracks parent channels with a parameter knob.
*done* http://forum.cockos.com/showthread.php?t=126784

Some other scripts that would be useful (if they are possible)

Changing the Midi Bus and channel of a send
Changing the source and destination Audio channel(s) of a send

Last edited by James HE; 08-07-2013 at 09:18 PM.
James HE is offline   Reply With Quote
Old 08-11-2013, 10:08 PM   #168
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Hello, back with another scripting request:

I need this action --> "Reposition/order selected media items by take name"



(it just needs to function on a per-track basis)
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 08-12-2013 at 12:51 AM.
Argitoth is offline   Reply With Quote
Old 08-15-2013, 12:55 PM   #169
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
Hello, back with another scripting request:

I need this action --> "Reposition/order selected media items by take name"



(it just needs to function on a per-track basis)
Hello Argitoth, here's a script that reorders the selected items alphabetically - by active take name. The tracks containing the selected items have to be selected also (it was a lot easier to do this way). Items get overlapped if there are items with different lengths.



Code:
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)

with undoable("Reorder items by take name"):
    def msg(m):
        RPR_ShowConsoleMsg(m)

    def repositionByTakeName():
        selTrackCount = RPR_CountSelectedTracks(0)
        selItemCount = RPR_CountSelectedMediaItems(0)

        if selTrackCount == 0 and selItemCount == 0:
            msg("Select tracks/items")
            return

        elif selTrackCount == 0 and selItemCount != 0:
            msg("Select tracks")
            return

        elif selTrackCount != 0 and selItemCount == 0:
            msg("Select items")
            return

        itemPosL = []
        itemInfo = []

        for i in range(selTrackCount):
            trackId = RPR_GetSelectedTrack(0, i)
            trackItemCount = RPR_CountTrackMediaItems(trackId)
            for item in range(trackItemCount):
                itemId = RPR_GetTrackMediaItem(trackId, item)
                if RPR_GetMediaItemInfo_Value(itemId, "B_UISEL"):
                    actTake = RPR_GetActiveTake(itemId)
                    takeName = RPR_GetSetMediaItemTakeInfo_String(actTake, "P_NAME", "", 0)[3]
                    itemPos = float(RPR_GetMediaItemInfo_Value(itemId, "D_POSITION"))
                    itemPosL.append(itemPos)
                    itemInfo.append([takeName, itemId])

            itemInfoReOrdered = sorted(itemInfo, key=lambda x: str(x[0]))
            for j, k in enumerate(itemInfoReOrdered):
                RPR_SetMediaItemPosition(k[1], itemPosL[j], 1)

            itemPosL = []
            itemInfo = []

        RPR_Undo_OnStateChange2(0, "Reorder items by take name")

    repositionByTakeName()

Last edited by spk77; 08-17-2013 at 12:52 AM.
spk77 is offline   Reply With Quote
Old 08-15-2013, 02:36 PM   #170
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

YESSSSS!!!! BRILLIANT!


Question, can you perform regex in these python scripts for REAPER? Do stuff like rename take names in a complex way? Would it be possible to create a console within REAPER to perform renames on all selected media items? Not asking for anyone to take this on, but just wondering if it's a possibility.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 08-15-2013, 02:56 PM   #171
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
YESSSSS!!!! BRILLIANT!


Question, can you perform regex in these python scripts for REAPER? Do stuff like rename take names in a complex way? Would it be possible to create a console within REAPER to perform renames on all selected media items? Not asking for anyone to take this on, but just wondering if it's a possibility.
There is actually a tool for renaming items/takes - (SWS) Label processor:
spk77 is offline   Reply With Quote
Old 08-15-2013, 02:59 PM   #172
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

that doesn't have enough functionality. I need to perform rename tasks like
"move # character to position #"
"delete 'some-word'"
"change 'some-word' to 'other-word'"

stuff like that, you know, RegEx stuff. But spk77, I guess you answered my question with a YES.

And bonus question: after renaming those items, can REAPER reflect those new names onto the media items? I know reaper can already do this with the basic rename action.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 08-15-2013, 03:19 PM   #173
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
that doesn't have enough functionality. I need to perform rename tasks like
"move # character to position #"
"delete 'some-word'"
"change 'some-word' to 'other-word'"

stuff like that, you know, RegEx stuff. But spk77, I guess you answered my question with a YES.

And bonus question: after renaming those items, can REAPER reflect those new names onto the media items? I know reaper can already do this with the basic rename action.
I think that item name is always the "active take name"
Yes it's possible to manipulate strings, but I don't know much about regex. I made a script earlier for track name editing (string replacing, change to upper/lowercase etc.)

http://forum.cockos.com/showthread.p...31#post1177831

spk77 is offline   Reply With Quote
Old 08-15-2013, 03:22 PM   #174
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

awesome. sounds good.

what would be immediately useful for renaming media items it to remove the extension, like .wav or whathaveyou. Not remove it from the actual file, just the take name.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 08-16-2013, 06:50 AM   #175
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Modify/edit take names (leave the items unselected and run the script to show instructions):



Code:
instructions ="""
String methods for take name manipulating (empty edit box = do nothing):

    upper or up
        Converts lowercase letters in string to uppercase
    lower or lo
        Converts all uppercase letters in string to lowercase
    swapcase or sc
        Inverts case for all letters in string
    capitalize or cap
        Capitalizes first letter of string
    titlecase or tc
        Returns "titlecased" version of string, that is, all words begin with
        uppercase, and the rest are lowercase
    strip or st
        Removes all leading and trailing whitespace of string
    delete or del
        Delete take names

Replace (old)/Replace with (new) (both edit boxes empty = do nothing):
    Replaces all occurrences of "old" in string with "new":

"""

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)

with undoable("Edit take names"):

    def msg(m):
        RPR_ShowConsoleMsg(m)

    def dialog():
        names = "String method:,Replace (old string):,Replace with (new string)" #:,Remove x chars from left"
        maxreturnlen = 200   # one more than what you expect to get back
        defvalues = ",,"   # default values
        nitems = len(defvalues.split(',')) # number of input boxes
        Query = RPR_GetUserInputs("Edit take names",nitems,names,defvalues,maxreturnlen) # call dialog and get result

        q = Query[0]
        if q == 1: # user clicked OK
            UserValues = Query[4].split(',')

            method = str(UserValues[0])
            replaceOld = str(UserValues[1])
            replaceWith = str(UserValues[2])

            return q, method, replaceOld, replaceWith
        else:
            q, method, replaceOld, replaceWith = 0, 0, 0, 0
            return q, method, replaceOld, replaceWith

    def applyMethod(currentName, method):
            if method == "upper" or method == "up":
                newName = currentName.upper()
                return newName
            elif method == "lower" or method == "lo":
                newName = currentName.lower()
                return newName
            elif method == "swapcase" or method == "sc":
                newName = currentName.swapcase()
                return newName
            elif method == "capitalize" or method == "cap":
                newName = currentName.capitalize()
                return newName
            elif method == "titlecase"or method == "tc":
                newName = currentName.title()
                return newName
            elif method == "strip" or method == "st":
                newName = currentName.strip()
                return newName
            elif method == "delete" or method == "del":
                newName = ""
                return newName
            elif method == "":
                newName = currentName
                return newName
            else:
                return -1
##                msg(instructions)

    def mainF():
        selItemCount = RPR_CountSelectedMediaItems(0)

        if selItemCount == 0:
            msg("")
            msg(instructions)
            msg("Select items")
            return
        try:
            q, method, replaceOld, replaceWith = dialog()
            if q == 0:
                return
        except TypeError as e:
            msg(e)
            return

        for i in range(selItemCount):
            selItem = RPR_GetSelectedMediaItem(0, i)
            takeCount = RPR_CountTakes(selItem)
            for takeIndex in range(takeCount):
                currTake = RPR_GetTake(selItem, takeIndex)
                currentName = str(RPR_GetSetMediaItemTakeInfo_String(currTake, "P_NAME", "", 0)[3])
                newName = applyMethod(currentName, method)

                if newName == -1:
                    msg("")
                    msg(instructions)
                    return
                if str(replaceOld) != "" or str(replaceWith) != "":
                    newName = currentName.replace(replaceOld, replaceWith)
                RPR_GetSetMediaItemTakeInfo_String(currTake, "P_NAME", newName, 1)
    mainF()

Last edited by spk77; 08-19-2013 at 11:23 PM.
spk77 is offline   Reply With Quote
Old 08-16-2013, 08:13 AM   #176
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Thank you spk77, I thought you might want to convert your script to deal with take names. Awesome, getting rid of one annoyance one script at a time.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 08-16-2013, 06:08 PM   #177
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

waaaa it no work! :'(

__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 08-16-2013, 11:39 PM   #178
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
waaaa it no work! :'(
Oh, RPR_IsMediaItemSelected() seems to be a new function (I'm using Reaper v4.5repre7). Post #178 updated, now it should work.
spk77 is offline   Reply With Quote
Old 08-16-2013, 11:52 PM   #179
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

thaaank yooou!
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 08-18-2013, 06:52 PM   #180
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Quote:
Originally Posted by spk77 View Post
Edit.
added: remove trailing \r\n
fixed: newname ->newName (thanks, Argitoth)

Load/apply item names from file (Actually take names because item names don't exist in reaper).

Code:
# Load/apply item names from file

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)

with undoable("Load/apply item names from file"):

    def msg(m):
        RPR_ShowConsoleMsg(m)

    actTakeIdL = []

    selItemCount = RPR_CountSelectedMediaItems(0)

    for i in range(selItemCount):
        selItemId = RPR_GetSelectedMediaItem(0, i)
        takeId = RPR_GetActiveTake(selItemId)
        actTakeIdL.append(takeId)

    a = RPR_GetUserFileNameForRead("Select item name list", "Load item names from file", ".txt")
    path = a[1]
    if a[0] == 1:
        try:
            f = open(path, "r")
            for i, newName in enumerate(f):
                newName = newName.rstrip("\r\n")  # remove trailing cr(carriage return) and n(new line)
                RPR_GetSetMediaItemTakeInfo_String(actTakeIdL[i], "P_NAME", str(newName), 1)
                if i + 1 == selItemCount:
                    break
            f.close()
        except IOError as e:
            msg(e)
Hey Spk77, remember this? I can't find where you posted the "get names" script. Well, here's the script you gave me:

Code:
# Get item names for copy/pasting
from reaper_python import *

def msg(m):
    RPR_ShowConsoleMsg(m)

actTakeNameL = []
selItemCount = RPR_CountSelectedMediaItems(0)

for i in range(selItemCount):
    selItemId = RPR_GetSelectedMediaItem(0, i)
    takeId = RPR_GetActiveTake(selItemId)
    # item gets active take's name
    actTakeName = RPR_GetSetMediaItemTakeInfo_String(takeId, "P_NAME", "", False)[3]
    actTakeNameL.append(actTakeName)

msg("\n".join(actTakeNameL))
BUT... :'( I need it to list around 1800 media items but it only gives me the LAST 425 items. Plz sir, can I have some more?... 1375 more to be exact. And as much as possible. Can REAPER export a list txt of selected media items' active take names? That would be ideal. Edit: Or put the list into clipboard so I can paste anywhere.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 08-18-2013 at 07:30 PM.
Argitoth is offline   Reply With Quote
Old 08-18-2013, 09:10 PM   #181
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
Hey Spk77, remember this? I can't find where you posted the "get names" script. Well, here's the script you gave me:

Code:
# Get item names for copy/pasting
from reaper_python import *

def msg(m):
    RPR_ShowConsoleMsg(m)

actTakeNameL = []
selItemCount = RPR_CountSelectedMediaItems(0)

for i in range(selItemCount):
    selItemId = RPR_GetSelectedMediaItem(0, i)
    takeId = RPR_GetActiveTake(selItemId)
    # item gets active take's name
    actTakeName = RPR_GetSetMediaItemTakeInfo_String(takeId, "P_NAME", "", False)[3]
    actTakeNameL.append(actTakeName)

msg("\n".join(actTakeNameL))
BUT... :'( I need it to list around 1800 media items but it only gives me the LAST 425 items. Plz sir, can I have some more?... 1375 more to be exact. And as much as possible. Can REAPER export a list txt of selected media items' active take names? That would be ideal. Edit: Or put the list into clipboard so I can paste anywhere.
Ok, it seems that "Reascript console output" can print only 425 rows. I'll look how to copy to clipboard in python.
spk77 is offline   Reply With Quote
Old 08-19-2013, 11:21 AM   #182
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

I'm just going to make another request that would make my life wayy easier:

"Copy active take name to file name."

So, just make the actual file have the same name as the media item. The script does not need to have any logic such as "Was this file already changed?" Just let it change the same file multiple times if two media items use the same file. HOWEVER, if you did want to add some logic, it would be useful if it checks to see if any media items share the same file and just give an error. "Error, some media items shares the same files." and then do nthing.

Problem: The .wav extension needs to be handled specially, so the file name does not become .wav.wav or loses .wav all together.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 08-19-2013, 01:00 PM   #183
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
BUT... :'( I need it to list around 1800 media items but it only gives me the LAST 425 items. Plz sir, can I have some more?... 1375 more to be exact. And as much as possible. Can REAPER export a list txt of selected media items' active take names? That would be ideal. Edit: Or put the list into clipboard so I can paste anywhere.
It seems that there is no easy way to copy to clipboard without importing extra modules (that was a bit surprising). Also, there isn't a "save as" -dialog in ReaScript - so, I have to use "reascript dialog" as "save as" dialog:

(.txt extension is not needed in file name - e.g. "TakeNames" without quotes is a valid file name)


(I didn't test this much)
Code:
# Get selected item names (active take) and save to file
from reaper_python import *
import sys
import os

def msg(m):
    RPR_ShowConsoleMsg(m)

def dialog():
    # change "pathName = str(RPR_GetProjectPath("", 512)[0])" to (existing) path e.g. pathName = "C:\Takenames"
    # otherwise file is saved to project path
##    pathName = str(sys.path[0])   # script's path
    pathName = str(RPR_GetProjectPath("", 512)[0])
    names = "Path:,File name:,"
    maxreturnlen = 200   # one more than what you expect to get back
    defvalues = "" + pathName   # default values
    nitems = 2
    Query = RPR_GetUserInputs("Save take names to file as...",nitems,names,defvalues,maxreturnlen) # call dialog and get result

    q = Query[0]
    if q == 1: # user clicked OK
        UserValues = Query[4].split(',')
        pathName = str(UserValues[0])
        fileName = str(UserValues[1])
        return q, fileName, pathName
    else:
        q, fileName, scriptPath = 0, 0, 0
        return q, fileName, pathName

def saveTakeNamesToFile():
    q, fileName, pathName = dialog()

    if not q or not fileName or not pathName:
        return
    elif fileName == "" or pathName == "":
        return
    fullName = os.path.join(pathName, fileName + ".txt")
    if os.path.exists(fullName):
        msg("File already exists")
        return

    actTakeNameL = []
    selItemCount = RPR_CountSelectedMediaItems(0)
    if selItemCount == 0:
        msg("Select items")
        return

    for i in range(selItemCount):
        selItemId = RPR_GetSelectedMediaItem(0, i)
        takeId = RPR_GetActiveTake(selItemId)
        # item gets active take's name
        actTakeName = RPR_GetSetMediaItemTakeInfo_String(takeId, "P_NAME", "", False)[3]
        actTakeNameL.append(actTakeName)

    takeNames = ("\n".join(actTakeNameL))
    with open(fullName, "w") as outFile:
        outFile.writelines(takeNames)

saveTakeNamesToFile()

Last edited by spk77; 08-19-2013 at 11:07 PM.
spk77 is offline   Reply With Quote
Old 08-19-2013, 03:14 PM   #184
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

awesome spk77, thank you very much! If you have time to improve the script, give a way to input a desired path (even if you can't include a file browser, I can easily copy/paste paths in). I see that you gave instructions on how to change the default path. I'll do that for now.

Oh, even better is if the default path could be the project relative media folder, if that's possible to retrieve in reacsript.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 08-19-2013 at 04:20 PM.
Argitoth is offline   Reply With Quote
Old 08-19-2013, 11:10 PM   #185
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
awesome spk77, thank you very much! If you have time to improve the script, give a way to input a desired path (even if you can't include a file browser, I can easily copy/paste paths in). I see that you gave instructions on how to change the default path. I'll do that for now.

Oh, even better is if the default path could be the project relative media folder, if that's possible to retrieve in reacsript.
Ok, now the default path is the project path - post #192 updated.
spk77 is offline   Reply With Quote
Old 08-21-2013, 02:13 PM   #186
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

just want to mention the get names script has been a huge help!
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 08-29-2013, 10:56 PM   #187
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Quote:
Originally Posted by Argitoth View Post
I'm just going to make another request that would make my life wayy easier:

"Copy active take name to file name."

So, just make the actual file have the same name as the media item. The script does not need to have any logic such as "Was this file already changed?" Just let it change the same file multiple times if two media items use the same file. HOWEVER, if you did want to add some logic, it would be useful if it checks to see if any media items share the same file and just give an error. "Error, some media items shares the same files." and then do nthing.

This feature apparently just got added... did the devs see this request or did they coincidentally decide to add it without any knowledge of my request?
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 08-30-2013 at 08:22 AM.
Argitoth is offline   Reply With Quote
Old 08-30-2013, 08:22 AM   #188
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Oops, I got it backwards. They added "file name -> item name" but I actually need the opposite. "file name <- item name"
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 09-01-2013, 01:28 AM   #189
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Ok guys I really need this script:



I need a script that does what I'm trying to do to all select items, that is: remove leading edge of media item

plzplzplzzzz!
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 09-01-2013, 03:13 AM   #190
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Trim left edge of media item (to item snap offset) - skip items with multiple takes:



Code:
# Trim left edge to item offset - skip items with multiple takes

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)

with undoable('Trim left edge to item offset'):

    def msg(m):
        RPR_ShowConsoleMsg(m)

    def setItemStartToOffset():
        selItemL = []
        selItemCount = RPR_CountSelectedMediaItems(0)
        for itemIndex in range(selItemCount):
            selItem = RPR_GetSelectedMediaItem(0, itemIndex)
            takeCount = RPR_CountTakes(selItem)
            # skip items with multiple takes
            if takeCount > 1:
                continue
            selItemL.append(selItem)

        RPR_Main_OnCommandEx(40289, 0, 0) # unselect all items

        for i in selItemL:
            RPR_SetMediaItemInfo_Value(i, "B_UISEL", 1)
            position = float(RPR_GetMediaItemInfo_Value(i, "D_POSITION"))
            offSet = float(RPR_GetMediaItemInfo_Value(i, "D_SNAPOFFSET"))
            RPR_ApplyNudge(0, 1, 1, 1, position + offSet, 0, 0)
            RPR_SetMediaItemInfo_Value(i, "B_UISEL", 0)

        # restore selection
        for i in selItemL:
            RPR_SetMediaItemInfo_Value(i, "B_UISEL", 1)

    setItemStartToOffset()

Last edited by spk77; 09-01-2013 at 05:05 AM.
spk77 is offline   Reply With Quote
Old 09-01-2013, 03:27 AM   #191
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
I'm just going to make another request that would make my life wayy easier:

"Copy active take name to file name."

So, just make the actual file have the same name as the media item. The script does not need to have any logic such as "Was this file already changed?" Just let it change the same file multiple times if two media items use the same file. HOWEVER, if you did want to add some logic, it would be useful if it checks to see if any media items share the same file and just give an error. "Error, some media items shares the same files." and then do nthing.

Problem: The .wav extension needs to be handled specially, so the file name does not become .wav.wav or loses .wav all together.
This will be easier to do if Breeder (hopefully ) exports "SetTakeSource" -function to ReaScripters.

http://forum.cockos.com/showthread.php?t=127712

Quote:
Originally Posted by Breeder View Post
Not all of stuff from reaper_plugin_function.h is exposed in reaper_python.py. GetSetMediaItemTakeInfo belongs to that group so if you call something like this:
Code:
take = RPR_GetTake(RPR_GetSelectedMediaItem(0, 0),0)
RPR_GetSetMediaItemTakeInfo(RPR_GetTake(item,0), "P_TRACK", 0)
you will get NameError for RPR_GetSetMediaItemTakeInfo

So if you're dealing with ReaScript reference only auto-generated HTML ReaScript documentation (or reaper_python.py if you're feeling adventurous)

That said, there is nothing in ReaScript to let you change source.
However, I guess this could be implemented in SWS and exposed to ReaScript.
Would something like this suffice?
Code:
bool SetTakeSource (MediaItem_Take* take, PCM_Source* newSource)
spk77 is offline   Reply With Quote
Old 09-01-2013, 01:51 PM   #192
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Quote:
Originally Posted by spk77 View Post
Trim left edge of media item (to item snap offset) - skip items with multiple takes:
oooh nooo that's not going to work, I am using snap offset for something else. see new image/proposal:



Quote:
Originally Posted by spk77 View Post
This will be easier to do if Breeder (hopefully ) exports "SetTakeSource" -function to ReaScripters.
awesome!
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 09-01-2013 at 02:04 PM.
Argitoth is offline   Reply With Quote
Old 09-01-2013, 02:16 PM   #193
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
oooh nooo that's not going to work, I am using snap offset for something else. see new image/proposal:
I guess you want to set "Start in source" to 0 (maybe there's already an action for it, I don't know)


I'll look into it tomorrow - have to go to sleep now.
spk77 is offline   Reply With Quote
Old 09-01-2013, 02:20 PM   #194
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Quote:
Originally Posted by spk77 View Post
I guess you want to set "Start in source" to 0 (maybe there's already an action for it, I don't know)
I tried all the actions and I also tried what you just suggested, but they always MOVE the media item in some way rather than trimming the edge off.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 09-01-2013, 02:28 PM   #195
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
I tried all the actions and I also tried what you just suggested, but they always MOVE the media item in some way rather than trimming the edge off.
Just tested - you are right, but I think it's possible to get "Start in source" -value by using reascript and then trim the left edge to that point.

It seems to be this line in chunk: "SOFFS -6.00000000000000" (Start in source = -6 seconds)

edit. I used RPR_GetMediaItemTakeInfo_Value() to get the "Start in source" -value: takeStart = float(RPR_GetMediaItemTakeInfo_Value(takeId, "D_STARTOFFS"))

Last edited by spk77; 09-02-2013 at 08:25 AM.
spk77 is offline   Reply With Quote
Old 09-02-2013, 06:08 AM   #196
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Trim left edge of item to take start (set "Start in source" to 0) - skip items with multiple takes:
(this script is also much faster because I don't have to use RPR_ApplyNudge())



Code:
# Trim left edge of item to take start (set take start to 0) - skip items with multiple takes

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)

with undoable('Trim left edge of item to take start'):

    def msg(m):
        RPR_ShowConsoleMsg(m)

    def leftTrimToTakeStart():
        selItemCount = RPR_CountSelectedMediaItems(0)
        for itemIndex in range(selItemCount):
            selItem = RPR_GetSelectedMediaItem(0, itemIndex)
            takeCount = RPR_CountTakes(selItem)
            # skip items with multiple takes
            if takeCount > 1:
                continue

            takeId = RPR_GetTake(selItem, 0)
            position = float(RPR_GetMediaItemInfo_Value(selItem, "D_POSITION"))
            offSet = float(RPR_GetMediaItemInfo_Value(selItem, "D_SNAPOFFSET"))
            length = float(RPR_GetMediaItemInfo_Value(selItem, "D_LENGTH"))
            takeStart = float(RPR_GetMediaItemTakeInfo_Value(takeId, "D_STARTOFFS"))

##            # ignore take if "Start in source" >= 0
##            if takeStart >= 0:
##                continue

            newLength = length + takeStart
            RPR_SetMediaItemPosition(selItem, position - takeStart, 0)
            RPR_SetMediaItemLength(selItem, newLength, 0)
            RPR_SetMediaItemTakeInfo_Value(takeId, "D_STARTOFFS", 0)
            RPR_SetMediaItemInfo_Value(selItem, "D_SNAPOFFSET", offSet + takeStart)

        RPR_UpdateArrange()

    leftTrimToTakeStart()

Last edited by spk77; 09-02-2013 at 11:46 AM.
spk77 is offline   Reply With Quote
Old 09-02-2013, 10:41 AM   #197
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

I see the if statement in the script to skip items with multiple takes. Is that because the script will mess up if the item has multiple takes?

Also, I'm not sure I will need this, but can you also add a commented-out line of code to ignore any items where it does not have that "empty trailing edge"? In your animated gif it would ignore the 3rd item down.

Thank you!!!!
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 09-02-2013, 11:33 AM   #198
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
I see the if statement in the script to skip items with multiple takes. Is that because the script will mess up if the item has multiple takes?
Possibly :



Quote:
Originally Posted by Argitoth View Post
Also, I'm not sure I will need this, but can you also add a commented-out line of code to ignore any items where it does not have that "empty trailing edge"? In your animated gif it would ignore the 3rd item down.

Thank you!!!!
Post #205 updated. "RPR_Main_OnCommandEx(RPR_NamedCommandLookup("_XEN AKIOS_RESETITEMLENMEDOFFS"), 0, 0)" removed.

Edit. I think I misunderstood this.

Last edited by spk77; 09-02-2013 at 11:39 AM.
spk77 is offline   Reply With Quote
Old 09-02-2013, 12:55 PM   #199
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Alright, the commented-out code works perfectly!

JUST ONE MORE REQUEST: I will use this script as a template. I just need a script that runs the "paste" action 200 times. I will be able to edit the number of times and I can see how to select an action to be done.

Thank you!
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template
Argitoth is offline   Reply With Quote
Old 09-03-2013, 01:54 AM   #200
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
Alright, the commented-out code works perfectly!

JUST ONE MORE REQUEST: I will use this script as a template. I just need a script that runs the "paste" action 200 times. I will be able to edit the number of times and I can see how to select an action to be done.

Thank you!
The fastest way is to use the nudge dialog:



Here's a simple script to show how to run actions from the action list (Main section):
(To make this work, "Move edit cursor when pasting/inserting media" has to be selected)



Code:
# Paste selected item x times

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)

with undoable('Paste selected item x times'):
# write your code after the with undoable(...)

    def paste():
        # right click on the action list if you can't see the action ids
        copyItems = 40698  # Edit: Copy items - cmdID = 40698
        pasteItems = 40058  # item: Paste items/tracks - cmdID = 40058
        cursorToEndOfItems = 41174  # Move cursor to end of (selected) items - cmdID = 41174
        howManyTimes = 10

        RPR_Main_OnCommandEx(copyItems, 0, 0)   # run action "Copy items"
        RPR_Main_OnCommandEx(cursorToEndOfItems, 0, 0)   # run action "Move cursor to end of (selected) items"

        for i in range(howManyTimes):   # "i" goes from 0 to 9
            RPR_Main_OnCommandEx(pasteItems, 0, 0)  # run action "Paste items/tracks"

    # call the function paste()
    paste()

Last edited by spk77; 09-03-2013 at 10:51 AM. Reason: Wrong action name
spk77 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 12:35 AM.


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