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

You made it, part 3! The last piece of the puzzle. If you missed parts 1 & 2 be sure to check them out here.

Part 1Part 2

So… how do we keep all the instruments in sync? We need a conductor! Luckily in the digital world this already exists, called the midi clock. A midi clock is typically used to synchronize DJ software, however we can use it for our own lighting purposes. A piece of software that is sending out a midi clock signal does so 24 times per beat. As you might guess, this is why we define our quarter notes with a value of 24. Since we have four of these beats per measure, we also get 4*24 = 96 for a measure. If we can connect this midi clock to our led controller we can feed the value to our functions as the “current time” to keep everything in sync. 

Now, what software do we use? how do we get this “MIDI clock”? and how do we send it to the LED controller (like an Arduino). Well, first and foremost, we’ll use a program called Traktor 3. It’s typically used for djing, but it will also do the tempo and beat analysis on our music and most importantly output our midi clock. 

While the full version is not free, there is a trial version available here. <Traktor>  What’s nice is the trial gives you access to the entire program, but it needs to be restarted every 30 minutes. This way you can give it a try without any financial investment. 

Once downloaded and installed, open up Traktor and run the trial. It should bring you here.

traktor1.PNG

There is a ton to learn and master in Traktor, but we can get by with only a couple features. At its core Traktor is a music player, but with all sorts of fancy knobs, dials, and buttons, for mixing, cutting, and well, djing music. 

Start by using the explorer in the bottom left to navigate to whatever music files you want to use. From there you can drag and drop them into either of the “tracks” above. Try clicking the play button below the track. If it turns green but the music doesn’t start it means we first have to tell Traktor what speakers to use.

trackred.png

Go to Preferences (gear in top right) -> Audio Setup -> Audio Device and select the correct output for the sound. It’s find to just trial and error them until you find the right one.

traktor1red.png

Now you should be able to play, pause, and scroll your way through the song playback. Next up, let's get the MIDI clock working. First go to Preferences -> External Sync -> Enable MIDI Clock and make sure the box is checked. Close out of preferences and there should be a little play/pause icon near the top middle. Click it to turn it blue and Traktor is sending out the MIDI Clock for whatever song you’re playing. If you can’t see the button, you might have to change the view to “mixer mode” from the drop down in the top right.

syncred.png

Unfortunately there are a couple more steps before the Arduino can get the signal. Long story short, we need to bridge traktor’s midi output to the serial port on our Arudino. To do this we need a couple awesome pieces of software. Note: LoopBe1 is only necessary for windows machines.

LoopBe1 - <link> https://www.nerds.de/en/loopbe1.html

Midi Serial - <link> https://projectgus.github.io/hairless-midiserial/

Note: Starting with Catalina, MacOS can only run 64 bit programs. As of 1/5/2020 the hairless midiserial bridge has not been updated.

Download both programs and run LoopBe1. It won’t visually do much but you should see it active in your hidden icon tray.

iconred.png

Now we have to go back into the Traktor settings one last time. Navigate to Preferences -> Controller Manager -> Add… -> Generic MIDI, and set the Out-Port to LoopBe Internal MIDI. This connect completes the connection from Traktor -> LoopBe -> Hairless -> Serial Port.

While we’re here we might as well add a hotkey so we can start the MIDI Clock and music simultaneously. In the Controller Manager, add Generic Keyboard then click Add In… -&gt; Deck Common -&gt; Play/Pause and Add In… -&gt; Master Clock -&gt; Clock …

While we’re here we might as well add a hotkey so we can start the MIDI Clock and music simultaneously. In the Controller Manager, add Generic Keyboard then click Add In… -> Deck Common -> Play/Pause and Add In… -> Master Clock -> Clock Send to add them to the assignment table. Change them to toggle and use the learn button to give them a hotkey on your keyboard. I used Shift+Z but anything will work. Once you close out of the preferences you should be able to use your new hotkey to start the music and activate the MIDI Clock signal simultaneously.

Next run the Hairless MIDI &lt;-&gt; Serial Bridge. Select LoopBe Internal MIDI (PC) or Traktor Virtual (Mac) as the MIDI In and the Serial Port of your Arduino as the MIDI Out. If the green lights are blinking you know that Traktor is correctly con…

Next run the Hairless MIDI <-> Serial Bridge. Select LoopBe Internal MIDI (PC) or Traktor Virtual (Mac) as the MIDI In and the Serial Port of your Arduino as the MIDI Out. If the green lights are blinking you know that Traktor is correctly connected to Hairless MIDI.

hairon.PNG

Now that we can receive our clock midi bytes from Traktor, let’s take a look at the code. Here is the outline we will use to receive the MIDI Clock bytes. After setup, we poll for new bytes in the Serial Port and increment our “mclock” or current time through the measure by one. Since we know it will take 96 bytes to get through the measure we can reset our mclock and increment the measure once we get to 96. Using the framework from part 2 we can add animations that will “conducted” to activate at the correct time by our mclock.

#include <FastLED.h>

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

CRGB leds[150];

byte data;
byte midi_clock = 0xf8; // MIDI Clock Byte
int mclock = 1; // Time through current measure 0 -> 96     
int measure = 1; // Current measure

void setup() 
{
  Serial.begin(115200); // Start Serial Port for Hairless MIDI
  FastLED.addLeds<WS2812, 2, GRB>(leds, 150); // Init LED Strip
}

void loop() 
{
  
  if(Serial.available() > 0) // Check if we got a byte
  {
    data = Serial.read(); // Read in the byte
    if(data == midi_clock) // Make sure the byte is a midi clock byte
    {
      mclock += 1;
  
      if(mclock >= (24 * 4)) // Reset current time and increment measure
      {
        measure += 1;
        mclock = 0;
      }
  
      // Do some lighting animations here

      FastLED.show();
    }
  }  
}

To fill in our animations we can simply use conditionals around the current measure value to follow along to the song. Here we use our quarter note pattern for 4 measures and then switch to our next pattern.

if(measure >= 1 && measure <= 4)
{
  SetStrip(mclock, QUARTER*0, QUARTER, 0, 150, 0, 0, 255);
  SetStrip(mclock, QUARTER*1, QUARTER, 0, 150, 255, 0, 0);
  SetStrip(mclock, QUARTER*2, QUARTER, 0, 150, 0, 255, 0);
  SetStrip(mclock, QUARTER*3, QUARTER, 0, 150, 255, 255, 0);
}
if(measure >= 5 && measure <= 8)
{
  SetStrip(mclock, QUARTER*0, QUARTER, 0, 30, 0, 0, 255);
  SetStrip(mclock, QUARTER*1, QUARTER, 30, 60, 255, 0, 0);
  SetStrip(mclock, QUARTER*2, EIGHTH, 60, 90, 0, 255, 0);
  SetStrip(mclock, QUARTER*2 + EIGHTH, EIGHTH, 90, 120, 255, 255, 0);
  SetStrip(mclock, QUARTER*3, QUARTER, 120, 150, 255, 0, 255);
}

The full code can be found here on Github.

Lastly upload the code to your controller, activate the Hairless MIDI Serial Bridge, set Traktor to the begging of your song, and then press your hotkey to start the song and MIDI Clock simultaneously.

From here it’s all about getting creative and making new animations to new songs. Experiment with different patterns and different ways to make the LEDs move. Hopefully these guides have at the very least peaked your interest in designing your own lights. The sky is the limit.

If your’re interested in the light show without all the work, be sure to check out our social media for updates on our upcoming product!

Youtube - Instagram - Twitter

Previous
Previous

Portable LED Strips

Next
Next

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