Keith Mitchell
Published © GPL3+

Audio Visualizer using the Intel Edison and a Launchpad S

I've had a Launchpad S sitting around for awhile and since it's basically a 3 color LED matrix I decided to make an audio visualizer with it

AdvancedFull instructions provided2,534
Audio Visualizer using the Intel Edison and a Launchpad S

Things used in this project

Hardware components

SparkFun Block for Intel® Edison - Base
SparkFun Block for Intel® Edison - Base
Or you could use the Intel breakout for the Edison
×1
USB-A to Micro-USB Cable
USB-A to Micro-USB Cable
×1
SparkFun USB OTG Micro
×1

Software apps and online services

Processing
Intel Edison Yocto Linux
PuTTY

Hand tools and fabrication machines

Novation Launchpad S

Story

Read more

Code

Processing Code

Java
The processing code that runs on the computer playing the music
import ddf.minim.*;
import ddf.minim.analysis.*;
import processing.opengl.*;

import processing.net.*; 

AudioInput stream;
FFT fft;

String url = "192.168.0.107:3000";
Client myClient;

boolean showGraphics = true;

int windowSize = 200;

int GridSize = 8;

int blockSize = windowSize / GridSize;

color red = color(255, 0, 0);
color green = color(0, 255, 0);
color yellow = color(255, 255, 0);


int[][] pads = {{ 0, 0, 0, 0, 0, 0, 0, 0 }, 
                { 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 0, 0, 0, 0, 0 }};

void setup(){
  if(showGraphics){
    size(windowSize,windowSize);
    colorMode(HSB, width, 100, width);
    noStroke();
    background(100,100,100);
  }
  Minim minim  = new Minim(this);
  stream = minim.getLineIn(Minim.STEREO);
  fft = new FFT(stream.bufferSize(), stream.sampleRate());
  
  println("Avaliable Spectrum Size: " + fft.specSize());
  
  myClient = new Client(this, "192.168.0.107", 3000);
}

void draw(){
   pads = new int[][] {{ 0, 0, 0, 0, 0, 0, 0, 0 }, 
            { 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0 }};
  
 if(showGraphics){ 
   background(100, 100, 100);
  }
  fft.forward(stream.mix);
  pushMatrix();
  for(int i = 0; i < GridSize; i=i+1)
  {
    int barHeight = Math.round(fft.getBand(i*10)*4)/8;
    if(barHeight > GridSize){
      barHeight = GridSize;
    }
    for(int i2 = 0; i2 < barHeight; i2=i2+1)
    {  
      int barX = i * blockSize;
      if(i2 > 5){
        fill(red);
        pads[i][i2] = 3;
      }else if(i2 > 2){
        fill(yellow);
        pads[i][i2] = 2;
      }else{
        fill(green);
        pads[i][i2] = 1;
      }
      rect(barX, (height-(blockSize*i2))-blockSize, blockSize, blockSize);
    } 
  }
  popMatrix();
  sendServerData();
  delay(80);
}

void stop(){
  stream.close();
  myClient.stop();
  super.stop();
}

void sendServerData (){
  String padData = "";
  for(int[] ia :  pads){
    for(int i :  ia){
      padData = padData + Integer.toString(i) + " ";
    }
  }
  sendToServer(padData);
}

void sendToServer(String s){
  myClient.write("POST / HTTP/1.1\n");
  myClient.write("Host: 192.168.0.107:3000\n");
  myClient.write("Cache-Control: no-cache\n");
  myClient.write("Content-Type: text/plain\n");
  myClient.write("content-length: " + s.length() + "\n");     
  myClient.write("\n");
  myClient.write(s);
  myClient.write("\n\n");
}

NodeJS code

JavaScript
The code for running the NodeJS server, to start it simply type "node ." after creating the Node project
var express = require('express');
var app = express();
var bodyParser = require('body-parser')

var logging = false

//Novation Programmers Referance
//https://d19ulaff0trnck.cloudfront.net/sites/default/files/novation/downloads/4700/launchpad-s-prm.pdf

var colors = {"off":"0C", 
              "dim_green":"3E", "med_green":"3D", "full_green":"3C",
              "dim_red":"0D",   "full_red":"0F",
              "full_orange":"2F",
              "full_amber":"3F",
              "full_yellow":"3E"}

var novation_id = "00 20 29"
var launchpad_id = "20 00"

var commands = {"reset":"B0 00 00",
                "all_on":          "B0 00 7F",
                "button_layout_1": "B0 00 01",
                "button_layout_2": "B0 00 02",
                "device_inquiry":  "F0 7E 7F 06 01 F7",
                "empty_scroll":    "F0 00 20 29 00 F7",
                "switch_buffers":  "B0 10 "}

var buffer_bits = {"s":"20",    // display and write one buffer
                   "b0":"24",   // display 0 write 1
                   "b1":"21",   // display 1 write 0
                   "b0c":"34",  // display 0 copy to 1
                   "b1c":"31",  // display 1 copy to 0
                   "flash":"28" // write 0 swap every 280 ms
                  }


var displayGrid = ["0C","0C","0C","0C","0C","0C","0C","0C",
                   "0C","0C","0C","0C","0C","0C","0C","0C",
                   "0C","0C","0C","0C","0C","0C","0C","0C",
                   "0C","0C","0C","0C","0C","0C","0C","0C",
                   "0C","0C","0C","0C","0C","0C","0C","0C",
                   "0C","0C","0C","0C","0C","0C","0C","0C",
                   "0C","0C","0C","0C","0C","0C","0C","0C",
                   "0C","0C","0C","0C","0C","0C","0C","0C"]

app.use( bodyParser.text());

app.post('/', function(req, res) {
    process_data(req.body);
});

app.listen(3000, function () {
  run_cmd("amidi", ["-l"], function(text) { console.log (text) })
  reset_pad ()

  console.log('Example app listening on port 3000!');
})

function process_data (data){
    switch_buffers();
    var splitData = data.split(" ");
    var arrayLength = splitData.length; 
    for (var i = 0; i < arrayLength; i++) {
        if(parseInt(splitData[i]) == 0)
            displayGrid[i] = colors["off"]
        if(parseInt(splitData[i]) == 1)
            displayGrid[i] = colors["full_green"]
        if(parseInt(splitData[i]) == 2)
            displayGrid[i] = colors["full_yellow"]
        if(parseInt(splitData[i]) == 3)
            displayGrid[i] = colors["full_red"]
    }
    push_grid ();
}

var buffer = 0

function switch_buffers(){
    if(buffer = 0)
        buffer = 1
    else if (buffer = 1)
        buffer = 0
      run_cmd("amidi", ["-phw:2", "-S "+commands["switch_buffers"]+buffer_bits["b"+buffer]])
}

function reset_pad (){
    run_cmd("amidi", ["-phw:2", "-S "+commands["reset"]])
}

function push_grid (){
    var gridCommand = "92 ";
    var arrayLength = displayGrid.length;
    for (var i = 0; i < arrayLength; i++) {
        gridCommand = gridCommand + displayGrid[i] + " ";
    }

    run_cmd("amidi", ["-S " + gridCommand])
    if(logging)
       console.log("amidi -S " + gridCommand);
}

function run_cmd(cmd, args, callBack) {
    var spawn = require('child_process').spawn;
    var child = spawn(cmd, args);
    var resp = "";

     child.stdout.on('data', function (buffer) { resp += buffer.toString() });
     child.stderr.on('data', function (buffer) { resp += buffer.toString() });
     if(typeof callBack !== 'undefined')
         child.stdout.on('end', function() { callBack (resp) });

     if(logging){
        child.on('close', function (code){
          console.log('child process exited with code ' + code);
        });
        child.on('error', function (error){
          console.log('child process errored ' + error);
        });
    }
}

Credits

Keith Mitchell

Keith Mitchell

10 projects • 43 followers
Canadian DevOps Engineer and hobbyist technology enthusiast

Comments