Files
GyverLamp2/firmware/GyverLamp2_v0.6b/VolAnalyzer.h
2021-02-03 23:34:17 +03:00

123 lines
3.8 KiB
C++

#pragma once
#include <Arduino.h>
#include "FastFilter.h"
class VolAnalyzer {
public:
VolAnalyzer (int pin = -1) {
volF.setDt(20);
volF.setPass(FF_PASS_MAX);
maxF.setPass(FF_PASS_MAX);
setVolK(25);
setAmpliK(31);
if (pin != -1) setPin(pin);
}
void setPin(int pin) {
_pin = pin;
pinMode(_pin, INPUT);
}
void setDt(int dt) {
_dt = dt;
}
void setPeriod(int period) {
_period = period;
}
void setVolDt(int volDt) {
volF.setDt(volDt);
}
void setAmpliDt(int ampliDt) {
_ampliDt = ampliDt;
}
void setWindow(int window) {
_window = window;
}
void setVolK(byte k) {
volF.setK(k);
}
void setAmpliK(byte k) {
maxF.setK(k);
minF.setK(k);
}
void setVolMin(int scale) {
_volMin = scale;
}
void setVolMax(int scale) {
_volMax = scale;
}
void setTrsh(int trsh) {
_trsh = trsh;
}
bool tick(int thisRead = -1) {
volF.compute();
if (millis() - tmr4 >= _ampliDt) { // период сглаживания амплитуды
tmr4 = millis();
maxF.setRaw(maxs);
minF.setRaw(mins);
maxF.compute();
minF.compute();
maxs = 0;
mins = 1023;
}
if (_period == 0 || millis() - tmr1 >= _period) { // период между захватом сэмплов
if (_dt == 0 || micros() - tmr2 >= _dt) { // период выборки
tmr2 = micros();
if (thisRead == -1) thisRead = analogRead(_pin);
if (thisRead > max) max = thisRead; // ищем максимум
if (!_first) {
_first = 1;
maxF.setFil(thisRead);
minF.setFil(thisRead);
}
if (++count >= _window) { // выборка завершена
tmr1 = millis();
raw = max;
if (max > maxs) maxs = max; // максимумы среди максимумов
if (max < mins) mins = max; // минимумы реди максимумов
maxF.checkPass(max); // проверка выше максимума
if (getMax() - getMin() < _trsh) max = 0; // если окно громкости меньше порого то 0
else max = constrain(map(max, getMin(), getMax(), _volMin, _volMax), _volMin, _volMax); // перевод в громкость
volF.setRaw(max); // фильтр столбика громкости
if (volF.checkPass(max)) _pulse = 1; // проверка выше максимума
max = count = 0;
return true; // выборка завершена
}
}
}
return false;
}
int getRaw() {
return raw;
}
int getVol() {
return volF.getFil();
}
int getMin() {
return minF.getFil();
}
int getMax() {
return maxF.getFil();
}
bool getPulse() {
if (_pulse) {
_pulse = false;
return true;
}
return false;
}
private:
int _pin;
int _dt = 600; // 600 мкс между сэмплами достаточно для музыки
int _period = 5; // 5 мс между выборами достаточно
int _ampliDt = 150;
int _window = 20; // при таком размере окна получаем длительность оцифровки 12 мс, вполне хватает
uint32_t tmr1 = 0, tmr2 = 0, tmr3 = 0, tmr4 = 0;
int raw = 0;
int max = 0, count = 0;
int maxs = 0, mins = 1023;
int _volMin = 0, _volMax = 100, _trsh = 30;
bool _pulse = 0, _first = 0;
FastFilter minF, maxF, volF;
};