1 /*
2  * Copyright (C) 2024 OWL Services LLC. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file zephyr/dsp/utils.h
9  *
10  * @brief Extra functions and macros for DSP
11  */
12 
13 #ifndef INCLUDE_ZEPHYR_DSP_UTILS_H_
14 #define INCLUDE_ZEPHYR_DSP_UTILS_H_
15 
16 #include <stdint.h>
17 #include <zephyr/kernel.h>
18 #include <zephyr/dsp/types.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 /**
25  * @ingroup math_dsp
26  * @defgroup math_dsp_utils_shifts Float/Fixed point shift conversion functions
27  *
28  * Convert number representation in Float or Double to/from Q31/Q15/Q7.
29  *
30  * @{
31  */
32 
33 /**
34  * @ingroup math_dsp_utils_shifts
35  * @defgroup math_dsp_basic_conv_to_float Fixed to Float point conversions
36  *
37  * Convert number Q7/Q15/Q31 to Float or Double representation with shift.
38  *
39  * There are separate functions for floating-point, Q7, Q15, and Q31 data types.
40  * @{
41  */
42 
43 /**
44  * @brief Convert a Q7 fixed-point value to a floating-point (float32_t) value with a left shift.
45  *
46  * @param src The input Q7 fixed-point value.
47  * @param m   The number of bits to left shift the input value (0 to 7).
48  * @return The converted floating-point (float32_t) value.
49  */
50 #define Z_SHIFT_Q7_TO_F32(src, m) ((float32_t)(((src << m)) / (float32_t)(1U << 7)))
51 
52 /**
53  * @brief Convert a Q15 fixed-point value to a floating-point (float32_t) value with a left shift.
54  *
55  * @param src The input Q15 fixed-point value.
56  * @param m   The number of bits to left shift the input value (0 to 15).
57  * @return The converted floating-point (float32_t) value.
58  */
59 #define Z_SHIFT_Q15_TO_F32(src, m) ((float32_t)((src << m) / (float32_t)(1U << 15)))
60 
61 /**
62  * @brief Convert a Q31 fixed-point value to a floating-point (float32_t) value with a left shift.
63  *
64  * @param src The input Q31 fixed-point value.
65  * @param m   The number of bits to left shift the input value (0 to 31).
66  * @return The converted floating-point (float32_t) value.
67  */
68 #define Z_SHIFT_Q31_TO_F32(src, m) ((float32_t)(((int64_t)src) << m) / (float32_t)(1U << 31))
69 
70 /**
71  * @brief Convert a Q7 fixed-point value to a floating-point (float64_t) value with a left shift.
72  *
73  * @param src The input Q7 fixed-point value.
74  * @param m   The number of bits to left shift the input value (0 to 7).
75  * @return The converted floating-point (float64_t) value.
76  */
77 #define Z_SHIFT_Q7_TO_F64(src, m) (((float64_t)(src << m)) / (1U << 7))
78 
79 /**
80  * @brief Convert a Q15 fixed-point value to a floating-point (float64_t) value with a left shift.
81  *
82  * @param src The input Q15 fixed-point value.
83  * @param m   The number of bits to left shift the input value (0 to 15).
84  * @return The converted floating-point (float64_t) value.
85  */
86 #define Z_SHIFT_Q15_TO_F64(src, m) (((float64_t)(src << m)) / (1UL << 15))
87 
88 /**
89  * @brief Convert a Q31 fixed-point value to a floating-point (float64_t) value with a left shift.
90  *
91  * @param src The input Q31 fixed-point value.
92  * @param m   The number of bits to left shift the input value (0 to 31).
93  * @return The converted floating-point (float64_t) value.
94  */
95 #define Z_SHIFT_Q31_TO_F64(src, m) ((float64_t)(((int64_t)src) << m) / (1ULL << 31))
96 
97 /**
98  * @}
99  */
100 
101 /**
102  * @ingroup math_dsp_utils_shifts
103  * @defgroup math_dsp_basic_conv_to_fixed Float to Fixed point conversions
104  *
105  * Convert number representation in Float or Double to Q31/Q15/Q7.
106  *
107  * There are separate functions for floating-point, Q7, Q15, and Q31 data types.
108  * @{
109  */
110 
111 /**
112  * @brief Convert a floating-point (float32_t) value to a Q7 fixed-point value with a right shift.
113  *
114  * @param src The input floating-point (float32_t) value.
115  * @param m   The number of bits to right shift the input value (0 to 7).
116  * @return The converted Q7 fixed-point value.
117  */
118 #define Z_SHIFT_F32_TO_Q7(src, m)                                                                  \
119 	((q7_t)clamp((int32_t)(src * (1U << 7)) >> m, INT8_MIN, INT8_MAX))
120 
121 /**
122  * @brief Convert a floating-point (float32_t) value to a Q15 fixed-point value with a right shift.
123  *
124  * @param src The input floating-point (float32_t) value.
125  * @param m   The number of bits to right shift the input value (0 to 15).
126  * @return The converted Q15 fixed-point value.
127  */
128 #define Z_SHIFT_F32_TO_Q15(src, m)                                                                 \
129 	((q15_t)clamp((int32_t)(src * (1U << 15)) >> m, INT16_MIN, INT16_MAX))
130 
131 /**
132  * @brief Convert a floating-point (float32_t) value to a Q31 fixed-point value with a right shift.
133  *
134  * @param src The input floating-point (float32_t) value.
135  * @param m   The number of bits to right shift the input value (0 to 31).
136  * @return The converted Q31 fixed-point value.
137  */
138 #define Z_SHIFT_F32_TO_Q31(src, m)                                                                 \
139 	((q31_t)clamp((int64_t)(src * (1U << 31)) >> m, INT32_MIN, INT32_MAX))
140 
141 /**
142  * @brief Convert a floating-point (float64_t) value to a Q7 fixed-point value with a right shift.
143  *
144  * @param src The input floating-point (float64_t) value.
145  * @param m   The number of bits to right shift the input value (0 to 7).
146  * @return The converted Q7 fixed-point value.
147  */
148 #define Z_SHIFT_F64_TO_Q7(src, m)                                                                  \
149 	((q7_t)clamp((int32_t)(src * (1U << 7)) >> m, INT8_MIN, INT8_MAX))
150 
151 /**
152  * @brief Convert a floating-point (float64_t) value to a Q15 fixed-point value with a right shift.
153  *
154  * @param src The input floating-point (float64_t) value.
155  * @param m   The number of bits to right shift the input value (0 to 15).
156  * @return The converted Q15 fixed-point value.
157  */
158 #define Z_SHIFT_F64_TO_Q15(src, m)                                                                 \
159 	((q15_t)clamp((int32_t)(src * (1U << 15)) >> m, INT16_MIN, INT16_MAX))
160 
161 /**
162  * @brief Convert a floating-point (float64_t) value to a Q31 fixed-point value with a right shift.
163  *
164  * @param src The input floating-point (float64_t) value.
165  * @param m   The number of bits to right shift the input value (0 to 31).
166  * @return The converted Q31 fixed-point value.
167  */
168 #define Z_SHIFT_F64_TO_Q31(src, m)                                                                 \
169 	((q31_t)clamp((int64_t)(src * (1U << 31)) >> m, INT32_MIN, INT32_MAX))
170 
171 /**
172  * @}
173  */
174 
175 /**
176  * @}
177  */
178 
179 #ifdef __cplusplus
180 }
181 #endif
182 
183 #endif /* INCLUDE_ZEPHYR_DSP_UTILS_H_ */
184