mumble-voip_mumble/src/VolumeAdjustment.cpp

67 lines
2.5 KiB
C++

// Copyright 2022-2023 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
#include "VolumeAdjustment.h"
#include <cassert>
#include <cmath>
constexpr float DB_THRESHOLD = 0.1f;
VolumeAdjustment::VolumeAdjustment(float factor, int dbAdjustment) : factor(factor), dbAdjustment(dbAdjustment) {
assert(dbAdjustment == INVALID_DB_ADJUSTMENT
// Verify that the used dbAdjustment is a reasonable representation of the given factor. Particularly, we
// want to make sure that the deviation of the true dB representation of the factor (usually a floating point
// value) doesn't deviate more than dbThreshold from the passed integer dB value. For all cases, where this
// would be the case, we expect INVALID_DB_ADJUSTMENT to be passed instead.
//
// If dB is the dB-representation of a loudness change factor f, we have
// dB = log2(f) * 6 <=> f = 2^{dB/6}
// (+6dB equals a doubling in loudness)
|| DB_THRESHOLD >= std::abs(static_cast< float >(dbAdjustment) - VolumeAdjustment::toDBAdjustment(factor)));
}
// Decibel formula: +6db = *2
float VolumeAdjustment::toFactor(int dbAdjustment) {
return static_cast< float >(std::pow(2.0, dbAdjustment / 6.0));
}
float VolumeAdjustment::toDBAdjustment(float factor) {
return static_cast< float >(std::log2(factor) * 6.0);
}
int VolumeAdjustment::toIntegerDBAdjustment(float factor) {
return static_cast< int >(std::roundf(VolumeAdjustment::toDBAdjustment(factor)));
}
VolumeAdjustment VolumeAdjustment::fromFactor(float factor) {
if (factor > 0) {
float dB = VolumeAdjustment::toDBAdjustment(factor);
if (std::abs(dB - static_cast< float >(static_cast< int >(dB))) < DB_THRESHOLD) {
// Close-enough
return VolumeAdjustment(factor, static_cast< int >(std::round(dB)));
} else {
return VolumeAdjustment(factor, INVALID_DB_ADJUSTMENT);
}
} else {
return VolumeAdjustment(factor, INVALID_DB_ADJUSTMENT);
}
}
VolumeAdjustment VolumeAdjustment::fromDBAdjustment(int dbAdjustment) {
float factor = VolumeAdjustment::toFactor(dbAdjustment);
return VolumeAdjustment(factor, dbAdjustment);
}
bool operator==(const VolumeAdjustment &lhs, const VolumeAdjustment &rhs) {
return lhs.dbAdjustment == rhs.dbAdjustment && std::abs(lhs.factor - rhs.factor) < 0.1f;
}
bool operator!=(const VolumeAdjustment &lhs, const VolumeAdjustment &rhs) {
return !(lhs == rhs);
}