Record Arm All Selected Tracks with Reascript

cksIf you’ve been following along with my previous Reascript posts, you know we previously wrote a script that record arms your currently selected track.

I’m going to help you expand on that today as our script is a little broken with how it currently works.  You can select multiple tracks, but if you do only the topmost track will be armed for record when you run the script.

To fix this, we’re going to update the script to arm all selected tracks by introducing you to the concept of the for loop.

Setting the stage

This update to our script is two steps.

  1. Figure out how many tracks have been selected
  2. Iterate through those tracks one by one and use our previous code to set the record arm to “ON” for each track.

To remind you, this is what the code we’ve written currently looks like:

track = reaper.GetSelectedTrack(0,0)
reaper.SetMediaTrackInfo_Value(track, "I_RECARM", 1)

We have a track variable that represents the topmost selected track in our active project.  The second line of the code turns on the record arm on that track.

Step one: How many tracks are selected?

The Reaper API helps make our first step easy.  The CountSelectedTracks function will give us an integer (which is just a number without a decimal) for the number of tracks that are currently selected.

So we need to use this function at the very top of our code (above what we already wrote) and assign a variable to it.  I’m using long variable names with underscores to make reading this code easy, but you can name your variable anything you want.

number_of_tracks = reaper.CountSelectedTracks(0)

Remember, “(0)” after CountSelectedTracks refers to the currently active project.  So this code is saying “Hey Reaper, give me the number of tracks that are selected in the active project and store that number in number_of_tracks.

Now if you have 3 tracks selected, number_of_tracks will equal 3.  The API is pretty helpful, right?!

Step Two: Iterate through the tracks

The next step requires what is called a loop in programming.  As an audio person, you’re already familiar with loops – you just call them feedback loops.  Programming loops are a similar concept, except the volume doesn’t get louder and whine at you!

In programming, loops are done with a purpose and we have control over them.  Loops are generally executed for the purpose of writing less code and being more precise with our code.  In our case, we don’t know exactly how many tracks will be selected – so we can’t “hard code” a record arm for all the selected tracks.  Even if we did know how many tracks will be selected before we run the code, we can write less code if we use a loop.

Before the loop begins we provide a condition that determines how long the loop should continue for.  In our case, we want to use a loop that record arms each track.  If we select 3 tracks, the loop needs to run 3 times.  If we select 5 tracks, the loop needs to run 5 times.  To set this up, we can use what’s called a for loop.

Explaining the for loop

for loop is common in most programming languages.  In layman’s terms the way it executes can be described as follows:

For as long as the loop condition is true, continue looping through the code

If that’s confusing, don’t worry – I’ll walk through our specific code below.

Writing a for loop

Our for loop is going to look like this:

for i = 0, number_of_tracks-1 do
 -- our code will go here
end

Okay, step-by-step here’s what the above means:

  • for indicates we’re starting a for loop
  • i = 0, in this case we’re creating a new variable that exists only within our loop called “i” and we’re making it equal to zero.  This variable will help us keep count of how many times we’ve looped through our code.  The name “i” isn’t important here, it’s just shorthand for “integer”.  You could name this variable “Fred” if you wanted.  Just make sure you put a comma after the 0.
  • number_of_tracks-1, this section after the comma wants a maximum or minimum value we want the “i” value to reach.  Unless we specify otherwise, our “i” value will increase in value by 1 each time the loop completes.  If we have 3 tracks selected, we want to go through the loop 3 times.  This explains subtracting our variable by 1, because number_of_tracks is equal to 3 in our example – which means “i” will increment in value 4 times.  If we subtract one from number_of_tracks, we will only loop 3 times!

At this point, I know what you might be thinking… Adam – we could just as easily start “i” equal to 1 and then not have to subtract from number_of_tracks!  But, if you do that – it’ll screw up the rest of our code.  Trust me, the above is the easiest and clearest way to do it.

  • do this means literally “do the below code that’s inside the loop”
  • — our code will go here is just a comment.  We’ll copy our previously written code in here shortly, and edit it a bit.
  • end is the end of the loop

Congratulations!  If you write this code and remove your previous code, the number of times the loop is executed will be equal to the number of tracks you’ve selected!  If you want to test this out, throw a console message inside the loop like so:

reaper.ShowConsoleMsg("I'm in the loop!\n")

Arming our tracks with the loop

Now it’s time to actually fill in the code within the loop.  Go ahead and paste the original code we used to arm a single track inside the for loop.  It should look like this:

for i = 0, number_of_tracks-1 do
track = reaper.GetSelectedTrack(0,0)
reaper.SetMediaTrackInfo_Value(track, "I_RECARM", 1)
end

However, as it is this code still won’t work right.  It will just set the topmost selected track to armed over and over again.  Why?  Because we’re instructing GetSelectedTrack to get track 0 over and over again.  How do we solve this?  With our for loop!

Check out this cool magic, change your code to the below (I’ve bolded what’s different):

for i = 0, number_of_tracks-1 do
track = reaper.GetSelectedTrack(0,i)
reaper.SetMediaTrackInfo_Value(track, "I_RECARM", 1)
end

If you remember right, each time we go through the loop the variable “i” increases in value by 1.  So if we use “i” in place of the second zero in GetSelectedTrack (which indicates the number of track we want), we iterate through all the tracks!

So your complete code (with comments) should be:

-- Get the number of tracks currently selected
number_of_tracks = reaper.CountSelectedTracks(0)


-- Loop through each track and arm it for record
for i = 0, number_of_tracks-1 do
track = reaper.GetSelectedTrack(0,i)
reaper.SetMediaTrackInfo_Value(track, "I_RECARM", 1)
end

super highly encourage you to write this code on your own and then run it.  It should record arm all the tracks you’ve selected.

We still need to add some conditions to our code to make it more complete.  But we’ll continue to flesh that out next week!


Copyright 2016-2017, Adam T. Croft, all rights reserved.