| Mozzi version v1.1.0 sound synthesis library for Arduino |

mozzi_fixmath.cpp
1 #include "mozzi_fixmath.h"
2
3 /** @ingroup fixmath
4 @{
5 */
6
7 //Snipped from http://code.google.com/p/ht1632c/wiki/Optimizations
8 //TB2012 changed names to not interfere with arduino compilation
9 //Fast integer math
10 //
11 //If you need to include arithmetic operations in you code but you don't need
12 //floating point operations, you could use boolean operations instead of arithmetic
13 //operations, or use smaller data types and custom functions instead of stdlib functions
14 //or C operators (expecially / and %).
15 //Look at IntegerCodeSnippets, http://code.google.com/p/ht1632c/wiki/IntegerCodeSnippets
16 //
17 //Here is some ready to use fast integer 1 uint8_t wide math functions (from ht1632c library).
18
19 /**
20 fast uint8_t modulus
21 @param n numerator
22 @param d denominator
23 @return modulus
24 */
25 uint8_t uint8_tMod(uint8_t n, uint8_t d)
26 {
27 while(n >= d)
28 n -= d;
29 return n;
30 }
31
32 /** Fast uint8_t division
33 @param n numerator
34 @param d denominator
35 @return quotient
36 */
37 uint8_t uint8_tDiv(uint8_t n, uint8_t d)
38 {
39 uint8_t q = 0;
40 while(n >= d)
41 {
42 n -= d;
43 q++;
44 }
45 return q;
46 }
47
48 /* fast integer (1 uint8_t) PRNG */
49 uint8_t uint8_tRnd(uint8_t min, uint8_t max)
50 {
51 static uint8_t seed;
52 seed = (21 * seed + 21);
53 return min + uint8_tMod(seed, --max);
54 }
55 //WARNING: don't use this uint8_tRnd() function for cryptography!
56
57 //} of snip from http://code.google.com/p/ht1632c/wiki/Optimizations
58
59
60
61 // from http://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int
62 /* Exponentiation by squaring.
63 */
64 int ipow(int base, int exp)
65 {
66 int result = 1;
67 while (exp)
68 {
69 if (exp & 1)
70 result *= base;
71 exp >>= 1;
72 base *= base;
73 }
74
75 return result;
76 }
77
78
79 /*
80 from: http://objectmix.com/vhdl/189970-2-powerof-x-where-x-fixed-point-value-2.html
81
82 to do 2^(x.y) first find
83 2^x and 2^(x+1) through bit shifting 1 to the left by x and (x + 1) places
84
85 now you do linear interpolation by drawing a line through these two points 2^x,
86 2^(x+1), then use f = m*x+b. the slope, m = rise over run
87 = (2^(x+1) - 2^x)/((x+1) - (x))
88 = 2^(x) * (2 - 1) / 1
89 = 2^(x)
90 b = 2^x, so to linearly interpolate do....(edited out typo)..
91 f = 2^(x) * (y) + 2^x
92 = 2^x * (y + 1)
93 where x is integer part, y is fractional part
94 */
95
96
97 /**
98 fast replacement for pow(2,x), where x is a Q8n8 fractional
99 fixed-point exponent. It's less accurate than pow(2,x), but useful where a
100 tradeoff between accuracy and speed is required to keep audio from glitching.
101 @param exponent in Q8n8 format.
102 @return pow(2,x) in Q16n16 format.
103 @todo Q16n16_pow2() accuracy needs more attention.
104 */
105 Q16n16 Q16n16_pow2(Q8n8 exponent)
106 {
107 // to do 2^(x.y) first find
108 //2^x and 2^(x+1) through bit shifting 1 to the left by x and (x + 1) places
109 uint8_t Q = (uint8_t)((Q8n8)exponent>>8); // integer part
110 uint8_t n = (uint8_t) exponent; // fractional part
111 // f = 2^x * (y + 1)
112 return (((Q16n16)Q8n8_FIX1 << Q) * (Q8n8_FIX1 + n));
113 }
114
115
116
117
118 //http://www.codecodex.com/wiki/Calculate_an_integer_square_root
119 //see Integer Square Roots by Jack W. Crenshaw, figure 2, http://www.embedded.com/electronics-blogs/programmer-s-toolbox/4219659/Integer-Square-Roots
120
121 uint32_t // OR uint16 OR uint8_t
122 isqrt32 (uint32_t n) // OR isqrt16 ( uint16_t n ) OR isqrt8 ( uint8_t n ) - respectively [ OR overloaded as isqrt (uint16_t?? n) in C++ ]
123 {
124 register uint32_t // OR register uint16_t OR register uint8_t - respectively
125 root, remainder, place;
126
127 root = 0;
128 remainder = n;
129 place = 0x40000000; // OR place = 0x4000; OR place = 0x40; - respectively
130
131 while (place > remainder)
132 place = place >> 2;
133 while (place)
134 {
135 if (remainder >= root + place)
136 {
137 remainder = remainder - root - place;
138 root = root + (place << 1);
139 }
140 root = root >> 1;
141 place = place >> 2;
142 }
143 return root;
144 }
145
146
147 //http://www.codecodex.com/wiki/Calculate_an_integer_square_root
148 uint16_t // OR uint16_t OR uint8_t
149 isqrt16 (uint16_t n) // OR isqrt16 ( uint16_t n ) OR isqrt8 ( uint8_t n ) - respectively [ OR overloaded as isqrt (uint16_t?? n) in C++ ]
150 {
151 register uint16_t // OR register uint16_t OR register uint8_t - respectively
152 root, remainder, place;
153
154 root = 0;
155 remainder = n;
156 place = 0x4000; // OR place = 0x4000; OR place = 0x40; - respectively
157
158 while (place > remainder)
159 place = place >> 2;
160 while (place)
161 {
162 if (remainder >= root + place)
163 {
164 remainder = remainder - root - place;
165 root = root + (place << 1);
166 }
167 root = root >> 1;
168 place = place >> 2;
169 }
170 return root;
171 }
172
173
174 /** @} */
Q8n8
uint16_t Q8n8
unsigned fractional number using 8 integer bits and 8 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:35
Q8n8_FIX1
#define Q8n8_FIX1
1 in Q8n8 format
Definition: mozzi_fixmath.h:55
uint8_tMod
uint8_t uint8_tMod(uint8_t n, uint8_t d)
fast uint8_t modulus
Definition: mozzi_fixmath.cpp:25
Q16n16
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:46