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 */
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  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  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 /** @} */
uint16_t Q8n8
unsigned fractional number using 8 integer bits and 8 fractional bits, represents 0 to 255...
Definition: mozzi_fixmath.h:35
#define Q8n8_FIX1
1 in Q8n8 format
Definition: mozzi_fixmath.h:55
uint8_t uint8_tMod(uint8_t n, uint8_t d)
fast uint8_t modulus
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:46