No internet connection
  1. Home
  2. How to

Dream Automation for Pro Tools: Split Clips On Track by Name to Multiple Tracks

By Jeremiah Moore @Jeremiah_Moore
    2021-04-28 05:07:41.658Z

    I have a dream automation I’d like to see... and maybe it’s possible:

    Step through a track and move the clips on it to multiple other tracks based first N characters of clip name.

    i.e. if N=4, all clips starting "ANDY" would end up on a track called "ANDY" and all clips starting "a50Q" would end up on a "a50Q" track.

    My immediate use case is splitting dialogue to character tracks for podcasts or videos.

    Not sure how to cope with crossfades, which are best kept intact.

    Quite similar to How to sort clip name and checkerboard on defined tracks
    Except the intent here is to create a new track per clip name.

    tagging: @sbiss

    • 33 replies

    There are 33 replies. Estimated reading time: 45 minutes

    1. J
      Jeremiah Moore @Jeremiah_Moore
        2021-04-28 05:22:17.154Z

        To elaborate:

        Very often, editors string out clips onto a minimum of tracks while building a show, but sound mixers need to separate out those clips by how they sound, to most efficiently edit and mix them.

        On these kinds of projects, the first step I take is separating dialogue to checkerboarded tracks, or to character tracks, and it's fairly common that related clips have related names, hence the idea for this automation.

        Just today I spent about 40 minutes laying out all the clips onto character tracks for a podcast program. If I could've automated that split (then manually collapsed the tracks to a more manageble number for mix) it would've saved me 30 or 35 minutes, and it's something that could absolutely be done programmatically.

        The big challenge is: This material often comes in with valuable crossfades between clips. In the event there are crossfades, selections would need to be extended to encompass head and tail fades, and appropriate commands issued to preserve full duration of those fades when clips were moved to other tracks. (Drag works but clipboard may not.)

        If crossfades are not plausible to include, it's not necessarily a dealbreaker.

        Some pseudocode For instance, and I'm presuming what soundflow can do:

        • read names of all clips in selection into an array
        • truncate the array to N quantity of characters
        • process the array to eliminate any duplicates
        • create a set of tracks for each entry in the processed array
        • select first clip and read name. Move clip to matching-named track.

        remarks:

        • these steps could iteratively create tracks during the process instead of creating them first.

        • obviously would need to do some preliminary "if" branches if fades are to be detected and preserved.

        1. samuel henriques @samuel_henriques
            2021-04-28 23:45:30.238Z

            hello @Jeremiah_Moore,

            I'm working on something but still needs a bit work.

            At this time it would preserve fades, but does't work if fades are present on the start of the clip.

            And you need to place a clip or clip group at the end otherwise he keeps selecting forever. One lonely clip at the end sorts it for now.

            Test it and let me know.

            Here's a video:
            https://we.tl/t-yeA9nUbJK6

            Here's the code:

            
            
            function onlyUnique(value, index, self) {
                return self.indexOf(value) === index;
            }
            
            function goToStartOfSession() {
                sf.ui.proTools.transportEnsureCluster();
            
                const trannsportCluster = sf.ui.proTools.mainWindow.transportViewCluster;
                const transportButtons = trannsportCluster.groups.whoseTitle.is("Normal Transport Buttons").first;
                transportButtons.buttons.whoseTitle.is("Return to Zero").first.elementClick();
            }
            
            function createNewTrack(newTrackName) {
            
                sf.ui.proTools.menuClick({ menuPath: ["Track", "New..."] });
            
                const newTrackWin = sf.ui.proTools.windows.whoseTitle.is("New Tracks")
            
                newTrackWin.first.elementWaitFor({ waitType: "Appear" });
            
                newTrackWin.first.textFields.allItems[1].elementSetTextFieldWithAreaValue({
                    value: newTrackName,
                });
            
                newTrackWin.first.buttons.whoseTitle.is("Create").first.elementClick();
            
                newTrackWin.first.elementWaitFor({ waitType: "Disappear" });
            
            }
            
            function getClipNames() {
                let selectedClips = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first.children.whoseRole.is("AXRow").allItems.map(row =>
                    row.children[1].children.first.value.value).filter(c => c.startsWith('Selected. ')).map(l =>
                        l.split("\n")[1]).map(n => n
                            .replace(/["\"]/g, '').trim().slice(0, 4))
                return selectedClips
            }
            
            function findTrackNameAndPaste(selectedClipsNames, processTrack) {
            
                const trackByName = sf.ui.proTools.trackGetByName({ name: selectedClipsNames })
            
                if (trackByName.track == null) {
            
                    createNewTrack(selectedClipsNames)
                    sf.ui.proTools.invalidate()
            
                    sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"] });
            
                } else {
            
                    trackByName.track.trackScrollToView()
            
                    sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"] });
                }
            
                sf.ui.proTools.trackSelectByName({ names: processTrack })
            }
            
            function main(processTrack) {
            
                goToStartOfSession()
            
                // one tab and select first clip
                sf.keyboard.press({ keys: "tab" });
                sf.keyboard.press({ keys: "shift+tab" })
            
            
                let selectedClipsNames
                let selectedArray = []
                while (true) {
            
                    selectedClipsNames = getClipNames()
            
                    selectedArray.push(selectedClipsNames[0])
            
                    if (selectedClipsNames.filter(onlyUnique).length == 1 || selectedClipsNames.length < 1) {
            
                        sf.keyboard.press({ keys: "shift+tab" });
            
                    } else {
            
                        sf.ui.proTools.menuClick({ menuPath: ["Edit", "Restore Last Selection"] });
            
                        sf.ui.proTools.menuClick({ menuPath: ["Edit", "Cut"] });
            
                        findTrackNameAndPaste(selectedArray[0], processTrack)
                        break;
                    }
            
                    //  Need this wait to update selection, otherwise, 'restore last selection' won't work
                    sf.wait({ intervalMs: 1000 })
                }
                //  }
            
            
            
            }
            
            
            function selectedClipCount() {
                const clipsTable = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first;
                const selectedClipCount = clipsTable.getElements("AXSelectedRows").allItems.length;
                return selectedClipCount
            
            }
            
            
            
            ////////////////    MAIN    ///////////////
            
            sf.ui.proTools.appActivateMainWindow()
            
            const processTrack = sf.ui.proTools.selectedTrackNames
            
            //sf.ui.proTools.menuClick({ menuPath: ["Edit", "Select All"] });
            
            while (true){
            //for (let i = 0; i < getClipNames().filter(onlyUnique).length; i++) {
            
            
                sf.ui.proTools.invalidate()
            
                sf.ui.proTools.menuClick({ menuPath: ["Edit", "Select All"] });
            
                let selectedClipsNames = getClipNames()
            
                const trackHasClips = sf.ui.proTools.selectionGetInfo().hasFullClip
            
                if (selectedClipCount() == 1) {
                    sf.ui.proTools.menuClick({ menuPath: ["Edit", "Cut"] });
                    findTrackNameAndPaste(selectedClipsNames[0], processTrack)
            
                } else if (trackHasClips && selectedClipCount() > 1) {
            
                    main(processTrack)
            
                } else {
            
                    goToStartOfSession()
                    log("Track is Empty")
                    break
                }
            }
            
            
            1. samuel henriques @samuel_henriques
                2021-04-29 10:21:36.710Z2022-07-10 18:55:57.272Z

                UPDATE:

                • Sorted last clip on track.
                • Fades look sorted
                • Much faster. By removing the "Restore Last Selection", the wait is not needed.
                • Mono and Stereo tracks
                • will process all selected tracks

                Let me know how it goes, so I can clean it a bit and figure some error checking.

                /**
                 * @param {array} path -  path menu path
                 */
                function clipListEnableMenu(path) {
                    sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                        menuPath: path, targetValue: "Enable",
                    });
                    sf.ui.proTools.appActivateMainWindow();
                };
                
                //    Enable menus from "clipListMenuItems" that are not yet enabled
                function clipListEnableSubmenu({ menu, subMenu }) {
                    sf.ui.proTools.menuClick({ menuPath: ["View", "Other Displays", "Clip List"], targetValue: "Enable" });
                
                    clipListEnableMenu(["Clear Find"])
                    const menuCheckedInShowMenu = sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuFetchAllItems().menuItems.filter(x =>
                        !x.element.isMenuChecked && //  Not MenuChecked
                        x.path[0] == menu).map(x => x.path[1]) // submenu item name
                    sf.ui.proTools.appActivateMainWindow()
                
                    // Get unchecked from "clipListMenuItemsShow list and create path
                    let menuToCheck = menuCheckedInShowMenu.filter(x => subMenu.includes(x)).map(x => [menu, x])
                    menuToCheck.forEach(clipListEnableMenu)
                }
                
                
                function onlyUnique(value, index, self) {
                    return self.indexOf(value) === index;
                }
                
                function goToStartOfSession() {
                    sf.ui.proTools.transportEnsureCluster();
                
                    const trannsportCluster = sf.ui.proTools.mainWindow.transportViewCluster;
                    const transportButtons = trannsportCluster.groups.whoseTitle.is("Normal Transport Buttons").first;
                    transportButtons.buttons.whoseTitle.is("Return to Zero").first.elementClick();
                }
                
                function selectedClipCount() {
                    const clipsTable = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first;
                    const selectedClipCount = clipsTable.getElements("AXSelectedRows").allItems.length;
                    return selectedClipCount
                
                }
                
                function askNumberChar() {
                    const chNumber = sf.interaction.displayDialog({
                        prompt: "Choose Number of Characters.",
                        defaultAnswer: "4" // Default number of characters here
                    }).text.match(/\d+/g)
                    return +chNumber
                }
                
                
                function duplicateSelectedTrack({ duplicateActivePlaylist: targetValue }) {
                    sf.ui.proTools.trackDuplicateSelected({
                        duplicateActivePlaylist: targetValue,
                        duplicateAlternatePlaylists: false,
                        duplicateAutomation: false,
                        duplicateInserts: false,
                        duplicateSends: false,
                        duplicateGroupAssignments: false,
                        insertAfterLastSelectedTrack: true,
                        onError: "ThrowError"
                    });
                }
                
                
                function timeCounter() {
                
                    // get current counter
                    const mainCounter = sf.ui.proTools.getCurrentTimecode().stringValue
                    let originalTimeCounter
                
                    /// Bars Beats .  
                    if (mainCounter.includes("|")) originalTimeCounter = "Bars|Beats"
                    //  Min Secs .    
                    else if (mainCounter.includes(":") && mainCounter.includes(".")) originalTimeCounter = "Min:Secs"
                    //  Time code
                    else if (mainCounter.split(":").length == 4) originalTimeCounter = "Timecode"
                    //  Feet+Frames
                    else if (mainCounter.includes("+")) originalTimeCounter = "Feet+Frames"
                    //  Samples.     
                    else originalTimeCounter = "Samples"
                
                    return originalTimeCounter
                }
                
                
                function getSelectedTrackWidth() {
                    var track = sf.ui.proTools.selectedTrack
                    var width = track.groups.whoseTitle.is('Audio IO').first.sliders.whoseTitle.contains('Pan').count;
                    return width;
                }
                
                
                function createNewTrack(newTrackName) {
                
                    let selectedTrackWidth = getSelectedTrackWidth()
                
                    sf.ui.proTools.menuClick({ menuPath: ["Track", "New..."] });
                
                    const newTrackWin = sf.ui.proTools.windows.whoseTitle.is("New Tracks")
                
                    newTrackWin.first.elementWaitFor({ waitType: "Appear" });
                
                    if (selectedTrackWidth === 2) newTrackWin.first.popupButtons.first.popupMenuSelect({ menuPath: ["Stereo"] });
                
                
                    newTrackWin.first.textFields.allItems[1].elementSetTextFieldWithAreaValue({
                        value: newTrackName,
                    });
                
                    newTrackWin.first.buttons.whoseTitle.is("Create").first.elementClick();
                
                    newTrackWin.first.elementWaitFor({ waitType: "Disappear" });
                
                }
                
                
                function getClipNames(chNumber) {
                    let selectedClips = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first.children.whoseRole.is("AXRow").allItems.map(row =>
                        row.children[1].children.first.value.value).filter(c => c.startsWith('Selected. ')).map(l =>
                            l.split("\n")[1]).map(n => n
                                .replace(/["\"]/g, '').trim().slice(0, chNumber))// Number of Characters to Grab
                    return selectedClips
                }
                
                
                function findTrackNameAndPaste(selectedClipsNames, processTrack) {
                
                    const trackByName = sf.ui.proTools.trackGetByName({ name: selectedClipsNames })
                
                
                    if (trackByName.track == null) {
                
                        createNewTrack(selectedClipsNames)
                        sf.ui.proTools.invalidate()
                
                        sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"] });
                
                    } else if (trackByName.track != null) {
                
                        trackByName.track.trackSelect()
                
                        //  Reset menu
                        sf.keyboard.press({ keys: "left" });
                
                        const selectionHasClip = sf.ui.proTools.getMenuItem("Edit", "Trim Clip").isEnabled
                
                        if (selectionHasClip) {
                            //  Reset menu
                            sf.keyboard.press({ keys: "left" });
                
                            duplicateSelectedTrack({ duplicateActivePlaylist: false })
                            sf.ui.proTools.invalidate()
                
                            sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"] });
                
                        } else {
                
                            sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"] });
                        }
                    }
                    sf.ui.proTools.trackSelectByName({ names: processTrack })
                }
                
                
                function mainProcess(processTrack, originaSelectionEndToString, numberOfCharacters, originalSelectionStart) {
                
                    goToStartOfSession()
                
                    // one tab and select first clip
                    sf.keyboard.press({ keys: "tab" });
                    sf.keyboard.press({ keys: "shift+tab" })
                
                    //let selectionInfo
                    let selectedClipsNames
                    let selectedArray = []
                    let selectionEnd
                    let halfCrossFadeDuration
                    while (true) {
                
                        let currentSelectionEndNumber = +sf.ui.proTools.selectionGet().selectionEnd.replace(/[ :\+\|.]/g, '')
                
                        selectedClipsNames = getClipNames(numberOfCharacters)
                
                
                        if (selectedClipsNames[0] != null) {
                            selectedArray.push(selectedClipsNames[0])
                        }
                
                        if (selectedArray.filter(onlyUnique).length <= 1) {
                
                            selectionEnd = sf.ui.proTools.selectionGetInSamples().selectionEnd
                
                            if (sf.ui.proTools.selectionGetInfo().hasCrossFade) {
                
                                halfCrossFadeDuration = +sf.ui.proTools.selectionGetInSamples().selectionLength / 2
                
                                selectionEnd = +sf.ui.proTools.selectionGetInSamples().selectionEnd - halfCrossFadeDuration
                            }
                        }
                
                
                        if (selectedArray.filter(onlyUnique).length <= 1 &&
                            !sf.ui.proTools.selectionGetInfo().hasEndFade &&
                            currentSelectionEndNumber < originaSelectionEndToString) {
                
                            sf.keyboard.press({ keys: "ctrl+tab" });
                
                        } else {
                
                            sf.ui.proTools.selectionSetInSamples({
                                selectionStart: +originalSelectionStart,
                                selectionEnd: +selectionEnd
                            })
                
                            sf.ui.proTools.menuClick({ menuPath: ["Edit", "Cut"] });
                
                            sf.ui.proTools.selectionSetInSamples({
                                selectionStart: +originalSelectionStart,
                                selectionEnd: +selectionEnd
                            })
                
                            findTrackNameAndPaste(selectedArray[0], processTrack)
                            break;
                        }
                        //sf.wait({ intervalMs: 1000 })
                    }
                }
                
                
                
                function main() {
                
                    //  Reset menu
                    sf.keyboard.press({ keys: "left" });
                
                    duplicateSelectedTrack({ duplicateActivePlaylist: true })
                
                    let processTrack = sf.ui.proTools.selectedTrackNames
                
                    sf.ui.proTools.mainCounterSetValue({ targetValue: "Samples" })
                
                    while (true) {
                
                        sf.ui.proTools.invalidate()
                
                        sf.ui.proTools.menuClick({ menuPath: ["Edit", "Select All"] });
                
                        let originaSelectionEndToString = +sf.ui.proTools.selectionGet().selectionEnd.replace(/[ :\+\|.]/g, '')
                
                        let originalSelectionStart = sf.ui.proTools.selectionGet().selectionStart
                
                        let selectedClipsNames = getClipNames(numberOfCharacters)
                
                        if (selectedClipsNames.length >= 1) {
                
                            mainProcess(processTrack, originaSelectionEndToString, numberOfCharacters, originalSelectionStart)
                
                        } else {
                
                            //  goToStartOfSession()
                
                            // Option to delete empy track in the end
                            sf.ui.proTools.menuClick({ menuPath: ["Track", "Delete"] });
                            break
                        }
                    }
                }
                
                
                
                
                
                /////////         MAIN          ///////// 
                /////////         MAIN          ///////// 
                sf.ui.proTools.appActivateMainWindow()
                
                
                // Ask how many characters to grab
                const numberOfCharacters = askNumberChar()
                
                if (numberOfCharacters == 0) {
                    alert("Numbers only, minimum  is 1.")
                }
                
                
                //  List of menus to enable
                clipListEnableSubmenu({
                    menu: "Show",
                    subMenu: [
                        "Audio",
                        "Groups",
                        "Auto-Created",
                    ]
                })
                
                let originalTimeCOunter = timeCounter()
                
                sf.ui.proTools.selectedTrackHeaders.slice().map(track => {
                
                    sf.ui.proTools.invalidate()
                
                    track.trackSelect();
                
                    track.trackScrollToView();
                
                    main()
                });
                
                sf.ui.proTools.mainCounterSetValue({ targetValue: originalTimeCOunter })
                
                alert(`Done!`)
                
            2. J
              In reply toJeremiah_Moore:
              Jeremiah Moore @Jeremiah_Moore
                2021-04-30 01:25:22.403Z

                Nice! Finally had a moment to try.
                I'm immediately hitting errors...

                What I did:

                • I pasted your script into a new soundflow script, named it "Split Track Clips by Name to Multiple Tracks v1"
                • and assigned to a streamdeck button (using streamdeck app.)

                Looks like a select-all took place, the first clip disappeared, and the script hung on a "create new tracks" dialogue.

                logs:
                https://www.dropbox.com/s/zansc06ulurnfha/210428_1822h-Soundflow-Log.txt?dl=0

                1. J
                  In reply toJeremiah_Moore:
                  Jeremiah Moore @Jeremiah_Moore
                    2021-04-30 01:42:15.163Z

                    Actually I think this beta report was made with the first iteration of the script... it pasted to 148 lines, whereas the recent iteration comes to 190 lines. (I added some top comments, where the script is from etc)

                    I cannot be sure things are working correctly. When I paste the script I get a warning "You're Currently Offline" ... which is not the case in terms of my internet connection, and soundflow

                    I'm about out of time for the moment but will try again after a reboot, probably tomorrow.

                    -jeremiah

                    1. samuel henriques @samuel_henriques
                        2021-04-30 05:16:23.420Z

                        Would you be able to do a video of the behaviour, and show me an example of the file names you are working with?
                        Thank you

                        1. samuel henriques @samuel_henriques
                            2021-04-30 05:17:28.165Z2021-04-30 05:59:03.372Z

                            You should use this second script.

                            Are you using one mono track?

                            I forgot to code show auto-created regions, I'll add it, but could you enable that and see if it helps?

                            1. samuel henriques @samuel_henriques
                                2021-04-30 07:40:24.225Z

                                UPDATED: with setting view of clip list view

                                1. JJeremiah Moore @Jeremiah_Moore
                                    2021-04-30 07:54:59.796Z

                                    Nice! I will try it in the morning here (pacific time / california) and I'll record a video if I can.

                                    to answer:

                                    • I was using a stereo track, within a session with a mix of stereo and mono tracks.
                                    1. samuel henriques @samuel_henriques
                                        2021-04-30 08:09:14.626Z

                                        yea... so, at this time it works with one mono track. Next step would be to know if track is stereo and create/move to stereo track. And when organising many tracks not to paste over existing clips( just as the script you mentioned).

                                        So lets test with one mono track to figure some mistakes and the naming rules,

                                        Just select the track you want to process and run the script.

                                        1. JJeremiah Moore @Jeremiah_Moore
                                            2021-04-30 17:40:28.978Z

                                            OK! I tested it twice, with different results.

                                            Test 1:

                                            • in a big session w/ many tracks of mixed types, I placed clips I wanted to work with on a mono track, and ran the script. Immediate error.

                                            Test 2:

                                            • made a session with one mono track only, with the same clips on it.

                                            video captures:
                                            https://jeremiahmooresound.filemail.com/d/hjeqajivykbnxii

                                            session document from test 2, with no media:
                                            https://jeremiahmooresound.filemail.com/d/ncqlecsvlqbzhbb

                                            Notes:

                                            • Ideally, the user could set the number of characters the script is scanning from the head of each clip name. Presumably this can be done by editing the script, but at quick glance I did not see where!
                                            1. samuel henriques @samuel_henriques
                                                2021-04-30 19:39:05.665Z

                                                Hello @Jeremiah_Moore,

                                                Form the first try:

                                                The error, "could not open popup menu" is because you are covering the clip list popup with the colour palette. If I cover mine the same way as you, I have the same error.

                                                On the second attempt, the popup button is free, so the script continues.

                                                About the fades, that's what I meant on the script post, I don'y know yet how to fix.
                                                The Script selects the next clip on the track, pro tools selects fades as clips, but doesn't display them anywhere, so I can't read there is a fade selected. And there is a way soundFlow reads info from selection, but in this case, there is no rule I can script to fix this.
                                                So, the script will select the next clip, using shift+Tab and read the clip name, once it detects a different name, it will make a selection, from last lime the script memorised all names were the same.
                                                Doing so, the last time it happened, was all the clips with one name, + silence + the fade.
                                                Then cut, select track by the clip name, and paste.

                                                When I have a bit, I will add to the script:

                                                • A popup asking the number of characters. At this time it's set at 4.
                                                  you can edit it here:
                                                function getClipNames() {
                                                    let selectedClips = sf.ui.proTools.mainWindow.tables.whoseTitle.is('CLIPS').first.children.whoseRole.is("AXRow").allItems.map(row =>
                                                        row.children[1].children.first.value.value).filter(c => c.startsWith('Selected. ')).map(l =>
                                                            l.split("\n")[1]).map(n => n
                                                                .replace(/["\"]/g, '').trim().slice(0, 4))// Number of Characters to Grab
                                                    return selectedClips
                                                }
                                                
                                                
                                                • Duplicate original track, so you can have the original intact.
                                                • If its a stereo track, create a stereo track to move to. I'm not sure if I'll encounter some issues to make it difficult, but I'll try

                                                Let's keep it as a track by track for now. And then work on a way to do it to all selected tracks.

                                                1. JJeremiah Moore @Jeremiah_Moore
                                                    2021-04-30 23:01:15.763Z

                                                    Fantastic... yes, I tried again on my large session, with the color window in a different place and it worked! On a single mono track.

                                                    It performed MUCH more slowly - perhaps due to the resource intensiveness of the large mix session loaded.

                                                    I also tried:

                                                    • removed all fades first using menu / Edit / Fades / Delete, and the output was clean.
                                                    • tried a version w/ crossfades between characters, and the output did not leave fragments as before, but did remove fade-ins where crossfades once were.

                                                    See video of this second test case: https://jeremiahmooresound.filemail.com/d/qpjwdwuegxdzrea

                                                    It would indeed be very useful to work across tracks with more than one channel, whether stereo or more.

                                                    It would be nice also to discover a way (if possible!) to preserve xfades between characters.

                                                    It might be nice to have the script dupe the worktrack at the start of it's run, then delete the empty track after running.

                                                    It would be nice to end more cleanly, perhaps return the insertion point to the last moved clip.

                                                    Brilliant! this is already quite useful.

                                                    1. samuel henriques @samuel_henriques
                                                        2021-04-30 23:25:53.975Z

                                                        Cool, so all the behaviour looks correct.
                                                        As for the speed, it's not good at all, even for a large session, unless you have many thousands of files in the clip list, I don't think it would get this slow. I'll try some stuff. You can try quit and restart SoundFlow or check if there is anything using your ram took much.

                                                        I'll finish the bits I spoke about and delete the original clean track as well.

                                                        As for the fades, they work as pro tools works. If you figure a better way let me know. I'll think about it as well.

                                                        1. JJeremiah Moore @Jeremiah_Moore
                                                            2021-04-30 23:38:45.846Z

                                                            Yes I've got a million apps open and probably fifty browser tabs - activity monitor reports currently about 25gb used out of 32.

                                                            I can do a few more test rounds Monday, likely -

                                                            1. samuel henriques @samuel_henriques
                                                                2021-05-01 08:34:55.773Z2021-05-01 22:35:37.465Z

                                                                So, I updated the script above with the bits we spoke about.

                                                                ``" I'm thinking the script should use "Find.." the chosen name, and "select object in edit window" this would make it a much better concept, fix the starting fades problem, but it would not fix cases where there is a crossfade between different names. In that case the first selected name + the clip it crossfades too would be moved together.`"

                                                                ` EDIT: was wrong about this idea

                                                                Another thing I think would be good is to define the clip name in a better way.

                                                                On the ptx you sent, clip names for characters separate the character names from other info with a ":"

                                                                so from "CATHERINE: IT'S NOT AN ENTIRE BUILDING-02"

                                                                we can trim it to be "CATHERINE". This makes more sense if it is a rule that character names have a symbol, separating to the rest of info.
                                                                Only in the cases this doesn't exist like "Mabel Wilson interview-109"
                                                                we can use a defined number of characters at the start of the script.(this is on the new version I just updated)

                                                                And I'm thinking I would be a good idea to run the script on a new session only for this, Not specifically because of the speed problem you encountered yesterday, but you never know, in a really large session if something goes wrong, its much harder to figure out.

                                                                Also, with the new script, it would be much easier to program to work on all selected tracks, and would process them one at a time.

                                                                I'll need a few days to put this together, and I'm not so free thru the weekend. But Let me know if this makes sense.

                                                                1. samuel henriques @samuel_henriques
                                                                    2021-05-01 11:08:32.091Z

                                                                    UPDATE:
                                                                    So still in the same script concept, I manages to fix the fades issue.
                                                                    Still needs a bit testing, witch I'll leave to you.
                                                                    Then I'll figure out working with any width track and do it for all selected tracks at once.

                                                                    1. samuel henriques @samuel_henriques
                                                                        2021-05-01 22:30:42.472Z

                                                                        UPDATE: just updated above, I will work for all selected tracks and do the process one at a time.

                                                                        Not sure if there is better solution for the fades thing.

                                                                        Start bu testing only one track at a time to figure some unintended behaviour and then go to all tracks.

                                                                        It works with mono or stereo tracks.

                                                                        1. DDJH @DJH
                                                                            2022-02-15 07:11:05.479Z

                                                                            Hey Samuel, I'm came looking for exactly this type of script and would love to give it a whirl. Is the one of the scripts above the most up-to-date version?

                                                                            1. samuel henriques @samuel_henriques
                                                                                2022-02-15 10:11:06.811Z

                                                                                Hello @DJ_Hofer,

                                                                                I don't actually use this script myself, I built it as a request from the forum, so I don't have any more updates. But if you find something you would like to improve, let me know and I'll see what I can do.

                                                  • In reply toJeremiah_Moore:
                                                    Trip Brock @Trip_Brock
                                                      2022-07-09 00:46:31.292Z

                                                      Hey Samuel, hope your week is going well! This is the 2nd random really cool script of yours I've come across this week that could be really useful - thanks again for all the ideas. I've tested the latest version of the script in this thread (above) exactly as-is and runs perfectly under PT 2021.12, but for some reason throws an error on line 15 in when running protools 2022.5 Any chance you can see what may be going on here? Below is thew firast part of your script from above as wqell as the error message that it throws while running PT 2022.5 Any help would be much appreciated!

                                                      1. samuel henriques @samuel_henriques
                                                          2022-07-10 11:51:11.530Z

                                                          Hello Trip,
                                                          Just tried and works well on my 2022.5.
                                                          I found that sometime Pro Tools is not sharing information correctly with SF so I restart Pro Tools and it works fine again.
                                                          Can you confirm de clip list popup is not covered in any way?

                                                          Let me know if it still giving problems and make a screen recording so I try to find any more info.

                                                          1. Trip Brock @Trip_Brock
                                                              2022-07-10 18:20:49.398Z

                                                              Hi Samuel, thank you for the update. I did the PT restart and made sure nothing was covering the popup, but still same issue when using PT 2022.5. Here's a quick screen record. Thank you for all your help it is much appreciated!

                                                              Here's a link to the quick screen record:
                                                              https://monkeylandftp.com/_UNaZUIFlME1ApR

                                                              1. samuel henriques @samuel_henriques
                                                                  2022-07-10 18:58:01.901Z

                                                                  Hello Trip,
                                                                  Updated above a fix that is working for me. I noticed earlier, but completely forgot this could be the problem.
                                                                  Updated this thread: Dream Automation for Pro Tools: Split Clips On Track by Name to Multiple Tracks #post-4

                                                                  let me know if this is it.

                                                                  1. Trip Brock @Trip_Brock
                                                                      2022-07-10 20:53:03.112Z

                                                                      Hey Samuel, whatever you just did fixed it for me - you are the best, thank you!

                                                              2. In reply toJeremiah_Moore:
                                                                Daniel Perez @daniel_perez
                                                                  2022-08-11 18:46:27.070Z

                                                                  @samuel_henriques

                                                                  hey samuel,

                                                                  can i somehow object select all clips with a certain channel name for example A3 or boom? i want to clean up AAFs faster by removing everything i dont need for the field recorder expand. so only keep MixL for example in the session/selection/certain tracks or whatever.

                                                                  1. samuel henriques @samuel_henriques
                                                                      2022-08-18 19:08:29.816Z

                                                                      If you know how to do it without a script, could you post the steps you do, please?
                                                                      I'll take a look how to script it what I have a bit.

                                                                      1. Daniel Perez @daniel_perez
                                                                          2022-08-18 19:41:08.187Z

                                                                          unfortunately it's not possible inside pro tools on it's own, as you can't search for channel names or A1-10 in the search field. we would need a custom soundflow search field, which already exists in other posts. pt won't let you search by channel name, only by clip name.

                                                                          1. samuel henriques @samuel_henriques
                                                                              2022-08-18 22:51:08.121Z

                                                                              At least I couldn't find a way within pro tools.
                                                                              But I found a way with soundFlow.
                                                                              This could use some work but does something already. And it takes a moment because it has to read all clip list.
                                                                              If this works for you I'll think of a way to improve it.
                                                                              Make sure the Clip List is open.
                                                                              Make sure the Show Channel Name is enabled, so you ( and Sound Flow) can read it.
                                                                              Make sure the multiple channel clips are expanded (alt + click the little triangle to the left of the clip name).
                                                                              In this line const channelName = "LAP4 BOOM" you can change the channel name you want to object select its clips.

                                                                              then run this, hope it helps.

                                                                              
                                                                              function objectSelectAllWithChannelName(channelName) {
                                                                              
                                                                                  const clipList = sf.ui.proTools.mainWindow.invalidate().clipListView.children.whoseRole.is("AXRow").map(clip => clip.children.whoseRole.is("AXCell").allItems[1].children.whoseRole.is("AXStaticText").first)
                                                                              
                                                                                  let chanelNameClips = clipList.filter(clip => clip.title.invalidate().value.includes(channelName))
                                                                              
                                                                                  chanelNameClips.forEach(el => el.elementClick());
                                                                              
                                                                                  chanelNameClips[0].popupMenuSelect({
                                                                                      isRightClick: true,
                                                                                      menuPath: ["Object Select in Edit Window"]
                                                                                  });
                                                                              };
                                                                              
                                                                              
                                                                              
                                                                              // Channel name 
                                                                              const channelName = "BOOM"
                                                                              
                                                                              
                                                                              objectSelectAllWithChannelName(`(${channelName})`)
                                                                              
                                                                              1. Hey @samuel_henriques thanks for the script. However, it didnt work for me... It gives me an error:

                                                                                "TypeError: Cannot read property 'popupMenuSelect' of undefined
                                                                                (Split Clips On Track by Channel Name (samuel henriques) line 10) "

                                                                                Can you help and recommend me what I should try? Ive got a PT 2023.3 on macos 12.6.2. I also made sure all the things you mentioned in the post.

                                                                                1. samuel henriques @samuel_henriques
                                                                                    2023-06-19 16:52:45.274Z

                                                                                    Hello Stepan,
                                                                                    Don't remember the specifics of the posted code but this one should work for you.
                                                                                    It will object select all clips that include a string in it's name. In this case we are naming the string channelName, but could be anything

                                                                                    function objectSelectAllWithChannelName(channelName) {
                                                                                    
                                                                                        const clipList = sf.ui.proTools.mainWindow.invalidate().clipListView.children.whoseRole.is("AXRow").map(clip => clip.children.whoseRole.is("AXCell").allItems[1].children.whoseRole.is("AXStaticText").first)
                                                                                    
                                                                                        let chanelNameClips = clipList.filter(clip => clip.title.invalidate().value.includes(channelName))
                                                                                    
                                                                                        chanelNameClips.forEach(el => el.elementClick());
                                                                                    
                                                                                        chanelNameClips[0].popupMenuSelect({
                                                                                            isRightClick: true,
                                                                                            menuPath: ["Object Select in Edit Window"]
                                                                                        });
                                                                                    };
                                                                                    
                                                                                    
                                                                                    
                                                                                    // Channel name 
                                                                                    const string = "String here"
                                                                                    
                                                                                    
                                                                                    objectSelectAllWithChannelName(`${string}`)
                                                                                    
                                                                          2. C
                                                                            In reply toJeremiah_Moore:
                                                                            Christopher Cleator @Christopher_Cleator
                                                                              2024-01-27 23:17:28.274Z2024-02-19 01:45:05.450Z

                                                                              Hi all,

                                                                              First off.. I just wanted to thank @samuel_henriques for writing this script. It's fantastic!

                                                                              I just wanted to add something that made it perfect for me as a dialogue editor. The way it is now, it creates a new track for every scene number, which, for a basic 90min MOW, would result in hundreds of tracks. (ie 01A-F thru to 99A-F) What I need to do is just split my Boom tracks by scene angle only, while ignoring the scene number. I did this here:

                                                                              125 .replace(/[""]/g, '').trim().slice(0, chNumber))// Number of Characters to Grab

                                                                              changed to: .replace(/[""]/g, '').trim().slice(2, chNumber))// Number of Characters to Grab

                                                                              Doing this and setting default characters to 3, will result in everything going to tracks: _,A,B,C,D,E etc. through the whole program! (If scenes 1-9 aren't 01-09, you need to batch rename them first) and if your MOV gets into the hundreds, you'd need to change it to "slice(3" and default at 4, or just do those manually.

                                                                              Anyway, hope this helps someone. You've certainly helped me! Cheers.

                                                                              1. JJeremiah Moore @Jeremiah_Moore
                                                                                  2024-01-29 06:55:33.472Z

                                                                                  Super cool. I love this script and it has helped me significantly - so thanks to @samuel_henriques for making it real!

                                                                                  -jeremiah