Mozzi  alpha 0.01.1t
sound synthesis library for Arduino
 All Classes Functions Typedefs
fixedMath.h
00001 #ifndef FIXEDMATH_H_
00002 #define FIXEDMATH_H_
00003 
00004 #include "Arduino.h" // for "byte" - but is this depreciated?
00005 
00011 // types
00012 typedef char Q0n7;                                                              
00013 typedef char Q7n0;                                                              
00014 typedef unsigned char Q0n8;                     
00015 typedef unsigned char Q8n0;                     
00016 typedef unsigned int Q0n16;                     
00017 typedef unsigned long Q0n31;                                                    
00018 typedef int Q7n8;                                                               
00019 typedef unsigned int Q3n13; 
00020 typedef int Q1n14;                                                              
00021 typedef int Q15n0;                                                              
00022 typedef unsigned int Q8n8;                      
00023 typedef unsigned int             Q1n15;         
00024 typedef unsigned int             Q16n0;         
00025 typedef long Q23n8;                                                             
00026 typedef long Q15n16;                                            
00027 typedef long Q31n0;                                                             
00028 typedef unsigned long Q32n0;                    
00029 typedef unsigned long           Q0n32;                          
00030 typedef unsigned long           Q8n24;                          
00031 typedef unsigned long Q24n8;                    
00032 typedef unsigned long Q16n16;   
00034 // macros to save runtime calculations for representations of 1
00035 #define Q0n7_FIX1 ((Q0n7) 127)                                  
00036 #define Q7n8_FIX1 ((Q7n8) 256)                                  
00037 #define Q8n8_FIX1 ((Q8n8) 256)                                  
00038 #define Q23n8_FIX1 ((Q23n8) 256)                                                
00039 #define Q1n14_FIX1 ((Q1n14) 16384)                              
00040 #define Q1n15_FIX1 ((Q1n15) 32768)                              
00041 #define Q16n16_FIX1 ((Q16n16) 65536)                            
00042 #define Q0n15_FIX1 ((Q0n15) 32767)                              
00043 #define Q0n16_FIX1 ((Q0n16) 65535)                              
00044 #define Q15n16_FIX1 ((Q15n16) 65536)                            
00045 #define Q8n24_FIX1 ((Q8n24) 16777216)           
00046 #define Q0n32_FIX1 ((Q0n32) 4294967295)         
00048 #define Q3n13_2PI ((Q3n13) 411775)                              
00049 #define Q16n16_2PI ((Q16n16) 411775)                            
00051 #define low15bits ((Q1n15) 32767) 
00053 // Type conversions:
00054 /*
00055 Float to Q
00056  
00057 To convert a number from floating point to Qm.n format:
00058  
00059   Multiply the floating point number by 2^n
00060   Round to the nearest integer
00061  
00062 Q to float
00063  
00064 To convert a number from Qm.n format to floating point:
00065  
00066   Convert the number to floating point as if it were an integer
00067   Multiply by 2^-n
00068 */
00069 
00070 inline
00071 Q0n7 float_to_Q0n7(float a) { return static_cast<Q0n7>(a*256); }                                
00073 inline
00074 Q0n8 float_to_Q0n8(float a) { return static_cast<Q0n8>(a*256); }                                
00076 inline
00077 Q7n8 float_to_Q7n8(float a) { return static_cast<Q7n8>(a*256); }                                
00079 inline
00080 Q8n8 float_to_Q8n8(float a) { return static_cast<Q8n8>(a*256); }                                
00082 inline
00083 Q1n14 float_to_Q1n14(float a) { return static_cast<Q1n14>(a*16384); }           
00085 inline
00086 Q1n15 float_to_Q1n15(float a) { return static_cast<Q1n15>(a*32768); }           
00088 inline
00089 Q8n24 float_to_Q8n24(float a) { return static_cast<Q8n24>(a*16777216); }        
00091 inline
00092 Q23n8 float_to_Q23n8(float a) { return static_cast<Q23n8>(a*256); }                             
00094 inline
00095 Q24n8 float_to_Q24n8(float a) { return static_cast<Q24n8>(a*256); }                             
00097 inline
00098 Q16n16 float_to_Q16n16(float a) { return static_cast<Q16n16>(a*65536); }        
00100 inline
00101 Q0n16 float_to_Q0n16(float a) { return static_cast<Q0n16>(a*65536); }           
00103 inline
00104 Q15n16 float_to_Q15n16(float a) { return static_cast<Q15n16>(a*65536); }        
00107 inline
00108 Q1n14 Q0n7_to_Q1n14(Q0n7 a) { return (static_cast<Q1n14>(a))<<7; }                              
00110 inline
00111 Q15n16 Q0n7_to_Q15n16(Q0n7 a) { return (static_cast<Q15n16>(a))<<8; }                           
00113 inline
00114 float Q0n7_to_float(Q0n7 a) { return (static_cast<float>(a))/256; }                             
00117 inline
00118 Q1n15 Q0n8_to_Q1n15(Q0n8 a) { return (static_cast<Q1n15>(a))<<7; }                                              
00120 inline
00121 Q8n8 Q0n8_to_Q8n8(Q0n8 a) { return (static_cast<Q8n8>(a))<<8; }                                 
00123 inline
00124 Q8n24 Q0n8_to_Q8n24(Q0n8 a) { return (static_cast<Q8n24>(a))<<16; }                             
00126 inline
00127 Q24n8 Q0n8_to_Q24n8(Q0n8 a) { return (static_cast<Q24n8>(a))<<8; }                                                              
00129 inline
00130 Q15n16 Q0n8_to_Q15n16(Q0n8 a) { return (static_cast<Q15n16>(a))<<8; }           
00132 inline
00133 Q16n16 Q0n8_to_Q16n16(Q0n8 a) { return (static_cast<Q16n16>(a))<<8; }                           
00135 inline
00136 float Q0n8_to_float(Q0n8 a) { return (static_cast<float>(a))/256; }             
00139 inline
00140 Q7n8 Q7n0_to_Q7n8(Q7n0 a) { return (static_cast<Q7n8>(a))<<8; }                                 
00143 inline
00144 Q7n8 Q8n0_to_Q7n8(Q8n0 a) { return (static_cast<Q7n8>(a))<<8; }                 
00146 inline
00147 Q8n8 Q8n0_to_Q8n8(Q8n0 a) { return (static_cast<Q8n8>(a))<<8; }                                 
00149 inline
00150 Q16n16 Q8n0_to_Q16n16(Q8n0 a) { return (static_cast<Q16n16>(a))<<16; }                                          
00153 inline
00154 Q7n0 Q7n8_to_Q7n0(Q7n8 a) { return static_cast<Q7n0>(a>>8); }                                   
00156 inline
00157 float Q7n8_to_float(Q7n8 a) { return (static_cast<float>(a))/256; }                                             
00160 inline
00161 Q8n0 Q8n8_to_Q8n0(Q8n8 a) { return static_cast<Q8n0>(a>>8); }                                   
00163 inline
00164 Q16n16 Q8n8_to_Q16n16(Q8n8 a) { return (static_cast<Q16n16>(a))<<8; }                                           
00166 inline
00167 float Q8n8_to_float(Q8n8 a) { return (static_cast<float>(a))/256; }                                                             
00170 inline
00171 Q0n7 Q1n14_to_Q0n7(Q1n14 a) { return static_cast<Q0n7>(a>>7); }                                 
00173 inline
00174 float Q1n14_to_float(Q1n14 a) { return (static_cast<float>(a))/16384; }                                         
00177 inline
00178 Q0n8 Q1n15_to_Q0n8(Q1n15 a) { return static_cast<Q0n8>(a>>7); }                                 
00180 inline
00181 float Q1n15_to_float(Q1n15 a) { return (static_cast<float>(a))/32768; }                                         
00184 inline
00185 float Q0n16_to_float(Q0n16 a) { return (static_cast<float>(a))/65536; }                                         
00188 inline
00189 Q15n16 Q15n0_to_Q15n16(Q15n0 a) { return (static_cast<Q15n16>(a))<<16; }                        
00192 inline
00193 Q15n16 Q16n0_to_Q15n16(Q16n0 a) { return (static_cast<Q15n16>(a))<<16; }                                        
00195 inline
00196 Q23n8 Q16n0_to_Q23n8(Q16n0 a) { return (static_cast<Q23n8>(a))<<8; }                                            
00198 inline
00199 Q24n8 Q16n0_to_Q24n8(Q16n0 a) { return (static_cast<Q24n8>(a))<<8; }                            
00201 inline
00202 Q16n16 Q16n0_to_Q16n16(Q16n0 a) { return (static_cast<Q16n16>(a))<<16; }                                        
00204 inline
00205 float Q16n0_to_float(Q16n0 a) { return (static_cast<float>(a)); }                                                                               
00209 inline
00210 Q0n8 Q8n24_to_Q0n8(Q8n24 a) { return static_cast<Q0n8>(a>>16); }                                
00212 inline
00213 float Q8n24_to_float(Q8n24 a) { return (static_cast<float>(a))/16777216; }                      
00216 inline
00217 Q31n0 Q23n8_to_Q31n0(Q23n8 a) { return static_cast<Q31n0>(a>>8); }                              
00219 inline
00220 Q16n0 Q23n8_to_Q16n0(Q23n8 a) { return static_cast<Q16n0>(a>>8); }                              
00222 inline
00223 Q15n0 Q23n8_to_Q15n0(Q23n8 a) { return static_cast<Q15n0>(a>>8); }                              
00225 inline
00226 Q7n8 Q23n8_to_Q7n8(Q23n8 a) { return static_cast<Q7n8>(a); }                                                    
00229 inline
00230 float Q23n8_to_float(Q23n8 a) { return (static_cast<float>(a))/256; }                                           
00233 inline
00234 Q0n8 Q24n8_to_Q0n8(Q24n8 a) { return static_cast<Q0n8>(a); }                                    
00236 inline
00237 Q32n0 Q24n8_to_Q32n0(Q24n8 a) { return static_cast<Q32n0>(a>>8); }                              
00239 inline
00240 Q16n16 Q24n8_to_Q16n16(Q24n8 a) { return (static_cast<Q16n16>(a))<<8; }                                         
00242 inline
00243 float Q24n8_to_float(Q24n8 a) { return (static_cast<float>(a))/256; }                                                           
00246 inline
00247 Q0n8 Q15n16_to_Q0n8(Q15n16 a) { return static_cast<Q0n8>(a>>8); }                                               
00249 inline
00250 Q15n0 Q15n16_to_Q15n0(Q15n16 a) { return static_cast<Q15n0>(a>>16); }                           
00252 inline
00253 Q7n8 Q15n16_to_Q7n8(Q15n16 a) { return static_cast<Q7n8>(a>>8); }                                               
00255 inline
00256 float Q15n16_to_float(Q15n16 a) { return (static_cast<float>(a))/65536; }                                       
00259 inline
00260 Q0n8 Q16n16_to_Q0n8(Q16n16 a) { return static_cast<Q0n8>(a>>8); }                                               
00262 inline
00263 Q16n0 Q16n16_to_Q16n0(Q16n16 a) { return static_cast<Q16n0>(a>>16); }                           
00265 inline
00266 Q24n8 Q16n16_to_Q24n8(Q16n16 a) { return static_cast<Q24n8>(a>>8); }                            
00268 inline
00269 float Q16n16_to_float(Q16n16 a) { return (static_cast<float>(a))/65536; }                       
00281 #define Q7n8_multfix(a,b)         \
00282 ({            \
00283 int prod, val1=a, val2=b ;    \
00284 __asm__ __volatile__ (    \
00285                 "muls %B1, %B2  \n\t"   \
00286                 "mov %B0, r0 \n\t"                 \
00287                 "mul %A1, %A2\n\t"                 \
00288                 "mov %A0, r1 \n\t"   \
00289                 "mulsu %B1, %A2 \n\t"   \
00290                 "add %A0, r0  \n\t"     \
00291                 "adc %B0, r1 \n\t"     \
00292                 "mulsu %B2, %A1 \n\t"   \
00293                 "add %A0, r0 \n\t"     \
00294                 "adc %B0, r1  \n\t"    \
00295                 "clr r1  \n\t"                     \
00296                 : "=&d" (prod)     \
00297                 : "a" (val1), "a" (val2)  \
00298                   );        \
00299   prod;        \
00300 })
00301 
00302 // based on:
00303 /*
00304 #define FMULS8(v1, v2)      \
00305 ({            \
00306   unsigned char res;        \
00307   unsigned char val1 = v1;      \
00308   unsigned char val2 = v2;      \
00309   __asm__ __volatile__      \
00310   (           \
00311     "fmuls $1, $2"   "\n\t" \
00312     "mov $0, r1"     "\n\t" \
00313     "clr r1"     "\n\t" \
00314     : "=&d" (res)       \
00315     : "a" (val1), "a" (val2)  \
00316   );            \
00317   res;          \
00318 }) */
00319 /*
00320 int divfix(int nn, int dd)
00321 begin
00322   int x, d ;
00323   signed char count, neg ;
00324   count = 0;
00325   neg = 0 ;
00326   d = dd ;
00327  
00328   // only works with + numbers
00329   if (d & 0x8000)
00330   begin
00331     neg = 1;
00332     d = -d ;
00333   end
00334  
00335   // range reduction
00336   while (d>0x0100)
00337   begin
00338     --count ;
00339     d >>= 1 ;
00340   end
00341  
00342   while (d<0x0080)
00343   begin
00344     ++count ;
00345     d <<= 1 ;
00346   end
00347  
00348   // Newton interation
00349   x = 0x02ea - (d<<1) ;
00350   x = multfix(x, 0x0200-multfix(d,x));
00351   //x = multfix(x, 0x0200-multfix(d,x));
00352  
00353  
00354   // range expansion
00355   if (count>0)  x = x<<count ;
00356   else if (count<0) x = x>>(-count) ;
00357  
00358   // fix sign
00359   if (neg==1) x=-x;
00360  
00361   //form ratio
00362   x = multfix(x,nn) ;
00363  
00364   return x ;
00365 end
00366  
00367 //========================================================
00368 int sqrtfix(int aa)
00369 begin
00370  
00371   int a;
00372   char nextbit, ahigh;
00373   int root, p ;
00374   a = aa;
00375   ahigh = a>>8 ;
00376   //
00377   // range sort to get integer part and to
00378   // check for weird bits near the top of the range
00379   if (ahigh >= 0x40)   //bigger than 64?
00380   begin
00381     if (a > 0x7e8f)  //>=126.562 = 11.25^2
00382     begin
00383     root = 0x0b40;  // 11
00384     nextbit = 0x10 ;
00385     end
00386     else if (ahigh >= 0x79)  //>=121
00387     begin
00388     root = 0x0b00;  // 11
00389     nextbit = 0x40 ;
00390     end
00391     else if (ahigh >= 0x64)  //>=100
00392     begin
00393     root = 0x0a00;  // 10
00394     nextbit = 0x80 ;
00395     end
00396     else if (ahigh >= 0x51)  //>=81
00397     begin
00398     root = 0x0900;  // 9
00399     nextbit = 0x80 ;
00400     end
00401     else //64
00402     begin
00403     root = 0x0800;  //8
00404     nextbit = 0x80 ;
00405     end
00406   end
00407   else if  (ahigh >= 0x10)  //16  //smaller than 64 and bigger then 16
00408   begin
00409     if (ahigh >= 0x31)  //49
00410     begin
00411     root = 0x0700;  //7
00412     nextbit = 0x80 ;
00413     end
00414     else if (ahigh >= 0x24)  //36
00415     begin
00416     root = 0x0600;  //6
00417     nextbit = 0x80 ;
00418     end
00419     else if (ahigh >= 0x19)  //25
00420     begin
00421     root = 0x0500;  //5
00422     nextbit = 0x80 ;
00423     end
00424     else //16
00425     begin
00426     root = 0x0400;  //4
00427     nextbit = 0x80 ;
00428     end
00429   end
00430   else   //smaller than 16
00431   begin
00432    if (ahigh >= 0x09)  //9
00433     begin
00434     root = 0x0300;  //3
00435     nextbit = 0x80 ;
00436     end
00437     else if (ahigh >= 0x04)  //4
00438     begin
00439     root = 0x0200;  //2
00440     nextbit = 0x80 ;
00441     end
00442     else if (ahigh >= 0x01)  //1
00443     begin
00444     root = 0x0100;  //1
00445     nextbit = 0x80 ;
00446     end
00447     else   //less than one
00448     begin
00449     root = 0;
00450     nextbit = 0x80 ;
00451     end
00452   end
00453   // now get the low order bits
00454   while (nextbit)
00455   begin
00456                                 root = nextbit + root;
00457                                 p =  multfix(root,root);
00458     if (p >= a) root = root - nextbit ;
00459                 nextbit = nextbit>>1 ;
00460   end
00461   return root ;
00462 end
00463 */
00464 /*
00465 // from octosynth, Joe Marshall 2011:
00466  
00467   // multiply 2 16 bit numbers together and shift 8 without precision loss
00468   // requires assembler really
00469   volatile unsigned char zeroReg=0;
00470   volatile unsigned int multipliedCounter=oscillators[c].phaseStep;
00471   asm volatile
00472   (
00473   // high unsigned chars mult together = high  unsigned char
00474   "ldi %A[outVal],0" "\n\t"
00475   "mul %B[phaseStep],%B[pitchBend]" "\n\t"
00476   "mov %B[outVal],r0" "\n\t"
00477   // ignore overflow into r1 (should never overflow)
00478   // low unsigned char * high unsigned char -> both unsigned chars
00479   "mul %A[phaseStep],%B[pitchBend]" "\n\t"
00480   "add %A[outVal],r0" "\n\t"
00481   // carry into high unsigned char
00482   "adc %B[outVal],r1" "\n\t"
00483   // high unsigned char* low unsigned char -> both unsigned chars
00484   "mul %B[phaseStep],%A[pitchBend]" "\n\t"
00485   "add %A[outVal],r0" "\n\t"
00486   // carry into high unsigned char
00487   "adc %B[outVal],r1" "\n\t"
00488   // low unsigned char * low unsigned char -> round
00489   "mul %A[phaseStep],%A[pitchBend]" "\n\t"
00490   // the adc below is to round up based on high bit of low*low:
00491   "adc %A[outVal],r1" "\n\t"
00492   "adc %B[outVal],%[ZERO]" "\n\t"
00493   "clr r1" "\n\t"
00494   :[outVal] "=&d" (multipliedCounter)
00495   :[phaseStep] "d" (oscillators[c].phaseStep),[pitchBend] "d"( pitchBendMultiplier),[ZERO] "d" (zeroReg)
00496   :"r1","r0"
00497   );
00498   oscillators[c].phaseStep=multipliedCounter;
00499  
00500   */
00501 
00502 
00503 // dangerous overflow-prone  int power function
00504 int ipow(int base, int exp);
00505 
00506 
00507 
00508 // Base 2 power, using fixed-point exponent
00509 Q16n16 Q16n16_pow2(Q8n8 exponent);
00510 
00511 
00512 unsigned char byteMod(unsigned char n, unsigned char d);
00513 unsigned char byteDiv(unsigned char n, unsigned char d);
00514 unsigned char byteRnd(unsigned char min, unsigned char max);
00515 
00519 #endif /* FIXEDMATH_H_ */