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/dsp.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 
29 /**
30  * @ingroup math_dsp_utils_shifts
31  * @addtogroup math_dsp_basic_conv_to_float Fixed to Float point conversions
32  *
33  * Convert number Q7/Q15/Q31 to Float or Double representation with shift.
34  *
35  * There are separate functions for floating-point, Q7, Q15, and Q31 data types.
36  * @{
37  */
38 
39 /**
40  * @brief Convert a Q7 fixed-point value to a floating-point (float32_t) value with a left shift.
41  *
42  * @param src The input Q7 fixed-point value.
43  * @param m   The number of bits to left shift the input value (0 to 7).
44  * @return The converted floating-point (float32_t) value.
45  */
46 #define Z_SHIFT_Q7_TO_F32(src, m) ((float32_t)(((src << m)) / (float32_t)(1U << 7)))
47 
48 /**
49  * @brief Convert a Q15 fixed-point value to a floating-point (float32_t) value with a left shift.
50  *
51  * @param src The input Q15 fixed-point value.
52  * @param m   The number of bits to left shift the input value (0 to 15).
53  * @return The converted floating-point (float32_t) value.
54  */
55 #define Z_SHIFT_Q15_TO_F32(src, m) ((float32_t)((src << m) / (float32_t)(1U << 15)))
56 
57 /**
58  * @brief Convert a Q31 fixed-point value to a floating-point (float32_t) value with a left shift.
59  *
60  * @param src The input Q31 fixed-point value.
61  * @param m   The number of bits to left shift the input value (0 to 31).
62  * @return The converted floating-point (float32_t) value.
63  */
64 #define Z_SHIFT_Q31_TO_F32(src, m) ((float32_t)(((int64_t)src) << m) / (float32_t)(1U << 31))
65 
66 /**
67  * @brief Convert a Q7 fixed-point value to a floating-point (float64_t) value with a left shift.
68  *
69  * @param src The input Q7 fixed-point value.
70  * @param m   The number of bits to left shift the input value (0 to 7).
71  * @return The converted floating-point (float64_t) value.
72  */
73 #define Z_SHIFT_Q7_TO_F64(src, m) (((float64_t)(src << m)) / (1U << 7))
74 
75 /**
76  * @brief Convert a Q15 fixed-point value to a floating-point (float64_t) value with a left shift.
77  *
78  * @param src The input Q15 fixed-point value.
79  * @param m   The number of bits to left shift the input value (0 to 15).
80  * @return The converted floating-point (float64_t) value.
81  */
82 #define Z_SHIFT_Q15_TO_F64(src, m) (((float64_t)(src << m)) / (1UL << 15))
83 
84 /**
85  * @brief Convert a Q31 fixed-point value to a floating-point (float64_t) value with a left shift.
86  *
87  * @param src The input Q31 fixed-point value.
88  * @param m   The number of bits to left shift the input value (0 to 31).
89  * @return The converted floating-point (float64_t) value.
90  */
91 #define Z_SHIFT_Q31_TO_F64(src, m) ((float64_t)(((int64_t)src) << m) / (1ULL << 31))
92 
93 /**
94  * @}
95  */
96 
97 /**
98  * @ingroup math_dsp_utils_shifts
99  * @addtogroup math_dsp_basic_conv_to_fixed Float to Fixed point conversions
100  *
101  * Convert number representation in Float or Double to Q31/Q15/Q7.
102  *
103  * There are separate functions for floating-point, Q7, Q15, and Q31 data types.
104  * @{
105  */
106 
107 /**
108  * @brief Convert a floating-point (float32_t) value to a Q7 fixed-point value with a right shift.
109  *
110  * @param src The input floating-point (float32_t) value.
111  * @param m   The number of bits to right shift the input value (0 to 7).
112  * @return The converted Q7 fixed-point value.
113  */
114 #define Z_SHIFT_F32_TO_Q7(src, m)                                                                  \
115 	((q7_t)Z_CLAMP((int32_t)(src * (1U << 7)) >> m, INT8_MIN, INT8_MAX))
116 
117 /**
118  * @brief Convert a floating-point (float32_t) value to a Q15 fixed-point value with a right shift.
119  *
120  * @param src The input floating-point (float32_t) value.
121  * @param m   The number of bits to right shift the input value (0 to 15).
122  * @return The converted Q15 fixed-point value.
123  */
124 #define Z_SHIFT_F32_TO_Q15(src, m)                                                                 \
125 	((q15_t)Z_CLAMP((int32_t)(src * (1U << 15)) >> m, INT16_MIN, INT16_MAX))
126 
127 /**
128  * @brief Convert a floating-point (float32_t) value to a Q31 fixed-point value with a right shift.
129  *
130  * @param src The input floating-point (float32_t) value.
131  * @param m   The number of bits to right shift the input value (0 to 31).
132  * @return The converted Q31 fixed-point value.
133  */
134 #define Z_SHIFT_F32_TO_Q31(src, m)                                                                 \
135 	((q31_t)Z_CLAMP((int64_t)(src * (1U << 31)) >> m, INT32_MIN, INT32_MAX))
136 
137 /**
138  * @brief Convert a floating-point (float64_t) value to a Q7 fixed-point value with a right shift.
139  *
140  * @param src The input floating-point (float64_t) value.
141  * @param m   The number of bits to right shift the input value (0 to 7).
142  * @return The converted Q7 fixed-point value.
143  */
144 #define Z_SHIFT_F64_TO_Q7(src, m)                                                                  \
145 	((q7_t)Z_CLAMP((int32_t)(src * (1U << 7)) >> m, INT8_MIN, INT8_MAX))
146 
147 /**
148  * @brief Convert a floating-point (float64_t) value to a Q15 fixed-point value with a right shift.
149  *
150  * @param src The input floating-point (float64_t) value.
151  * @param m   The number of bits to right shift the input value (0 to 15).
152  * @return The converted Q15 fixed-point value.
153  */
154 #define Z_SHIFT_F64_TO_Q15(src, m)                                                                 \
155 	((q15_t)Z_CLAMP((int32_t)(src * (1U << 15)) >> m, INT16_MIN, INT16_MAX))
156 
157 /**
158  * @brief Convert a floating-point (float64_t) value to a Q31 fixed-point value with a right shift.
159  *
160  * @param src The input floating-point (float64_t) value.
161  * @param m   The number of bits to right shift the input value (0 to 31).
162  * @return The converted Q31 fixed-point value.
163  */
164 #define Z_SHIFT_F64_TO_Q31(src, m)                                                                 \
165 	((q31_t)Z_CLAMP((int64_t)(src * (1U << 31)) >> m, INT32_MIN, INT32_MAX))
166 
167 /**
168  * @}
169  */
170 
171 #ifdef __cplusplus
172 }
173 #endif
174 
175 #endif /* INCLUDE_ZEPHYR_DSP_UTILS_H_ */
176