diff options
author | kleines Filmröllchen <malu.bertsch@gmail.com> | 2021-08-27 23:47:09 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-12 23:38:57 +0200 |
commit | 152ec28da0d1a51ade18fe6799a34ac9b7aa07b0 (patch) | |
tree | 540e62552da0d9bb767e566f8951f081009e136a /Userland/Services/AudioServer/FadingProperty.h | |
parent | 2909c3a931439d0cbed3e4599d9eed47a6fdb446 (diff) | |
download | serenity-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.h | 85 |
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; +}; + +} |