Sound Byte Libs 1ee2ca6
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
integer_math.hpp
Go to the documentation of this file.
1/**
2 * @file integer_math.hpp
3 * @brief Integer math utilities for embedded systems
4 * @ingroup primitives
5 *
6 * Provides efficient integer math operations optimized for ARM Cortex-M.
7 * No floating point operations - suitable for M0+ without FPU.
8 */
9
10#ifndef SBL_PRIMITIVES_MATH_INTEGER_MATH_HPP_
11#define SBL_PRIMITIVES_MATH_INTEGER_MATH_HPP_
12
13#include <cstdint>
14
15namespace sbl {
16namespace core {
17namespace primitives {
18namespace math {
19
20/**
21 * @brief Integer math utilities optimized for ARM Cortex-M
22 *
23 * Static utility functions for common mathematical operations
24 * using only integer arithmetic.
25 */
27public:
28 /**
29 * @brief Calculate greatest common divisor
30 *
31 * @param a First value
32 * @param b Second value
33 * @return Greatest common divisor
34 */
35 static constexpr uint32_t gcd(uint32_t a, uint32_t b) {
36 while (b != 0) {
37 uint32_t temp = b;
38 b = a % b;
39 a = temp;
40 }
41 return a;
42 }
43
44 /**
45 * @brief Calculate least common multiple
46 *
47 * @param a First value
48 * @param b Second value
49 * @return Least common multiple
50 */
51 static constexpr uint32_t lcm(uint32_t a, uint32_t b) {
52 return (a / gcd(a, b)) * b; // Avoid overflow by dividing first
53 }
54
55 /**
56 * @brief Integer division with rounding
57 *
58 * @param dividend Value to divide
59 * @param divisor Value to divide by
60 * @return Rounded result
61 */
62 static constexpr uint32_t divideRounded(uint32_t dividend, uint32_t divisor) {
63 return (dividend + divisor / 2) / divisor;
64 }
65
66 /**
67 * @brief Calculate timer prescaler for desired frequency
68 *
69 * Given a base clock frequency and desired output frequency,
70 * calculate the best prescaler value.
71 *
72 * @param base_freq Base clock frequency (Hz)
73 * @param target_freq Desired output frequency (Hz)
74 * @return Prescaler value (1-65536)
75 */
76 static constexpr uint32_t calculatePrescaler(uint32_t base_freq, uint32_t target_freq) {
77 if (target_freq == 0 || target_freq > base_freq) {
78 return 1;
79 }
80
81 uint32_t prescaler = divideRounded(base_freq, target_freq);
82
83 // Clamp to typical ARM timer prescaler limits
84 if (prescaler > 65536) {
85 return 65536;
86 } else if (prescaler < 1) {
87 return 1;
88 }
89
90 return prescaler;
91 }
92
93 /**
94 * @brief Calculate timer reload value for interval
95 *
96 * Given timer frequency and desired interval, calculate reload value.
97 *
98 * @param timer_freq Timer tick frequency (Hz)
99 * @param interval_us Desired interval (microseconds)
100 * @return Timer reload value
101 */
102 static constexpr uint32_t calculateTimerReload(uint32_t timer_freq, uint32_t interval_us) {
103 // Convert microseconds to timer ticks
104 // ticks = (timer_freq * interval_us) / 1000000
105 // Use 64-bit to avoid overflow
106 uint64_t ticks = (static_cast<uint64_t>(timer_freq) * interval_us) / 1000000;
107
108 // Clamp to 32-bit range
109 if (ticks > 0xFFFFFFFF) {
110 return 0xFFFFFFFF;
111 }
112
113 return static_cast<uint32_t>(ticks);
114 }
115
116 /**
117 * @brief Clamp value to range
118 *
119 * @param value Value to clamp
120 * @param min Minimum value
121 * @param max Maximum value
122 * @return Clamped value
123 */
124 template<typename T>
125 static constexpr T clamp(T value, T min, T max) {
126 return (value < min) ? min : (value > max) ? max : value;
127 }
128
129 /**
130 * @brief Get minimum of two values
131 *
132 * @param a First value
133 * @param b Second value
134 * @return Minimum value
135 */
136 template<typename T>
137 static constexpr T min(T a, T b) {
138 return (a < b) ? a : b;
139 }
140
141 /**
142 * @brief Get maximum of two values
143 *
144 * @param a First value
145 * @param b Second value
146 * @return Maximum value
147 */
148 template<typename T>
149 static constexpr T max(T a, T b) {
150 return (a > b) ? a : b;
151 }
152
153 /**
154 * @brief Check if value is power of two
155 *
156 * @param value Value to check
157 * @return true if power of two
158 */
159 static constexpr bool isPowerOfTwo(uint32_t value) {
160 return value && !(value & (value - 1));
161 }
162
163 /**
164 * @brief Get next power of two
165 *
166 * @param value Input value
167 * @return Next power of two >= value
168 */
169 static constexpr uint32_t nextPowerOfTwo(uint32_t value) {
170 if (value == 0) return 1;
171
172 value--;
173 value |= value >> 1;
174 value |= value >> 2;
175 value |= value >> 4;
176 value |= value >> 8;
177 value |= value >> 16;
178 value++;
179
180 return value;
181 }
182};
183
184} // namespace math
185} // namespace primitives
186} // namespace core
187} // namespace sbl
188
189#endif // SBL_PRIMITIVES_MATH_INTEGER_MATH_HPP_
Integer math utilities optimized for ARM Cortex-M.
static constexpr uint32_t calculatePrescaler(uint32_t base_freq, uint32_t target_freq)
Calculate timer prescaler for desired frequency.
static constexpr uint32_t calculateTimerReload(uint32_t timer_freq, uint32_t interval_us)
Calculate timer reload value for interval.
static constexpr T max(T a, T b)
Get maximum of two values.
static constexpr T min(T a, T b)
Get minimum of two values.
static constexpr uint32_t gcd(uint32_t a, uint32_t b)
Calculate greatest common divisor.
static constexpr bool isPowerOfTwo(uint32_t value)
Check if value is power of two.
static constexpr uint32_t nextPowerOfTwo(uint32_t value)
Get next power of two.
static constexpr uint32_t lcm(uint32_t a, uint32_t b)
Calculate least common multiple.
static constexpr uint32_t divideRounded(uint32_t dividend, uint32_t divisor)
Integer division with rounding.
static constexpr T clamp(T value, T min, T max)
Clamp value to range.
Root namespace for all Sound Byte Libs functionality.
Definition aliases.hpp:24