Animating Music - How to Create a Light Show (Part 2)

If you missed part one be sure to check it out here! Animating Music (Part 1)

Once we have the rhythmic representation for a measure of music we have to translate it into something the LED controller can understand. While there are surely many ways to accomplish this, it all boils down to describing how the lights should act in the most concise way possible. We don’t want to rewrite the same code over and over if we can avoid it. A simple and effective way to do this is to create a function as a sort of “animation template”, whose parameters we can tweak to represent any type of note. To do this we’ll define a function with the following parameters.

StripSet(int time_current,  int time_start, int time_length, int first_pixel, int last_pixel, int red, int green, int blue);

time_current - This is the value we will get from our “conductor” to keep everything in sync. We’ll go over this in detail during part 3, however it can be thought of as a number that quickly goes from 0 -> 96 (from beginning to end of our measure). It represents how far we are through the current measure and therefore determines which animations should trigger.

time_start - How far through the measure the note starts. If our note starts on beat 1, it would be 0. If it start on beat 3, it would be 48. We are essentially describing how far through the measure a particular note should begin.

time_length - How long a note should be held for. This value is just the type of note as we defined. For a half note 48, quarter note 24, or an eighth note 12. etc.

first_pixel - Since we don’t want to write a function for every single LED on our strip, we set a group of them at once. This value should be the first pixel in the group we want to set.

last_pixel - For this simple function we are just going to set a continuous group of pixel. Therefore this value should be the last pixel in a group.

red - red pixel value for all LEDs in the group

green - green pixel value for all LEDs in the group

blue - blue pixel value for all LEDs in the group

It's a mouthful of parameters but it’s everything we need to define a section of LED strip for a note in the musical rhythm. In practice we might write a function call that looks a little something like this.

single_beat.png

“current_time” will be defined and discussed in part three, however we can check out the rest of the example. Our function defines a note that starts at 0 (the beginning of the measure) and last for 24 (one quarter note). Our “first_pixel” is 0 or the very first pixel in our strip. Our “last_pixel” is 150, so assuming we are using a strip with 150 LEDs, we will be commanding all pixels. The last three numbers, RGB, gives us the color blue.

Okay great we’ve got a function written but how does running it actually turn on the LEDs at the correct time? Let’s dive into the function. 

StripSet(int time_current,  int time_start, int time_length, int first_pixel, int last_pixel, int red, int green, int blue)
{
  if(time_current >= time_start && time_current < time_start+time_length)
  {
    for(int i = first_pixel; i < last_pixel; i++)
    {
      leds[i] = CRGB(red, green, blue);
    }
  }
}

This “animation template” can become much more complicated, adding more parameters and sophisticated functionality, however this represents the meat and potatoes of it. First we check to see if our “current_time”, or our progress through the current measure, is within the bounds of our note, and if so, set the group of LEDs to the appropriate color. 

Now we will prepare a whole measure of notes!

metro.png

While slightly repetitive, the simplicity of this framework allows us to list our functions one after another. Copy paste to your heart's content and then edit the parameters accordingly.

SetStrip(current_time,  0, 24, 0, 150, 0, 0, 255);
SetStrip(current_time, 24, 24, 0, 150, 255, 0, 0);
SetStrip(current_time, 48, 24, 0, 150, 0, 255, 0);
SetStrip(current_time, 72, 24, 0, 150, 255, 255, 0);

Here we’ve made a function call for each of the four notes in our measure. The “time_start” have all been spaced by 24 (a quarter note, also the note length) thus only one will activate at a time. They all command the entire 150 LED strip, however the RGB color values have been adjusted to cycle blue->red->green->yellow as each quarter note passes.

We can also define our note types and make a substitution of our timing parameters so function calls are more readable. Notice all the values remain the same, but the #defines and multiplication make constructing more complex measures and rhythms easier on the eyes.

#define WHOLE 96
#define HALF 48
#define QUARTER 24
#define EIGHTH 12
#define SIXTEENTH 6

SetStrip(current_time, QUARTER*0, QUARTER, 0, 150, 0, 0, 255);
SetStrip(current_time, QUARTER*1, QUARTER, 0, 150, 255, 0, 0);
SetStrip(current_time, QUARTER*2, QUARTER, 0, 150, 0, 255, 0);
SetStrip(current_time, QUARTER*3, QUARTER, 0, 150, 255, 255, 0);
full_measure.png

At this point we can add/remove more function calls to accommodate other rhythm patterns. We can change the group of LEDs each function commands and the color they will display. Let’s look at one more example before moving on to part 3.

simple.png

No big surprises on this one. Five notes, five function calls. The only tricky part is the eighth notes in the middle. Just keep track of where each note starts and how long they should last. In this example we also changed the groups so each note represents a fifth of the strip.

SetStrip(current_time, QUARTER*0, QUARTER, 0, 30, 0, 0, 255);
SetStrip(current_time, QUARTER*1, QUARTER, 30, 60, 255, 0, 0);
SetStrip(current_time, QUARTER*2, EIGHTH, 60, 90, 0, 255, 0);
SetStrip(current_time, QUARTER*2 + EIGHTH, EIGHTH, 90, 120, 255, 255, 0);
SetStrip(current_time, QUARTER*3, QUARTER, 120, 150, 255, 0, 255);
With our rhythm model and this framework we can create all sorts of interesting patterns for our LED strip. And now that we have put together animations for a couple measures, we can tie them all together in the final part.&nbsp;Before moving on, th…

With our rhythm model and this framework we can create all sorts of interesting patterns for our LED strip. And now that we have put together animations for a couple measures, we can tie them all together in the final part. 

Before moving on, think about how our “animation template” function could be modified to make more complex patterns. Also how we might set a group of LEDs that aren’t adjacent.

Also be sure to follow us on socials for updates and guides!

Instagram

Youtube

Twitter

Part 3 - Coming Soon!

Previous
Previous

Animating Music - How to Create a Light Show (Part 3)

Next
Next

Animating Music - How to Create a Light Show (Part 1)