No internet connection
  1. Home
  2. How to

Master Fader Dim/Undim toggle- help

By Bergatron Music @Bergatron_Music
    2024-09-30 17:43:42.062Z

    Hey SF,
    I'm trying to combine (2) templates onto 1 button. I have a button to "Dim" my master fader by -15 and another button to set it back to unity. I tried creating a template for each of these and throwing them into a Toggle template, but I couldn't get them to work. I've pasted them below. Any help on getting these two things to toggle from one button? Thanks in advance.

    Dim Master -15dB (first) then Set to Unity below

    sf.ui.proTools.trackGetByName({ name: "MASTER", makeVisible: true }).track.trackSelect();
    
    //Calling command "VOLUME -15" from package "PRO TOOLS"
    sf.soundflow.runCommand({
        commandId: 'package:cl6tpnnhc000f9a10b9v2kvgh',
        props: {}
    });
    
    
    
    sf.ui.proTools.trackGetByName({ name: "MASTER", makeVisible: true }).track.trackSelect();
    
    //Calling command "VOLUME 0" from package "PRO TOOLS"
    sf.soundflow.runCommand({
        commandId: 'package:cl6tpnnhc000f9a10b9v2kvgh',
        props: {}
    });
    Solved in post #19, click to view
    • 22 replies

    There are 22 replies. Estimated reading time: 18 minutes

    1. You could use this to determine if the master volume is set to zero or a value below zero and use that to trigger the appropriate command:
      (Note - this script can't tell what value the volume is set at other than 0 or less than zero)

      const masterName = "---Master---";
      
      const masterTrack = sf.ui.proTools.trackGetByName({ name: masterName, makeVisible: true }).track;
      const masterAudioIo = masterTrack.groups.whoseTitle.is("Audio IO").first;
      const masterVolSlider = masterAudioIo.sliders.whoseTitle.is("Volume").first;
      const masterVolValue = Number(masterVolSlider.value.intValue);
      
      if (masterVolValue < 0) {
          
          /// run command that sets volume to 0
      
      } else {
      
          //  runcommand that sets value to -15
         
      }
      
      1. Bergatron Music @Bergatron_Music
          2024-10-01 18:02:18.373Z

          Thanks @Chris_Shaw
          Here is what I think you're saying, but I know I'm doing something wrong because this doesn't work:

          const masterName = "MASTER";
          
          const masterTrack = sf.ui.proTools.trackGetByName({ name: masterName, makeVisible: true }).track;
          const masterAudioIo = masterTrack.groups.whoseTitle.is("Audio IO").first;
          const masterVolSlider = masterAudioIo.sliders.whoseTitle.is("Volume").first;
          const masterVolValue = Number(masterVolSlider.value.intValue);
          
          if (masterVolValue < 0) {
              
          sf.ui.proTools.trackGetByName({ name: "MASTER", makeVisible: true }).track.trackSelect();
          
          //Calling command "VOLUME 0" from package "PRO TOOLS"
          sf.soundflow.runCommand({
              commandId: 'package:cl6tpnnhc000f9a10b9v2kvgh',
              props: {}
          });
          
          } else {
          
          sf.ui.proTools.trackGetByName({ name: "MASTER", makeVisible: true }).track.trackSelect();
          
          //Calling command "VOLUME -15" from package "PRO TOOLS"
          sf.soundflow.runCommand({
              commandId: 'package:cl6tpnnhc000f9a10b9v2kvgh',
              props: {}
          });
             
          }
          1. Try deleting lines 10 and 20 they are not needed: Line 1 is doing that for you already.
            If that doesn't work then try running the following to narrow down what's going on.
            If the fader is below zero it will log "Fader is below zero db" and if the fader is at zero it should log "Fader is at zero db"

            const masterName = "---Master---";
            
            const masterTrack = sf.ui.proTools.trackGetByName({ name: masterName, makeVisible: true }).track;
            const masterAudioIo = masterTrack.groups.whoseTitle.is("Audio IO").first;
            const masterVolSlider = masterAudioIo.sliders.whoseTitle.is("Volume").first;
            const masterVolValue = Number(masterVolSlider.value.intValue);
            
            if (masterVolValue < 0) {
                
                log(" Fader is below zero db")
            
            } else {
            
                log(" Fader is at zero db")
                //  runcommand that sets value to -15
               
            }
            
            1. Also,, when you say it doesn't work, do you get an error? Does anything happen?
              More details please…

              1. You also may have the command ID's wrong. It looks like they are both the same. Go to the command you'd like to run (the preset you created in the Pro Tools package), select it in the SF editor and from the SF editor "Command" menu select "Copy Command ID" (not command ID Local to Package)" and paste the command ID for zero DB into line 14 and the -15 db command ID into line 24 (as seen above in your script.

                1. In reply toChris_Shaw:
                  Bergatron Music @Bergatron_Music
                    2024-10-01 20:39:44.425Z

                    Hey @Chris_Shaw sorry about that! Nothing was happening when I tried it. My bad.

                    I'll try deleting those lines and see what happens. Thank you!

                    1. Check my post above Re: command ID issues you might be having

                      1. Bergatron Music @Bergatron_Music
                          2024-10-01 21:55:07.245Z

                          Hey @Chris_Shaw I copied and pasted the correct ID's. Thanks for that. After doing that I got lost in the weeds trying to go back and do everything in order laid out. I am still not great with scripts, but I'm trying!

                          I can get the master fader to drop to -15, then pop back up to zero with this script pasted below, but what I'm trying to do is make them a toggle. I couldn't figure out what I was (or wasn't) pasting in the right place to make the toggle work. I appreciate any further help with this and thanks in advance!

                          //What I started with
                          sf.ui.proTools.trackGetByName({ name: "MASTER", makeVisible: true }).track.trackSelect();
                          
                          //Calling command "VOLUME -15" from package "PRO TOOLS"
                          sf.soundflow.runCommand({
                              commandId: 'package:cl6tpnnhc000f9a10b9v2kvgh',
                              props: {}
                          });
                          
                          //Calling command "VOLUME -0+" from package "PRO TOOLS"
                          sf.soundflow.runCommand({
                              commandId: 'package:cl6totvr400099a10wl1k3f2x',
                              props: {}
                          });
                          
                          1. The script above should toggle. If the fader is at zero it should set it to to -15.
                            Triggering it again should set it back to zero.
                            Are you looking for a different behavior?

                            1. It should be this:

                              const masterName = "---Master---";
                              
                              const masterTrack = sf.ui.proTools.trackGetByName({ name: masterName, makeVisible: true }).track;
                              const masterAudioIo = masterTrack.groups.whoseTitle.is("Audio IO").first;
                              const masterVolSlider = masterAudioIo.sliders.whoseTitle.is("Volume").first;
                              const masterVolValue = Number(masterVolSlider.value.intValue);
                              
                              if (masterVolValue < 0) {
                              
                                  //Calling command "VOLUME -0+" from package "PRO TOOLS"
                                  sf.soundflow.runCommand({
                                      commandId: 'package:cl6totvr400099a10wl1k3f2x',
                                      props: {}
                                  });
                              
                              } else {
                              
                                  //Calling command "VOLUME -15" from package "PRO TOOLS"
                                  sf.soundflow.runCommand({
                                      commandId: 'package:cl6tpnnhc000f9a10b9v2kvgh',
                                      props: {}
                                  });
                              
                              }
                              1. I have to point out again that I think the command IDs are wrong.
                                I'm assuming you're triggering a preset that you created in the Pro Tools package (control volume fader (Edit Window) as seen below (I created presets for both 0 and -15):

                                If you copy the command ID the way I described above then it should look something like
                                user:ckp49i4j60000a2100yfwywgf:cklphujq60000u91070dmknxf#cm1qw694l00010510mt4dfwzp

                                The command Id you have set in your script looks like you used "Copy Command ID Local to Package"

                                1. Bergatron Music @Bergatron_Music
                                    2024-10-01 22:40:29.703Z

                                    @Chris_Shaw I've created (2) new commands just like in your screenshot and copied and pasted their ID's. Here is the current script, but it's not changing anything. There are errors popping up this time though! I know its got to be something I'm doing.

                                    const masterName = "MASTER";
                                    
                                    const masterTrack = sf.ui.proTools.trackGetByName({ name: masterName, makeVisible: true }).track;
                                    const masterAudioIo = masterTrack.groups.whoseTitle.is("Audio IO").first;
                                    const masterVolSlider = masterAudioIo.sliders.whoseTitle.is("Volume").first;
                                    const masterVolValue = Number(masterVolSlider.value.intValue);
                                    
                                    if (masterVolValue < 0) {
                                    
                                        sf.soundflow.runCommand({
                                            commandId: 'user:ckp49i4j60000a2100yfwywgf:cklphujq60000u91070dmknxf#cm1r0kzp4001ba910p5mhs40z',
                                            props: {}
                                        });
                                    
                                    } else {
                                    
                                        sf.soundflow.runCommand({
                                            commandId: 'user:ckp49i4j60000a2100yfwywgf:cklphujq60000u91070dmknxf#cm1r0k4b4001aa9105y56ru3m',
                                            props: {}
                                        });
                                    
                                    }
                                    1. What are the errors?

                                      1. I need to know:

                                        • what the errors are (copy them from the SF log immediately after the script is run / failed))
                                        • What version of PT are you using? (give me the version number)
                                        • What version of SF are you using?
                                        • What MacOS are you using?
                                        1. Bergatron Music @Bergatron_Music
                                            2024-10-01 23:25:41.604Z

                                            Ok great! On it. One sec..

                                          • In reply toChris_Shaw:
                                            Bergatron Music @Bergatron_Music
                                              2024-10-01 23:24:29.640Z

                                              @Chris_Shaw What is the best way to show the errors? Here is a screenshot:

                      2. In reply toBergatron_Music:
                        Bergatron Music @Bergatron_Music
                          2024-10-01 23:30:29.490Z2024-10-02 00:04:20.657Z

                          @Chris_Shaw

                          Apologies for this (probably dumb) question: Do you want me to Copy/Paste the whole error log that I showed in that screenshot? It's pretty massive.

                          This is from the Log in SoundFlow:
                          Couldn't get item #0 as the array's parent node wasn't found - sf.ui.app('com.avid.ProTools')....groups.whoseTitle.is('Audio IO').first.sliders (AxElementArrayIndexedItem) (DIM MASTER WIP 4: Line 6)

                          -ProTools 2024.6 Ultimate
                          -Soundflow 5.8.2
                          -Sonoma 14.5

                          1. In reply toBergatron_Music:
                            Kitch Membery @Kitch2024-10-02 00:09:54.952Z

                            Hi @Bergatron_Music,

                            Great to meet you the other night!

                            Here is a more bespoke solution using Chris' method but without using presets to change the volume.

                            Create a new script and then paste the following code, being sure to change the "targetTrackName" to the name of your master track.

                            const targetTrackName = "MASTER";
                            
                            /**@param {{
                                track: AxPtTrackHeader,
                                action: (AxWindow) => void,
                            }} args */
                            function withTrackOutput(args) {
                                const { track, action } = args;
                            
                                //Define reusable state funcs
                                function getOutputWin() {
                                    return sf.ui.proTools.floatingWindows.whoseTitle.is('').filter(w => {
                                        let trackSel = w.children.whoseTitle.startsWith('Track selector').first;
                                        if (!trackSel.exists) return false;
                                        return trackSel.value.value === track.normalizedTrackName;
                                    })[0];
                                }
                            
                                let initialState = {
                                    outputOpen: undefined,
                                };
                            
                                try {
                                    let outputWin = getOutputWin();
                                    initialState.outputOpen = !!outputWin;
                            
                                    if (!initialState.outputOpen) {
                                        track.trackOutputToggleShow({}, `Couldn't open track output window.\nMake sure you're displaying track I/O`);
                                        sf.waitFor({
                                            callback: () => {
                                                outputWin = getOutputWin();
                                                return !!outputWin;
                                            },
                                            timeout: 2000,
                                        }, `Track output window didn't open`);
                                    }
                            
                                    try {
                                        action(outputWin);
                                    } catch (err) {
                                        throw { inner: err };
                                    }
                            
                                } catch (err) {
                            
                                    //Errors happening inside the action shouldn't be wrapped by us, so re-throw them directly
                                    if (err.inner) throw err.inner;
                            
                                    throw `${err}`;
                            
                                } finally {
                            
                                    //Restore initial state, ignoring potential errors
                                    if (initialState.outputOpen === false)
                                        track.trackOutputToggleShow({ onError: 'Continue' });
                                }
                            }
                            
                            /**@param {{
                                track: AxPtTrackHeader,
                                amount: number,
                            }} args Track to make the changes on
                            */
                            function setVolume(args) {
                                const { track, amount } = args;
                            
                                if (!track) throw `Track is required`;
                                if (isNaN(Number(amount))) throw `Amount must be a number`;
                            
                                /**@param {AxWindow} trackOutputWin */
                                function main(trackOutputWin) {
                                    try {
                                        let volumeField = trackOutputWin.textFields.whoseTitle.is('Volume Numerical').first;
                                        if (!volumeField.exists) throw `Couldn't find volume field`;
                            
                                        var newValue = amount;
                            
                                        volumeField.elementClick({}, `Couldn't focus volume text field`);
                            
                                        sf.keyboard.type({ text: String(newValue) }, `Couldn't type trim amount`);
                            
                                        sf.keyboard.press({ keys: 'enter' }, `Couln't press enter`);
                            
                                        sf.wait({ intervalMs: 50 });
                            
                                        sf.keyboard.press({ keys: 'left' }, `Couldn't update Pro Tools state`); //to update things...
                            
                                    } catch (err) {
                                        throw `Couldn't trim volume.\n${err}`;
                                    }
                                }
                            
                                withTrackOutput({
                                    track,
                                    action: main,
                                });
                            }
                            
                            function main() {
                                sf.ui.proTools.appActivateMainWindow();
                            
                                const targetTrack = sf.ui.proTools.trackGetByName({ name: targetTrackName, makeVisible: true }).track;
                                const audioIo = targetTrack.groups.whoseTitle.endsWith("IO").first;
                                const volumeSlider = audioIo.sliders.whoseTitle.is("Volume").first;
                                const volumeValue = Number(volumeSlider.value.intValue);
                            
                                if (volumeValue < 0) {
                                    setVolume({
                                        track: targetTrack,
                                        amount: 0,
                                    });
                                } else {
                                    setVolume({
                                        track: targetTrack,
                                        amount: -15,
                                    });
                                }
                            }
                            
                            main();
                            

                            Let me know how it runs for you. :-)

                            ReplySolution
                            1. In reply toBergatron_Music:
                              Bergatron Music @Bergatron_Music
                                2024-10-02 00:20:49.286Z

                                @Kitch @Chris_Shaw Thank you guys for all the help on this. This does it, Kitch!

                                I'm certain my inability to properly script is what was hanging me up on Chris's solution. I learned so much today just poking around and trying to comprehend the responses. I really appreciate all the help. I owe you both a few beers, at least!

                                1. Kitch Membery @Kitch2024-10-02 00:27:46.996Z

                                  Rock on!!

                                  I did notice one line that may have been causing the issue in @Chris_Shaw's script.

                                  const masterAudioIo = masterTrack.groups.whoseTitle.is("Audio IO").first;
                                  

                                  needed to be changed for it to work for me.

                                  const masterAudioIo = masterTrack.groups.whoseTitle.endsWith("IO").first;
                                  

                                  Chris may have been testing the script on an Audio Track and may have not noticed that the master track's group (for some reason) had a different name.

                                  Glad it's working now. :-)

                                  1. Bergatron Music @Bergatron_Music
                                      2024-10-02 00:31:26.670Z

                                      Awesome. You're both geniuses! THANK YOU both.

                                      1. Kitch Membery @Kitch2024-10-02 00:42:15.920Z

                                        Listen to @Chris_Shaw’s body of work. I’ll take a back seat to the genius call.