Nu:Tekt NTS-1 digital SDK  v1.1-0
fixed_math.h
Go to the documentation of this file.
1 /*
2  BSD 3-Clause License
3 
4  Copyright (c) 2018, KORG INC.
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without
8  modification, are permitted provided that the following conditions are met:
9 
10  * Redistributions of source code must retain the above copyright notice, this
11  list of conditions and the following disclaimer.
12 
13  * Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17  * Neither the name of the copyright holder nor the names of its
18  contributors may be used to endorse or promote products derived from
19  this software without specific prior written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 
32 //*/
33 
46 #ifndef __fixed_math_h
47 #define __fixed_math_h
48 
49 #include <stdint.h>
50 
51 #include "cortexm4.h"
52 
53 // TODO: add fill-in implementations for intel builds
54 
55 /*===========================================================================*/
56 /* Data Types and Conversions. */
57 /*===========================================================================*/
58 
64 typedef int8_t q7_t;
65 typedef int8_t q7_0_t;
66 
67 typedef uint8_t q8_t;
68 typedef uint8_t q8_0_t;
69 
70 typedef int16_t q15_t;
71 typedef int16_t q1_14_t;
72 typedef int16_t q2_13_t;
73 typedef int16_t q3_12_t;
74 typedef int16_t q4_11_t;
75 typedef int16_t q5_10_t;
76 typedef int16_t q6_9_t;
77 typedef int16_t q7_8_t;
78 typedef int16_t q8_7_t;
79 typedef int16_t q13_2_t;
80 typedef int16_t q15_0_t;
81 
82 typedef uint16_t uq16_t;
83 typedef uint16_t uq16_0_t;
84 
85 typedef int32_t q23_t;
86 
87 typedef int32_t q31_t;
88 typedef int32_t q1_30_t;
89 typedef int32_t q2_29_t;
90 typedef int32_t q3_28_t;
91 typedef int32_t q4_27_t;
92 typedef int32_t q5_26_t;
93 typedef int32_t q6_25_t;
94 typedef int32_t q7_24_t;
95 typedef int32_t q8_23_t;
96 typedef int32_t q15_16_t;
97 typedef int32_t q16_15_t;
98 typedef int32_t q17_14_t;
99 typedef int32_t q18_13_t;
100 typedef int32_t q19_12_t;
101 typedef int32_t q20_11_t;
102 typedef int32_t q21_10_t;
103 typedef int32_t q22_9_t;
104 typedef int32_t q23_8_t;
105 typedef int32_t q31_0_t;
106 
107 typedef uint32_t uq32_t;
108 typedef uint32_t uq14_18_t;
109 typedef uint32_t uq32_0_t;
110 
111 typedef int64_t q63_t;
112 typedef int64_t q1_62_t;
113 typedef int64_t q2_61_t;
114 typedef int64_t q3_60_t;
115 typedef int64_t q4_59_t;
116 typedef int64_t q5_58_t;
117 typedef int64_t q6_57_t;
118 typedef int64_t q7_56_t;
119 typedef int64_t q8_55_t;
120 typedef int64_t q16_47_t;
121 typedef int64_t q23_40_t;
122 typedef int64_t q31_32_t;
123 typedef int64_t q63_0_t;
124 
125 typedef uint64_t uq64_t;
126 typedef uint64_t uq64_0_t;
127 
136 #define q15_to_f32_c 3.05175781250000e-005f
137 #define q31_to_f32_c 4.65661287307739e-010f
138 
139 #define q15_to_f32(q) ((float)(q) * q15_to_f32_c)
140 #define q31_to_f32(q) ((float)(q) * q31_to_f32_c)
141 
142 #define f32_to_q15(f) ((q15_t)ssat((q31_t)((float)(f) * ((1<<15)-1)),16))
143 #define f32_to_q31(f) ((q31_t)((float)(f) * (float)0x7FFFFFFF))
144 
147 /*===========================================================================*/
148 /* Constants. */
149 /*===========================================================================*/
150 
156 #define M_HALPI_Q1_14 0x6488
157 #define M_HALPI_Q1_30 0x6487ED51
158 #define M_PI_Q2_13 0x6488
159 #define M_PI_Q2_29 0x6487ED51
160 #define M_1OVERPI_Q15 0x28BE
161 #define M_1OVERPI_Q31 0x28BE60DC
162 #define M_TWOPI_Q3_12 0x6488
163 #define M_TWOPI_Q3_28 0x6487ED51
164 
165 #define M_1OVER48K_Q31 0x0000AEC3 // 1/48000
166 #define M_1OVER44K_Q31 0x0000BE38 // 1/44100
167 #define M_1OVER22K_Q31 0x00017C70 // 1/22050
168 
171 /*===========================================================================*/
172 /* Common Primitives. */
173 /*===========================================================================*/
174 
175 // Some useful references:
176 // For absolute value see: https://community.arm.com/processors/f/discussions/6636/how-to-get-absolute-value-of-a-32-bit-signed-integer-as-fast-as-possible
177 // For min/max see: https://www.m4-unleashed.com/parallel-comparison/#more-164
178 
185 #define q15add(a,b) ((q15_t)(qadd16((q15_t)(a),(q15_t)(b)) & 0xFFFF))
186 #define q15sub(a,b) ((q15_t)(qsub16((q15_t)(a),(q15_t)(b)) & 0xFFFF))
187 #define q15mul(a,b) ((q15_t)(((int32_t)(q15_t)(a) * (q15_t)(b))>>15))
188 #define q15absmul(a,b) (-q15mul(a, -b))
189 #define q15abs(a) ((q15_t)(qsub16(((q15_t)(a) ^ ((q15_t)(a)>>15)), ((q15_t)(a)>>15)) & 0xFFFF))
190 
193 static inline __attribute__((optimize("Ofast"),always_inline))
194 q15_t q15max(q15_t a, q15_t b) {
195  qsub16(a,b);
196  return sel(a,b);
197 }
198 
201 static inline __attribute__((optimize("Ofast"),always_inline))
202 q15_t q15min(q15_t a, q15_t b) {
203  qsub16(b,a);
204  return sel(a,b);
205 }
206 
207 #define q15addp(a,b) ((simd32_t)(qadd16((simd32_t)(a),(simd32_t)(b))))
208 #define q15subp(a,b) ((simd32_t)(qsub16((simd32_t)(a),(simd32_t)(b))))
209 #define q15absp(a) ((simd32_t)(qsub16((simd32_t)(a) ^ ((simd32_t)(a)>>15), (simd32_t)(a)>>15)))
210 
213 static inline __attribute__((optimize("Ofast"),always_inline))
214 simd32_t q15maxp(simd32_t a, simd32_t b) {
215  qsub16(a,b);
216  return sel(a,b);
217 }
218 
221 static inline __attribute__((optimize("Ofast"),always_inline))
222 simd32_t q15minp(simd32_t a, simd32_t b) {
223  qsub16(b,a);
224  return sel(a,b);
225 }
226 
235 #define q31add(a,b) (qadd((q31_t)(a),(q31_t)(b)))
236 #define q31sub(a,b) (qsub((q31_t)(a),(q31_t)(b)))
237 #define q31mul(a,b) ((q31_t)(((q63_t)(q31_t)(a) * (q31_t)(b))>>31))
238 #define q31absmul(a,b) (-q31mul(a,-b))
239 #define q31abs(a) (qsub((q31_t)(a) ^ ((q31_t)(a)>>31), (q31_t)(a)>>31))
240 
243 static inline __attribute__((optimize("Ofast"),always_inline))
244 q31_t q31max(q31_t a, q31_t b) {
245  qsub(a,b);
246  return sel(a,b);
247 }
248 
251 static inline __attribute__((optimize("Ofast"),always_inline))
252 q31_t q31min(q31_t a, q31_t b) {
253  qsub(b,a);
254  return sel(a,b);
255 }
256 
260 #endif // __fixed_math_h
261 
q15minp
static simd32_t q15minp(simd32_t a, simd32_t b)
Minimum.
Definition: fixed_math.h:222
q15maxp
static simd32_t q15maxp(simd32_t a, simd32_t b)
Maximum.
Definition: fixed_math.h:214
cortexm4.h
ARM Cortex-M4 specific header.
q31min
static q31_t q31min(q31_t a, q31_t b)
Minimum.
Definition: fixed_math.h:252
q15max
static q15_t q15max(q15_t a, q15_t b)
Maximum.
Definition: fixed_math.h:194
q31max
static q31_t q31max(q31_t a, q31_t b)
Maximum.
Definition: fixed_math.h:244
q15min
static q15_t q15min(q15_t a, q15_t b)
Minimum.
Definition: fixed_math.h:202