Browse Source

Clean up VuMeter2.

tags/v1.0.0
Andrew Belt 5 years ago
parent
commit
9bac9c8d7b
2 changed files with 32 additions and 10 deletions
  1. +4
    -0
      include/dsp/digital.hpp
  2. +28
    -10
      include/dsp/vumeter.hpp

+ 4
- 0
include/dsp/digital.hpp View File

@@ -143,6 +143,10 @@ struct Counter {
period = 1;
}

void setPeriod(int period) {
this->period = period;
}

/** Returns true if the counter reaches `period` and resets. */
bool process() {
if (++count >= period) {


+ 28
- 10
include/dsp/vumeter.hpp View File

@@ -33,22 +33,44 @@ struct VuMeter {
DEPRECATED typedef VuMeter VUMeter;


/** Models a VU meter with smoothing.
Supports peak and RMS (root-mean-square) metering
Usage example for a strip of lights with 3dB increments:

// Update VuMeter state every frame.
vuMeter.process(deltaTime, output);
// Iterate lights every ~512 frames (less than a screen refresh).
for (int i = 0; i < 6; i++) {
float b = vuMeter.getBrightness(-3.f * (i + 1), -3.f * i);
// No need to use setSmoothBrightness() since VuMeter2 smooths the value for you.
lights[i].setBrightness(b);
}
*/
struct VuMeter2 {
enum Mode {
PEAK,
RMS
};
Mode mode = PEAK;
float v = 0.f;
/** Either the smoothed peak or the mean-square of the brightness, depending on the mode. */
float v;
/** Inverse time constant in 1/seconds */
float lambda = 0.f;
float lambda = 30.f;

VuMeter2() {
reset();
}

void reset() {
v = 0.f;
}

void process(float deltaTime, float value) {
if (mode == PEAK) {
if (mode == RMS) {
value = std::pow(value, 2);
v += (value - v) * lambda * deltaTime;
}
else {
value = std::abs(value);
if (value >= v) {
v = value;
@@ -57,22 +79,18 @@ struct VuMeter2 {
v += (value - v) * lambda * deltaTime;
}
}
else {
value = std::pow(value, 2);
v += (value - v) * lambda * deltaTime;
}
}

/** Returns the LED brightness measuring tick marks between dbMin and dbMax.
For example, `getBrightness(-6.f, 0.f)` will be at minimum brightness at -6dB and maximum brightness at 0dB.
Set dbMin == dbMax == 0.f for a clip indicator.
Set dbMin == dbMax == 0.f for a clip indicator that turns fully on when db >= dbMax.
Expensive, so call this infrequently.
*/
float getBrightness(float dbMin, float dbMax) {
float db = amplitudeToDb((mode == RMS) ? std::sqrt(v) : v);
if (db > dbMax)
if (db >= dbMax)
return 1.f;
else if (db < dbMin)
else if (db <= dbMin)
return 0.f;
else
return math::rescale(db, dbMin, dbMax, 0.f, 1.f);


Loading…
Cancel
Save