hi there,
is it possible to make a script or macro to pan pro tools tracks to specific values? i saw the post about setting stereo values, but havn't been able to figure out a way to do mono tracks.
my ideal end goal would be to have a few buttons set on a soundflow surface that could snap a selected track's pan to a handful of specific values i use regularly.
thanks for any sugestions.
-nick
- Christian Scheuer @chrscheuer2020-08-23 06:43:13.975Z
Hi Nick.
Can you link us to the thread you found? Then perhaps we can help adapt that script (we've got thousands of forum entries so can be hard to know which one you're referring to without a link).
You may also be able to find inspiration in my package "Pro Tools Clip Panning" in the Store.
- Nnick krill @nick_krill
Hi Christian,
Thanks for the quick reply, sorry for not linking to the post i referenced.
The stereo track script I was experimenting with is the first one mentioned in this post:
https://forum.soundflow.org/-181I actually had a bit of trouble tweaking values on it though...if I set the pan value in the script to 38, when the script ran would put the pan at 35.
I'll try to experiment with your clip pan package and see what I can come up with too. In the thread I linked to above, is that second script the same one that is found in your panning package?
-nick
- NIn reply tonick_krill⬆:nick krill @nick_krill
Hi again Christian,
I just figured out how to do this using UI automation! Got it working on mono tracks pretty smoothly.
Here is a copy of my macro as a script (sorry I can't seem to figure out how to format it like the scripts other people post):
sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.selectedTrack.trackOutputToggleShow(); sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementWaitFor(); sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick(); sf.keyboard.type({ text: "-100", }); sf.keyboard.press({ keys: "numpad enter", }); sf.ui.proTools.mainTrackOutputWindow.getElement('AXCloseButton').elementClick(); sf.ui.proTools.mainTrackOutputWindow.groups.whoseTitle.is('LEAD_1 - Audio Track ').first.elementWaitFor({ waitType: "Disappear", });
Two quick follow up questions:
-
If the selected tracks output window is aready open, the toggle function closes it and the marco doesn't work. Are there any solutions for this?
-
Seems like with the above UI automation method i'll need to make separate macros for stereo or mono tracks. Is there a simple bit of code or macro to check if the track is mono or stereo first, and then decide which macro to run? So kinda one umbrella macro that would check track type and then trigger the appropriae actions?
Sorry if these are basic questions that I should not be buggin you with (feel free to let me knwo if they are!!), I'm just begining to learn the world of macros and java.
-nick
- Nnick krill @nick_krill
Hi Everyone,
I was able to make a script that will work on both mono and stereo tracks using an If / Else construct based on if SoundFlow sees a UI element that is only contained in a stereo track output window. Figured I'd share it here in case it is useful for anyone else. Also, this is my first script...so if anyone has any feedback on ways to clean it up, or make it smoother, I'm all ears.
sf.ui.proTools.appActivateMainWindow();
sf.ui.proTools.selectedTrack.trackOutputToggleShow();
if (sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Link').exists)
{sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementWaitFor();
/* sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Link').first.elementClick(); */
/* sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Inverse Pan').first.elementClick(); */
sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick();
sf.keyboard.type({
text: "-100",
});sf.keyboard.press({
keys: "numpad enter",
});sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').allItems[1].elementClick();
sf.keyboard.type({
text: "100",
});sf.keyboard.press({
keys: "numpad enter",
});sf.ui.proTools.mainTrackOutputWindow.getElement('AXCloseButton').elementClick();
sf.ui.proTools.mainTrackOutputWindow.groups.whoseTitle.is('LEAD_1 - Audio Track ').first.elementWaitFor({
waitType: "Disappear",
});
}else
{
sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementWaitFor();sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick();
sf.keyboard.type({
text: "-100",
});sf.keyboard.press({
keys: "numpad enter",
});sf.ui.proTools.mainTrackOutputWindow.getElement('AXCloseButton').elementClick();
sf.ui.proTools.mainTrackOutputWindow.groups.whoseTitle.is('LEAD_1 - Audio Track ').first.elementWaitFor({
waitType: "Disappear",
});
}-nick
PS - I still haven't been sucsessful in any of my attempts to make a script that checks to see if the Track Output window is already open. If anyone has some thoughts I'd love to hear em.
- Nnick krill @nick_krill
Hi @chrscheuer,
Thanks for recomending your clip panning package..it did lead to some helpful discoveries.
In particular I found the follwing line that seems to check if the track output window is open,
if (sf.ui.proTools.selectedTrack.outputWindowButton.value.invalidate().value !== 'open')
I added this to my script, and it seemed to do the trick.
One quick follow up, rigth now in my script, it closes the track output window as the final step. Do you have any advice on a line of code that would leave the track output window open, if that window was already open when the script was triggered?
thanks,
nickChristian Scheuer @chrscheuer2020-09-08 05:38:56.050Z
Hi Nick,
Great to see you had some progress with this.You can store the open state in the beginning of your script with something like:
var wasOpen = sf.ui.proTools.selectedTrack.outputWindowButton.value.invalidate().value === 'open';
Then in the bottom where you close it, make sure to not close it if it was open:
if (!wasOpen) { //Only close it within this if }
- Nnick krill @nick_krill
Thanks for your help! This works great.
Here is an updated panning script in case it is ever useful to anyone else. In Pro Tools it allows for panning selected tracks that are either mono or stero to preset values using the pan in the track output window.
This version is for a 100% Left Pan on a mono track, or a symetrical 100% Left / Right pan on a stereo track. Change the pan values in the script to make whatever pan preset is useful.
sf.ui.proTools.appActivateMainWindow(); var wasOpen = sf.ui.proTools.selectedTrack.outputWindowButton.value.invalidate().value === 'open'; if (sf.ui.proTools.selectedTrack.outputWindowButton.value.invalidate().value !== 'open') sf.ui.proTools.selectedTrack.trackOutputToggleShow(); if (sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Link').exists) {sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementWaitFor(); /* sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Link').first.elementClick(); */ /* sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Inverse Pan').first.elementClick(); */ sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick(); sf.keyboard.type({ text: "-100", }); sf.keyboard.press({ keys: "numpad enter", }); sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').allItems[1].elementClick(); sf.keyboard.type({ text: "100", }); sf.keyboard.press({ keys: "numpad enter", }); if (!wasOpen) { sf.ui.proTools.mainTrackOutputWindow.getElement('AXCloseButton').elementClick(); sf.ui.proTools.mainTrackOutputWindow.groups.whoseTitle.is('LEAD_1 - Audio Track ').first.elementWaitFor({ waitType: "Disappear", });} } else { sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementWaitFor(); sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick(); sf.keyboard.type({ text: "-100", }); sf.keyboard.press({ keys: "numpad enter", }); if (!wasOpen) { sf.ui.proTools.mainTrackOutputWindow.getElement('AXCloseButton').elementClick(); sf.ui.proTools.mainTrackOutputWindow.groups.whoseTitle.is('LEAD_1 - Audio Track ').first.elementWaitFor({ waitType: "Disappear", });} }
-nick
- DDaniel Knobler @Daniel_Knobler
Any chance someone could modify this so that it gives a pop up and you can type in the pan value you'd like the track set to?
Brenden @nednednerb
I will tell you how, but you can do the work ; )
Change where relevant the
sf.keyboard.type({ text: "-100", });
for example, to
sf.keyboard.type({ text: prompt("Enter your value for THIS STEP"), });
That should be it. Maybe you have to make a variable just above the sf.keyboard.type line
Such as:
const leftPannerValue = prompt("Enter value for Left channel:"); sf.keyboard.type({ text: leftPannerValue, });
-
- AIn reply tonick_krill⬆:Alex Gamble @Alex_Gamble
Hey there! Trying to expand on this script and iterate this operation across several selected tracks. Is this possible somehow?
- AAlex Gamble @Alex_Gamble
Hey! Actually with some playing around, I got this to work myself.
Often I'm given a large volume of tracks that make up a single sound (group vocals, claps, stomps, etc). For size, I pan things off semi-randomly but for upwards of 20 tracks it's time consuming.
I expanded on this script to randomize the panning of a selection of tracks. The wait times is because sometimes it misses a mouse click when working so fast on so many tracks.
sf.ui.proTools.appActivateMainWindow(); var tracks = sf.ui.proTools.selectedTrackHeaders; var num_of_tracks = sf.ui.proTools.selectedTrackNames.length; for (var i = 0; i < num_of_tracks; i++) { if (tracks[i].outputWindowButton.value.invalidate().value !== 'open') tracks[i].trackOutputToggleShow(); sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick(); var randompan_left = -100 + Math.floor(Math.random() * 201); sf.wait({ intervalMs: 20 }); var randompan_right = -100 + Math.floor(Math.random() * 201); sf.wait({ intervalMs: 20 }); var rpl = randompan_left.toString(); sf.wait({ intervalMs: 20 }); var rpr = randompan_right.toString(); sf.wait({ intervalMs: 20 }); sf.keyboard.type({ text: rpl, }); sf.wait({ intervalMs: 20 }); sf.keyboard.press({ keys: "numpad enter", }); sf.wait({ intervalMs: 20 }); if (sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Link').exists) { sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').allItems[1].elementClick(); sf.keyboard.type({ text: rpr, }); sf.wait({ intervalMs: 20 }); sf.keyboard.press({ keys: "numpad enter", }); sf.wait({ intervalMs: 20 }); } }
- JIn reply tonick_krill⬆:Joe Kearns @Joe_Kearns
Hey Guys,
This is really great! Alex particular like the random panner element. I was wondering if you could help me make a version that takes the number of selected tracks and divides that by total pan values and spreads them evenly if that makes sense?
thanks so much in advance!
Joe. - JIn reply tonick_krill⬆:Joe Kearns @Joe_Kearns
Here's where Ive got to with auto spread panner. Sometimes the roundup function seems to work and sometimes not? Any help much appreciated to make this more solid/effective etc please!
Im also not sure how im applying the panning to the Stereo channels is the best way to do it but it does work....sf.ui.proTools.appActivateMainWindow(); var tracks = sf.ui.proTools.selectedTrackHeaders; var num_of_tracks = sf.ui.proTools.selectedTrackNames.length; var originterval = Math.floor(200 / (num_of_tracks - 1)); var interval = Math.floor(200 / (num_of_tracks - 1)); var pan = Math.floor(-100 - originterval) for (var i = 0; i < num_of_tracks; i++) { if (tracks[i].outputWindowButton.value.invalidate().value !== 'open') tracks[i].trackOutputToggleShow(); sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').first.elementClick(); function round(x) { return Math.ceil(x / 5) * 5; } var pan1 = pan + interval; (round(pan1)); sf.wait({ intervalMs: 20 }); var pan2 = pan1 sf.wait({ intervalMs: 20 }); var pl = pan1.toString(); sf.wait({ intervalMs: 20 }); var pr = pan2.toString(); sf.wait({ intervalMs: 20 }); sf.keyboard.type({ text: pl, }); sf.wait({ intervalMs: 20 }); sf.keyboard.press({ keys: "numpad enter", }); sf.wait({ intervalMs: 20 }); var interval = Math.floor(originterval + interval); if (sf.ui.proTools.mainTrackOutputWindow.buttons.whoseTitle.is('Link').exists) { sf.ui.proTools.mainTrackOutputWindow.textFields.whoseTitle.is('Front Pan Numerical').allItems[1].elementClick(); sf.keyboard.type({ text: pr, }); sf.wait({ intervalMs: 20 }); sf.keyboard.press({ keys: "numpad enter", }); sf.wait({ intervalMs: 20 }); } }
thanks so much in advance