Select Tracks that are located between two defined tracks
Hi everyone,
I'm trying to write a code to help me prepare mixing sessions and I'm looking for a way to select all tracks that are positionned between 2 other tracks like so
TRACK A
track to select 1
track to select 2
track to select 3
etc.
TRACK B
TRACK A & TRACK B are always in my template.
Is there a way to tell sound flow to select all tracks that are between TRACK A & TRACK B?
Any input welcome!
Thank you!
Linked from:
- Raphael Sepulveda @raphaelsepulveda2022-04-16 19:15:30.152Z2022-04-18 17:50:16.314Z
@Thomas_Gloor, here you go!
/** @param {{ trackA: string, trackB: string, includeHidden?: boolean }} args */ function selectTracksBetween({ trackA, trackB, includeHidden = false }) { function getTrackIndex(trackName) { const trackIndex = allTrackNames.indexOf(trackName); if (trackIndex === -1) throw `${trackName} not found in session`; return trackIndex; } sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); const allTrackNames = includeHidden ? sf.ui.proTools.trackNames : sf.ui.proTools.visibleTrackNames; const trackIndexes = Object .values(arguments[0]) .map(getTrackIndex) .sort((a, b) => a - b); trackIndexes[0]++; const trackRange = allTrackNames.slice(...trackIndexes); sf.ui.proTools.trackSelectByName({ names: trackRange, deselectOthers: true }); } selectTracksBetween({ trackA: "Track A", // Insert track names here trackB: "Track B" });
- TThomas Gloor @Thomas_Gloor
Thank you very much for taking the time to do this! I will try it as soon as I'm back at the studio!
I'm trying to up my very poor Javascript game (tutorials, online courses, etc...) but also want to move forward and turns out every idea I have is pretty complicated haha
Best,
T.
Raphael Sepulveda @raphaelsepulveda2022-04-16 19:48:03.299Z
Let me know how it works out when you do!
Oh, yeah I know how that is. One function at a time gets it done eventually!
- TThomas Gloor @Thomas_Gloor
Thanks! Will do tomorrow.
Let you know! One last question though @raphaelsepulveda
If I wanted to use that script more than one time within a bigger script, but let's say the first time it selects between tracks A and B but the second time between C and D, can I simply copy/paste the script twice and change the name of the tracks?
Raphael Sepulveda @raphaelsepulveda2022-04-17 16:42:17.180Z
You would only need to copy/paste the function call and modify it accordingly, like so:
selectTracksBetween({ trackA: "Track C", trackB: "Track D" });
I suggest you put the function definition—the part that starts with
function
—at the top of your script since none of the code in it gets executed until you call it, like shown above.- TThomas Gloor @Thomas_Gloor
OK! I get it. Thank you so much.
While we are talking about selections, would you have an idea of a way I could use to select all tracks in the session that start with a particular character? in a CASE SENSITIVE manner?
Thank you again for your time, it's awsome :)
Raphael Sepulveda @raphaelsepulveda2022-04-17 23:46:42.316Z
Yeah! Check it out here Script Sharing - Select Tracks Whose Name Starts with Prefix
I created a new thread for it so other people looking for that can easily find it when searching the forum.
- TThomas Gloor @Thomas_Gloor
Thanks @raphaelsepulveda
I tried both scripts and the both work perfectly. You are definately the "Track Selection MVP" haha
One thing about the "select between 2 tracks" script. Is it possible to have it ignore hidden tracks?
Not a major problem that it doesn't, but I imagine it could be depending on the situation.Best
T
Raphael Sepulveda @raphaelsepulveda2022-04-18 17:54:08.598Z
Yeah for sure! Sorry totally forgot about hidden tracks lol
I updated the code above. Now, by default, it will ignore hidden tracks with the same function call as before, but if you did want to include them, you'd do the call like this:
selectTracksBetween({ trackA: "Track A", trackB: "Track B", includeHidden: true });
- TThomas Gloor @Thomas_Gloor
Thank you so much for changing it so fast! You're of GREAT help.
- In reply toraphaelsepulveda⬆:
Eric Huergo @Eric_Huergo
Hey @raphaelsepulveda , first off thanks for all of the help on the forums - I've seen you around everywhere for a while now!!
I was just wondering. If I wanted to modify the following script to select everything in between the tracks but also the tracks designated "trackA" and "trackB" themselves. AND, simultaneously make sure to include all hidden tracks in the selection. What would be a good way of achieving that result? I've been scratching my head at it for a while but keep getting errors! Any help would be greatly appreciated! :)
Your code I'm trying to modify:
/** @param {{ trackA: string, trackB: string, includeHidden?: boolean }} args */ function selectTracksBetween({ trackA, trackB, includeHidden = false }) { function getTrackIndex(trackName) { const trackIndex = allTrackNames.indexOf(trackName); if (trackIndex === -1) throw `${trackName} not found in session`; return trackIndex; } sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); const allTrackNames = includeHidden ? sf.ui.proTools.trackNames : sf.ui.proTools.visibleTrackNames; const trackIndexes = Object .values(arguments[0]) .map(getTrackIndex) .sort((a, b) => a - b); trackIndexes[0]++; const trackRange = allTrackNames.slice(...trackIndexes); sf.ui.proTools.trackSelectByName({ names: trackRange, deselectOthers: true }); } selectTracksBetween({ trackA: "Track A", trackB: "Track B" });
Raphael Sepulveda @raphaelsepulveda2023-02-24 04:41:07.562Z
@Eric_Huergo,hanks for the kind words!, Always happy to help :D
This small adjustment should do the trick!
/** @param {{ trackA: string, trackB: string, includeTargetTracks?: boolean, includeHidden?: boolean }} args */ function selectTracksBetween({ trackA, trackB, includeTargetTracks = false, includeHidden = false }) { function getTrackIndex(trackName) { const trackIndex = allTrackNames.indexOf(trackName); if (trackIndex === -1) throw `${trackName} not found in session`; return trackIndex; } sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); const allTrackNames = includeHidden ? sf.ui.proTools.trackNames : sf.ui.proTools.visibleTrackNames; const trackIndexes = [trackA, trackB] .map(getTrackIndex) .sort((a, b) => a - b); trackIndexes[+includeTargetTracks]++; const trackRange = allTrackNames.slice(...trackIndexes); sf.ui.proTools.trackSelectByName({ names: trackRange, deselectOthers: true }); } selectTracksBetween({ trackA: "Audio 1", trackB: "Audio 15", includeTargetTracks: true, includeHidden: true });
Eric Huergo @Eric_Huergo
@raphaelsepulveda , Increíble! :p
The change definitely took care of selecting the appropriate range of tracks in my scenario!! This being said, when the script reaches a hidden track now, it fails and I get the following error in the log:Could not make track visible ( -- Workspace: Line 22) Track ' _st_06_HI_ARPS' did not show up after several attempts
In this instance it crashes when it reaches the track " _st_06_HI_ARPS", but the same is true with any track I try. The script seems to select and unhide the first hidden track it encounters, after which the script immediately fails and I get the error I included above.
My best guess at the moment is that maybe this means that when the script encounters a hidden track it shows and selects it but that somehow this breaks the loop of selecting the rest of the tracks?
Any idea how I might be able to get past this?
Many thanks. :)
- Eric
Additionally, maybe I should mention that the hidden tracks are located within a folder track - is there a chance this is part of the issue?
Raphael Sepulveda @raphaelsepulveda2023-02-24 21:49:41.570Z
Oh no. This seems to be an issue with the
trackSelectByName()
function.Yes, the normal behavior would be for it to unhide the track and then select it. This is all handled by that function. It waits for the track to appear before moving on but, for some reason, it's not detecting that the track has been unhidden. Unfortunately, I'm not able to make the error happen on my end.
Let's distill it down. If you run this by itself, do you still get the error?
sf.ui.proTools.trackSelectByName({ names: [" _st_06_HI_ARPS"], deselectOthers: true });
If so, could you log a bug report immediately after getting the error, so we can take a closer look? A screen recording of it happening would also be helpful, which you can put on the report after you've filed it.
Eric Huergo @Eric_Huergo
Dang, unfortunately still get the error. Managed to submit a bug report though!
- In reply toraphaelsepulveda⬆:
Eric Huergo @Eric_Huergo
Alright @raphaelsepulveda , turns out I made a very silly mistake and didn't catch a simple, silly mistake.
At some point a space ended up before the track name and so was not able to find the track because, well.... it wasn't there.
Needless to say, if I now run the following script:
/** @param {{ trackA: string, trackB: string, includeTargetTracks?: boolean, includeHidden?: boolean }} args */ function selectTracksBetween({ trackA, trackB, includeTargetTracks = false, includeHidden = false }) { function getTrackIndex(trackName) { const trackIndex = allTrackNames.indexOf(trackName); if (trackIndex === -1) throw `${trackName} not found in session`; return trackIndex; } sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); const allTrackNames = includeHidden ? sf.ui.proTools.trackNames : sf.ui.proTools.visibleTrackNames; const trackIndexes = [trackA, trackB] .map(getTrackIndex) .sort((a, b) => a - b); trackIndexes[+includeTargetTracks]++; const trackRange = allTrackNames.slice(...trackIndexes); sf.ui.proTools.trackSelectByName({ names: trackRange, deselectOthers: true }); } selectTracksBetween({ trackA: ">> STEREO FD <<", trackB: "_99_Click", includeTargetTracks: true, includeHidden: true });
it will run fine until it encounters the first hidden track. It then proceeds to unhide it and the script stops running and shows me the following in the error log:
24.02.2023 14:36:35.88 <info> [Backend]: Logging error in action (01) TrackMakeVisibleByListItemAction: Track ' _st_08_KEYS' did not show up after several attempts Logging error in action (01) SelectTracksByNameAction: Could not make track visible 24.02.2023 14:36:35.88 <info> [Backend]: !! Command Error: -- Workspace [user:cldav56zg00006p10fry8qf84:cldkjdllg0000td106m00l1af]: Could not make track visible ( -- Workspace: Line 22) Track ' _st_08_KEYS' did not show up after several attempts
Any idea what I might be doing wrong?
Raphael Sepulveda @raphaelsepulveda2023-02-24 22:50:39.432Z
This seems to be the same error from before. It wasn't your fault that the space was added before the track name, SoundFlow is reporting that that's actually the track name.
Ahhhh, you know what, I bet you have track numbers enabled. If you do, try turning it off and run the script again.
Eric Huergo @Eric_Huergo
BOOM! You called it, works like a charm now!
Now I just have to make a function that stores the value of whether track numbers are enabled or not, make it so that before this part of the script runs track numbers are turned off, and afterwards set the state of Track Numbers to whatever the value was set as in the function!
Thanks so much dude!!! Lo aprecio un chingo!. ;)
Raphael Sepulveda @raphaelsepulveda2023-02-24 23:24:44.608Z
Hahah, no hay problema, hermano! :D Let me know if you need help with that.
In the meantime, I was able to repro the source of the problem and posted my findings on your bug report from earlier. Could you remove the "Solved" status of it so that we can still keep track of it?
Eric Huergo @Eric_Huergo
Claro que si! Just removed the "Solved" status. ;)
For the track numbers part, would you just go the globalstate way or what method do you think would work best? :p
Raphael Sepulveda @raphaelsepulveda2023-02-25 00:31:26.989Z
I'd approach it like this:
/** @param {{ trackA: string, trackB: string, includeTargetTracks?: boolean, includeHidden?: boolean }} args */ function selectTracksBetween({ trackA, trackB, includeTargetTracks = false, includeHidden = false }) { function getTrackIndex(trackName) { const trackIndex = allTrackNames.indexOf(trackName); if (trackIndex === -1) throw `${trackName} not found in session`; return trackIndex; } sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); const allTrackNames = includeHidden ? sf.ui.proTools.trackNames : sf.ui.proTools.visibleTrackNames; const trackIndexes = [trackA, trackB] .map(getTrackIndex) .sort((a, b) => a - b); trackIndexes[+includeTargetTracks]++; const trackRange = allTrackNames.slice(...trackIndexes); sf.ui.proTools.trackSelectByName({ names: trackRange, deselectOthers: true }); } /** Ensures a menu item is menu checked (or not) while an action takes place. * @param {{ * menuItemPath: [string, string, string?, string?, string?, string?], * doWithout?: boolean, // Ensures the menu item is NOT menu checked * callback: function * }} args */ function doWithMenuItemToggle({ menuItemPath, doWithout = false, callback }) { const menuItem = sf.ui.proTools.getMenuItem(...menuItemPath); const isMenuItemChecked = menuItem.isMenuChecked; if (!isMenuItemChecked && !doWithout || isMenuItemChecked && doWithout) { menuItem.elementClick(); } callback(); if (!isMenuItemChecked && !doWithout || isMenuItemChecked && doWithout) { menuItem.elementClick(); } } doWithMenuItemToggle({ menuItemPath: ["View", "Track Number"], doWithout: true, callback: () => { selectTracksBetween({ trackA: ">> STEREO FD <<", trackB: "_99_Click", includeTargetTracks: true, includeHidden: true }); } });
PS. This could've been simpler but I prefer to write reusable functions I can implement in other scripts 🤘🏼
Eric Huergo @Eric_Huergo
Wow, thank you so much! Will definitely be applying this technique with other values further down the line!
The part of the script that I've been struggling with is now fully running now thanks to you!
Lo aprecio demasiado! Un abrazo y enserio muchas gracias! <3