No internet connection
  1. Home
  2. How to

How to select Audio Suite key input dynamically via the Stream Deck

By Dario Ramaglia @dario.ramaglia
    2019-04-15 16:45:13.412Z

    I was wondering if it is possibile for the StreamDeck to recieve information.
    An example could be selecting the SideChain track using AutoAlign Post.
    The StreamDeck could show a selection of tracks (maybe filtered by name) to use as SideChain track.
    Another way could be to tell the plugin which track to look for: Let say we prepare 15 favorite track on the StreamDeck as buttons, once we focus the plugin, SoundFlow could wait for us to press a Button on the StreamDeck (that we have already prepared in a profile) to know which track we want to select.

    This kind of dynamic behavior could be applied to a lot of things: Selecting colors on the Color Palette, Selecting Input and Output for Tracks, Selecting presets on a plugin, and so on.

    Hope what I wrote make sense ;)

    Solved in post #5, click to view
    • 40 replies

    There are 40 replies. Estimated reading time: 24 minutes

    1. In reply todario.ramaglia:

      @dario.ramaglia, also see this one that I just posted for selecting an AudioSuite/insert preset via your Stream Deck:

      https://forum.soundflow.org/-507/how-to-select-an-audiosuiteinsert-user-preset-via-the-stream-deck
      1. In reply todario.ramaglia:

        @Andy_Kris, here's an example where you set the Key Input to a constant - here the track "Boom 1". This doesn't need the Stream Deck dynamic "showModal" action.

        var keyInputName = 'Boom 1';
        sf.ui.proTools.appActivate();
        
        var asWin = sf.ui.proTools.getAudioSuiteWindow("Auto-Align Post");
        asWin.elementRaise();
        
        var keyInputBtn = sf.ui.proTools.firstAudioSuiteWindow.invalidate().popupButtons.whoseTitle.is('Key Input').first;
        keyInputBtn.popupMenuSelect({
            menuPath: [keyInputName]
        });
        
        
        asWin.getFirstWithTitle("Analyze").elementClick();
        
        //Render
        asWin.audioSuiteRender();
        
        1. N
          In reply todario.ramaglia:
          N Leyers @NickLeyers_old_acc
            2019-07-10 13:27:10.222Z

            Cool idea. I've been workign around this by sending the clips (also the reference) to work tracks, deselecting the reference clip and rendering the other ones with Autoalign. The sidechain was always fixed on the first worktrack. Work very nice when filtering out big confo sessions because it demands no scrolling and everything is on a few tracks in no time.

            Changing the sidechain like this is even more powerfull. But I wouldn't need all of the options on SD. Maybe even better to go to the track that is the reference (or selecting the clip) and get the trackname with the push of a button + imediatelly changing the sidechain in Post Align to this track. Saves looking for the right track.
            => In a next step, I think I will make a macro that will align all the clips I select to eachother with one button, no matter where they are situated.

            My question: How to get the trackname from the selected track? I can use the 'Rename track'-function, followed by ESC, but I think this can go faster?

            1. This gives you the name of the first selected track:

              var name = sf.ui.proTools.selectedTrackNames[0];
              
            2. Progress
            3. Great question, @dario.ramaglia

              I would divide this into 2 separate problems/features:

              1. The ability to dynamically populate the Stream Deck's buttons from a script in SoundFlow. This is what we do with the showModal action and is already possible in the test script we showed there (although with a few bugs). The data could come from anywhere, track names, files on disk, colors, etc.

              2. The ability to automatically run a SoundFlow script based on whatever you have open in Pro Tools. We also already have support for this via long-running background commands. Basically these are scripts that will check for a certain condition (eg. is a specific window or plugin open in Pro Tools) and whenever the condition is met, for example it could call a script like mentioned in no.1 above, for example to control the Stream Deck.

              1. For example the "Clip Colors" folder you have on your Stream Deck could be implemented as a single script instead. That script would just use the showModal to populate the Stream Deck with colors and then when you choose a color it would do the action. I put up a demo of my script for Cubase in the FB group

                1. Dario Ramaglia @dario.ramaglia
                    2019-04-15 17:20:41.936Zreplies tochrscheuer:

                    Yes, I didn't want to create to many posts ;)

                    1. For example, this script will allow you to select which Key Input you want for the open Audio Suite window:

                      
                      var trackNames = ['Boom 1', 'Boom 2', 'Boom 3', 'Boom 4'];
                      
                      var selectedName = sf.devices.streamDeck.firstDevice.showModal({
                          items: trackNames.map(function (name, i) {
                              return {
                                  title: name,
                                  value: name,
                                  color: {
                                      r: i * 255 / 15,
                                      g: 100,
                                      b: 100,
                                  }
                              };
                          })
                      }).selectedItem.value;
                      
                      sf.ui.proTools.appActivate();
                      var keyInputBtn = sf.ui.proTools.firstAudioSuiteWindow.invalidate().popupButtons.whoseTitle.is('Key Input').first;
                      keyInputBtn.popupMenuSelect({
                          menuPath: [selectedName]
                      });
                      

                      I hard coded the names of the tracks here. The idea is you run this script, it will show you the track names on the SD, once you select a track name on the SD, it will use that as the key input in your Audio Suite window.

                      ReplySolution
                      1. Note, you could make an even longer workflow, where you just make a button in SD that does:

                        1. Opens the Auto Align window and displays the list of possible key inputs (via something like the above script)
                        2. Once you've selected your key input, it selects it in the drop down and also clicks render, waits for it to be done and then closes the plugin again.
                        1. Dario Ramaglia @dario.ramaglia
                            2019-04-15 17:44:57.834Zreplies tochrscheuer:

                            It works and does exactly what I meant. Thank you so much.
                            I just need to integrate this piece of code in the code I already created to send clips to AutoAlign Post and Render it ;)

                            Thank you so much

                            1. Dario Ramaglia @dario.ramaglia
                                2019-04-15 18:00:22.127Zreplies todario.ramaglia:

                                Here it is. Sorry for the very stupid question. I'd like to choose a color for Booms and another color for Radios.
                                Is it possible? If not, it is great as it is ;)

                                1. Example for different colors (100, 100, 100 for boom, 50, 150, 100 for lavs):

                                  
                                  var trackNames = ['Boom 1', 'Boom 2', 'Boom 3', 'Boom 4', 'Lav 1', 'Lav 2'];
                                  
                                  var selectedName = sf.devices.streamDeck.firstDevice.showModal({
                                      items: trackNames.map(function (name) {
                                          return {
                                              title: name,
                                              value: name,
                                              color: name.indexOf('Boom') >= 0
                                                  ? {
                                                      r: 100,
                                                      g: 100,
                                                      b: 100,
                                                  } : {
                                                      r: 50,
                                                      g: 150,
                                                      b: 100,
                                                  }
                                          };
                                      })
                                  }).selectedItem.value;
                                  
                                  sf.ui.proTools.appActivate();
                                  var keyInputBtn = sf.ui.proTools.firstAudioSuiteWindow.invalidate().popupButtons.whoseTitle.is('Key Input').first;
                                  keyInputBtn.popupMenuSelect({
                                      menuPath: [selectedName]
                                  });
                                  
                                  1. Dario Ramaglia @dario.ramaglia
                                      2019-05-16 11:51:47.446Zreplies tochrscheuer:

                                      What if I want to add a track name that is too long for the stream deck to show?
                                      At the moment I shortened the name of the track but it is possible to SHOW A NAME X on the SD who would SELECT A NAME Y on the plugin?

                                      Of course all this questions I come up with are just to learn so feel free to ignore them :) Or answer whenever you are bored ;)

                                      Cheers guys

                                      1. @dario.ramaglia yes - the "title" is what will be displayed on the Stream Deck, the "value" is the one used to select your track.
                                        You can use this function to shorten titles:

                                        function shortenTitle(s) {
                                            var res = '', i = 0;
                                            while (s.length > 0 && i < 3) {
                                                res += s.substring(0, 7) + '\n';
                                                s = s.substring(7);
                                                i++;
                                            }
                                            return res;
                                        }
                                        

                                        And use it like this:

                                        var selectedName = sf.devices.streamDeck.firstDevice.showModal({
                                            items: trackNames.map(function (name, i) {
                                                return {
                                                    title: shortenTitle(name),
                                                    value: name,
                                                    color: {
                                                        r: i * 255 / 15,
                                                        g: 100,
                                                        b: 100,
                                                    }
                                                };
                                            })
                                        }).selectedItem.value;
                                        
                                        1. Dario Ramaglia @dario.ramaglia
                                            2019-05-16 14:27:43.598Zreplies tochrscheuer:

                                            Sorry for my lack of knowledge. Where should I put the TITLE in the code?

                                            1. It's already there, find the line with title: name, and replace with title: shortenTitle(name), and add the function at the top of your script.

                                              1. Comment deleted
                                                1. Dario Ramaglia @dario.ramaglia
                                                    2019-05-16 14:49:35.260Zreplies todario.ramaglia:

                                                    ok, I begin to understand javascript-
                                                    The code says: every 7 characters insert a break.

                                                    1. Dario Ramaglia @dario.ramaglia
                                                        2019-05-16 17:44:46.938Zreplies tochrscheuer:

                                                        Ok, let's move to the next question :) You'll never get rid of me ihihihihihi

                                                        I'm tryin to assign a color for each and every category but I'm having trouble with syntax I suppose.
                                                        I'm pasting the wrong code.

                                                        Thanks as usual in advance

                                                        //Select SideChain
                                                        var trackNames = ['Boom1', 'Boom2', 'Boom3', 'Boom4', 'Boom5', 'Radio1', 'Radio2', 'Radio3', 'Radio4', 'Radio5'];
                                                        
                                                        var selectedName = sf.devices.streamDeck.firstDevice.showModal({
                                                            items: trackNames.map(function (name, i) {
                                                                return {
                                                                    title: name,
                                                                    value: name,
                                                                    color: name.indexOf('Boom') >= 0
                                                                        ? {
                                                                            r: 74,
                                                                            g: 0,
                                                                            b: 106
                                                                        } : {
                                                                    name.indexOf('Radio') >= 0 {
                                                                        r: 22,
                                                                        g: 100,
                                                                        b: 106,
                                                                        }
                                                            };
                                                        })
                                                        }).selectedItem.value;
                                                        
                                                        1. Oh yea. Ok so the ... ? ... : ... (aka the terniary operator ?!) actually is akin to if/then/else.
                                                          So what we were originally saying was:
                                                          name.indexOf('Boom') >= 0 ?
                                                          which means if name.indexOf('Boom') >= 0 then
                                                          followed by the color for the boom, followed by : meaning else, then the color if not the boom.

                                                          If you want to test for more categories, you need to chain them...: if/then/else if/then/else
                                                          So for example:

                                                          color: name.indexOf('Boom') >= 0
                                                                          ? {
                                                                              r: 74,
                                                                              g: 0,
                                                                              b: 106
                                                                          } : 
                                                                      name.indexOf('Radio') >= 0 ? {
                                                                              r: 22,
                                                                              g: 100,
                                                                              b: 106,
                                                                          } :
                                                                          { /* this is the last else, so will receive if neither Boom nor Radio */
                                                                              r: 22,
                                                                              g: 100,
                                                                              b: 106,
                                                                          }
                                                          
                                                          1. Dario Ramaglia @dario.ramaglia
                                                              2019-05-16 17:51:15.454Zreplies tochrscheuer:

                                                              I was gonna try to use IF and ELSE because I didn't know ? was that. Thanks so much

                                                              1. It's good you didn't use if/else/then. If/else/then cannot be used as expressions, that is, here we're using them inside in the middle of a call to a function. If you wanted to use if/else you'd have to assign to a variable, like this:

                                                                var color;
                                                                if (name.indexOf('Boom') >= 0)
                                                                    color = { r: 74, g: 0, b: 106 };
                                                                else if (name.indexOf('Radio') >= 0)
                                                                    color = { r: 22, g: 100, b: 106 };
                                                                else
                                                                    ;//color = some default color here...
                                                                

                                                                And then use this variable in the script - here I have inserted it where it makes sense (eg. before the return statement):

                                                                var selectedName = sf.devices.streamDeck.firstDevice.showModal({
                                                                    items: trackNames.map(function (name, i) {
                                                                        var color;
                                                                        if (name.indexOf('Boom') >= 0)
                                                                            color = { r: 74, g: 0, b: 106 };
                                                                        else if (name.indexOf('Radio') >= 0)
                                                                            color = { r: 22, g: 100, b: 106 };
                                                                        else
                                                                            ;//color = some default color here...
                                                                
                                                                        return {
                                                                            title: name,
                                                                            value: name,
                                                                            color: color
                                                                        };
                                                                    })
                                                                }).selectedItem.value;
                                                                
                                                                1. And since this syntax is much much easier to read I would probably go for this version :)

                                                                  1. Dario Ramaglia @dario.ramaglia
                                                                      2019-05-16 17:59:52.977Zreplies tochrscheuer:

                                                                      Oh my god. Tomorrow I'll try to convert my script to this script.
                                                                      Meanwhile if anyone is interested, this is my script for selecting sidechain and rendering AutoAlign Post with Name Shortener and the same color I have in my template session

                                                                      //Focus AAP
                                                                      
                                                                      var asWin = sf.ui.proTools.getAudioSuiteWindow("Auto-Align Post");
                                                                      asWin.elementRaise();
                                                                      
                                                                      //Select SideChain
                                                                      var trackNames = ['Boom1', 'Boom2', 'Boom3', 'Boom4', 'Boom5', 'Radio1', 'Radio2', 'Radio3', 'Radio4', 'Radio5','Adr Sync B'];
                                                                      
                                                                      ///Title Shortener
                                                                      function shortenTitle(s) {
                                                                          var res = '', i = 0;
                                                                          while (s.length > 0 && i < 3) {
                                                                              res += s.substring(0, 8) + '\n';
                                                                              s = s.substring(8);
                                                                              i++;
                                                                          }
                                                                          return res;
                                                                      }
                                                                      
                                                                      var selectedName = sf.devices.streamDeck.firstDevice.showModal({
                                                                          items: trackNames.map(function (name, i) {
                                                                              return {
                                                                                  title: shortenTitle(name),
                                                                                  value: name,
                                                                                  color: name.indexOf('Boom') >= 0
                                                                                      ? {
                                                                                          r: 74,
                                                                                          g: 0,
                                                                                          b: 106,
                                                                                      } :
                                                                                      name.indexOf('Radio') >= 0 ? {
                                                                                          r: 22,
                                                                                          g: 100,
                                                                                          b: 106,
                                                                                      } :
                                                                                      { /* this is the last else, so will receive if neither Boom nor Radio */
                                                                                          r: 142,
                                                                                          g: 15,
                                                                                          b: 8,
                                                                                      }
                                                                              };
                                                                          })
                                                                      }).selectedItem.value;
                                                                      
                                                                      sf.ui.proTools.appActivate();
                                                                      var keyInputBtn = sf.ui.proTools.firstAudioSuiteWindow.invalidate().popupButtons.whoseTitle.is('Key Input').first;
                                                                      keyInputBtn.popupMenuSelect({
                                                                          menuPath: [selectedName]
                                                                      });
                                                                      
                                                                      
                                                                      asWin.getFirstWithTitle("Analyze").elementClick();
                                                                      
                                                                      //Render
                                                                      asWin.audioSuiteRender();
                                                                      
                                                                      1. Dario Ramaglia @dario.ramaglia
                                                                          2019-05-16 18:12:17.467Zreplies todario.ramaglia:

                                                                          And for any other color i want to assign I just add a IF ELSE right?
                                                                          Like:

                                                                          if (name.indexOf('Boom') >= 0)
                                                                                      color = { r: 74, g: 0, b: 106 };
                                                                                  else if (name.indexOf('Radio') >= 0)
                                                                                      color = { r: 22, g: 100, b: 106 };
                                                                                  else if (name.indexOf('Adr Sync B') ) 
                                                                          color = { r: 142, g: 15, b: 8 };
                                                                          
                                                                          

                                                                          Here is the whole code with the different syntax

                                                                          //Focus AAP
                                                                          
                                                                          var asWin = sf.ui.proTools.getAudioSuiteWindow("Auto-Align Post");
                                                                          asWin.elementRaise();
                                                                          
                                                                          
                                                                          //Select SideChain
                                                                          var trackNames = ['Boom1', 'Boom2', 'Boom3', 'Boom4', 'Boom5', 'Radio1', 'Radio2', 'Radio3', 'Radio4', 'Radio5','Adr Sync B'];
                                                                          
                                                                          ///Title Shortener
                                                                          function shortenTitle(s) {
                                                                              var res = '', i = 0;
                                                                              while (s.length > 0 && i < 3) {
                                                                                  res += s.substring(0, 8) + '\n';
                                                                                  s = s.substring(8);
                                                                                  i++;
                                                                              }
                                                                              return res;
                                                                          }
                                                                          
                                                                          var selectedName = sf.devices.streamDeck.firstDevice.showModal({
                                                                              items: trackNames.map(function (name, i) {
                                                                                  var color;
                                                                                  if (name.indexOf('Boom') >= 0)
                                                                                      color = { r: 74, g: 0, b: 106 };
                                                                                  else if (name.indexOf('Radio') >= 0)
                                                                                      color = { r: 22, g: 100, b: 106 };
                                                                                  else color = { r: 142, g: 15, b: 8 };
                                                                                  return {
                                                                                      title: shortenTitle(name),
                                                                                      value: name,
                                                                                      color: color
                                                                              };
                                                                          })
                                                                          }).selectedItem.value;
                                                                          
                                                                          sf.ui.proTools.appActivate();
                                                                          var keyInputBtn = sf.ui.proTools.firstAudioSuiteWindow.invalidate().popupButtons.whoseTitle.is('Key Input').first;
                                                                          keyInputBtn.popupMenuSelect({
                                                                              menuPath: [selectedName]
                                                                          });
                                                                          
                                                                          
                                                                          asWin.getFirstWithTitle("Analyze").elementClick();
                                                                          
                                                                          //Render
                                                                          asWin.audioSuiteRender();
                                                                          
                                                                          1. To your first question: Yes - almost!
                                                                            Your "whole code with different syntax" is correct.

                                                                            In your code:

                                                                            if (name.indexOf('Boom') >= 0)
                                                                                        color = { r: 74, g: 0, b: 106 };
                                                                                    else if (name.indexOf('Radio') >= 0)
                                                                                        color = { r: 22, g: 100, b: 106 };
                                                                                    else if (name.indexOf('Adr Sync B') ) 
                                                                            color = { r: 142, g: 15, b: 8 };
                                                                            

                                                                            you forget to check for >= 0 in your 3rd check. Correct code:

                                                                                    if (name.indexOf('Boom') >= 0)
                                                                                        color = { r: 74, g: 0, b: 106 };
                                                                                    else if (name.indexOf('Radio') >= 0)
                                                                                        color = { r: 22, g: 100, b: 106 };
                                                                                    else if (name.indexOf('Adr Sync B') >= 0) 
                                                                                        color = { r: 142, g: 15, b: 8 };
                                                                            
                                                                            1. Dario Ramaglia @dario.ramaglia
                                                                                2019-05-16 18:59:40.885Zreplies tochrscheuer:

                                                                                I maybe forgot a

                                                                                  sf.ui.proTools.waitForNoModals();
                                                                                

                                                                                At the end ;)

                                                                                1. Dario Ramaglia @dario.ramaglia
                                                                                    2019-05-17 09:29:18.898Zreplies todario.ramaglia:

                                                                                    @chrscheuer did you notice that with the shortener script the label are on the top half of the button on the StreamDeck while without it the stay in the center?

                                                                                    1. No haven't seen that. Can you send a photo of the Stream Deck exhibiting this behavior?

                                                                                      1. Dario Ramaglia @dario.ramaglia
                                                                                          2019-05-17 11:48:16.452Zreplies tochrscheuer:

                                                                                          Script with the shortener:

                                                                                          Script without the shortener:

                                                                                          1. Gotcha. Change shortenTitle to this:

                                                                                            function shortenTitle(s) {
                                                                                                var res = '', i = 0;
                                                                                                while (s.length > 0 && i < 3) {
                                                                                                    if (i > 0) res += '\n';
                                                                                                    res += s.substring(0, 8);
                                                                                                    s = s.substring(8);
                                                                                                    i++;
                                                                                                }
                                                                                                return res;
                                                                                            }
                                                                                            
                                                                                            1. Dario Ramaglia @dario.ramaglia
                                                                                                2019-05-17 11:58:07.070Zreplies tochrscheuer:

                                                                                                It works :)
                                                                                                I'm trying to understand what did you do there.
                                                                                                You put a break before the shortening process... right?

                                                                                                1. Yes I made sure to only put breaks if line 2, 3, 4, etc. are created. So when you get to line 2 (i will be 1 since we count the first line as i=0, hence i > 0 will be true, the newline will be added before line 2, and before line 3, and before line 4.. just not before line 1, where i would be 0 and so i > 0 would be false).

                                                                                                  1. N
                                                                                                    N Leyers @NickLeyers_old_acc
                                                                                                      2019-07-10 16:49:39.343Zreplies todario.ramaglia:

                                                                                                      Hmm, I can't get this script working. Do you have to do something to the SD to make it listen to SF?
                                                                                                      I copied everything exact but get nothing out of it. If that's a bug, I will post it, but it might be something I'm not doing right because it's working for you guys...

                                                                                                      1. The requirements for this are:

                                                                                                        • The "SoundFlow Full Screen" profile needs to be installed on the Stream Deck. This should be installed together with the plugin. The profile can only be installed once, or it won't work. (Stream Deck bug)
                                                                                                        • The Stream Deck editor app cannot be open. When it's open, we cannot switch to the SF full screen profile programmatically.
                                                                                                        1. N
                                                                                                          N Leyers @NickLeyers_old_acc
                                                                                                            2019-07-10 18:23:03.741Zreplies tochrscheuer:

                                                                                                            Aha, that's why. But where can I find this profile?

                                                                                                            1. It should come if you uninstall the plugin and reinstall it. Do you have the link to the installer for the plugin?

                                                                                                              1. Note this is super annoying because Stream Deck made their API this way... :/

                                                                                                                1. N
                                                                                                                  N Leyers @NickLeyers_old_acc
                                                                                                                    2019-07-11 05:20:55.151Zreplies tochrscheuer:

                                                                                                                    No, and if I try the downloadlink from here on the forum, I get a timeout of the link.