Old 01-26-2014, 12:42 PM   #401
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Quote:
Originally Posted by spk77 View Post
Hi Tod,
Here's a quick test - it (currently) works if only one item is selected (and "numChannels" = 2). Edit the "sampleRate" -value if needed:
Wow thanks spk77, this look promising. The samplerate is okay, can I change the numChannels to = 1? Most of the samples I'm using for this are mono.

Thankyou so much,

Tod
Tod is offline   Reply With Quote
Old 01-26-2014, 01:19 PM   #402
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Tod View Post
Wow thanks spk77, this look promising. The samplerate is okay, can I change the numChannels to = 1? Most of the samples I'm using for this are mono.

Thankyou so much,

Tod
Just tested it with a mono item - it can be used with mono items too (no need to edit the script). I made a little update to post #409; the script wasn't working correctly if take/item volume was != 0 dB. Where should the peak value be placed in take name? Currently it's added to the end. If this script seems to be working, I'll add some improvements to it.

Last edited by spk77; 01-26-2014 at 01:44 PM.
spk77 is offline   Reply With Quote
Old 01-26-2014, 01:44 PM   #403
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Quote:
Originally Posted by spk77 View Post
Just tested it with a mono item - it can be used with mono items too (no need to edit the script). I made a little update to post #409; the script wasn't working correctly if take/item volume was != 0 dB.
Aah okay, I just tested this and it's going to work perfectly.

There's just one other little script that would work perfectly with this and that is one that would completely remove the name from the item. I've got an SWS action that can do this but it's for renaming so I have to delete the name manually and then hit enter. It would be great to have a separate script for this that would just simply delete the name, I've got other uses for it too.

I can't tell you enough how much I appreciate this spk77, these are some very valuble scripts you guys/gals are giving us.
Tod is offline   Reply With Quote
Old 01-26-2014, 02:02 PM   #404
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Tod View Post
Aah okay, I just tested this and it's going to work perfectly.

There's just one other little script that would work perfectly with this and that is one that would completely remove the name from the item. I've got an SWS action that can do this but it's for renaming so I have to delete the name manually and then hit enter. It would be great to have a separate script for this that would just simply delete the name, I've got other uses for it too.

I can't tell you enough how much I appreciate this spk77, these are some very valuble scripts you guys/gals are giving us.
Remove item names (actually "remove active take name")
Code:
# Remove item names (selected items - active take)

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

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

    for i in range(selItemCount):
        item = RPR_GetSelectedMediaItem(0, i)
        activeTake = RPR_GetActiveTake(item)
        RPR_GetSetMediaItemTakeInfo_String(activeTake, "P_NAME", "", True)

with undoable("Remove item names (active take)"):
    removeTakeNames()
spk77 is offline   Reply With Quote
Old 01-26-2014, 02:27 PM   #405
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Quote:
Originally Posted by spk77 View Post
Remove item names (actually "remove active take name")
Heh heh, that's pretty fast, I'll check this out right away and get back.
Tod is offline   Reply With Quote
Old 01-26-2014, 02:41 PM   #406
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Quote:
Originally Posted by Tod View Post
Heh heh, that's pretty fast, I'll check this out right away and get back.
It works great spk77, much better than anticipated.

Thankyou Thankyou, these are going to be used a lot.

Tod
Tod is offline   Reply With Quote
Old 01-26-2014, 02:47 PM   #407
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Tod View Post
It works great spk77, much better than anticipated.

Thankyou Thankyou, these are going to be used a lot.

Tod
Very nice!
spk77 is offline   Reply With Quote
Old 01-27-2014, 03:47 AM   #408
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Trying to create a script "Move selected items to (first) selected track" but it seems VERY BUGGY!

Bug 1: Attempting to move items to a lower track only moves some items.

Bug 2: I tried moving 3000 items to a lower track and it COPIED all the items to that track.

WORKING!
Code:
# Move selected items to selected track

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('Move selected items to selected track'):

    def msg(m):
        RPR_ShowConsoleMsg(m)

    def script():
        num_items = RPR_CountSelectedMediaItems(0)

        track = RPR_GetSelectedTrack(0, 0)
        sel_items = []
        for x in range(num_items):
            item = RPR_GetSelectedMediaItem(0, x)
            sel_items.append(item)

        for x in range(num_items):
            RPR_MoveMediaItemToTrack(sel_items[x], track)

        RPR_UpdateArrange()

    # do script
    script()
Edit: OH I KNOW WHATS GOING ON! It didn't copy the items, it simply... yet again... moved some items... because the selected item index/order changes as the items are moved which confuses the script and causes all hell to break loose. Ok, I need to store the items in an array first.

Edit: Hell yes I did it!
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 01-27-2014 at 03:58 AM.
Argitoth is offline   Reply With Quote
Old 01-27-2014, 11:26 AM   #409
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Here's an updated version of "Add peak value to take name":



Add peak value to take name (selected items)

Code:
# Add peak value to take name (selected items)
# (should work if a take has 1 or 2 channels)

from reaper_python import *
from contextlib import contextmanager
import math

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

def msg(m):
    RPR_ShowConsoleMsg(str(m))

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

    selItemL = []

    sampleRate = 44100 # edit if needed
    numChannels = 2

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

    RPR_Main_OnCommand(RPR_NamedCommandLookup("_SWS_SAVEALLSELITEMS1"), 0)  # save selected items
    RPR_SelectAllMediaItems(0, False)

    sampleRate = 44100
    numChannels = 2

    for item in selItemL:
        RPR_SetMediaItemSelected(item, True)
        activeTake = RPR_GetActiveTake(item)
        audioAccessor = RPR_CreateTakeAudioAccessor(activeTake)
        ##buf = list([0]*2*1024) # 2 channels, 1024 samples each, initialized to zero
        buf = list([0] * numChannels * 1) # 2 channels, 1 sample each, initialized to zero
        ##(ret, buf) = RPR_GetAudioAccessorSamples(aa, 44100, 4, pos, 1, buf) # buf now holds the first 2*1 audio samples from the track.
        RPR_Main_OnCommand(RPR_NamedCommandLookup("_SWS_FINDITEMPEAK"), 0)  # move cursor to item peak sample
        cursorPos = RPR_GetCursorPosition()
        itemPos = RPR_GetMediaItemInfo_Value(item, "D_POSITION")
        peakPos = cursorPos - itemPos
        itemVolume = RPR_GetMediaItemInfo_Value(item, "D_VOL")
        takeVolume = RPR_GetMediaItemTakeInfo_Value(activeTake, "D_VOL")

        """ int GetAudioAccessorSamples(void* accessor, int samplerate, int numchannels, double starttime_sec, int numsamplesperchannel, double* samplebuffer)
        typically GetAudioAccessorSamples() would be called within a loop, increasing pos each time."""
        ret, buf = RPR_GetAudioAccessorSamples(audioAccessor, sampleRate, numChannels, peakPos, 1, buf)

        if ret:
            channel1 = buf[0] * itemVolume * takeVolume
            channel2 = buf[1] * itemVolume * takeVolume

            if channel1 != 0 and channel2 != 0:
                channel1dB = 20 * math.log10(abs(channel1))
                channel2dB = 20 * math.log10(abs(channel2))

                peakValue = max(channel1dB, channel2dB)
                if peakValue < -150:
                    peakValue = -150

            else:
                peakValue = -150

            oldName = RPR_GetSetMediaItemTakeInfo_String(activeTake, "P_NAME", "", False)[3]
            RPR_GetSetMediaItemTakeInfo_String(activeTake, "P_NAME", oldName + " " + str(round(peakValue, 3)) + "dB", True)
            RPR_SetMediaItemSelected(item, False)
            RPR_DestroyAudioAccessor(audioAccessor)

    RPR_Main_OnCommand(RPR_NamedCommandLookup("_SWS_RESTALLSELITEMS1"), 0)  # restore selected items

with undoable("Add peak value to take name"):
    addPeakValueToName()
spk77 is offline   Reply With Quote
Old 01-27-2014, 11:39 AM   #410
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Spk77, if you search SWS/IX: Label processor in actions, you can do that same thing, and it's very flexible.
__________________
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 01-27-2014, 12:00 PM   #411
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Quote:
Originally Posted by spk77 View Post
Here's an updated version of "Add peak value to take name":

Add peak value to take name (selected items)
Just checked this out spk77, it works great. Now all it takes to clear and rename the items is two button presses.

I had no idea you were going to do this spk77 but I appreciate it beyond measure. I've already got it in my toolbar.
Tod is offline   Reply With Quote
Old 01-27-2014, 12:37 PM   #412
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Quote:
Originally Posted by Argitoth View Post
Spk77, if you search SWS/IX: Label processor in actions, you can do that same thing, and it's very flexible.
This is true, I just checked it out. However, Spk77's script only takes a button press, and more inportantly, it doesn't round it off to the 10th. With lots of samples, many times they would appear to have the same peak value when rounded off to 10ths, so the added precision is better.

And I really like being able to select all the items and press one button.
Tod is offline   Reply With Quote
Old 01-27-2014, 12:40 PM   #413
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
Spk77, if you search SWS/IX: Label processor in actions, you can do that same thing, and it's very flexible.

Oh, I didn't know.

This seems to do the same thing (add peak value to takes):
spk77 is offline   Reply With Quote
Old 01-27-2014, 02:19 PM   #414
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Quote:
Originally Posted by spk77 View Post
Oh, I didn't know.

This seems to do the same thing (add peak value to takes):
Yah, I didn't realize you could add the "[3]". Still, like I said in the other thread, yours is better, it just takes the press of one button so thanks again spk77.
Tod is offline   Reply With Quote
Old 01-28-2014, 11:59 AM   #415
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

SCRIPT REQUEST!

"Select all media items with same name of selected media item"

Edit: By the way, with my "move selected items to selected track" I was able to create a macro that essentially moves selected items to a duplicated track. So I can easily create new tracks for specific items to add fx to, or adjust the existing fx. I needed this for proper sample tuning quickness. Also, I am consantly having to move items spread across many tracks to one track.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 01-28-2014 at 12:28 PM.
Argitoth is offline   Reply With Quote
Old 01-28-2014, 12:49 PM   #416
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
SCRIPT REQUEST!

"Select all media items with same name of selected media item"

Edit: By the way, with my "move selected items to selected track" I was able to create a macro that essentially moves selected items to a duplicated track. So I can easily create new tracks for specific items to add fx to, or adjust the existing fx. I needed this for proper sample tuning quickness. Also, I am consantly having to move items spread across many tracks to one track.
This selects by "active take name":
Select all media items with same name of selected media item
Code:
# Select items (by selected item name)

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

def selectByName():
    selItemCount = RPR_CountSelectedMediaItems(0)
    if selItemCount == 0:
        msg("Select one item")
        return

    selItem = RPR_GetSelectedMediaItem(0, 0)
    activeTake = RPR_GetActiveTake(selItem)
    name = str(RPR_GetSetMediaItemTakeInfo_String(activeTake, "P_NAME", "", False)[3])

    allItemsCount = RPR_CountMediaItems(0)
    for i in range(allItemsCount):
        item = RPR_GetMediaItem(0, i)
        activeTake = RPR_GetActiveTake(item)
        if str(RPR_GetSetMediaItemTakeInfo_String(activeTake, "P_NAME", "", False)[3]) == name:
            RPR_SetMediaItemSelected(item, True)
        else:
            RPR_SetMediaItemSelected(item, False)

    RPR_UpdateArrange()

with undoable("Select items (by selected item name)"):
    selectByName()
spk77 is offline   Reply With Quote
Old 01-28-2014, 01:34 PM   #417
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

awesome!
__________________
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 01-29-2014, 04:12 PM   #418
Ozymandias
Human being with feelings
 
Join Date: Apr 2011
Posts: 144
Default

Hey all,

I noticed there's a function called Track_GetPeakHoldDB in the API. Would it be possible for a script to return a list of track numbers and names for any tracks which have a peak hold above a certain level (excluding the Master Track)? For example, you might want to search for any tracks with a peak hold above -1.0dB to find out which are at risk of clipping.

In small projects you wouldn't really need this, but in mixes with 100+ tracks it's definitely something I would find useful.

Thanks for any help!

Last edited by Ozymandias; 01-29-2014 at 04:22 PM.
Ozymandias is offline   Reply With Quote
Old 01-30-2014, 07:14 AM   #419
Anton9
Human being with feelings
 
Anton9's Avatar
 
Join Date: Jun 2009
Location: Earth
Posts: 1,340
Default

spk77,

Since you did such an awesome job of retro-fitting your Arpeggiator to the beyond code I was wondering if you would be up to the task of writing a "simple" OSC sequencer using beyond.REAPER? ...if not, no problem

Here is what I had in mind.., (open to any ideas you may have aswell)

1) 5 rows, each with these 4 fields (OSC_message, Start_Time[min.sec.ms], Resend_Interval[min.sec.ms], End_Time[min.sec.ms])
1a) Another idea might be an additional field that could be used for increasing/decreasing each messages value by 'x' amount.
2) Button labeled "Go" which would start the sending of messages.
3) Button labeled "Stop", this is for manually stopping the messages.
4) What would be really cool is an option for the Go,Stop buttons to be triggered either manually, synced to REAPER's play/stop buttons, or via an incoming OSC message.

The timing of events should be based on a python timer or system timer, this is so that they can be sent regardless of REAPER's play status.

Thank you
Anton9 is offline   Reply With Quote
Old 01-31-2014, 04:19 PM   #420
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Don't know how to access the item chunk. So far I got this:

Code:
# Get item chunk

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('Get item chunk'):

    def msg(m):
        RPR_ShowConsoleMsg(m)

    def script():
        msg(RPR_GetItemState(RPR_GetSelectedMediaItem(0), "", 9999))

    # do script
    script()
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 01-31-2014 at 04:30 PM.
Argitoth is offline   Reply With Quote
Old 01-31-2014, 11:35 PM   #421
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Anton9 View Post
spk77,

Since you did such an awesome job of retro-fitting your Arpeggiator to the beyond code I was wondering if you would be up to the task of writing a "simple" OSC sequencer using beyond.REAPER? ...if not, no problem

Here is what I had in mind.., (open to any ideas you may have aswell)

1) 5 rows, each with these 4 fields (OSC_message, Start_Time[min.sec.ms], Resend_Interval[min.sec.ms], End_Time[min.sec.ms])
1a) Another idea might be an additional field that could be used for increasing/decreasing each messages value by 'x' amount.
2) Button labeled "Go" which would start the sending of messages.
3) Button labeled "Stop", this is for manually stopping the messages.
4) What would be really cool is an option for the Go,Stop buttons to be triggered either manually, synced to REAPER's play/stop buttons, or via an incoming OSC message.

The timing of events should be based on a python timer or system timer, this is so that they can be sent regardless of REAPER's play status.

Thank you
Hi Anton9,
I have been able to send OSC messages from tkinter to Reaper (using "python-osc 1.2"), but couldn't send MIDI note messages for some reason.
spk77 is offline   Reply With Quote
Old 02-02-2014, 09:40 AM   #422
Breeder
Human being with feelings
 
Breeder's Avatar
 
Join Date: Nov 2010
Posts: 2,436
Default

Quote:
Originally Posted by Argitoth View Post
Don't know how to access the item chunk. So far I got this:
Use SWS function to get chunks, unlike reaper api, they don't have a limit of 4 MB

Code:
from reaper_python import *
from sws_python import *
from contextlib import contextmanager

def msg(m):
	RPR_ShowConsoleMsg(m)

def GetChunk(item):
	fastString = SNM_CreateFastString("")
	SNM_GetSetObjectState(item, fastString, 0, 0)
	chunk = SNM_GetFastString(fastString)
	SNM_DeleteFastString(fastString)
	return chunk


def SetChunk(item, chunk):
	fastString = SNM_CreateFastString(chunk)
	SNM_GetSetObjectState(item, fastString, 1, 0)
	SNM_DeleteFastString(fastString)

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

with undoable('Get item chunk'):

	item = RPR_GetSelectedMediaItem(0,0)
	chunk = GetChunk(item)
	msg(chunk)

Last edited by Breeder; 02-02-2014 at 10:04 AM.
Breeder is offline   Reply With Quote
Old 02-02-2014, 12:21 PM   #423
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Thank you Breeder! Now I can manipulate stretch markers.
__________________
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 02-02-2014, 12:58 PM   #424
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Hi spk77, I'v got a problem with one of the scripts you wrote for me, Move selected notes by n MIDI ticks.

http://forum.cockos.com/showpost.php...&postcount=394

It don't work in the latest Reaper and it might have something to do with all the new Reaper code stuff, probably the reaper_python.py.
Tod is offline   Reply With Quote
Old 02-02-2014, 01:16 PM   #425
gofer
-blänk-
 
gofer's Avatar
 
Join Date: Jun 2008
Posts: 11,359
Default

Tod, that one seems to work alright for me using the newest pre with the new ReaScript stuff, so it's not that. Or does it fail in certain circumstances? I only just imported it and used it on a few notes, so my test was not exactly deep... but the test item contained a bunch of CC and pitch events, too...

That said, it will probably work considerably faster using the new functions
gofer is offline   Reply With Quote
Old 02-02-2014, 01:54 PM   #426
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Quote:
Originally Posted by gofer View Post
Tod, that one seems to work alright for me using the newest pre with the new ReaScript stuff, so it's not that. Or does it fail in certain circumstances? I only just imported it and used it on a few notes, so my test was not exactly deep... but the test item contained a bunch of CC and pitch events, too...

That said, it will probably work considerably faster using the new functions
Thanks gofer and sorry spk77, I found out it had to do with SWS extensions. I used an older install which I updated to the latest Reaper. In order to get the old reaper_python.py replaced with the new one I deleted the plugin folder. Consequently I must have deleted an important SWS file(s) too.

I reinstalled SWS and it's working fine now.

I guess if I want to just replace the reaper_python.py file with Reaper's new one I should just delete that file instead of the whole plugin folder, right?
Tod is offline   Reply With Quote
Old 02-02-2014, 01:57 PM   #427
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Would anyone know how to count "open project tabs" so I can perform actions on every project tab open by using the tab number as a variable?
__________________
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 02-02-2014, 02:00 PM   #428
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Tod View Post
Hi spk77, I'v got a problem with one of the scripts you wrote for me, Move selected notes by n MIDI ticks.

http://forum.cockos.com/showpost.php...&postcount=394

It don't work in the latest Reaper and it might have something to do with all the new Reaper code stuff, probably the reaper_python.py.
Hi Tod,
It works here (pre10a) - do you still have SWS installed? (just a guess). It would probably work faster with the new functions (as gofer mentioned)

Edit: I see you got it working - nice
spk77 is offline   Reply With Quote
Old 02-02-2014, 02:14 PM   #429
spk77
Human being with feelings
 
Join Date: Aug 2012
Location: Finland
Posts: 2,668
Default

Quote:
Originally Posted by Argitoth View Post
Would anyone know how to count "open project tabs" so I can perform actions on every project tab open by using the tab number as a variable?
All projects have their own IDs - you can use RPR_EnumProjects() to get the IDs:

Code:
def get_all_projects():
    """ Returns a project list:
    [first_project_Id,..., last_project_Id]"""
    projects = []
    i = 0
    while True:
        projectId = str(RPR_EnumProjects(i, "", 0)[0])
        p = projectId.lstrip("(ReaProject*)")
        p = int(p, 16)
        if p == 0:
            break
        projects.append(projectId)
        i += 1
    return projects

RPR_ShowConsoleMsg(get_all_projects())
RPR_ShowConsoleMsg("\n")
RPR_ShowConsoleMsg(len(get_all_projects())) # to get project (tab) count
Edit: added "RPR_ShowConsoleMsg(len(get_all_projects())) # to get project (tab) count"

Last edited by spk77; 02-02-2014 at 02:20 PM.
spk77 is offline   Reply With Quote
Old 02-02-2014, 02:49 PM   #430
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Perfect! Seeing as how you can't "select" tabs the script won't be able to perform the action on just some tabs, so I'm going to use the tab count to just create the number to perform the action "go to next tab".

loop x times: go to next tab, perform 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 02-02-2014, 05:00 PM   #431
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Hey Spk77, couldn't figure out how to use the "on main command ex" project variable. But this does the trick anway.

Code:
# Add all projects to render queue

from reaper_python import *

projects = []
i = 0
while True:
    projectId = str(RPR_EnumProjects(i, "", 0)[0])
    p = projectId.lstrip("(ReaProject*)")
    p = int(p, 16)
    if p == 0:
        break
    projects.append(projectId)
    i += 1

for i in range(len(projects)):
    # Add project to render queue
    RPR_Main_OnCommandEx(41823, 0, 0)
    # Go to next project tab
    RPR_Main_OnCommandEx(40861, 0, 0)
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 02-02-2014 at 05:25 PM.
Argitoth is offline   Reply With Quote
Old 02-03-2014, 06:49 PM   #432
Anton9
Human being with feelings
 
Anton9's Avatar
 
Join Date: Jun 2009
Location: Earth
Posts: 1,340
Default

Quote:
Hi Anton9,
I have been able to send OSC messages from tkinter to Reaper (using "python-osc 1.2"), but couldn't send MIDI note messages for some reason.
The idea was just for sequencing OSC messages.., not anything MIDI related.
Rethinking my original post.., I guess the 'End_Time' parameter would not really be of any use.

Here are a couple of examples.

Example 1)
/fxparam/7/value, 0.5 [sent at specific time]
[wait 'x' amount of min.sec.ms]
/fxparam/7/value, 1.0
[loop 'x' amount of times]

Example 2)
/fxparam/7/value, 0.5 [sent at specific time]
[wait 'x' amount of min.sec.ms]
[increase or decrease value by 'x' amount]
[loop 'x' amount of times]

The idea was to use beyond.REAPER so that it could run continuously and still be able to execute other scripts.., but now that RPR_defer() has been added it could be done without using beyond.REAPER.
Anton9 is offline   Reply With Quote
Old 02-04-2014, 08:39 PM   #433
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

I need to get all project marker positions, how do you does it?
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 02-04-2014 at 10:10 PM.
Argitoth is offline   Reply With Quote
Old 02-09-2014, 04:27 PM   #434
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

Hello!

A small request by me... I am trying to make a custom action that mutes all children tracks in a folder except the selected track (umnute the selected track if muted and mute all the other children of the folder), but it seems I cannot do it with the actions available. Is it possible to do it with a script?

Thanks!

Last edited by amagalma; 02-09-2014 at 04:29 PM. Reason: additions
amagalma is offline   Reply With Quote
Old 02-09-2014, 04:57 PM   #435
amagalma
Human being with feelings
 
amagalma's Avatar
 
Join Date: Apr 2011
Posts: 3,451
Default

Please ignore my request! I managed to do it with a custom action!

SWS: Save current track selection
SWS: Select all folders (parents only)
SWS: Mute children of selected folder(s)
SWS: Restore saved track selection
Track: Unmute tracks

Thanks!
amagalma is offline   Reply With Quote
Old 02-09-2014, 10:41 PM   #436
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Hey Spk77, I really need a script that crops items by changing item properties, because all crop actions currently use DELETION method, thereby causing MediaItem* IDs to no longer exist, making it impossible to run actions to items one at a time after cropping.

OH what's this? I just pulled something out of my head! Thanks for being such a great teacher, Spk77!

In all seriousness, this script needed a lot of uses of if statements. Hey fellow scripters, is this how you would approach creating a non-deleting crop action?

Logic:
-if time selection is not overlapping item, do nothing
-if time selection is at the edge of an item, do nothing
-if there is no time selection, do nothing
-if there are no items selected, select all items in time selection
-if item end is within time selection, don't change item end position
-if item start position is within time selection, don't change item start position
-if item fully intersects time selection, change start and end position


SAVE SCRIPT AS .EEL

Code:
// Crop items to time selection

function SWSCommand(name) 
(
	command = NamedCommandLookup(name);
	Main_OnCommandEx(command,0,0);
);


// get time selection
GetSet_LoopTimeRange(0, 0, time_start, time_end, 0);
time_length = time_end - time_start;

time_length > 0 ? (
	num_items = CountSelectedMediaItems(0); // count items
	num_items == 0 ? (
		Main_OnCommandEx(40717, 0, 0); // select items if no items are select
		num_items = CountSelectedMediaItems(0); // count items again
		); 
	
	PreventUIRefresh(1);
	SWSCommand("_SWS_SAVEALLSELITEMS1"); // save item selection	
	Undo_BeginBlock2(0);
	
	// create array of items
	i = 0; loop(num_items, item_list[i] = GetSelectedMediaItem(0, i); i += 1;); 

	i = 0;
	loop(num_items,
		Main_OnCommandEx(40289, 0, 0); // unselect all items
		
		// select item
		item = item_list[i];
		SetMediaItemInfo_Value(item, "B_UISEL", 1);
		
		// get item info
		length = GetMediaItemInfo_Value(item, "D_LENGTH");
		position = GetMediaItemInfo_Value(item, "D_POSITION");
		snap_offset = GetMediaItemInfo_Value(item, "D_SNAPOFFSET");
		
		// get take info
		take = GetActiveTake(item);
		offset = GetMediaItemTakeInfo_Value(take, "D_STARTOFFS");
		
		// calculate variables
		end = length + position;
		snap_position = position + snap_offset;
		move = time_start - position;
		
		// crop item
		time_start < end ? (
			time_start >= position ? (
				SetMediaItemInfo_Value(item, "D_POSITION", time_start);
				SetMediaItemInfo_Value(item, "D_LENGTH", time_length);
				SetMediaItemTakeInfo_Value(take, "D_STARTOFFS", offset + move);
				SetMediaItemInfo_Value(item, "D_SNAPOFFSET", snap_position - time_start)
			);
			time_start < position ? (SetMediaItemInfo_Value(item, "D_LENGTH", time_end - position ););
			time_end > end ? (
				SetMediaItemInfo_Value(item, "D_LENGTH", length - move);
				SetMediaItemInfo_Value(item, "D_SNAPOFFSET", 0)
			);
		);
		i += 1;
	);	
	SWSCommand("_SWS_RESTALLSELITEMS1"); // restore item selection
	Undo_EndBlock2(0, "Crop items to time selection", -1);
	PreventUIRefresh(-1);
	UpdateArrange();
);
Edit: oh... wait a minute... I should probably have used the nudge API instead of banging my head against the wall trying to figure out how to edit item properties correctly... oh well, good learning experience!
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 02-11-2014 at 01:36 PM.
Argitoth is offline   Reply With Quote
Old 02-11-2014, 06:57 PM   #437
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Hey Spk77 or anyone,

How might I approach creating a script to see if there are any overlapping media items? Ultimately it would place a red project marker at every place media items are overlapping. I can figure out how to do that. What I don't know how to do is the comparison... oh I just got an idea:

1. get list of items
2. move cursor to position of first item
3. store cursor position
4. move cursor to next item
5. calculate item position + length = range
6. store cursor position
7. if cursor did not move more than range, we have an overlapping item.

hmmm, i'll play with these ideas in my head.

Edit: one way would be to move all items to one track before running the script! Then put the items back to the original track. That'd require two arrays. One for item IDs, one for original track.
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 02-11-2014 at 09:46 PM.
Argitoth is offline   Reply With Quote
Old 02-11-2014, 07:38 PM   #438
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Hi Spk77, you've given me so much I'm feel guilty asking more of you. But I do have a couple of requests.

I'm primarily cutting up multi mic samples and I've got it to the point I can cut up, align, and set the db levels of 32 multi miced samples in about 25 minutes. A huge time saving has been the delete names script and add peak value script to the item names that you made.

About 20 to 15 minutes of this 25 minutes has been involved with putting the regions/files in order according to their peak value along with normalizing them to a particular value. Each region has it's own level so that the regions volume values are spread evenly for obvious velocity considerations.

Now I realize there's an action to align the samples according to their peak values but that don't deal with multi miced samples or regions. So I'm wondering if there might be a way to align the regions according to their region names. With the scripts you've already given me, I can name the regions according to the peak values, so if there's any way to move these regions, including all the multi track samples, to put them in order, it would be great?

Also as I mentioned, the other thing is to normalize the samples in an organized way so that they go from a lower pre-determined value to an upper pre-determined value. The way I'm doing it now is with the Xenakios/SWS Normalize selected takes to db value. I've got a macro set up to go quickly from region to region and selects all the samples. The biggest problem with this is that it's easy to lose track of where I am and takes a considerable amount time to get it straightened out when I mess up.

These are probably pretty difficult but I thought I'd run it by you.
Tod is offline   Reply With Quote
Old 02-11-2014, 09:29 PM   #439
Argitoth
Human being with feelings
 
Argitoth's Avatar
 
Join Date: Feb 2008
Location: Mesa, AZ
Posts: 2,057
Default

Tod,

region = media item?
align = sort?

do you want to sort items by name? (python code made by Spk77)
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")

    RPR_Main_OnCommandEx(53780, 0, 0) # Save track selection
    RPR_Main_OnCommandEx(40296, 0, 0) # Select all tracks
    repositionByTakeName() # Reorder items by take name
    RPR_Main_OnCommandEx(53781, 0, 0) # Restore track selection
__________________
Soundemote - Home of the chaosfly and pretty oscilloscope.
MyReaperPlugin - Easy-to-use cross-platform C++ REAPER extension template

Last edited by Argitoth; 02-11-2014 at 09:40 PM.
Argitoth is offline   Reply With Quote
Old 02-11-2014, 10:06 PM   #440
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Quote:
Originally Posted by Argitoth View Post
Tod,

region = media item?
align = sort?

do you want to sort items by name? (python code made by Spk77)
Hi Argitoth and thankyou for your reply. Yes, the regions have been created by the items in the first track. Subsequently all the rest of the tracks and items were cut accordingly.

Actually I want to sort by region name, unless I can keep all the other tracks and items in line with the sorting.

In other words, all the items in each track (which make up the regions) need to be re-aligned at the same time.

Will this script do that?

Incidentally Argitoth, if it's okay may I ask, are you the same argitoth on VI-Control?
Tod 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:20 PM.


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