52 lines
1.5 KiB
C++
52 lines
1.5 KiB
C++
// master_gain.cpp — see master_gain.h. Pure math; no LICE/VST3/REAPER includes.
|
|
|
|
#include "core/instrument/engine/master_gain.h"
|
|
|
|
#include "core/util/clamp01.h"
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
#include <cstdio>
|
|
#include <limits>
|
|
|
|
namespace reasampler::instrument::engine {
|
|
|
|
using util::clamp01;
|
|
|
|
double masterGainMaxLinear() { return std::pow(10.0, kMasterGainMaxDb / 20.0); }
|
|
|
|
double masterGainDbFromNorm(double norm) {
|
|
norm = clamp01(norm);
|
|
if (norm <= 0.0) return -std::numeric_limits<double>::infinity();
|
|
return kMasterGainMinDb + norm * (kMasterGainMaxDb - kMasterGainMinDb);
|
|
}
|
|
|
|
double masterGainNormFromDb(double db) {
|
|
if (!(db > kMasterGainMinDb)) return 0.0; // -inf, NaN, and the floor all read 0
|
|
return clamp01((db - kMasterGainMinDb) / (kMasterGainMaxDb - kMasterGainMinDb));
|
|
}
|
|
|
|
double masterGainLinearFromNorm(double norm) {
|
|
norm = clamp01(norm);
|
|
if (norm <= 0.0) return 0.0; // TRUE silence at the bottom — not an epsilon
|
|
return std::pow(10.0, masterGainDbFromNorm(norm) / 20.0);
|
|
}
|
|
|
|
double masterGainNormFromLinear(double linear) {
|
|
if (!std::isfinite(linear) || linear <= 0.0) return 0.0;
|
|
return masterGainNormFromDb(20.0 * std::log10(linear));
|
|
}
|
|
|
|
void formatMasterGainLabel(double norm, char* buf, std::size_t len) {
|
|
if (!buf || len == 0) return;
|
|
norm = clamp01(norm);
|
|
if (norm <= 0.0) {
|
|
std::snprintf(buf, len, "-inf");
|
|
return;
|
|
}
|
|
const double db = masterGainDbFromNorm(norm);
|
|
std::snprintf(buf, len, "%+.1fdB", db);
|
|
}
|
|
|
|
} // namespace reasampler::instrument::engine
|