Audio VU Meter

Dlama
Offline
Зарегистрирован: 17.09.2014

Всем привет!

Захотел сделать уровень звука на светиках. Нашел вот такую схемку http://home.comcast.net/~kkrausnick/arduino_projects/index.html#vumeter

/*

  VU Meter

  Reads analog input from the left or right channel of an audio device.
  Relative volume is rendered across a series of ten resistors.
  Sensitivity can be adjusted using a potentiometer whose value is also read.

  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and 

ground.
  Attach audio channel positive wire to pin A1 and the other to ground.
 */

const int sensitivityPin = A0;  // Analog input pin that the potentiometer is attached to
const int audioPin = A1;        // Analog input pin that the audio channel is attached to
const int ledCount = 10;        // The number of LEDs in the bar graph
const int numReadings = 20;     // Number of samples to keep track of (for smoothing)

int audioValue;                 // Analog value read from audio channel
int maxAudioValue = 0;          // Maximum analog value read from audio channel
int sensitivityValue;           // Analog value read from potentiometer
int ledLevel;                   // Value to map to the output LEDs
int ledPins[] = {
  11, 10, 9, 8, 7, 6, 5, 4, 3, 2};  // Pin numbers to which LEDs are attached
int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

void setup() {
  // loop over the pin array and set them all to output:
  for (int thisLed = 0; thisLed < ledCount; thisLed++)
    pinMode(ledPins[thisLed], OUTPUT);
  // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;          
}

void loop() {
  // subtract the last reading:
  total = total - readings[index];
  // read from the sensor:  
  readings[index] = analogRead(audioPin);
  // add the reading to the total:
  total= total + readings[index];
  // advance to the next position in the array:
  index = index + 1;

  // if we're at the end of the array...
  if (index >= numReadings)
    // ...wrap around to the beginning:
    index = 0;

  // calculate the average:
  average = total / numReadings;
 
  audioValue = average;
  if (audioValue > maxAudioValue)
    maxAudioValue = audioValue;  

  sensitivityValue = analogRead(sensitivityPin);
  ledLevel = map(audioValue, 0, 1023, 0, sensitivityValue);
  if (ledLevel > ledCount) {
    ledLevel = ledCount;
  }
  
  for (int thisLed = 0; thisLed < ledCount; thisLed++) {
    if (thisLed < ledLevel)
      digitalWrite(ledPins[thisLed], HIGH);
    else
      digitalWrite(ledPins[thisLed], LOW);
  }

  delay(1);        // delay in between reads for stability
}

Собрал, залил скетч, все работает на ура! Порадовался я, значит, несколько дней, и мне стало не нравится то что громкость звука в одних песнях большая - светики всегда горят, а вдругих маленькая - светики еле подергиваются. А крутить всегда резистор уже надоело. Вобщем в этом то и вопрос. Каким образом выровнять громкость? Может есть какие нибудь программные или железные способы, подскажите или пните в нужную сторону.

com
Offline
Зарегистрирован: 06.09.2013

так вы определитесь - вам надо громкость выровнять или сделать чтобы светодиоды равномерно по всей шкале дергались независимо от громкости?

Dlama
Offline
Зарегистрирован: 17.09.2014

> сделать чтобы светодиоды равномерно по всей шкале дергались независимо от громкости

Это! Извиняюсь, что не конкретно выразился.

com
Offline
Зарегистрирован: 06.09.2013

представьте себе: первая песня  тихая, но светодиоды дергаются равномерно по всей шкале. вторая песня громкая, но светодиоды опять равномерно дергаются по всей шкале, ибо диапазон min/max динамический - так? немного утрирую, и получится - припев тихий, куплет громкий, а индикатору уровня сигнала по барабану, моргает по всему диапазону.

а смысл в таком индикаторе?

да и как оценить максимальный уровень диапазона песни? по первым нескольким секундам?

можно, к примеру, сделать так, плавно меняя максимальный уровень по ходу песни: после очередного измерения уровня сигнала оценивать его на близость к минимуму или максимуму, и если он меньше 200 или больше 800, то вводить повышающий или понижающий коэффициент ко всему массиву. и только потом вычислять среднее.