This was developed in coop with @Fokke.
It makes a copy of your current track, removes the ".dup1" suffix and just adds an increasing number.
So if you duplicate "Audio 5" it will create a new copy of that with the name "Audio 6".
I have slightly different duplication settings than Fokke - you can freely set your true/false settings as wished.
//Research and code from Fokke van Saane and Christian Scheuer
sf.ui.proTools.trackDuplicateSelected({
duplicateActivePlaylist: false,
duplicateAlternatePlaylists: false,
duplicateAutomation: false,
duplicateGroupAssignments: true,
duplicateInserts: true,
duplicateSends: true,
insertAfterLastSelectedTrack: true,
numberOfDuplicates: 1
})
sf.ui.proTools.selectedTrack.trackRename({
renameFunction: function (name) {
var grps = name.match(/^([^\d]*)( ?)(\d*)\.dup.*/);;
var baseName = grps[1];
var space = grps[2];
var numName = grps[3];
if (numName == "") space = " ";
var newNum = numName == "" ? 2 : Number(numName) + 1;
return baseName + space + (newNum + '');
}
});
For a commented version, see: https://forum.soundflow.org/-232#post-15
- ?In reply tochrscheuer⬆:@anon6770933309
Nice, I only wish this was commented better so that others can learn from this. These private solutions for a single someone do not help anyone else. 😕
And it simply doesn't work here.
What does this mean/do: var grps = name.match(/^([^\d])(\d).dup.*/);; ?
Christian Scheuer @chrscheuer2018-07-29 17:17:59.356Z
Cool, I'll update with comments. First let's see what doesn't work for you - can you elaborate on doesn't work (what's the track you're trying on, what happens)?
- ?@anon6770933309
I ran the script while selecting a stereo Audio track called "Audio 1", the script duplicated the track and then hang. 100% reproducible. The duplicated track was not renamed. The SF icon stays blue so the script was still running, only way out is to quit SF.
I'll send you the log file.- ?@anon6770933309
Turns out it fails when the Track List is closed. 😉
30.07.2018 11:23:03.41 [Backend]: Clicking with mouse here: 1287, 424
30.07.2018 11:23:04.04 [Backend]: Could not get UIElement for AxPtTrackListView: Could not find Track List table in PT11/12
30.07.2018 11:23:04.06 [Backend]: Could not get UIElement for AxPtTrackListView: Could not find Track List table in PT11/12
- ?@anon6770933309
And another issue, if the track is called "Bass" or the like -when it has no number- the duplicated track will be named "Bass2" (with no space).
I don't wanna sound fussy but I thought I mention it nevertheless. 😉Christian Scheuer @chrscheuer2018-07-30 12:35:10.238Z
Thanks for detailed replys, @Oli_Em. I can repro it here. Looking into it.
If you didn't already know - when the blue icon is hanging, there are 2 new options in SF to deal with this:
- Stop all running commands
- Restart SoundFlow
The "Restart SoundFlow" will only restart the backend, so the icon will flash red for a second and you'll be back to normal.
- ?@anon6770933309
Ah yeah, forgot about it, thx for reminding me! I need to get used to the new features. 😉
- In reply toanon6770933309⬆:
Christian Scheuer @chrscheuer2018-07-30 15:10:43.727Z
This is fixed in this script (un-commented version first).
This script will duplicate "Bass" to "Bass 2" (per default a space), "Bass1" (no space) to "Bass2" (no space), "Bass 1" to "Bass 2", etc.sf.ui.proTools.selectedTrack.trackRename({ renameFunction: function (name) { var grps = name.match(/^([^\d]*)( ?)(\d*)\.dup.*/);; var baseName = grps[1]; var space = grps[2]; var numName = grps[3]; if (numName == "") space = " "; var newNum = numName == "" ? 2 : Number(numName) + 1; return baseName + space + (newNum + ''); } });
Christian Scheuer @chrscheuer2018-07-30 15:14:12.460Z
Commented version:
sf.ui.proTools.selectedTrack.trackRename({ renameFunction: function (name) { //This function gets called after the Rename track dialog is open //the argument 'name' holds the existing name, eg. "Audio 4.dup1" //We're supposed to eventually return the target name we want from this function. var grps = name.match(/^([^\d]*)( ?)(\d*)\.dup.*/);; //This regular expression matches a string containing of the following groups (each group is in parentheses) //Group 1 - syntax: ([^\d]*) - meaning: Match any number (*) of characters that are NOT digits ([^\d]). This will match "Audio" //Group 2 - syntax: ( ?) - meaning: Match either 0 or 1 (?) space character //Group 3 - syntax: (\d*) - meaning: Match any number (*) of characters that are digits (\d). This will match "4". //After last group- syntax: \.dup.* - meaning: Match a dot (\.), the text "dup", and then ANY character (.), any number of times (*) //Save out the groups, baseName, space, numName var baseName = grps[1]; var space = grps[2]; var numName = grps[3]; //If you didn't have a number, by default we want a space ' ' before our new #2 track if (numName == "") space = " "; //Create the new number. If there wasn't one, we'll default to 2, if there was one, convert our string to a number, and add 1 to that var newNum = numName == "" ? 2 : Number(numName) + 1; //Return the new name, a combination of the base name "Audio", a space or not " ", and the new number (converted to a string to make sure we don't mix up types) return baseName + space + (newNum + ''); } });
- ?@anon6770933309
Thank you.
- In reply tochrscheuer⬆:?@anon6770933309
Can this be modified so that the renamed tracks don't get number suffixes but letters starting from "b"? So that "Audio.dup1" becomes "Audio b", "Audio b" becomes "Audio c", "Bass 1" becomes "Bass 1b" etc etc.?
Christian Scheuer @chrscheuer2018-10-03 08:28:57.782Z
Yes.
Question is though, the script above deals with it by reading the number from the existing track that you were duplicating. So it would use that input (say you were duping "Audio 6") it would then use the 6 to know that the next track should be called 7.
If we use letters for the numbering the algo would be more difficult (for the user) to understand. Since all words end with a letter, if you had a track "Bass a" it becomes "Bass b". But what if you just have "Bass", then it would become "Bast" (just based on last letter). Should it only match if there is a space followed by a single letter?- ?@anon6770933309
I know what I asked for is complicated which is why I asked in the first place. Lets make it as easy as possible and less complicated. So yes, it should only match if there is a space followed by a single letter. But then it wouldn't rename track names like"Vo 1b", right? I think I could live with that.
Christian Scheuer @chrscheuer2018-10-03 08:48:08.844Z
@Oli_Em try this:
sf.ui.proTools.selectedTrack.trackRename({ renameFunction: function (name) { var letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; //This function gets called after the Rename track dialog is open //the argument 'name' holds the existing name, eg. "Audio B.dup1" //We're supposed to eventually return the target name we want from this function. var grps = name.match(/^(.*)( )([a-zA-Z])(\.dup.*|)$/); //This regular expression matches a string containing of the following groups (each group is in parentheses) //Group 1 - syntax: (.*) - meaning: Match any number (*) of any characters (.) This will match "Audio" //Group 2 - syntax: ( ) - meaning: Match 1 space character //Group 3 - syntax: ([a-zA-Z]) - meaning: Match 1 character that is a letter. This will match "B" //After last group- syntax: \.dup.* - meaning: Match a dot (\.), the text "dup", and then ANY character (.), any number of times (*) //Save out the groups, baseName, space, numName var baseName, space, numName; if (grps) { baseName = grps[1]; space = grps[2]; numName = grps[3]; } else { //It didn't match our format. Try again without the requirement of a suffix if (name.indexOf('.dup') >= 0) baseName = name.substring(0, name.indexOf('.dup')); //Get the base name before any .dup else baseName = name; space = " "; //default space numName = ""; } //If you didn't have a number, by default we want a space ' ' before our new #2 track if (numName == "") space = " "; //Create the new number. If there wasn't one, we'll default to 2, if there was one, convert our string to a number, and add 1 to that var newIndex = 1; //Start with 2nd index (1 because indices are always 0-based) if (numName) { var idx = letters.indexOf(numName.toUpperCase()); //Find the index (0-based) if (idx >= 0) { newIndex = idx + 1; //Set to the found index + 1 } //If not found, default to 2nd index (1) which is already set } if (newIndex < 0 || newIndex >= letters.length) throw 'New index out of bounds'; //We reached Z or some other error //Return the new name, a combination of the base name "Audio", a space or not " ", and the new letter return baseName + space + letters[newIndex]; } });
Christian Scheuer @chrscheuer2018-10-03 08:49:39.290Z
And if you try this instead (2nd version) it might help with the 1B -> 1C case:
sf.ui.proTools.selectedTrack.trackRename({ renameFunction: function (name) { var letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; //This function gets called after the Rename track dialog is open //the argument 'name' holds the existing name, eg. "Audio B.dup1" //We're supposed to eventually return the target name we want from this function. var grps = name.match(/^(.*)([ \d])([a-zA-Z])(\.dup.*|)$/); //This regular expression matches a string containing of the following groups (each group is in parentheses) //Group 1 - syntax: (.*) - meaning: Match any number (*) of any characters (.) This will match "Audio" //Group 2 - syntax: ( ) - meaning: Match 1 space character //Group 3 - syntax: ([a-zA-Z]) - meaning: Match 1 character that is a letter. This will match "B" //After last group- syntax: \.dup.* - meaning: Match a dot (\.), the text "dup", and then ANY character (.), any number of times (*) //Save out the groups, baseName, space, numName var baseName, space, numName; if (grps) { baseName = grps[1]; space = grps[2]; numName = grps[3]; } else { //It didn't match our format. Try again without the requirement of a suffix if (name.indexOf('.dup') >= 0) baseName = name.substring(0, name.indexOf('.dup')); //Get the base name before any .dup else baseName = name; space = " "; //default space numName = ""; } //If you didn't have a number, by default we want a space ' ' before our new #2 track if (numName == "") space = " "; //Create the new number. If there wasn't one, we'll default to 2, if there was one, convert our string to a number, and add 1 to that var newIndex = 1; //Start with 2nd index (1 because indices are always 0-based) if (numName) { var idx = letters.indexOf(numName.toUpperCase()); //Find the index (0-based) if (idx >= 0) { newIndex = idx + 1; //Set to the found index + 1 } //If not found, default to 2nd index (1) which is already set } if (newIndex < 0 || newIndex >= letters.length) throw 'New index out of bounds'; //We reached Z or some other error //Return the new name, a combination of the base name "Audio", a space or not " ", and the new letter return baseName + space + letters[newIndex]; } });
- ?@anon6770933309
Excellent! Thx so much. 😀
I cannot see a difference in the performance of the 2 versions though. I see the code differences but they both handle the 1B -> 1C cases just fine.Christian Scheuer @chrscheuer2018-10-03 09:10:57.141Z
Oh cool, but nice that it works!
The second version considers a digit a valid "space" before the last character so it should take a different code path.
I don't remember what didn't work for me in the 1st version though :/- ?@anon6770933309
I see the difference now, a track named “Vo 1b” (exactly like this with no space before lowercase letter b) becomes “Vo 1b B” while the 2nd one renames it to “Vo 1C”, thus better. 😉
Christian Scheuer @chrscheuer2018-10-03 09:27:12.216Z
Nice. Also try this version. It will use a lowercase letter if your original letter was also lowercase.
sf.ui.proTools.selectedTrack.trackRename({ renameFunction: function (name) { var letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; //This function gets called after the Rename track dialog is open //the argument 'name' holds the existing name, eg. "Audio B.dup1" //We're supposed to eventually return the target name we want from this function. var grps = name.match(/^(.*)([ \d])([a-zA-Z])(\.dup.*|)$/); //This regular expression matches a string containing of the following groups (each group is in parentheses) //Group 1 - syntax: (.*) - meaning: Match any number (*) of any characters (.) This will match "Audio" //Group 2 - syntax: ( ) - meaning: Match 1 space character //Group 3 - syntax: ([a-zA-Z]) - meaning: Match 1 character that is a letter. This will match "B" //After last group- syntax: \.dup.* - meaning: Match a dot (\.), the text "dup", and then ANY character (.), any number of times (*) //Save out the groups, baseName, space, numName var baseName, space, numName; if (grps) { baseName = grps[1]; space = grps[2]; numName = grps[3]; } else { //It didn't match our format. Try again without the requirement of a suffix if (name.indexOf('.dup') >= 0) baseName = name.substring(0, name.indexOf('.dup')); //Get the base name before any .dup else baseName = name; space = " "; //default space numName = ""; } //If you didn't have a number, by default we want a space ' ' before our new #2 track if (numName == "") space = " "; //Create the new number. If there wasn't one, we'll default to 2, if there was one, convert our string to a number, and add 1 to that var newIndex = 1; //Start with 2nd index (1 because indices are always 0-based) if (numName) { var idx = letters.indexOf(numName.toUpperCase()); //Find the index (0-based) if (idx >= 0) { newIndex = idx + 1; //Set to the found index + 1 } //If not found, default to 2nd index (1) which is already set } if (newIndex < 0 || newIndex >= letters.length) throw 'New index out of bounds'; //We reached Z or some other error var letter = letters[newIndex]; if (numName && numName.toLowerCase() === numName) letter = letter.toLowerCase(); //Make letter lowercase if the input was lowercase //Return the new name, a combination of the base name "Audio", a space or not " ", and the new letter return baseName + space + letter; } });
- ?@anon6770933309
Very cool. 👍
- In reply toanon6770933309⬆:
Christian Scheuer @chrscheuer2018-07-30 14:32:24.328Z
This has been fixed now in internal build.
Christian Scheuer @chrscheuer2018-07-30 15:18:47.301Z
This build is out now:
https://forum.soundflow.org/-234/200-beta310
- In reply tochrscheuer⬆:Christian Scheuer @chrscheuer2018-07-29 17:25:22.281Z
Commented version of the rename action:
//Rename the selected track - use the renameFunction so we can rename based on the current name //Since we just made a duplicate, the current track will be called something like "Audio 4.dup1" sf.ui.proTools.selectedTrack.trackRename({ renameFunction: function (name) { //This function gets called after the Rename track dialog is open //the argument 'name' holds the existing name, eg. "Audio 4.dup1" //We're supposed to eventually return the target name we want from this function. //This regular expression matches a string containing of the following groups (each group is in parentheses) //Group 1 - syntax: ([^\d]*) - meaning: Match any number (*) of characters that are NOT digits ([^\d]). This will match "Audio " //Group 2 - syntax: (\d*) - meaning: Match any number (*) of characters that are digits (\d). This will match "4". //After last group- syntax: \.dup.* - meaning: Match a dot (\.), the text "dup", and then ANY character (.), any number of times (*) var grps = name.match(/^([^\d]*)(\d*)\.dup.*/);; //The groups will be accessible in grps[1] for group 1, grps[2] for group 2, etc. //Save the baseName - "Audio " var baseName = grps[1]; //If group 2 (the existing number) is empty (Maybe we didn't use "Audio 4.dup1" but a track like "Guitar.dup1"), then set the number to 1 (so that when we increase, we will make "Guitar 2"). If it DID have a number, eg. "4" for "Audio 4", then save the "4" as a number. var num = grps[2] == "" ? 1 : Number(grps[2]); //Make a complete string based on the base name ("Audio ") plus the number "4", increased by 1, ("5"). We're converting the number to a string by appending the empty string and putting that in a parenthesis to make sure the conversion goes fine. //By returning the new name, we tell SF that this is the name we would like it to rename the track to. return baseName + ((num + 1) + ''); } });
- ?@anon6770933309
This is great, thank you! 👍
- In reply tochrscheuer⬆:JJascha Viehl @Jascha_Viehl
Hi,
is there any chance anyone could modify this handy script to work for the duplication of multiple tracks?
Christian Scheuer @chrscheuer2020-11-11 08:30:02.754Z
Hi Jascha.
It's best to start a new thread and link to this one as this one is already marked as solved. We prioritize resources towards unsolved threads :)
- In reply tochrscheuer⬆:Jesper Ankarfeldt @JesperA2018-07-29 23:02:33.614Z
Here's a similar function for Cubase: https://gist.github.com/ankarfeldt/1c15d6f1385622b6e08752ef509494b3