Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: Audio Visualizer

  1. #1
    Junior Member
    Join Date
    Dec 2020
    Posts
    16

    Audio Visualizer

    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[i] = 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;
    }

  2. #2
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,742
    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

  3. #3
    Junior Member
    Join Date
    Dec 2020
    Posts
    16

    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();
    }

  4. #4
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    412
    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();
    }

  5. #5
    Junior Member
    Join Date
    Dec 2020
    Posts
    16
    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).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •