Control Surface  1.1.0
MIDI Control Surface library for Arduino
IncreaseBitDepth.hpp
Go to the documentation of this file.
1 #pragma once
2 
4 AH_DIAGNOSTIC_WERROR() // Enable errors on warnings
5 
6 #include <AH/STL/type_traits> // enable_if
7 #include <limits.h> // CHAR_BIT
8 #include <stddef.h> // size_t
9 
11 
12 template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
13 std::enable_if_t<(Bits_out <= 2 * Bits_in), T_out>
15 
16 template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
17 std::enable_if_t<(Bits_out > 2 * Bits_in), T_out>
19  constexpr size_t leftShift = Bits_out - Bits_in;
20  return (T_out(in) << leftShift) |
21  increaseBitDepthImpl<leftShift, Bits_in, T_out>(in);
22 }
23 
24 template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
25 std::enable_if_t<(Bits_out <= 2 * Bits_in), T_out>
27  constexpr size_t leftShift = Bits_out - Bits_in;
28  constexpr size_t rightShift = Bits_in - leftShift;
29  return (T_out(in) << leftShift) | (in >> rightShift);
30 }
31 
32 /// @addtogroup AH_Math
33 /// @{
34 
35 /**
36  * @brief Increase the bit depth of the given value from `Bits_in` bits wide
37  * to `Bits_out` bits wide, evenly distributing the error across the
38  * entire range, such that the error for each element is between -0.5
39  * and +0.5.
40  *
41  * For example, converting 3-bit numbers to 7-bit numbers would result in the
42  * following:
43  *
44  * | in (dec) | in (bin) | out (bin) | out (dec) | exact | error |
45  * |:--------:|:--------:|:---------:|:---------:|:------:|:-----:|
46  * | 0 | 000 | 000'0000 | 0 | 0.00 | +0.00 |
47  * | 1 | 001 | 001'0010 | 18 | 18.14 | +0.14 |
48  * | 2 | 010 | 010'0100 | 36 | 36.29 | +0.29 |
49  * | 3 | 011 | 011'0110 | 54 | 54.43 | +0.43 |
50  * | 4 | 100 | 100'1001 | 73 | 72.57 | -0.43 |
51  * | 5 | 101 | 101'1011 | 91 | 90.71 | -0.29 |
52  * | 6 | 110 | 110'1101 | 109 | 108.86 | -0.14 |
53  * | 7 | 111 | 111'1111 | 127 | 127.00 | +0.00 |
54  *
55  * @tparam Bits_out
56  * The number of bits of the output range.
57  * @tparam Bits_in
58  * The number of bits of the input range.
59  * @tparam T_out
60  * The type of the output (return type).
61  * @tparam T_in
62  * The type of the input.
63  * @param in
64  * The value to scale up.
65  * @return The scaled up value.
66  */
67 template <size_t Bits_out, size_t Bits_in, class T_out, class T_in>
68 T_out increaseBitDepth(T_in in) {
69  static_assert(Bits_in <= sizeof(T_in) * CHAR_BIT,
70  "Error: Bits_in > bits(T_in)");
71  static_assert(Bits_out <= sizeof(T_out) * CHAR_BIT,
72  "Error: Bits_out > bits(T_out)");
73  return increaseBitDepthImpl<Bits_out, Bits_in, T_out>(in);
74 }
75 
76 /// @}
77 
79 
AH::increaseBitDepthImpl
std::enable_if_t<(Bits_out<=2 *Bits_in), T_out > increaseBitDepthImpl(T_in in)
Definition: IncreaseBitDepth.hpp:26
Warnings.hpp
AH::increaseBitDepth
T_out increaseBitDepth(T_in in)
Increase the bit depth of the given value from Bits_in bits wide to Bits_out bits wide,...
Definition: IncreaseBitDepth.hpp:68
AH_DIAGNOSTIC_POP
#define AH_DIAGNOSTIC_POP()
Definition: Warnings.hpp:17
AH_DIAGNOSTIC_WERROR
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:16
BEGIN_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
Definition: AH/Settings/NamespaceSettings.hpp:9
END_AH_NAMESPACE
#define END_AH_NAMESPACE
Definition: AH/Settings/NamespaceSettings.hpp:10