7constexpr float dbIntervals[] = {
9 12.1, 7, 5, 3.9, 3.2, 2.6, 2.4, 2, 1.8, 1.7, 1.5, 1.4, 1.3, 1.2, 1.1,
14inline int32_t shiftVolumeByDB(int32_t oldValue,
float offset) {
15 uint32_t oldValuePositive =
static_cast<uint32_t
>(oldValue) + 2147483648u;
16 uint32_t currentInterval = oldValuePositive >> 28;
19 if (currentInterval < 1) {
23 float howFarUpInterval =
static_cast<float>(oldValuePositive & 268435455u) / 268435456.0f;
26 float dbThisInterval = dbIntervals[currentInterval];
30 float dbLeftThisInterval = (1.0f - howFarUpInterval) * dbThisInterval;
31 if (dbLeftThisInterval > offset) {
32 howFarUpInterval += offset / dbThisInterval;
35 if (currentInterval == 15) {
36 return std::numeric_limits<int32_t>::max();
38 offset -= dbLeftThisInterval;
40 howFarUpInterval = 0.0f;
44 float dbLeftThisInterval = howFarUpInterval * dbThisInterval;
45 if (dbLeftThisInterval > -offset) {
46 howFarUpInterval += offset / dbThisInterval;
49 if (currentInterval == 1) {
50 return std::numeric_limits<int32_t>::min();
52 offset += dbLeftThisInterval;
54 howFarUpInterval = 1.0f;
58 howFarUpInterval = std::clamp(howFarUpInterval, 0.0f, 0.99999994f);
59 uint32_t newValuePositive = (currentInterval << 28) + static_cast<uint32_t>(howFarUpInterval * 268435456.0f);
60 return static_cast<int32_t
>(newValuePositive - 2147483648u);