No internet connection
  1. Home
  2. How to

Separate clip at marker location

By Rostislav Supa @Rostislav_Supa
    2025-11-13 14:25:17.433Z

    Hi there,
    I've been using this come for some time but suddenly it stoped working and I wasn't able to find a solution. It should split the selected audio track at marker locations. It stops with an error at this line -> const memoryLocations = sf.proTools.memoryLocationsFetch();
    Here's the whole code:

    // Stealed code from the forum. It splits the imported audio where the markers are located.
    
    
    function splitAtMemoryLocations() {
        //Activate Pro Tools main window
        sf.ui.proTools.appActivateMainWindow();
    
        //Disable tab to transient
        sf.ui.proTools.menuClick({
            menuPath: ['Options', 'Tab to Transient'],
            targetValue: 'Disable'
        });
    
        //Fetch memory locations
        const memoryLocations = sf.proTools.memoryLocationsFetch();
    
        //Map memory location times to an array.
        const memorylocationArray = memoryLocations.collection['List'].map(ml => ml['MainCounterValue']);
    
        memorylocationArray.forEach(ml => {
            //Set cursor position
            sf.ui.proTools.selectionSet({ mainCounter: ml });
    
            try {
                //Separate clip at cursor
                sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Separate Clip', 'At Selection'], });
    
                //Select previous clip
                sf.keyboard.press({
                    keys: "ctrl+alt+tab",
                });
    
                //Consolidate clip
                sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Consolidate Clip'] });
    
                //Wait for clip to consolidate
                sf.ui.proTools.waitForNoModals();
            } catch (err) {
            }
        });
    
        //Get current cursor position
        const cursorPosition = sf.ui.proTools.selectionGetInSamples();
    
        //Select next clip
        sf.keyboard.press({
            keys: "ctrl+tab",
        });
    
        if (sf.ui.proTools.selectionGetInSamples() !== cursorPosition) {
            //Consolidate clip
            sf.ui.proTools.menuClick({ menuPath: ['Edit', 'Consolidate Clip'] });
        }
    }
    
    //Switch Main Counter to samples for duration of script.
    sf.ui.proTools.mainCounterDoWithValue({
        targetValue: 'Samples',
    
        //Run Script
        action: splitAtMemoryLocations,
    });
    
    • 4 replies
    1. Chris Shaw @Chris_Shaw2025-11-13 18:38:06.227Z2025-11-14 17:44:27.454Z

      sf.proTools.memoryLocationsFetch() has been depreciated with SF 6. Getting markers is much easier and robust using the Pro Tools SDK commands. Additionally, the above script uses keyboard presses which can be unreliable and not recommended whenever possible.


      It looks like your code will separate clips at markers and then consolidate them.

      If you don't want to consolidate the clips just delete everything from line 76 onward (or insert throw 0 at line 75:

      // ============================================
      // Separate and Consolidate Clips at Markers
      // ============================================
      
      // ============================================
      // Functions
      // ============================================
      
      const separateClipAtSelection = () => {
          const separateMenuPath = ['Edit', 'Separate Clip', 'At Selection'];
      
          sf.ui.proTools.menuClick({ 
              menuPath: separateMenuPath 
          });
          sf.waitFor({
              //@ts-ignore
              callback: () => !sf.ui.proTools.getMenuItem(...separateMenuPath).isEnabled
          })
      };
      
      const consolidateClipAtSelection = () => {
          sf.ui.proTools.menuClick({ 
              menuPath: ['Edit', 'Consolidate Clip'] 
          });
          sf.ui.proTools.waitForNoModals();
      };
      
      const setTimelineSelection = (inTime, outTime) => {
          sf.app.proTools.setTimelineSelection({
              inTime: String(inTime),
              outTime: String(outTime)
          });
      };
      
      // ============================================
      // Initialize Pro Tools
      // ============================================
      
      sf.ui.proTools.appActivate();
      sf.ui.proTools.mainWindow.invalidate();
      
      // ============================================
      // Get Selected Tracks
      // ============================================
      
      const tracks = sf.app.proTools.tracks.invalidate().allItems;
      const selectedTracks = tracks.filter(t => t.isSelected);
      const selectedTrackNames = selectedTracks.map(t => t.name);
      
      // ============================================
      // Get and Sort Markers
      // ============================================
      
      const memoryLocations = sf.app.proTools.memoryLocations.invalidate().allItems;
      
      // Filter marker locations (no track assignment) and sort by time
      const markers = memoryLocations
          .filter(ml => ml.trackName == null)
          .sort((a, b) => Number(a.startTimeInSamples) - Number(b.startTimeInSamples));
      
      // ============================================
      // Separate Clips at Markers
      // ============================================
      
      markers.forEach((m, index, markers) => {
          // Split clip at every other pair of markers
          // Skip the last marker (no next marker to separate to)
          if (index >= markers.length - 1 || index % 2 == 1) return;
      
          const nextMarkerTime = markers[index + 1].startTimeInSamples;
      
          setTimelineSelection(m.startTimeInSamples, nextMarkerTime);
          separateClipAtSelection();
      });
      
      // ============================================
      // Consolidate Clips Between Markers
      // ============================================
      
      // Get all clips on selected track
      sf.app.proTools.selectAllClipsOnTrack({ trackName: selectedTrackNames[0] });
      const allClipsSelection = sf.app.proTools.getTimelineSelection();
      
      const firstMarkerTime = Number(markers[0].startTimeInSamples);
      const lastMarkerTime = Number(markers[markers.length - 1].startTimeInSamples);
      const selectionStart = Number(allClipsSelection.inTime);
      const selectionEnd = Number(allClipsSelection.outTime);
      
      // Consolidate first clip if it starts before first marker
      if (firstMarkerTime > selectionStart) {
          setTimelineSelection(selectionStart, firstMarkerTime);
          consolidateClipAtSelection();
      }
      
      // Consolidate clips between markers
      markers.forEach((m, index, markers) => {
          // Skip the last marker (no next marker to consolidate to)
          if (index >= markers.length - 1) return;
      
          const nextMarkerTime = markers[index + 1].startTimeInSamples;
      
          setTimelineSelection(m.startTimeInSamples, nextMarkerTime);
          consolidateClipAtSelection();
      });
      
      // Consolidate last clip if it ends after last marker
      if (lastMarkerTime < selectionEnd) {
          setTimelineSelection(lastMarkerTime, selectionEnd);
          consolidateClipAtSelection();
      }
      

      tag: SeparateAndConsolidateClipsBetweenMarkers

      1. UPDATE:
        I refactored the script above to make sure a clip has been separated before moving onto the next pair of markers

        1. UPDATE:
          Refactored again - the first pair of markers were being skipped during separation

      2. R
        In reply toRostislav_Supa:
        Rostislav Supa @Rostislav_Supa
          2025-11-21 12:35:48.713Z

          Thank you, Chris! Works brilliantly. I need to consolidate the clips in order to batch rename them afterwards. It won't let me do that if the clips are not created in the Clips window.