Audio VU Meter
- Войдите на сайт для отправки комментариев
Ср, 17/09/2014 - 01:41
Всем привет!
Захотел сделать уровень звука на светиках. Нашел вот такую схемку 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 }
Собрал, залил скетч, все работает на ура! Порадовался я, значит, несколько дней, и мне стало не нравится то что громкость звука в одних песнях большая - светики всегда горят, а вдругих маленькая - светики еле подергиваются. А крутить всегда резистор уже надоело. Вобщем в этом то и вопрос. Каким образом выровнять громкость? Может есть какие нибудь программные или железные способы, подскажите или пните в нужную сторону.
так вы определитесь - вам надо громкость выровнять или сделать чтобы светодиоды равномерно по всей шкале дергались независимо от громкости?
> сделать чтобы светодиоды равномерно по всей шкале дергались независимо от громкости
Это! Извиняюсь, что не конкретно выразился.
представьте себе: первая песня тихая, но светодиоды дергаются равномерно по всей шкале. вторая песня громкая, но светодиоды опять равномерно дергаются по всей шкале, ибо диапазон min/max динамический - так? немного утрирую, и получится - припев тихий, куплет громкий, а индикатору уровня сигнала по барабану, моргает по всему диапазону.
а смысл в таком индикаторе?
да и как оценить максимальный уровень диапазона песни? по первым нескольким секундам?
можно, к примеру, сделать так, плавно меняя максимальный уровень по ходу песни: после очередного измерения уровня сигнала оценивать его на близость к минимуму или максимуму, и если он меньше 200 или больше 800, то вводить повышающий или понижающий коэффициент ко всему массиву. и только потом вычислять среднее.