= Units

include::../common.adoc[]

== Overview

image:decibel.png[alt="dB Image courtesy of Wikipedia", float="right"] The Q DSP library processes audio signals by applying various audio processors to sample inputs. These processors typically operate with floating-point input samples in the typical -1.0 to 1.0 range. However, the values are not restricted to sampled signals. For instance, signal envelopes are best represented as decibels processed in the logarithmic domain. Consequently, dynamic-range processors such as compressors and expanders accept decibel as input and return decibel as output.

The Q DSP library is typeful and typesafe, which means that each data type is explicitly defined and enforced. This is crucial because it avoids the potentially catastrophic errors that could result from mismatching values of different types. For example, if all values were just raw floating point types, it would be possible to accidentally mix up the frequency and decibel values. Mistakenly interchanging frequency and decibel values could result in erroneous processing of the audio signal and will lead to undefined results.

This document aims to provide comprehensive documentation of the fundamental data types used by the Q DSP library. These basic units are utilized consistently throughout the library and serve as the basis for quantifying specific parameters, such as decibels (dB) for signal level and hertz (Hz) for frequency.

== Unit

`Unit` is a concept representation of a physical unit.

== Expressions

=== Notation

`U`      :: `Unit` type.
`T`      :: Underlying arithmetic value type.
`v`      :: `{arithmetic-concept}` value.
`a`      :: Instance of a type that conforms to `Unit`.
`b`      :: Object with the same `unit_type` as `a`.
`A`      :: Type of object `a`.
`B`      :: Type of object `b`.

=== Arithmetic Concept

The arithmetic value concept is documented in {basic_concepts} and declared in this C++ concept as:

```c++
namespace cycfi::q::concepts
{
   template <typename T>
   concept Arithmetic = std::integral<T> || std::floating_point<T>;
}
```

=== Type Definitions

[cols="1,1,1"]
|===
| Expression         | Semantics                                  | Type

| `U::value_type`    | Get the underlying arithmetic value type.  | `T`
| `U::unit_type`     | Get the unique unit type. Each Unit type
                       has its own unique unit type to distinguish
                       from differnt `Unit` types.                | unspecified
|===

=== SameUnit Concept

Compatible unit types `A` and `B` are allowed for certain expressions as defined below. These types conform to the `SameUnit` concept declared below:

```c++
namespace cycfi::q::concepts
{
   template <typename A, typename B>
   concept SameUnit = std::same_as<typename A::unit_type, typename B::unit_type>;
}
```

Basically, the declaration states that unit types `A` and `B` are the same if they have the same `unit_type`.

=== Constructors and Assignment

[cols="1,1"]
|===
| Expression         |  Semantics

| `U(v)`             |  Construct a `Unit` from an arithmetic value `v`.
| `U(b)`             |  Copy construct from `b`.
| `a = b`            |  Assign `b`, to `a`.
|===

NOTE: C++ brace initialization may also be used.

=== Access

[cols="1,1,1"]
|===
| Expression   | Semantics                               | Return Type

| `a.rep`      | Direct access to the underlying
                 arithmetic value representation.        | `T`
|===

=== Comparison

[cols="1,1,1"]
|===
| Expression   | Semantics                                     | Return Type

| `a == b`     | Equality.                                     | `bool`
| `a == v`     | Equality with an arithmetic value.            | `bool`
| `v == b`     | Equality with an arithmetic value.            | `bool`
| `a != b`     | Non-Equality.                                 | `bool`
| `a != v`     | Non-Equality with an arithmetic value.        | `bool`
| `v != b`     | Non-Equality with aan arithmetic value.       | `bool`
| `a < b`      | Less than.                                    | `bool`
| `a < v`      | Less than with an arithmetic value.           | `bool`
| `v < b`      | Less than with an arithmetic value.           | `bool`
| `a \<= b`    | Less than equal.                              | `bool`
| `a \<= v`    | Less than equal with an arithmetic value.     | `bool`
| `v \<= b`    | Less than equal with an arithmetic value.     | `bool`
| `a > b`      | Greater than.                                 | `bool`
| `a > v`      | Greater than with an arithmetic value.        | `bool`
| `v > b`      | Greater than with an arithmetic value.        | `bool`
| `a >= b`     | Greater than equal.                           | `bool`
| `a >= v`     | Greater than equal with an arithmetic value.  | `bool`
| `v >= b`     | Greater than equal with an arithmetic value.  | `bool`
|===

=== Arithmetic

[cols="1,1,1"]
|===
| Expression   | Semantics                                     | Return Type

| `+a`         | Positive.                                     | `Unit`
| `-a`         | Negative.                                     | `Unit`
| `a += b`     | Add assign.                                   | `Unit&`
| `a += v`     | Add assign with an arithmetic value.          | `Unit&`
| `a -= b`     | Subtract assign.                              | `Unit&`
| `a -= v`     | Subtract assign with an arithmetic value.     | `Unit&`
| `a *= v`     | Multiply assign with an arithmetic value.     | `Unit&`
| `a /= v`     | Divide assign with an arithmetic value.       | `Unit&`
| `a + b`      | Addition.                                     | `Unit`
| `a + v`      | Addition with an arithmetic value.            | `Unit`
| `v + b`      | Addition with an arithmetic value.            | `Unit`
| `a - b`      | Subtraction.                                  | `Unit`
| `a - v`      | Subtraction with an arithmetic value.         | `Unit`
| `v - b`      | Subtraction with an arithmetic value.         | `Unit`
| `a * v`      | Multiplication with an arithmetic value.      | `Unit`
| `v * b`      | Multiplication with an arithmetic value.      | `Unit`
| `a / b`      | Division.                                     | `T`
| `a / v`      | Division with an arithmetic value.            | `Unit`
|===

=== Unit Promotion

On binary operations `a + b` and `a - b`, where `a` and `b` conform to the `SameUnit` concept (see above), the resuling type will be whichever has the `value_type` of `decltype(a.ref + b.rep)`, else if both operands are promoted, then whichever has the larger `value_type` will be chosen.

For example, if a.rep is `double` and b.rep is `int`, the result will be the unit type of `a`.

== Models

* xref:reference/units/frequency.adoc[frequency]
* xref:reference/units/duration.adoc[duration]
* xref:reference/units/period.adoc[period]
* xref:reference/units/phase.adoc[phase]
* xref:reference/units/decibel.adoc[decibel]
* xref:reference/units/interval.adoc[interval]





