Title
Solo Selected Track, bounce mix.
What do you expect to happen when you run the script/macro?
I want this macro to solo the selected track, bounce the mix, fill in the fill name with the solo'd track name, create a directory Bounced Files/Stems, wait for the file to finish bouncing, then unsolo the track. Mabe even move to the next selected track if possible.
Are you seeing an error?
I cant rename the track, create the directory, or pick the bounce window element to wait for it to disappear.
What happens when you run this script?
I can get it to the point of bringing up the bounce window, but thats it.
How were you running this script?
I used a Stream Deck button
How important is this issue to you?
5
Details
{ "inputExpected": "I want this macro to solo the selected track, bounce the mix, fill in the fill name with the solo'd track name, create a directory Bounced Files/Stems, wait for the file to finish bouncing, then unsolo the track. Mabe even move to the next selected track if possible. ", "inputIsError": true, "inputError": "I cant rename the track, create the directory, or pick the bounce window element to wait for it to disappear. ", "inputWhatHappens": "I can get it to the point of bringing up the bounce window, but thats it. ", "inputHowRun": { "key": "-MpfwmPg-2Sb-HxHQAff", "title": "I used a Stream Deck button" }, "inputImportance": 5, "inputTitle": "Solo Selected Track, bounce mix.\n" }
Source
//Macro converted to script
//Calling command "If App is Frontmost" from package "Basics" (installed from user/pkg/version "srAasovvDiQacRZ2mcId4RrOA8R2/ckuxffxq80000u010m7g02u3l/cll0rgzcl00003k107vghms2d")
sf.soundflow.runCommand({
commandId: 'user:ckuxffxq80000u010m7g02u3l:ckuxh629a000pu0104y1a40zx',
props: {
application: sf.ui.proTools,
}
});
sf.ui.proTools.selectedTrack.trackSetSolo({
targetValue: "Enable",
});
//Calling command "Bounce Mix..." from package "Pro Tools" (installed from user/pkg/version "srAasovvDiQacRZ2mcId4RrOA8R2/ckp49i4j60000a2100yfwywgf/clcf936ky0000l110ggp9f9bf")
sf.soundflow.runCommand({
commandId: 'user:ckp49i4j60000a2100yfwywgf:cktcnf0ra000x9r109i8wen1u#cktcms2j4000h9r103zqxnmg5',
props: {}
});
sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first.textFields.whoseValue.is("All Eyes on Me").first.elementSetTextAreaValue({
value: "First Selected Track",
});
sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first.groups.whoseTitle.is("Location").first.textFields.whoseValue.is("Bounced Files/Stems/").first.elementSetTextAreaValue({
value: "Bounced Files/Stems",
});
sf.keyboard.press({
keys: "return",
});
(throw 'context missing').elementWaitFor({
waitType: "Disappear",
});
sf.ui.proTools.selectedTrack.trackSetSolo({
targetValue: "Disable",
});
Links
User UID: zNchbgqMvBUNXIhmLZsA7wqfiDl1
Feedback Key: sffeedback:zNchbgqMvBUNXIhmLZsA7wqfiDl1:-NeP6DCUS-IBvinyanCH
- LLynn Graber @Lynn_Graber
Been working on this. Finally got it to grab the track name and paste into the bounce mix dialog. Still hung on waiting for the file to bounce, then clear solo.
//Calling command "If App is Frontmost" from package "Basics" (installed from user/pkg/version "srAasovvDiQacRZ2mcId4RrOA8R2/ckuxffxq80000u010m7g02u3l/cll0rgzcl00003k107vghms2d") sf.soundflow.runCommand({ commandId: 'user:ckuxffxq80000u010m7g02u3l:ckuxh629a000pu0104y1a40zx', props: { application: sf.ui.proTools, } }); sf.ui.proTools.selectedTrack.trackSetSolo({ targetValue: "Enable", }); //Calling command "Rename Selected Track" from package "Pro Tools" (installed from user/pkg/version "srAasovvDiQacRZ2mcId4RrOA8R2/ckp49i4j60000a2100yfwywgf/clcf936ky0000l110ggp9f9bf") sf.soundflow.runCommand({ commandId: 'user:ckp49i4j60000a2100yfwywgf:ckou1qcq6009wzv108n39uknd', props: {} }); sf.ui.proTools.children.whoseRole.is("AXWindow").first.elementWaitFor({ waitType: "Appear", }); sf.keyboard.press({ keys: "cmd+c", }); sf.ui.proTools.focusedWindow.buttons.whoseTitle.is("OK").first.elementClick(); //Calling command "Bounce Mix..." from package "Pro Tools" (installed from user/pkg/version "srAasovvDiQacRZ2mcId4RrOA8R2/ckp49i4j60000a2100yfwywgf/clcf936ky0000l110ggp9f9bf") sf.soundflow.runCommand({ commandId: 'user:ckp49i4j60000a2100yfwywgf:cktcnf0ra000x9r109i8wen1u#cktcms2j4000h9r103zqxnmg5', props: {} }); sf.ui.proTools.children.whoseRole.is("AXWindow").first.elementWaitFor({ waitType: "Appear", }); sf.keyboard.press({ keys: "cmd+v", }); sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first.groups.whoseTitle.is("Location").first.textFields.whoseValue.is("Bounced Files/Stems/").first.elementSetTextAreaValue({ value: "Bounced Files/Stems/", }); sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first.buttons.whoseTitle.is("Bounce").first.elementClick(); sf.ui.proTools.elementWaitFor({ waitType: "Disappear", }); //Calling command "Clear Solos" from package "Pro Tools" (installed from user/pkg/version "srAasovvDiQacRZ2mcId4RrOA8R2/ckp49i4j60000a2100yfwywgf/clcf936ky0000l110ggp9f9bf") sf.soundflow.runCommand({ commandId: 'user:ckp49i4j60000a2100yfwywgf:ck1w33cdv000kef10dzdy73uw', props: {} });
Chad Wahlbrink @Chad2023-09-18 15:43:53.335Z
Hey @Lynn_Graber,
In general, we highly encourage users to utilize Andrew Scheps' Bounce Factory for printing stems in Pro Tools. This is the most thoroughly used and tested way to bounce stems on SoundFlow's platform. There is a reason that Andrew has spent hours and hours dialing this workflow in.
However, I did flesh out a possible version of the script you were working on below and I have linked to sections of the forum that helped piece this together. This should also satisfy your original post regarding this workflow.
For the "Wait for Bounce to finish" section, I'm referencing: Waiting for the bounce dialog to complete/close #post-10
For the "do for each track" section, I'm referencing: How to adapt this code to selected tracks #post-10
The only other changes I made were to how the track name is retrieved. You can use:sf.ui.proTools.invalidate().selectedTrack.normalizedTrackName;
to get the track name as text variable.
Here is the script:
// Activate Pro Tools Window and Invalidate if (!sf.ui.proTools.isRunning) throw `Pro Tools is not running`; sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); function bounceSelectedTrack() { // Get Selected Track let selectedTrack = sf.ui.proTools.invalidate().selectedTrack; // Get Track Name of Selected Track let selectedTrackName = selectedTrack.normalizedTrackName; // Solo Selected Track selectedTrack.trackSetSolo({ targetValue: "Enable", }); // Click "Bounce Mix..." from File Menu sf.ui.proTools.menuClick({ menuPath: ["File", "Bounce Mix..."], }, `Could not click "Bounce Mix" in Pro Tools`); // Define Bounce Window let bounceWin = sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first; // Wait for Bounce Window to Appear bounceWin.elementWaitFor({ waitType: "Appear", }); // Set Track Name sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first.textFields.first.elementSetTextFieldWithAreaValue({ value: selectedTrackName }); // Set Bounce Path bounceWin.groups.whoseTitle.is("Location").first.textFields.first.elementSetTextFieldWithAreaValue({ value: "Bounced Files/Stems/", }); // Click Bounce bounceWin.buttons.whoseTitle.is("Bounce").first.elementClick(); // Wait for Bounce Window to Disappear bounceWin.elementWaitFor({ waitType: "Disappear", timeout: -1, onError: "Continue" }); // Wait for Bounce to finish (Wait for bounce dialog to appear, then to disappear) var bouncingLabel = sf.ui.proTools.windows.whoseTitle.is('').first.children.whoseRole.is("AXStaticText").whoseValue.is('Bouncing...').first; bouncingLabel.elementWaitFor({ timeout: 1000, onError:"Continue" }); bouncingLabel.elementWaitFor({ waitType: 'Disappear', timeout: -1 }); // -1 is endless timeout (cancel by Ctrl+Shift+Esc) // Clear Solo on Selected Track selectedTrack.trackSetSolo({ targetValue: "Disable", }); } //Get selected tracks const originalTracks = sf.ui.proTools.selectedTrackNames; //Do for each track. sf.ui.proTools.selectedTracks.trackHeaders.slice().map(track => { //Select track track.trackSelect(); //Scroll track into View track.trackScrollToView(); //Code to execute here bounceSelectedTrack(); }); //Restore previously selected tracks sf.ui.proTools.trackSelectByName({ names: originalTracks }); log('Bouncing Complete');
- LLynn Graber @Lynn_Graber
Dang, this works great.
I did see Andrews Bounce Factory, but honestly I really like learning this stuff. Give a man a fish, tech a man to fish. ;)
Really appreciate yalls patience. SF is game changing for my current workflow and workload.
Chad Wahlbrink @Chad2023-09-18 16:15:07.481Z
That's great, @Lynn_Graber! Learning the principles behind SoundFlow can open many doors for other workflows. Glad this one is helping.
- In reply toLynn_Graberā¬:LLynn Graber @Lynn_Graber
One last thing I am trying to do with this script is edit it to just bounce and rename my main mix using the session title.
// Activate Pro Tools Window and Invalidate if (!sf.ui.proTools.isRunning) throw `Pro Tools is not running`; sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); // Click "Bounce Mix..." from File Menu sf.ui.proTools.menuClick({ menuPath: ["File", "Bounce Mix..."], }, `Could not click "Bounce Mix" in Pro Tools`); // Define Bounce Window let bounceWin = sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first; // Wait for Bounce Window to Appear bounceWin.elementWaitFor({ waitType: "Appear", }); // Set Track Name sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first.textFields.first.elementSetTextFieldWithAreaValue({ value: }); // Set Bounce Path bounceWin.groups.whoseTitle.is("Location").first.textFields.first.elementSetTextFieldWithAreaValue({ value: "Bounced Files/Mixes/", }); // Click Bounce bounceWin.buttons.whoseTitle.is("Bounce").first.elementClick(); // Wait for Bounce Window to Disappear bounceWin.elementWaitFor({ waitType: "Disappear", timeout: -1, onError: "Continue" }); // Wait for Bounce to finish (Wait for bounce dialog to appear, then to disappear) var bouncingLabel = sf.ui.proTools.windows.whoseTitle.is('').first.children.whoseRole.is("AXStaticText").whoseValue.is('Bouncing...').first; bouncingLabel.elementWaitFor({ timeout: 1000, onError:"Continue" }); bouncingLabel.elementWaitFor({ waitType: 'Disappear', timeout: -1 }); // -1 is endless timeout (cancel by Ctrl+Shift+Esc) log('Bouncing Complete');```
Chad Wahlbrink @Chad2023-09-18 16:30:09.362Z
This should be a good script for generic mix bounces with the session name as the title. Note that I'm using:
let sessionName = sf.app.proTools.getSessionName().sessionName;
ā This is utilizing the Pro Tools SDK to get the Session Name.
I also moved the "Bounced Files/Mixes/" to a variable.
// Activate Pro Tools Window and Invalidate if (!sf.ui.proTools.isRunning) throw `Pro Tools is not running`; sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); // Get Session Name let sessionName = sf.app.proTools.getSessionName().sessionName; // Set Bounce Path let bouncePath = "Bounced Files/Mixes/"; function bounceMix() { // Click "Bounce Mix..." from File Menu sf.ui.proTools.menuClick({ menuPath: ["File", "Bounce Mix..."], }, `Could not click "Bounce Mix" in Pro Tools`); // Define Bounce Window let bounceWin = sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first; // Wait for Bounce Window to Appear bounceWin.elementWaitFor({ waitType: "Appear", }); // Set Track Name sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first.textFields.first.elementSetTextFieldWithAreaValue({ value: sessionName }); // Set Bounce Path bounceWin.groups.whoseTitle.is("Location").first.textFields.first.elementSetTextFieldWithAreaValue({ value: bouncePath, }); // Click Bounce bounceWin.buttons.whoseTitle.is("Bounce").first.elementClick(); // Wait for Bounce Window to Disappear bounceWin.elementWaitFor({ waitType: "Disappear", timeout: -1, onError: "Continue" }); // Wait for Bounce to finish (Wait for bounce dialog to appear, then to disappear) var bouncingLabel = sf.ui.proTools.windows.whoseTitle.is('').first.children.whoseRole.is("AXStaticText").whoseValue.is('Bouncing...').first; bouncingLabel.elementWaitFor({ timeout: 1000, onError:"Continue" }); bouncingLabel.elementWaitFor({ waitType: 'Disappear', timeout: -1 }); // -1 is endless timeout (cancel by Ctrl+Shift+Esc) } // Bounce Mix bounceMix(); log('Bouncing Complete');
- LLynn Graber @Lynn_Graber
Hmm, copied and pasted this, doesnt trigger at all.
- In reply toChadā¬:LLynn Graber @Lynn_Graber
Nevermind, found it. Copied and pasted two different times, both times I was missing the first /. Ooops.
Chad Wahlbrink @Chad2023-09-18 17:47:23.230Z
Great! Is this working as expected now @Lynn_Graber ?
- LLynn Graber @Lynn_Graber
Yeah dude, Ive added a few things like marker selection and using a group to auto select the tracks. And I also combined the CSV, Mix Print, and Stem Bounce all on to one key. :) Life is good. haha
- AAndrew Sherman @Andrew_Sherman
Thank you for posting this, I'm also wanting a more bespoke bouncing solution like this. How are you working with markers in this, are you defining the bounced filenames from markers, and time-ranges?
- LLynn Graber @Lynn_Graber
Ive added this script below to the top to select my start and end markers in my session, which in my case are always marker 1 and marker 99. You can change those numbers to whatever you want in your session.
// Activate Pro Tools Window and Invalidate if (!sf.ui.proTools.isRunning) throw `Pro Tools is not running`; sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); function selectBetween(no1, no2) { sf.ui.proTools.memoryLocationsGoto({ memoryLocationNumber: no1, restoreWindowOpenState: true, useKeyboard: true, }); sf.ui.proTools.memoryLocationsGoto({ extendSelection: true, memoryLocationNumber: no2, restoreWindowOpenState: true, useKeyboard: true, }); } selectBetween(1, 99);```
- AAndrew Sherman @Andrew_Sherman
Thank you for sharing this