summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkleines Filmröllchen <malu.bertsch@gmail.com>2021-10-31 12:31:58 +0100
committerBrian Gianforcaro <b.gianfo@gmail.com>2021-11-08 16:29:25 -0800
commit61d9082da668ecac81428027dd6f25f67e91d38b (patch)
tree661eb73403388a48f43bdf041428a65c9aa83262
parent8945cc83583170d8e2dc9e9a408e84120c67b8c5 (diff)
downloadserenity-61d9082da668ecac81428027dd6f25f67e91d38b.zip
LibAudio: Replace log_pan with a constant power panning algoritm
This little functional change uses the most common algorithm for panning audio, known as constant power panning. It makes it so that the total output power (not directly the sample value, i.e. the peak) stays the same no matter how the audio is panned.
-rw-r--r--Userland/Libraries/LibAudio/Sample.h18
1 files changed, 11 insertions, 7 deletions
diff --git a/Userland/Libraries/LibAudio/Sample.h b/Userland/Libraries/LibAudio/Sample.h
index 23faf6244a..50e3c84907 100644
--- a/Userland/Libraries/LibAudio/Sample.h
+++ b/Userland/Libraries/LibAudio/Sample.h
@@ -90,18 +90,22 @@ struct Sample {
return new_frame;
}
- ALWAYS_INLINE Sample& log_pan(double const pan)
+ // Constant power panning
+ ALWAYS_INLINE Sample& pan(double const position)
{
- left *= linear_to_log(min(pan * -1 + 1.0, 1.0));
- right *= linear_to_log(min(pan + 1.0, 1.0));
+ double const pi_over_2 = AK::Pi<double> * 0.5;
+ double const root_over_2 = AK::sqrt(2.0) * 0.5;
+ double const angle = position * pi_over_2 * 0.5;
+ left *= root_over_2 * (AK::cos(angle) - AK::sin(angle));
+ right *= root_over_2 * (AK::cos(angle) + AK::sin(angle));
return *this;
}
- ALWAYS_INLINE Sample log_pan(double const pan) const
+ ALWAYS_INLINE Sample panned(double const position) const
{
- Sample new_frame { left, right };
- new_frame.log_pan(pan);
- return new_frame;
+ Sample new_sample { left, right };
+ new_sample.pan(position);
+ return new_sample;
}
constexpr Sample& operator*=(double const mult)