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