Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User6412
Level 4
Level 4
If you need to calculate the sinus function as fast as possible, then this is the possible solution:


float sin_tab[65]; // sinus approximation table

/**
* Initialization of the sinus approximation table.
* Call this before using fast_sin.
*/
void init_sinus(void) {
for(int i = 0; i < 65; i++) {
float arg = M_PI * i / 128.0;
sin_tab = sin(arg);
}
}

/**
* Fast sinus calculation.
* Max |argument| is 205887.3835 radians.
* Put this function in to PSRAM.
*/
__attribute__ ((section (".text.fastcode")))
inline float fast_sin(float radians) {
float val1, val2;
float sign = 1.0f;
if(radians < 0) {
sign = -sign;
radians = -radians;
}
// Translate radians in 16-bit format (2*Pi <=> 65536)
uint32_t index = ((uint32_t)(10430.38f * radians)) & 0xFFFF;
// 8 bits for linear approximation between left and right table values
float approx = (index & 0xFF) * 0.00390625f;
// 8 bits for full table access
uint16_t tbl_index = index >> 8;
if(tbl_index >= 128) {
// negative value
sign = -sign;
tbl_index -= 128;
}
if(tbl_index < 64) {
val1 = sin_tab[tbl_index];
val2 = sin_tab[tbl_index + 1];
}
else {
// table index should be mirrored
tbl_index = 127 - tbl_index;
val1 = sin_tab[tbl_index + 1];
val2 = sin_tab[tbl_index];
}
return (val1 + (val2 - val1) * approx) * sign;
}

/**
* Fast cosinus calculation.
* Max |argument| is 205887.3835 radians.
*/
__attribute__ ((section (".text.fastcode")))
inline float fast_cos(float radians) {
return fast_sin(radians + 0.5f * (float)M_PI);
}


Call the function init_sinus once before using fast_sin. As you see, the fast_cos is also here. This approach uses the linear approximation with 256 table points accross one sinus period and 256 points between them. It is pretty faster as the arm32 library and still usable.
0 Likes
0 Replies