![]() |
Mozzi
alpha 0.01.1t
sound synthesis library for Arduino
|
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_ */