Audio Visualizer

Status
Not open for further replies.
Hello! I am making an audio visualizer in a 30 x 30 array. I have gotten everything to work and display properly, but it is extremely slow. I've debugged down to a super basic setup and it seems like the fft1024.read() function is performing really slow. Any suggestions? I have attached my code below. Thanks!



//libraries needed in order for the Fourier transforms to work properly
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <OctoWS2811.h>

// all OctoWS2811 variables and instantiations
const int ledsPerStrip = 30 * 8;
DMAMEM int displayMemory[ledsPerStrip*6];
int drawingMemory[ledsPerStrip*6];
const int config = WS2811_GRB | WS2811_800kHz;
OctoWS2811 leds(ledsPerStrip, displayMemory, drawingMemory, config);


// GUItool: begin automatically generated code
AudioInputUSB usb1; //xy=149,269
AudioInputI2S i2s1; //xy=202,375
AudioMixer4 mixer1; //xy=329,292
AudioAnalyzeFFT1024 fft1024_1; //xy=489,283
AudioConnection patchCord1(usb1, 0, mixer1, 0);
AudioConnection patchCord2(usb1, 1, mixer1, 1);
AudioConnection patchCord3(mixer1, fft1024_1);
AudioControlSGTL5000 sgtl5000_1; //xy=461,377
// GUItool: end automatically generated code

//variables for the colors and strip length
const float multiplier = 100;
const float stripLength = 30;
int rainbowColors[180];
int temp;

void setup(){
Serial.begin(9600);
AudioMemory(12);
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
// pinMode(0, INPUT_PULLUP);
// pinMode(1, INPUT_PULLUP);
// pinMode(2, INPUT_PULLUP);
// pinMode(ledPin, OUTPUT);
mixer1.gain(0, 0.5);
mixer1.gain(1, 0.5);
// Uncomment one these to try other window functions
//fft1024_1.windowFunction(NULL);
//fft1024_1.windowFunction(AudioWindowBartlett1024);
//fft1024_1.windowFunction(AudioWindowFlattop1024);

for (int i=0; i<180; i++) {
int hue = i * 2;
int saturation = 100;
int lightness = 50;
// pre-compute the 180 rainbow colors
rainbowColors = makeColor(hue, saturation, lightness);
}

leds.begin();
leds.show();
delay(1000);
}

void loop() {
//reading fft values for the strip
if (fft1024_1.available()) {
band(fft1024_1.read(0), multiplier, stripLength, 29);
band(fft1024_1.read(1), multiplier, stripLength, 28);
band(fft1024_1.read(2), multiplier, stripLength, 27);
band(fft1024_1.read(3,4), multiplier, stripLength, 26);
band(fft1024_1.read(5,6), multiplier, stripLength, 25);
band(fft1024_1.read(7,9), multiplier, stripLength, 24);
band(fft1024_1.read(10,12), multiplier, stripLength, 23);
band(fft1024_1.read(13,15), multiplier, stripLength, 22);
band(fft1024_1.read(16,18), multiplier, stripLength, 21);
band(fft1024_1.read(19,22), multiplier, stripLength, 20);
band(fft1024_1.read(23,27), multiplier, stripLength, 19);
band(fft1024_1.read(28,32), multiplier, stripLength, 18);
band(fft1024_1.read(33,39), multiplier, stripLength, 17);
band(fft1024_1.read(40,46), multiplier, stripLength, 16);
band(fft1024_1.read(47,56), multiplier, stripLength, 15);
band(fft1024_1.read(57,66), multiplier, stripLength, 14);
band(fft1024_1.read(67,79), multiplier, stripLength, 13);
band(fft1024_1.read(80,93), multiplier, stripLength, 12);
band(fft1024_1.read(94,112), multiplier, stripLength, 11);
band(fft1024_1.read(113,131), multiplier, stripLength, 10);
band(fft1024_1.read(132,157), multiplier, stripLength, 9);
band(fft1024_1.read(158,184), multiplier, stripLength, 8);
band(fft1024_1.read(185,220), multiplier, stripLength, 7);
band(fft1024_1.read(221,257), multiplier, stripLength, 6);
band(fft1024_1.read(258,288), multiplier, stripLength, 5);
band(fft1024_1.read(289,324), multiplier, stripLength, 4);
band(fft1024_1.read(325,364), multiplier, stripLength, 3);
band(fft1024_1.read(365,410), multiplier, stripLength, 2);
band(fft1024_1.read(411,460), multiplier, stripLength, 1);
band(fft1024_1.read(461,511), multiplier, stripLength, 0);
}
}

//calucate what LEDs need to be on
void band(float n, float m, int len, int col){
for (int i = 0; i < len; i++){
int pix = translate(col, i, len);
if ( i < n*m){
leds.setPixel(pix, rainbowColors[temp]);
}else {
leds.setPixel(pix, 000000);
}
}
temp++;

if (temp == 180){
temp = 0;
}
leds.show();
}

int translate(int col, int row, int len){
if (col % 2 ==0){
return ((col*len)+row);
}else{
return ((col*len)+len-1-row);
}
}

//create the color spectrum in the setup stage
int makeColor(unsigned int hue, unsigned int saturation, unsigned int lightness)
{
unsigned int red, green, blue;
unsigned int var1, var2;

if (hue > 359) hue = hue % 360;
if (saturation > 100) saturation = 100;
if (lightness > 100) lightness = 100;

// algorithm from: http://www.easyrgb.com/index.php?X=MATH&H=19#text19
if (saturation == 0) {
red = green = blue = lightness * 255 / 100;
} else {
if (lightness < 50) {
var2 = lightness * (100 + saturation);
} else {
var2 = ((lightness + saturation) * 100) - (saturation * lightness);
}
var1 = lightness * 200 - var2;
red = h2rgb(var1, var2, (hue < 240) ? hue + 120 : hue - 240) * 255 / 600000;
green = h2rgb(var1, var2, hue) * 255 / 600000;
blue = h2rgb(var1, var2, (hue >= 120) ? hue - 120 : hue + 240) * 255 / 600000;
}
return (red << 16) | (green << 8) | blue;
}

unsigned int h2rgb(unsigned int v1, unsigned int v2, unsigned int hue)
{
if (hue < 60) return v1 * 60 + (v2 - v1) * hue;
if (hue < 180) return v2 * 60;
if (hue < 240) return v1 * 60 + (v2 - v1) * (240 - hue);
return v1 * 60;
}
 
The FFT will execute 43 times per second or once every 23 milliseconds. Which should be fast enough.
However, you are redrawing every one of the 900 pixels each time. I haven't used led strips so I don't know how long it would take to refresh all of them but I'd guess that it could be what is slowing things down.
Can you modify the code so that it only refreshes those pixels which have changed from the previous frame?

Pete
 
solution?

Ok, so if im understanding correctly this should provide a quick solution to the problem?


void band(float n, float m, int len, int col){
for (int i = 0; i < len; i++){
int pix = translate(col, i, len);
if ( i < n*m){
leds.setPixel(pix, rainbowColors[temp]);
}else {
if(leds.getPixel(pix) != 000000){ <----------------------------------------------
leds.setPixel(pix, 000000); <---------------------------------------------
}
}
}
temp++;

if (temp == 180){
temp = 0;
}
leds.show();
}
 
Your code is much more readable if you enclose it with the CODE tags using the # button above. It's not space science but makes reading and helping so much easier. See below.
Code:
void band(float n, float m, int len, int col){
    for (int i = 0; i < len; i++){
        int pix = translate(col, i, len);
        if ( i < n*m){
            leds.setPixel(pix, rainbowColors[temp]);
        }else {
             if(leds.getPixel(pix) != 000000){ <----------------------------------------------
                  leds.setPixel(pix, 000000); <---------------------------------------------
             }
         }
    }
    temp++;

    if (temp == 180){
        temp = 0;
    }
    leds.show();
}
 
Thank you all for the help. It seems the problem was with leds.show() because I was showing all 900 LEDs everytime one strip was being updated, thus making it 30 times slower than it should be (30 strips).
 
Status
Not open for further replies.
Back
Top