summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Isaksson <davidisaksson93@gmail.com>2021-09-18 16:43:44 +0200
committerBrian Gianforcaro <b.gianfo@gmail.com>2021-11-08 16:29:25 -0800
commitfa4255bcf11889f0ab0739e04502ff927e246f14 (patch)
tree27e61c71368fdc51fec7068e12cbdddcdbb79c30
parent1e3e0477cbb06e7510523d4a24b2bf9f3a400434 (diff)
downloadserenity-fa4255bcf11889f0ab0739e04502ff927e246f14.zip
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.
-rw-r--r--Userland/Libraries/LibAudio/Buffer.h49
1 files changed, 41 insertions, 8 deletions
diff --git a/Userland/Libraries/LibAudio/Buffer.h b/Userland/Libraries/LibAudio/Buffer.h
index dc4f4d4e7b..6020a0f6a5 100644
--- a/Userland/Libraries/LibAudio/Buffer.h
+++ b/Userland/Libraries/LibAudio/Buffer.h
@@ -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.