2#include <ossia/network/dataspace/dataspace_base.hpp>
3#include <ossia/network/domain/domain_base_impl.hpp>
9template <
typename Impl>
12 using is_unit = std::true_type;
13 using neutral_unit = linear_u;
14 using value_type = float;
15 using concrete_type = Impl;
16 using dataspace_type = gain_u;
17 using is_multidimensional = std::false_type;
24static const constexpr T DecibelHeadroom = 96.;
35static const constexpr T GainMidiPower = -1.02098087016161476192621649;
38static const constexpr T GainMidiPowPow2 = 0.492781202603372214809951402;
41T LinearGainToDecibels(
const T value)
43 return value >= T(0.) ? T(20.0) * std::log10(value) : T(0.);
47T LinearGainToDecibelsClipped(
const T value)
49 return value <= T(0.) ? -DecibelHeadroom<T>
50 :
ossia::max(T(20.0) * std::log10(value), -DecibelHeadroom<T>);
54T DecibelsToLinearGain(
const T value)
56 return std::pow(T(10.), value * T(0.05));
60T DecibelsToLinearGainClipped(
const T value)
62 return value <= -DecibelHeadroom<T> ? T(0.) : DecibelsToLinearGain(value);
66T MidiToLinearGain(
const T value)
70 : DecibelsToLinearGainClipped(
72 T> * (std::pow(value / T(100.), GainMidiPowPow2<T>) - T(1.)));
76T DecibelsToMidi(
const T value)
78 return value <= -DecibelHeadroom<T>
82 ossia::log1p(value / DecibelHeadroom<T>) / GainMidiPowPow2<T>);
86T LinearGainToMidi(
const T value)
88 return DecibelsToMidi(LinearGainToDecibels(value));
92struct OSSIA_EXPORT linear_u :
public gain_unit<linear_u>
94 static constexpr auto text() { constexpr_return(ossia::make_string_array(
"linear")); }
96 static constexpr strong_value<neutral_unit>
97 to_neutral(strong_value<concrete_type> self)
102 static constexpr value_type from_neutral(strong_value<neutral_unit> self)
104 return self.dataspace_value;
107 static ossia::domain_base<float> domain() {
return {0.f, 1.f}; }
112struct OSSIA_EXPORT midigain_u :
public gain_unit<midigain_u>
114 static constexpr auto text()
116 constexpr_return(ossia::make_string_array(
"midigain"));
119 static strong_value<neutral_unit> to_neutral(strong_value<concrete_type> self)
121 return detail::MidiToLinearGain(self.dataspace_value);
124 static value_type from_neutral(strong_value<neutral_unit> self)
126 return detail::LinearGainToMidi(self.dataspace_value);
129 static ossia::domain_base<float> domain() {
return {0.f, 127.f}; }
134struct OSSIA_EXPORT decibel_u :
public gain_unit<decibel_u>
136 static constexpr auto text()
138 constexpr_return(ossia::make_string_array(
"db",
"dB"));
141 static strong_value<neutral_unit> to_neutral(strong_value<concrete_type> self)
143 return detail::DecibelsToLinearGainClipped(self.dataspace_value);
146 static value_type from_neutral(strong_value<neutral_unit> self)
148 return detail::LinearGainToDecibelsClipped(self.dataspace_value);
151 static ossia::domain_base<float> domain() {
return {-96.f, 12.f}; }
156struct OSSIA_EXPORT decibel_raw_u :
public gain_unit<decibel_raw_u>
158 static constexpr auto text()
160 constexpr_return(ossia::make_string_array(
"db-raw",
"dB-raw"));
163 static strong_value<neutral_unit> to_neutral(strong_value<concrete_type> self)
165 return detail::DecibelsToLinearGain(self.dataspace_value);
168 static value_type from_neutral(strong_value<neutral_unit> self)
170 return 20.0f * std::log10(self.dataspace_value);
173 static ossia::domain_base<float> domain() {
return {-96.f, 12.f}; }
175 static constexpr auto bounding() {
return ossia::bounding_mode::FREE; }
OSSIA_INLINE constexpr auto max(const T a, const U b) noexcept -> typename std::conditional<(sizeof(T) > sizeof(U)), T, U >::type
max function tailored for values
Definition math.hpp:96