No internet connection
  1. Home
  2. How to

Create new tracks and rename it with soundflow prompt typing manually and selecting words from a predefined lists

By Fukurou Toshima @Fukurou_Toshima
    2021-11-18 12:08:33.459Z

    inspired by this thread below.
    with @raphaelsepulveda

    When tracking vocals or other instruments, I need to create new track quickly.
    But it must also have to been named right to make the editing process to safe and easy.

    Everyone may has its own words and orders of them to use repeatedly when naming or renaming track.

    Then I want SF prompt ask me what the track name is and I want choose both ways to name: typing manually and selecting from the predefined list of words.

    I hardly use numbers for track name and I usually name track as "[instrument] [Section] [Suffix]"

    For instance,

    Chorus A hi
    Chorus A mid
    Chorus A lo
    Harm A
    Harm A+
    Guitar B solo
    Bass C
    Ad-lib A
    Ad-lib B rvb

    So, I need three SF prompt steps asking name.

    1. "instrument" (Lead, Chorus, Guitar, Bass, etc…)
    2. "Section" (alphabets)
    3. "Suffix" (hi, mid, lo, rvb, dly, etc…)

    It will be useful we can choose "None" to type nothing (not even space) 2 and 3 steps.

    Thank you in advance for your support!

    Solved in post #3, click to view
    • 9 replies
    1. Chris Shaw @Chris_Shaw2021-11-18 17:32:46.795Z2021-11-18 19:39:38.307Z

      This should do it.
      Just fill in / add the the names you wish to use in the trackNameItems object.
      When using the script, select "ENTER NAME" to manually enter the item for the track name (you can use the up/down arrow keys on your keyboard) .
      Leave "<NONE>" as the first item in the section and suffix arrays. This acts as the default selection; when you hit enter the script will move to the next name item.

      const trackNameItems = {
          instrument: [
              "ENTER NAME",
              "GTR",
              "Ld Voc",
              "Bass",
              "Keys",
              "Ad-lib"
          ],
          section: [
              "<NONE>",
              "ENTER NAME",
              "A",
              "B",
              "C",
              "D",
              "E",
              "F"
          ],
          suffix: [
              "<NONE>",
              "ENTER NAME",
              "hi",
              "mid",
              "lo",
              "rvb",
              "dly",
          ]
      }
      
      var selectedTrackNameItems = []
      
      // Enter / select track name items
      for (const i in trackNameItems) {
          var selectedNameItem = sf.interaction.popupSearch({
             title: `Select/Search/Enter ${i} name`,
              items: trackNameItems[i].map(item => ({ name: item })),
              onCancel: 'Abort',
          }).item.name;
      
          if (selectedNameItem == "<NONE>") selectedNameItem = "";
      
          if (selectedNameItem == "ENTER NAME") {
              selectedNameItem = sf.interaction.displayDialog({
                  title: `Name ${i}`,
                  prompt: `Enter ${i} name`,
                  defaultAnswer: `<${i}>`,
                  buttons: ["Cancel", "OK"],
                  defaultButton: "OK",
              }).text
          };
          selectedTrackNameItems.push(selectedNameItem)
      };
      
      // Join all selectedTrackNameItems to create newTrackName
      var newTrackName = selectedTrackNameItems.join(" ")
      
      log(newTrackName)
      
      1. FFukurou Toshima @Fukurou_Toshima
          2021-11-24 14:04:50.071Z

          Thank you so much, Chris!
          Your idea of ENTER NAME and is great...
          It save a lot of my time.

        • In reply toFukurou_Toshima:
          Raphael Sepulveda @raphaelsepulveda2021-11-20 02:14:32.940Z2021-11-20 19:31:46.214Z

          Hey @Fukurou_Toshima ! @Chris_Shaw has supplied a great script for putting together the name for the new track! I'll contribute by adding a script to create a new track. Below are both scripts combined to achieve what you're looking for! Let us know how it goes!

          function composeTrackName() {
              const trackNameItems = {
                  instrument: [
                      "ENTER NAME",
                      "GTR",
                      "Ld Voc",
                      "Bass",
                      "Keys",
                      "Ad-lib"
                  ],
                  section: [
                      "<NONE>",
                      "ENTER NAME",
                      "A",
                      "B",
                      "C",
                      "D",
                      "E",
                      "F"
                  ],
                  suffix: [
                      "<NONE>",
                      "ENTER NAME",
                      "hi",
                      "mid",
                      "lo",
                      "rvb",
                      "dly",
                  ]
              }
          
              var selectedTrackNameItems = []
          
              // Enter / select track name items
              for (const i in trackNameItems) {
                  var selectedNameItem = sf.interaction.popupSearch({
                      title: `Select/Search/Enter ${i} name`,
                      items: trackNameItems[i].map(item => ({ name: item })),
                      onCancel: 'Abort',
                  }).item.name;
          
                  if (selectedNameItem == "<NONE>") selectedNameItem = "";
          
                  if (selectedNameItem == "ENTER NAME") {
                      selectedNameItem = sf.interaction.displayDialog({
                          title: `Name ${i}`,
                          prompt: `Enter ${i} name`,
                          defaultAnswer: `<${i}>`,
                          buttons: ["Cancel", "OK"],
                          defaultButton: "OK",
                      }).text
                  };
                  selectedTrackNameItems.push(selectedNameItem)
              };
          
              // Join all selectedTrackNameItems to create newTrackName
              var newTrackName = selectedTrackNameItems.join(" ")
          
              return newTrackName;
          }
          
          /**
           * @param {Object} args
           * @param {'Audio Track' | 'Aux Input' | 'Master Fader' | 'Instrument Track' | 'VCA Master' | 'MIDI Track' } [args.trackType]
           * @param {'Mono' | 'Stereo' } [args.trackFormat]
           * @param {'Samples' | 'Ticks' } [args.timebase]
           * @param {string} [args.trackName]
           */
          function createNewTrack({ trackType = 'Audio Track', trackFormat, timebase, trackName }) {
              const newWin = sf.ui.proTools.windows.whoseTitle.is('New Tracks').first;
              const trackNameTextfield = newWin.textFields.whoseTitle.is('Track Name').first;
              const tickTracks = ['Instrument Track', 'MIDI Track'];
              const tracksWithNoFormat = ['VCA Master', 'MIDI Track'];
              const setTrackType = () => newWin.popupButtons.whoseDescription.is('Track type').first.popupMenuSelect({ menuPath: [trackType] });
              const setTrackFormat = () => newWin.popupButtons.whoseDescription.is('Track format').first.popupMenuSelect({ menuPath: [trackFormat] });
              const setTimebase = () => newWin.popupButtons.whoseDescription.is('Track Timebase').first.popupMenuSelect({ menuPath: [timebase] });
              function setTrackSettings() {
                  trackType !== 'Audio Track' && setTrackType();
                  if (trackFormat && !tracksWithNoFormat.includes(trackType) && trackFormat !== 'Mono') setTrackFormat();
                  if (timebase) {
                      if (tickTracks.includes(trackType) && timebase === 'Samples') setTimebase();
                      if (!tickTracks.includes(trackType) && timebase !== 'Samples') setTimebase();
                  }
              }
          
              function main() {
                  sf.ui.proTools.appActivateMainWindow();
          
                  sf.ui.proTools.menuClick({ menuPath: ['Track', 'New...'] });
                  newWin.elementWaitFor();
          
                  setTrackSettings();
                  trackName && trackNameTextfield.elementSetTextFieldWithAreaValue({ value: trackName });
          
                  newWin.buttons.whoseTitle.is('Create').first.elementClick();
                  newWin.elementWaitFor({ waitType: 'Disappear' });
              }
          
              main();
          }
          
          createNewTrack({
              trackType: 'Audio Track',
              trackName: composeTrackName(),
              trackFormat: 'Mono', // Optional
              timebase: 'Samples' // Optional
          });
          

          Updated! Less code, same fun. Added the rest of the available properties to the function call so that users can see what can be changed. These are optional though!

          Reply2 LikesSolution
          1. Great addition @raphaelsepulveda !

            Just need to to define the rest of the track properties in the last line:

            createNewTrack({
                trackType: 'Audio Track',
                trackFormat: "Stereo",
                timebase:"Samples",
                trackName: composeTrackName()
            });
            
            1. This whole thing could easily be turned into a template.

              1. In reply toChris_Shaw:

                Ahh, I see. If "Audio Track" is the only property passed into createNewTrack(), The new track defaults to mono/samples.
                NIce!

                1. Yeah! The user only needs to specify a property if they want to steer away from the PT default! The function works even if you don't pass any arguments— createNewTrack() creates a new audio track with the PT default settings and the name 'Audio 1'.

                  1. FFukurou Toshima @Fukurou_Toshima
                      2021-11-24 14:22:41.693Z

                      I like that choosability of track type, format and time base.
                      Your scripts are always very helpful!!!

              2. M
                In reply toFukurou_Toshima:
                Matthew Bronleewe @Matthew_Bronleewe
                  2024-02-01 20:43:20.248Z

                  I'm curious if this script could be modified to create several tracks with a numbering system? For example, if I wanted to create 8 mono tracks with a name of my choosing that would be given a number suffix (i.e. Choir A 01, Choir A 02, Choir A 03...) It'd be really cool to additionally be able to pan those tracks hard left/right/left/right/etc and assign their outputs to a routing folder. I'm very new to all this, but I'm trying to cobble together a deck that saves me time!