Creating an Audio Visualizer with 1 LED String

Hi everyone, i'm new with arduino and Audio Visualizer. I'd like to create a LED show with the song Highway to hell. I'd like to create 2 different effect using FFT (Or any other similar libraries). In a first moment i've tried with MSGEQ7, but every chip was faulty, so now I must virtualize everything.
The effects are:

  1. Create a "rainbow VU Meter effect", which doesn't really work with the volume, but only when some instruments are playing.
  2. Power on all the LED When a Range of Frequency reach a minimum value. It's hard to explain, so I'm going to explain with Highway to hell. In the first seconds, we can hear only the guitar, which surely has a Specific Frequency(so the led turns on in time with the instrument). When another instrument comes, I'd like that the light continues following only the guitar.

I understand that this won't be really accurate, but I'm wondering if this is possible.
When I look for the VU METER effect with FFT, everyone uses a matrix of led, but I only want to power on one string.

For better understanding, this is MSGEQ7 datasheet

In the end, I want to emulate the MSGEQ7 to make a light effect. The audio comes from DFMini Player pins DAC_R/L
image

For the moment, I'm using this code which works correctly, but as I said, is a matrix and I'm not understanding how to manipulate It to make it works with 1 single led String. Moreover, i don't know how to choose only one instrument from this code.
Source of the code

#include <arduinoFFT.h>
#include <FastLED.h>

#define SAMPLES 64        // Must be a power of 2
#define MIC_IN A0         // Use A0 for mic input
#define LED_PIN     2     // Data pin to LEDS
#define NUM_LEDS    49  
#define BRIGHTNESS  150    // LED information 
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB 
#define BUTTON_PIN 3
#define xres 7            // Total number of  columns in the display
#define yres 7            // Total number of  rows in the display

double vReal[SAMPLES];
double vImag[SAMPLES];

int Intensity[xres] = { }; // initialize Frequency Intensity to zero
int Displacement = 1;

CRGB leds[NUM_LEDS];            // Create LED Object
arduinoFFT FFT = arduinoFFT();  // Create FFT object

void setup() {
  pinMode(MIC_IN, INPUT);
  Serial.begin(115200); 
  //Serial.begin(9600);        //Initialize Serial
  delay(3000);                  // power-up safety delay
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); //Initialize LED strips
  FastLED.setBrightness(BRIGHTNESS);
}

void loop() {
  Visualizer(); 
}

void Visualizer(){
  //Collect Samples
  getSamples();
  
  //Update Display
  displayUpdate();
  
  FastLED.show();
}

void getSamples(){
  for(int i = 0; i < SAMPLES; i++){
    vReal[i] = analogRead(MIC_IN);
    Serial.println(vReal[i]);
    vImag[i] = 0;
  }

  //FFT
  FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
  
  

  //Update Intensity Array
  for(int i = 2; i < (xres*Displacement)+2; i+=Displacement){
    vReal[i] = constrain(vReal[i],0 ,2047);            // set max value for input data
    vReal[i] = map(vReal[i], 0, 2047, 0, yres);        // map data to fit our display

    Intensity[(i/Displacement)-2] --;                      // Decrease displayed value
    if (vReal[i] > Intensity[(i/Displacement)-2])          // Match displayed value to measured value
      Intensity[(i/Displacement)-2] = vReal[i];
  }
}

void displayUpdate(){
  int color = 0;
  for(int i = 0; i < xres; i++){
    for(int j = 0; j < yres; j++){
      if(j <= Intensity[i]){                                // Light everything within the intensity range
        if(j%2 == 0){
          leds[(xres*(j+1))-i-1] = CHSV(color, 255, BRIGHTNESS);
        }
        else{
          leds[(xres*j)+i] = CHSV(color, 255, BRIGHTNESS);
        }
      }
      else{                                                  // Everything outside the range goes dark
        if(j%2 == 0){
          leds[(xres*(j+1))-i-1] = CHSV(color, 255, 0);
        }
        else{
          leds[(xres*j)+i] = CHSV(color, 255, 0);
        }
      }
    }
    color += 255/xres;                                      // Increment the Hue to get the Rainbow
  }
}

There are a lot of reports about defective or "fake" MSGEQ7 chips. They should be OK if you buy from a reliable supplier like SparkFun. SparkFun also sells an assembled MSGEQ7 board which is probably tested.

But yes, FFT and FHT are also options and you can get more frequency bands.

The main thing is to get the effects and the audio analysis both working before you put them together. The effects you can make are only limited by your imagination!

:frowning: It's not that simple... Most instruments, and the human voice, cover most of the frequency range. Even when playing one note, there are harmonics & overtones and that's what makes a guitar sound different from a piano and it's why every singer sounds different.

Audacity has a spectrum analyzer if you want to look at different parts of the song, etc. Audacity can also generate pure tones which is very useful for testing.

A VU meter just shows loudness without regard to frequency. A spectrum analyzer is like multiple VU meters for multiple frequency bands. But right... A real spectrum analyzer is a measurement instrument and much more accurate than a spectrum analyzer effect made with the Arduino.

Unfortunately i'm from italy and it takes too much time. There isn't any way to emulate this chip with FFT?

There are SparkFun distributors in a lot of different countries

and
www.robot-domestici.it
Are two.

Get the whole world map from
https://www.sparkfun.com/distributors

1 Like

A good overview reference site:

ArduinoFFT - Open Music Labs Wiki

and

Graphic Equalizer Display using ESP8266-12, MSGEQ7 and WS2812 « Adafruit Industries – Makers, hackers, artists, designers and engineers!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.