1 /* ----------------------------------------------------------------------
2 * Copyright (C) 2010 ARM Limited. All rights reserved.
7 * Project: CMSIS DSP Library
10 * Description: Fast sine calculation for Q31 values.
12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
14 * Version 1.0.10 2011/7/15
15 * Big Endian support added and Merged M0 and M3/M4 Source code.
17 * Version 1.0.3 2010/11/29
18 * Re-organized the CMSIS folders and updated documentation.
20 * Version 1.0.2 2010/11/11
21 * Documentation updated.
23 * Version 1.0.1 2010/10/05
24 * Production release and review comments incorporated.
26 * Version 1.0.0 2010/09/20
27 * Production release and review comments incorporated.
28 * -------------------------------------------------------------------- */
33 * @ingroup groupFastMath
43 * Tables generated are in Q31(1.31 Fixed point format)
44 * Generation of sin values in floating point:
45 * <pre>tableSize = 256;
46 * for(n = -1; n < (tableSize + 1); n++)
48 * sinTable[n+1]= sin(2*pi*n/tableSize);
50 * where pi value is 3.14159265358979
52 * Convert Floating point to Q31(Fixed point):
53 * (sinTable[i] * pow(2, 31))
55 * rounding to nearest integer is done
56 * sinTable[i] += (sinTable[i] > 0 ? 0.5 :-0.5);
59 static const q31_t sinTableQ31[259] = {
60 0xfcdbd541, 0x0, 0x3242abf, 0x647d97c, 0x96a9049, 0xc8bd35e, 0xfab272b,
62 0x15e21445, 0x18f8b83c, 0x1c0b826a, 0x1f19f97b, 0x2223a4c5, 0x25280c5e,
63 0x2826b928, 0x2b1f34eb,
64 0x2e110a62, 0x30fbc54d, 0x33def287, 0x36ba2014, 0x398cdd32, 0x3c56ba70,
65 0x3f1749b8, 0x41ce1e65,
66 0x447acd50, 0x471cece7, 0x49b41533, 0x4c3fdff4, 0x4ebfe8a5, 0x5133cc94,
67 0x539b2af0, 0x55f5a4d2,
68 0x5842dd54, 0x5a82799a, 0x5cb420e0, 0x5ed77c8a, 0x60ec3830, 0x62f201ac,
69 0x64e88926, 0x66cf8120,
70 0x68a69e81, 0x6a6d98a4, 0x6c242960, 0x6dca0d14, 0x6f5f02b2, 0x70e2cbc6,
71 0x72552c85, 0x73b5ebd1,
72 0x7504d345, 0x7641af3d, 0x776c4edb, 0x78848414, 0x798a23b1, 0x7a7d055b,
73 0x7b5d039e, 0x7c29fbee,
74 0x7ce3ceb2, 0x7d8a5f40, 0x7e1d93ea, 0x7e9d55fc, 0x7f0991c4, 0x7f62368f,
75 0x7fa736b4, 0x7fd8878e,
76 0x7ff62182, 0x7fffffff, 0x7ff62182, 0x7fd8878e, 0x7fa736b4, 0x7f62368f,
77 0x7f0991c4, 0x7e9d55fc,
78 0x7e1d93ea, 0x7d8a5f40, 0x7ce3ceb2, 0x7c29fbee, 0x7b5d039e, 0x7a7d055b,
79 0x798a23b1, 0x78848414,
80 0x776c4edb, 0x7641af3d, 0x7504d345, 0x73b5ebd1, 0x72552c85, 0x70e2cbc6,
81 0x6f5f02b2, 0x6dca0d14,
82 0x6c242960, 0x6a6d98a4, 0x68a69e81, 0x66cf8120, 0x64e88926, 0x62f201ac,
83 0x60ec3830, 0x5ed77c8a,
84 0x5cb420e0, 0x5a82799a, 0x5842dd54, 0x55f5a4d2, 0x539b2af0, 0x5133cc94,
85 0x4ebfe8a5, 0x4c3fdff4,
86 0x49b41533, 0x471cece7, 0x447acd50, 0x41ce1e65, 0x3f1749b8, 0x3c56ba70,
87 0x398cdd32, 0x36ba2014,
88 0x33def287, 0x30fbc54d, 0x2e110a62, 0x2b1f34eb, 0x2826b928, 0x25280c5e,
89 0x2223a4c5, 0x1f19f97b,
90 0x1c0b826a, 0x18f8b83c, 0x15e21445, 0x12c8106f, 0xfab272b, 0xc8bd35e,
92 0x3242abf, 0x0, 0xfcdbd541, 0xf9b82684, 0xf6956fb7, 0xf3742ca2, 0xf054d8d5,
94 0xea1debbb, 0xe70747c4, 0xe3f47d96, 0xe0e60685, 0xdddc5b3b, 0xdad7f3a2,
95 0xd7d946d8, 0xd4e0cb15,
96 0xd1eef59e, 0xcf043ab3, 0xcc210d79, 0xc945dfec, 0xc67322ce, 0xc3a94590,
97 0xc0e8b648, 0xbe31e19b,
98 0xbb8532b0, 0xb8e31319, 0xb64beacd, 0xb3c0200c, 0xb140175b, 0xaecc336c,
99 0xac64d510, 0xaa0a5b2e,
100 0xa7bd22ac, 0xa57d8666, 0xa34bdf20, 0xa1288376, 0x9f13c7d0, 0x9d0dfe54,
101 0x9b1776da, 0x99307ee0,
102 0x9759617f, 0x9592675c, 0x93dbd6a0, 0x9235f2ec, 0x90a0fd4e, 0x8f1d343a,
103 0x8daad37b, 0x8c4a142f,
104 0x8afb2cbb, 0x89be50c3, 0x8893b125, 0x877b7bec, 0x8675dc4f, 0x8582faa5,
105 0x84a2fc62, 0x83d60412,
106 0x831c314e, 0x8275a0c0, 0x81e26c16, 0x8162aa04, 0x80f66e3c, 0x809dc971,
107 0x8058c94c, 0x80277872,
108 0x8009de7e, 0x80000000, 0x8009de7e, 0x80277872, 0x8058c94c, 0x809dc971,
109 0x80f66e3c, 0x8162aa04,
110 0x81e26c16, 0x8275a0c0, 0x831c314e, 0x83d60412, 0x84a2fc62, 0x8582faa5,
111 0x8675dc4f, 0x877b7bec,
112 0x8893b125, 0x89be50c3, 0x8afb2cbb, 0x8c4a142f, 0x8daad37b, 0x8f1d343a,
113 0x90a0fd4e, 0x9235f2ec,
114 0x93dbd6a0, 0x9592675c, 0x9759617f, 0x99307ee0, 0x9b1776da, 0x9d0dfe54,
115 0x9f13c7d0, 0xa1288376,
116 0xa34bdf20, 0xa57d8666, 0xa7bd22ac, 0xaa0a5b2e, 0xac64d510, 0xaecc336c,
117 0xb140175b, 0xb3c0200c,
118 0xb64beacd, 0xb8e31319, 0xbb8532b0, 0xbe31e19b, 0xc0e8b648, 0xc3a94590,
119 0xc67322ce, 0xc945dfec,
120 0xcc210d79, 0xcf043ab3, 0xd1eef59e, 0xd4e0cb15, 0xd7d946d8, 0xdad7f3a2,
121 0xdddc5b3b, 0xe0e60685,
122 0xe3f47d96, 0xe70747c4, 0xea1debbb, 0xed37ef91, 0xf054d8d5, 0xf3742ca2,
123 0xf6956fb7, 0xf9b82684,
124 0xfcdbd541, 0x0, 0x3242abf
129 * @brief Fast approximation to the trigonometric sine function for Q31 data.
130 * @param[in] x Scaled input value in radians.
133 * The Q31 input value is in the range [0 +1) and is mapped to a radian value in the range [0 2*pi).
139 q31_t sinVal, in, in2; /* Temporary variables for input, output */
140 uint32_t index; /* Index variables */
141 q31_t wa, wb, wc, wd; /* Cubic interpolation coefficients */
142 q31_t a, b, c, d; /* Four nearest output values */
143 q31_t *tablePtr; /* Pointer to table */
144 q31_t fract, fractCube, fractSquare; /* Temporary values for fractional values */
145 q31_t oneBy6 = 0x15555555; /* Fixed point value of 1/6 */
146 q31_t tableSpacing = TABLE_SPACING_Q31; /* Table spacing */
147 q31_t temp; /* Temporary variable for intermediate process */
151 /* Calculate the nearest index */
152 index = (uint32_t) in / (uint32_t) tableSpacing;
154 /* Calculate the nearest value of input */
155 in2 = (q31_t) index *tableSpacing;
157 /* Calculation of fractional value */
158 fract = (in - in2) << 8;
160 /* fractSquare = fract * fract */
161 fractSquare = ((q31_t) (((q63_t) fract * fract) >> 32));
162 fractSquare = fractSquare << 1;
164 /* fractCube = fract * fract * fract */
165 fractCube = ((q31_t) (((q63_t) fractSquare * fract) >> 32));
166 fractCube = fractCube << 1;
168 /* Initialise table pointer */
169 tablePtr = (q31_t *) & sinTableQ31[index];
171 /* Cubic interpolation process */
172 /* Calculation of wa */
173 /* wa = -(oneBy6)*fractCube + (fractSquare >> 1u) - (0x2AAAAAAA)*fract; */
174 wa = ((q31_t) (((q63_t) oneBy6 * fractCube) >> 32));
176 wa = (q31_t) ((((q63_t) wa << 32) + ((q63_t) temp * fract)) >> 32);
178 wa += (fractSquare >> 1u);
180 /* Read first nearest value of output from the sin table */
184 sinVal = ((q31_t) (((q63_t) a * wa) >> 32));
186 /* q31(1.31) Fixed point value of 1 */
189 /* Calculation of wb */
190 wb = ((fractCube >> 1u) - (fractSquare + (fract >> 1u))) + temp;
192 /* Read second nearest value of output from the sin table */
196 sinVal = (q31_t) ((((q63_t) sinVal << 32) + (q63_t) b * (wb)) >> 32);
198 /* Calculation of wc */
199 wc = -fractCube + fractSquare;
200 wc = (wc >> 1u) + fract;
202 /* Read third nearest value of output from the sin table */
206 sinVal = (q31_t) ((((q63_t) sinVal << 32) + ((q63_t) c * wc)) >> 32);
208 /* Calculation of wd */
209 /* wd = (oneBy6) * fractCube - (oneBy6) * fract; */
210 fractCube = fractCube - fract;
211 wd = ((q31_t) (((q63_t) oneBy6 * fractCube) >> 32));
214 /* Read fourth nearest value of output from the sin table */
217 /* sinVal += d*wd; */
218 sinVal = (q31_t) ((((q63_t) sinVal << 32) + ((q63_t) d * wd)) >> 32);
220 /* convert sinVal in 2.30 format to 1.31 format */
221 return (sinVal << 1u);
226 * @} end of sin group