Hi,
Do you think is possible to bounce each track automatic (one by one)?
Imagine, 3 tracks that share 2 aux but I want to have each track committed with is own AUX I only see possible doing this with Bounce and Solo.
Do you think this is kind crazy?
Thanks
Linked from:
- In reply tombernardo⬆:Marco Bernardo @mbernardo2019-11-12 18:47:56.073Z2019-11-13 22:47:06.048Z
Hi Christian,
This is a variant of the other code but instead of creating a new post I think it could be here. Let me know if is ok.
I'm trying to achieve this - user select tracks to bounce then the macro will:
- Select each track one by one and
- Solo track
- Bounce track and add to the prefix name bnc-
- Import selection and hide and inactive the source track
this in loop till the end.
I've made the script till this part but I'm getting some issues, tracks that I don't have selected are appearing (check the video)
var popupMenu = sf.ui.proTools.trackOpenListPopupMenu().popupMenu; popupMenu.menuClickPopupMenu({ menuPath: ["Show Only Selected Tracks"], }); var nameAudioTracks = sf.ui.proTools.visibleTrackNames for (var i = 0; i < nameAudioTracks.length; i++) { //log (nameAudioTracks[i]) var trackName = nameAudioTracks[i] //select the track sf.ui.proTools.trackSelectByName({ names: [trackName], deselectOthers: true }) //solo the track sf.ui.proTools.trackSetSoloByName({ name: trackName }) //Invoke the File->Bounce to->Disk... menu item sf.ui.proTools.getMenuItem('File', 'Bounce to', 'Disk...').elementClick(); //Wait for the 'Bounce' dialog to appear and assign it to the bounceDlg variable var bounceDlg = sf.ui.proTools.dialogWaitForManual({ dialogTitle: 'Bounce' }).dialog; //Special code for now (this will change and be made easier) //What this does is get the Children of the bounceDialog, filter them so we only get the popupbuttons, //and then slice the resulting array so the we only get the last 4. //This is needed since there are no names/titles/labels on the 4 buttons used to set up file type, format, bit depth and //sample rate. We take the last 4, since the bounce sources will be the first X number of popup buttons in the dialogue, //but we don't know how many of those that there are. var popupButtons = bounceDlg.getElements("AXChildren").filter(function (e) { return e.fullRole == "AXPopUpButton" }).slice(-4); //Assign the four buttons coming out of the previous instruction to individual variables var fileTypeBtn = popupButtons[0]; var formatBtn = popupButtons[1]; var bitDepthBtn = popupButtons[2]; var sampleRateBtn = popupButtons[3]; var deliverFormat = popupButtons[4]; //If the value is not already WAV, use the popupMenuSelect action to (1. click the button, 2. select the corresponding menuPath item in the popup menu) if (fileTypeBtn.value.value != 'WAV') fileTypeBtn.popupMenuSelect({ menuPath: ['WAV'] }); if (formatBtn.value.value != 'Interleaved') formatBtn.popupMenuSelect({ menuPath: ['Interleaved'] }); if (bitDepthBtn.value.value != '24 Bit') bitDepthBtn.popupMenuSelect({ menuPath: ['24 Bit'] }); if (sampleRateBtn.value.value != '48 kHz') sampleRateBtn.popupMenuSelect({ menuPath: ['48 kHz'] }); //if (deliverFormat.value.value != 'Single File') // deliverFormat.popupMenuSelect({ menuPath: ['Single'] }); // click Import After Bouce function selectImportAfterBounce(name, val) { bounceDlg.getFirstWithTitle(name).checkboxSet({ targetValue: val ? 'Enable' : 'Disable' }); } selectImportAfterBounce("Import After Bounce", true); // click offline function selectOffline(name, val) { bounceDlg.getFirstWithTitle(name).checkboxSet({ targetValue: val ? 'Enable' : 'Disable' }); } selectOffline("offline", true); //paste track name into File name log(trackName) bounceDlg.textFields.first.elementSetTextFieldWithAreaValue({ value: "bnc-" + trackName }); bounceDlg.buttons.whoseTitle.is('Bounce').first.elementClick(); sf.wait({intervalMs: 2000}); var win = sf.ui.proTools.windows.whoseTitle.is('Audio Import Options').first; win.elementWaitFor(); win.radioButtons.whoseTitle.startsWith('New Track').first.elementClick(); win.buttons.whoseTitle.is('OK').first.elementClick(); sf.wait({intervalMs: 2000}); sf.ui.proTools.trackSelectByName({ names: [trackName], deselectOthers: true }); sf.wait({intervalMs: 2000}); sf.ui.proTools.selectedTrack.titleButton.popupMenuSelect({ isRightClick: true, menuPath: ['Hide and Make Inactive'], }); sf.wait({intervalMs: 2000}); }
As you can see in the video AUX 5 is being selected and then it will Hide and inactive 2 tracks it should be only one and the last tracks isn't hide and inactive too.
I only selected the audio tracks and the instrument track as you can see in the video.
link to the video
https://wetransfer.com/downloads/def229d9d3981585794ec0e4ebeabb2820191112184527/930b245c362d8f631574577bbfc9ce8e20191112184528/f261f2mb_Soundflow.ptx (59.47 kB)
Thanks
Christian Scheuer @chrscheuer2019-11-13 23:38:13.457Z
Hi Marco
Wow, cool workflow. Ok there are a couple of important things.
You shouldn't use manual waits in 99% of cases. You should wait for dialogs to open and close. I sent you a link to a youtube video describing how to implement this (https://www.youtube.com/watch?v=20ECpTUy_jk).
Secondly, after the bounce is done, you should invalidate the SF PT cache, by inserting this code:sf.ui.proTools.invalidate();
Before the last call to
trackSelectByName
.Marco Bernardo @mbernardo2019-11-13 23:44:30.349Z
Roger!!
The 2000 wait intervals it was needed for test proposes, I want to see what the script is doing eheheh I forgot to remove it.
Thanks for the clarification!!!!
I didn't know this!! I've missed somewhere in time!
sf.ui.proTools.invalidate();
Did you saw my video?
I can't understand why is showing the AUX when I only asked to do what it was selected.
I need to dig more on this.Thanks
ps: here in Portugal is getting more cold too, tomorrow will be 7º less than today :) but that doesn't compared to your country ;) ehehe For you here is still Summer!!Christian Scheuer @chrscheuer2019-11-13 23:53:35.982Z
Did you saw my video?
I can't understand why is showing the AUX when I only asked to do what it was selected.
I need to dig more on this.Yes I saw it and my reply was a reply to the video.
There are a couple of reasons for this behavior. One is Pro Tools actually doesn't update correctly after you've created a new track (you can view this by pressing P or semicolon after a new track has been created, and you'll see it doesn't select the correct tracks). It takes a mouse click or keyboard press for it to understand correctly that this new track was created. Secondly, SoundFlow has a cache of tracks to speed up performance, but this cache needs to be updated as well, when a new track has been created or one has been deleted.So actually you might need to insert 2 actions after the bounce has completed.
One action to press "P", and a second one to invalidate the SF cache.Marco Bernardo @mbernardo2019-11-14 00:25:08.992Z
Get it!! :)
Thanks
Marco Bernardo @mbernardo2019-11-14 00:49:49.061Z
Here is the final code if anyone want to use it or make it better
I got the need to add the two interval waits, if you remove you will see the the last track would be disable.
Thank YOU
if (!confirm(`This script will perform an export of ALL Tracks Selected, each in SOLO for a Stem Folder inside Bounced Files\nDo you want to continue?`)) throw 0; sf.ui.proTools.mainWindow.counterDisplay.mouseClickElement({ relativePosition: { x: 299, y: 67 } }); sf.ui.proTools.menuClick({ menuPath: [ 'Options', 'Solo Mode', 'X-OR (Cancels Previous Solo)'] }); var popupMenu = sf.ui.proTools.trackOpenListPopupMenu().popupMenu; popupMenu.menuClickPopupMenu({ menuPath: ["Show Only Selected Tracks"], }); var nameAudioTracks = sf.ui.proTools.visibleTrackNames for (var i = 0; i < nameAudioTracks.length; i++) { //log (nameAudioTracks[i]) var trackName = nameAudioTracks[i] //select the track sf.ui.proTools.trackSelectByName({ names: [trackName], deselectOthers: true }) //solo the track sf.ui.proTools.trackSetSoloByName({ name: trackName }) //Invoke the File->Bounce to->Disk... menu item sf.ui.proTools.getMenuItem('File', 'Bounce to', 'Disk...').elementClick(); //Wait for the 'Bounce' dialog to appear and assign it to the bounceDlg variable var bounceDlg = sf.ui.proTools.dialogWaitForManual({ dialogTitle: 'Bounce' }).dialog; var outputBtn = bounceDlg.popupButtons.first; // Change what the output name for your needs if (outputBtn.value.value.indexOf('output 1/2') < 0) { outputBtn.popupMenuSelect({ menuPath: ['output', '*output 1/2*'], useWildcards: true }); } //Special code for now (this will change and be made easier) //What this does is get the Children of the bounceDialog, filter them so we only get the popupbuttons, //and then slice the resulting array so the we only get the last 4. //This is needed since there are no names/titles/labels on the 4 buttons used to set up file type, format, bit depth and //sample rate. We take the last 4, since the bounce sources will be the first X number of popup buttons in the dialogue, //but we don't know how many of those that there are. var popupButtons = bounceDlg.getElements("AXChildren").filter(function (e) { return e.fullRole == "AXPopUpButton" }).slice(-4); //Assign the four buttons coming out of the previous instruction to individual variables var fileTypeBtn = popupButtons[0]; var formatBtn = popupButtons[1]; var bitDepthBtn = popupButtons[2]; var sampleRateBtn = popupButtons[3]; var deliverFormat = popupButtons[4]; //If the value is not already WAV, use the popupMenuSelect action to (1. click the button, 2. select the corresponding menuPath item in the popup menu) if (fileTypeBtn.value.value != 'WAV') fileTypeBtn.popupMenuSelect({ menuPath: ['WAV'] }); if (formatBtn.value.value != 'Interleaved') formatBtn.popupMenuSelect({ menuPath: ['Interleaved'] }); if (bitDepthBtn.value.value != '24 Bit') bitDepthBtn.popupMenuSelect({ menuPath: ['24 Bit'] }); if (sampleRateBtn.value.value != '48 kHz') sampleRateBtn.popupMenuSelect({ menuPath: ['48 kHz'] }); //if (deliverFormat.value.value != 'Single File') // deliverFormat.popupMenuSelect({ menuPath: ['Single'] }); // click Import After Bouce function selectImportAfterBounce(name, val) { bounceDlg.getFirstWithTitle(name).checkboxSet({ targetValue: val ? 'Enable' : 'Disable' }); } selectImportAfterBounce("Import After Bounce", true); // click offline function selectOffline(name, val) { bounceDlg.getFirstWithTitle(name).checkboxSet({ targetValue: val ? 'Enable' : 'Disable' }); } selectOffline("offline", true); //paste track name into File name log(trackName) bounceDlg.textFields.first.elementSetTextFieldWithAreaValue({ value: "bnc-" + trackName // bnc- could be the name of the music change if you want to }); bounceDlg.buttons.whoseTitle.is('Bounce').first.elementClick(); // Audio Import Window var win = sf.ui.proTools.windows.whoseTitle.is('Audio Import Options').first; win.elementWaitFor({ waitType: "Appear", }) win.radioButtons.whoseTitle.startsWith('New Track').first.elementClick(); win.popupButtons.first.popupMenuSelect({ menuPath: ["Session Start"], // or change to your needs - Selection - Spot - Song Start }); win.buttons.whoseTitle.is('OK').first.elementClick(); win.elementWaitFor({ waitType: "Disappear", }); sf.ui.proTools.trackSelectByName({ names: [trackName], deselectOthers: true }); sf.wait({intervalMs: 500}); sf.ui.proTools.selectedTrack.titleButton.popupMenuSelect({ isRightClick: true, menuPath: ['Hide and Make Inactive'], }); sf.wait({intervalMs: 1000}); sf.ui.proTools.invalidate(); sf.keyboard.press({ keys: "p", }); } sf.ui.proTools.mainWindow.counterDisplay.mouseClickElement({ relativePosition: { x: 299, y: 67 } }); sf.ui.proTools.invalidate();
- Progress
- Christian Scheuer @chrscheuer2019-11-12 07:39:05.871Zreplies tombernardo⬆:
Hi Marco. What do you mean by this? Did you find a solution yourself? :)