LibAudio: Refactor out linear_to_log function and add its inverse

The conversion from a linear scale (how we think about audio) to a
logarithmic scale (how audio actually works) will be useful for other
operations, so let's extract it to its own utility function. Its inverse
will also allow reversible operations to be written more easily.
This commit is contained in:
David Isaksson 2021-09-18 16:43:44 +02:00 committed by Brian Gianforcaro
parent 1e3e0477cb
commit fa4255bcf1
Notes: sideshowbarker 2024-07-18 01:22:26 +09:00

View File

@ -28,11 +28,7 @@ double const VOLUME_B = log(DYNAMIC_RANGE);
// A single sample in an audio buffer.
// Values are floating point, and should range from -1.0 to +1.0
struct Frame {
constexpr Frame()
: left(0)
, right(0)
{
}
constexpr Frame() = default;
// For mono
constexpr Frame(double left)
@ -70,9 +66,26 @@ struct Frame {
// This is a good dynamic range because it can represent all loudness values from
// 30 dB(A) (barely hearable with background noise)
// to 90 dB(A) (almost too loud to hear and about the reasonable limit of actual sound equipment).
//
// Format ranges:
// - Linear: 0.0 to 1.0
// - Logarithmic: 0.0 to 1.0
ALWAYS_INLINE double linear_to_log(double const change)
{
// TODO: Add linear slope around 0
return VOLUME_A * exp(VOLUME_B * change);
}
ALWAYS_INLINE double log_to_linear(double const val)
{
// TODO: Add linear slope around 0
return log(val / VOLUME_A) / VOLUME_B;
}
ALWAYS_INLINE Frame& log_multiply(double const change)
{
double factor = VOLUME_A * exp(VOLUME_B * change);
double factor = linear_to_log(change);
left *= factor;
right *= factor;
return *this;
@ -85,6 +98,20 @@ struct Frame {
return new_frame;
}
ALWAYS_INLINE Frame& log_pan(double const pan)
{
left *= linear_to_log(min(pan * -1 + 1.0, 1.0));
right *= linear_to_log(min(pan + 1.0, 1.0));
return *this;
}
ALWAYS_INLINE Frame log_pan(double const pan) const
{
Frame new_frame { left, right };
new_frame.log_pan(pan);
return new_frame;
}
constexpr Frame& operator*=(double const mult)
{
left *= mult;
@ -103,14 +130,20 @@ struct Frame {
right += other.right;
return *this;
}
constexpr Frame& operator+=(double other)
{
left += other;
right += other;
return *this;
}
constexpr Frame operator+(Frame const& other)
{
return { left + other.left, right + other.right };
}
double left;
double right;
double left { 0 };
double right { 0 };
};
// Supported PCM sample formats.