summaryrefslogtreecommitdiff
path: root/Userland/Services/AudioServer/FadingProperty.h
diff options
context:
space:
mode:
authorkleines Filmröllchen <malu.bertsch@gmail.com>2021-08-27 23:47:09 +0200
committerAndreas Kling <kling@serenityos.org>2021-09-12 23:38:57 +0200
commit152ec28da0d1a51ade18fe6799a34ac9b7aa07b0 (patch)
tree540e62552da0d9bb767e566f8951f081009e136a /Userland/Services/AudioServer/FadingProperty.h
parent2909c3a931439d0cbed3e4599d9eed47a6fdb446 (diff)
downloadserenity-152ec28da0d1a51ade18fe6799a34ac9b7aa07b0.zip
Audio: Change how volume works
Across the entire audio system, audio now works in 0-1 terms instead of 0-100 as before. Therefore, volume is now a double instead of an int. The master volume of the AudioServer changes smoothly through a FadingProperty, preventing clicks. Finally, volume computations are done with logarithmic scaling, which is more natural for the human ear. Note that this could be 4-5 different commits, but as they change each other's code all the time, it makes no sense to split them up.
Diffstat (limited to 'Userland/Services/AudioServer/FadingProperty.h')
-rw-r--r--Userland/Services/AudioServer/FadingProperty.h85
1 files changed, 85 insertions, 0 deletions
diff --git a/Userland/Services/AudioServer/FadingProperty.h b/Userland/Services/AudioServer/FadingProperty.h
new file mode 100644
index 0000000000..5df78fe79c
--- /dev/null
+++ b/Userland/Services/AudioServer/FadingProperty.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2021, kleines Filmröllchen <malu.bertsch@gmail.com>.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include "Mixer.h"
+#include <compare>
+
+namespace AudioServer {
+
+// This is in buffer counts.
+// As each buffer is approx 1/40 of a second, this means about 1/4 of a second of fade time.
+constexpr int DEFAULT_FADE_TIME = 10;
+
+// A property of an audio system that needs to fade briefly whenever changed.
+template<typename T>
+class FadingProperty {
+public:
+ FadingProperty(T const value)
+ : FadingProperty(value, DEFAULT_FADE_TIME)
+ {
+ }
+ FadingProperty(T const value, int const fade_time)
+ : m_old_value(value)
+ , m_new_value(move(value))
+ , m_fade_time(fade_time)
+ {
+ }
+ virtual ~FadingProperty()
+ {
+ m_old_value.~T();
+ m_new_value.~T();
+ }
+
+ FadingProperty<T>& operator=(T const& new_value)
+ {
+ // The origin of the fade is wherever we're right now.
+ m_old_value = static_cast<T>(*this);
+ m_new_value = new_value;
+ m_current_fade = 0;
+ return *this;
+ }
+ FadingProperty<T>& operator=(FadingProperty<T> const&) = delete;
+
+ operator T() const
+ {
+ if (!is_fading())
+ return m_new_value;
+ return m_old_value * (1 - m_current_fade) + m_new_value * (m_current_fade);
+ }
+
+ auto operator<=>(FadingProperty<T> const& other) const
+ {
+ return static_cast<T>(this) <=> static_cast<T>(other);
+ }
+
+ auto operator<=>(T const& other) const
+ {
+ return static_cast<T>(*this) <=> other;
+ }
+
+ void advance_time()
+ {
+ m_current_fade += 1.0 / static_cast<double>(m_fade_time);
+ m_current_fade = clamp(m_current_fade, 0.0, 1.0);
+ }
+
+ bool is_fading() const
+ {
+ return m_current_fade < 1;
+ }
+
+ T target() const { return m_new_value; }
+
+private:
+ T m_old_value {};
+ T m_new_value {};
+ double m_current_fade { 0 };
+ int const m_fade_time;
+};
+
+}