75 static constexpr const char*
symbol =
"dB";
79template<
typename Rep,
typename Precision = std::ratio<1>>
108 static constexpr const char*
symbol =
"dBm";
116 static constexpr const char*
symbol =
"dBW";
124 static constexpr const char*
symbol =
"dBV";
132 static constexpr const char*
symbol =
"dBmV";
140 static constexpr const char*
symbol =
"dBµV";
152template<
typename Reference>
154 typename Reference::unit;
155 typename Reference::precision;
156 { Reference::factor } -> std::convertible_to<int>;
157 { Reference::symbol } -> std::convertible_to<const char*>;
158} && (Reference::factor == 10 || Reference::factor == 20);
161template<
typename Reference>
164template<decibel_reference Reference>
168template<
typename Reference>
171template<decibel_reference Reference>
178template<
typename Reference,
typename Rep,
typename Precision = std::ratio<1>>
188template<
typename Reference,
typename Rep,
typename Precision>
211template<
typename Reference,
typename Rep,
typename Precision>
237 template<
typename Rep2>
240 : _o(
static_cast<rep>(
r)) {}
251 template<
typename Rep2,
typename Precision2>
252 requires std::convertible_to<gain<Rep2, Precision2>,
offset>
257 template<
typename Rep2,
typename Precision2>
258 requires(!std::is_same_v<level, level<Reference, Rep2, Precision2>>) &&
260 std::constructible_from<offset, gain<Rep2, Precision2>>
312template<
typename ToLevel,
typename Reference,
typename Rep,
typename Precision>
315 std::is_same_v<typename ToLevel::reference, Reference>,
"level_cast cannot convert between different references"
321template<
typename ToLevel,
typename Reference,
typename Rep,
typename Precision>
323 static_assert(std::is_same_v<typename ToLevel::reference, Reference>,
"floor cannot convert between references");
328template<
typename ToLevel,
typename Reference,
typename Rep,
typename Precision>
330 static_assert(std::is_same_v<typename ToLevel::reference, Reference>,
"ceil cannot convert between references");
335template<
typename ToLevel,
typename Reference,
typename Rep,
typename Precision>
337 static_assert(std::is_same_v<typename ToLevel::reference, Reference>,
"round cannot convert between references");
346template<
typename R1,
typename P1,
typename R2,
typename P2>
351template<
typename Reference,
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
356 return cl(
cg(
l.offset_from_reference()) +
cg(
g));
360template<
typename Reference,
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
367template<
typename Reference,
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
372 return cl(
cg(
l.offset_from_reference()) -
cg(
g));
382template<
typename Reference,
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
384 return a.offset_from_reference() -
b.offset_from_reference();
387template<
typename Reference,
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
389 return a.offset_from_reference() ==
b.offset_from_reference();
392template<
typename Reference,
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
393 requires std::three_way_comparable<std::common_type_t<Rep1, Rep2>>
395 return a.offset_from_reference() <=>
b.offset_from_reference();
403template<
typename Offset>
411template<
typename Offset>
416 using p =
typename Offset::precision;
417 const double scaled =
db *
static_cast<double>(p::den) /
static_cast<double>(p::num);
437template<
typename Reference,
typename Rep,
typename Precision>
440 return linear(std::pow(10.0,
_db_value(
l.offset_from_reference()) / Reference::factor));
461template<
typename ToLevel,
typename Unit,
typename Rep,
typename Precision>
463 using ref =
typename ToLevel::reference;
465 std::is_same_v<typename ref::unit, Unit>,
"to_level: quantity unit does not match the level reference"
470 if (!(
ratio > 0.0)) {
471 assert(
ratio >= 0.0 &&
"to_level: a negative quantity has no logarithmic level");
472 return ToLevel::min();
486template<
typename Rep,
typename Precision>
500template<
typename Rep,
typename Precision>
507 assert(
ratio > 0.0 &&
"power_gain: ratio must be positive");
513 assert(
ratio > 0.0 &&
"amplitude_gain: ratio must be positive");
533template<
typename Reference,
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
551template<
typename Rep,
typename Precision = std::ratio<1>>
555template<
typename Rep,
typename Precision = std::ratio<1>>
559template<
typename Rep,
typename Precision = std::ratio<1>>
563template<
typename Rep,
typename Precision = std::ratio<1>>
567template<
typename Rep,
typename Precision = std::ratio<1>>
600template<
typename Precision>
611 while (
den % 10 == 0) {
618template<
typename Precision>
621template<
typename Precision,
typename Rep>
625 return std::to_string(
static_cast<double>(count) * Precision::num / Precision::den);
628 if constexpr (
places == 0) {
629 return std::to_string(count);
655template<
typename Rep,
typename Precision>
664template<
typename Reference,
typename Rep,
typename Precision>
674template<
typename Reference,
typename Rep1,
typename Precision1,
typename Rep2,
typename Precision2>
675struct common_type<
electro::level<Reference, Rep1, Precision1>,
electro::level<Reference, Rep2, Precision2>> {
683#if CONFIG_ELECTRO_STD_FORMAT
687template<
typename Rep,
typename Precision>
689struct formatter<
electro::quantity<electro::decibel_unit, Rep, Precision>, char> {
691 std::formatter<double> _num;
692 bool _has_spec =
false;
695 constexpr auto parse(format_parse_context& ctx) {
696 auto it = ctx.begin();
697 if (it == ctx.end() || *it ==
'}') {
701 return _num.parse(ctx);
704 template<
typename FormatContext>
707 double value =
static_cast<double>(g.
count()) * Precision::num / Precision::den;
708 auto out = _num.format(value, ctx);
711 return std::format_to(
719template<
typename Reference,
typename Rep,
typename Precision>
721struct formatter<
electro::level<Reference, Rep, Precision>, char> {
723 std::formatter<double> _num;
724 bool _has_spec =
false;
727 constexpr auto parse(format_parse_context& ctx) {
728 auto it = ctx.begin();
729 if (it == ctx.end() || *it ==
'}') {
733 return _num.parse(ctx);
736 template<
typename FormatContext>
739 double value =
static_cast<double>(l.
count()) * Precision::num / Precision::den;
740 auto out = _num.format(value, ctx);
743 return std::format_to(
755template<
char... Digits>
761template<
char... Digits>
767template<
char... Digits>
769 return electro::dbm(detail::check_overflow<electro::decibels, Digits...>());
773template<
char... Digits>
775 return electro::centi_dbm(detail::check_overflow<electro::centidecibels, Digits...>());
779template<
char... Digits>
781 return electro::dbw(detail::check_overflow<electro::decibels, Digits...>());
785template<
char... Digits>
787 return electro::dbv(detail::check_overflow<electro::decibels, Digits...>());
791template<
char... Digits>
793 return electro::dbmv(detail::check_overflow<electro::decibels, Digits...>());
797template<
char... Digits>
799 return electro::dbuv(detail::check_overflow<electro::decibels, Digits...>());
803template<
char... Digits>
805 return electro::dbuv(detail::check_overflow<electro::decibels, Digits...>());
An absolute point on a logarithmic scale, relative to a reference.
level(const level &)=default
constexpr level & operator-=(const offset &o)
constexpr level()=default
Constructs a level at the reference point (0 dB offset).
constexpr level(const Rep2 &r)
Constructs from an offset count in dB.
gain< Rep, Precision > offset
The gain type measuring the offset from the reference.
level & operator=(const level &)=default
Reference reference
The reference tag type.
static constexpr level min() noexcept
Returns the minimum representable level.
constexpr level operator+() const
static constexpr level max() noexcept
Returns the maximum representable level.
Rep rep
The representation type.
static constexpr level reference_level() noexcept
Returns the reference point itself (a 0 dB offset).
constexpr offset offset_from_reference() const
Returns the offset from the reference point.
constexpr level & operator+=(const offset &o)
constexpr level(const level< Reference, Rep2, Precision2 > &l)
Explicit constructor for lossy precision conversions.
typename Precision::type precision
The offset precision, in dB, as a std::ratio.
constexpr rep count() const
Returns the raw offset count, in units of Precision.
constexpr level(const level< Reference, Rep2, Precision2 > &l)
Converts from a level with the same reference.
constexpr level operator-() const
Reflects the level about its reference point.
constexpr level(const offset &o)
Constructs from an offset relative to the reference.
A quantity of an electrical unit with a representation and precision.
static constexpr quantity zero() noexcept
Returns a zero quantity.
static constexpr quantity max() noexcept
Returns the maximum representable quantity.
constexpr rep count() const
Returns the tick count.
static constexpr quantity min() noexcept
Returns the minimum representable quantity.
Concept for decibel reference tags.
dbw_level< int64_t > dbw
Power level in dBW, with 1 dB precision.
dbm_level< int64_t > dbm
Power level in dBm, with 1 dB precision.
dbmv_level< int64_t > dbmv
Voltage level in dBmV, with 1 dB precision.
dbm_level< int64_t, std::centi > centi_dbm
Power level in dBm, with 0.01 dB precision.
dbv_level< int64_t > dbv
Voltage level in dBV, with 1 dB precision.
dbuv_level< int64_t > dbuv
Voltage level in dBµV, with 1 dB precision.
User-defined literals for electrical quantity types.
Electrical unit types and utilities.
auto to_linear(const level< Reference, Rep, Precision > &l)
Converts a level to the equivalent linear quantity.
gain< double > amplitude_gain(double ratio)
The gain corresponding to a linear amplitude ratio (20*log10(ratio)).
auto add_powers(const level< Reference, Rep1, Precision1 > &a, const level< Reference, Rep2, Precision2 > &b)
Combines the powers of two uncorrelated signals.
gain< double > power_gain(double ratio)
The gain corresponding to a linear power ratio (10*log10(ratio)).
constexpr auto operator+(const level< Reference, Rep1, Precision1 > &l, const quantity< decibel_unit, Rep2, Precision2 > &g)
Applies a gain to a level.
double amplitude_ratio(const quantity< decibel_unit, Rep, Precision > &g)
The linear amplitude ratio a gain represents (10^(dB/20)).
constexpr auto operator-(const level< Reference, Rep1, Precision1 > &l, const quantity< decibel_unit, Rep2, Precision2 > &g)
Applies a loss to a level.
gain< int64_t > decibels
Gain with 1 dB precision.
constexpr auto operator<=>(const level< Reference, Rep1, Precision1 > &a, const level< Reference, Rep2, Precision2 > &b)
constexpr bool is_field_reference_v
True if the reference measures a field quantity (20*log10).
ToLevel to_level(const quantity< Unit, Rep, Precision > &q)
Converts a linear quantity to a level.
constexpr bool is_field_reference_v< Reference >
constexpr ToLevel ceil(const level< Reference, Rep, Precision > &l)
Converts a level to the target type, rounding toward positive infinity.
constexpr bool is_level_v
constexpr bool is_power_reference_v< Reference >
constexpr bool treat_as_inexact_v
gain< int64_t, std::centi > centidecibels
Gain with 0.01 dB precision.
constexpr ToLevel round(const level< Reference, Rep, Precision > &l)
Converts a level to the target type, rounding to nearest (ties to even).
constexpr bool is_power_reference_v
True if the reference measures a power quantity (10*log10).
double power_ratio(const quantity< decibel_unit, Rep, Precision > &g)
The linear power ratio a gain represents (10^(dB/10)).
constexpr ToLevel level_cast(const level< Reference, Rep, Precision > &l)
Converts a level to a different precision or representation.
constexpr ToLevel floor(const level< Reference, Rep, Precision > &l)
Converts a level to the target type, rounding toward negative infinity.
std::string to_string(const quantity< decibel_unit, Rep, Precision > &g)
Converts a gain to a string, e.g.
constexpr bool operator==(const level< Reference, Rep1, Precision1 > &a, const level< Reference, Rep2, Precision2 > &b)
A dimensionless logarithmic ratio, measured in decibels.
static constexpr const char * symbol
Trait to detect level specializations.
Reference of 1 µV, for dBµV.
static constexpr const char * symbol
static constexpr int factor
Reference of 1 mV, for dBmV.
static constexpr int factor
static constexpr const char * symbol
Reference of 1 mW, for dBm.
static constexpr int factor
static constexpr const char * symbol
Trait giving the display suffix for a (unit, precision) pair.
Reference of 1 V, for dBV.
static constexpr const char * symbol
std::ratio< 1 > precision
static constexpr int factor
Voltage, measured in volts.
Reference of 1 W, for dBW.
static constexpr const char * symbol
static constexpr int factor
std::ratio< 1 > precision
Power, measured in watts.