PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

808 line
23KB

  1. #define FASTLED_INTERNAL
  2. #include "FastLED.h"
  3. #include <string.h>
  4. FASTLED_NAMESPACE_BEGIN
  5. #define P(x) FL_PGM_READ_BYTE_NEAR(p + x)
  6. FL_PROGMEM static uint8_t const p[] = { 151,160,137,91,90,15,
  7. 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
  8. 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
  9. 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
  10. 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
  11. 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
  12. 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
  13. 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
  14. 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
  15. 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
  16. 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
  17. 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
  18. 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,151
  19. };
  20. #if FASTLED_NOISE_ALLOW_AVERAGE_TO_OVERFLOW == 1
  21. #define AVG15(U,V) (((U)+(V)) >> 1)
  22. #else
  23. // See if we should use the inlined avg15 for AVR with MUL instruction
  24. #if defined(__AVR__) && (LIB8_ATTINY == 0)
  25. #define AVG15(U,V) (avg15_inline_avr_mul((U),(V)))
  26. // inlined copy of avg15 for AVR with MUL instruction; cloned from math8.h
  27. // Forcing this inline in the 3-D 16bit noise produces a 12% speedup overall,
  28. // at a cost of just +8 bytes of net code size.
  29. static int16_t inline __attribute__((always_inline)) avg15_inline_avr_mul( int16_t i, int16_t j)
  30. {
  31. asm volatile(
  32. /* first divide j by 2, throwing away lowest bit */
  33. "asr %B[j] \n\t"
  34. "ror %A[j] \n\t"
  35. /* now divide i by 2, with lowest bit going into C */
  36. "asr %B[i] \n\t"
  37. "ror %A[i] \n\t"
  38. /* add j + C to i */
  39. "adc %A[i], %A[j] \n\t"
  40. "adc %B[i], %B[j] \n\t"
  41. : [i] "+a" (i)
  42. : [j] "a" (j) );
  43. return i;
  44. }
  45. #else
  46. #define AVG15(U,V) (avg15((U),(V)))
  47. #endif
  48. #endif
  49. // See fastled_config.h for notes on this;
  50. // "#define FASTLED_NOISE_FIXED 1" is the correct value
  51. #if FASTLED_NOISE_FIXED == 0
  52. #define EASE8(x) (FADE(x) )
  53. #define EASE16(x) (FADE(x) )
  54. #else
  55. #define EASE8(x) (ease8InOutQuad(x) )
  56. #define EASE16(x) (ease16InOutQuad(x))
  57. #endif
  58. //
  59. // #define FADE_12
  60. #define FADE_16
  61. #ifdef FADE_12
  62. #define FADE logfade12
  63. #define LERP(a,b,u) lerp15by12(a,b,u)
  64. #else
  65. #define FADE(x) scale16(x,x)
  66. #define LERP(a,b,u) lerp15by16(a,b,u)
  67. #endif
  68. static int16_t inline __attribute__((always_inline)) grad16(uint8_t hash, int16_t x, int16_t y, int16_t z) {
  69. #if 0
  70. switch(hash & 0xF) {
  71. case 0: return (( x) + ( y))>>1;
  72. case 1: return ((-x) + ( y))>>1;
  73. case 2: return (( x) + (-y))>>1;
  74. case 3: return ((-x) + (-y))>>1;
  75. case 4: return (( x) + ( z))>>1;
  76. case 5: return ((-x) + ( z))>>1;
  77. case 6: return (( x) + (-z))>>1;
  78. case 7: return ((-x) + (-z))>>1;
  79. case 8: return (( y) + ( z))>>1;
  80. case 9: return ((-y) + ( z))>>1;
  81. case 10: return (( y) + (-z))>>1;
  82. case 11: return ((-y) + (-z))>>1;
  83. case 12: return (( y) + ( x))>>1;
  84. case 13: return ((-y) + ( z))>>1;
  85. case 14: return (( y) + (-x))>>1;
  86. case 15: return ((-y) + (-z))>>1;
  87. }
  88. #else
  89. hash = hash&15;
  90. int16_t u = hash<8?x:y;
  91. int16_t v = hash<4?y:hash==12||hash==14?x:z;
  92. if(hash&1) { u = -u; }
  93. if(hash&2) { v = -v; }
  94. return AVG15(u,v);
  95. #endif
  96. }
  97. static int16_t inline __attribute__((always_inline)) grad16(uint8_t hash, int16_t x, int16_t y) {
  98. hash = hash & 7;
  99. int16_t u,v;
  100. if(hash < 4) { u = x; v = y; } else { u = y; v = x; }
  101. if(hash&1) { u = -u; }
  102. if(hash&2) { v = -v; }
  103. return AVG15(u,v);
  104. }
  105. static int16_t inline __attribute__((always_inline)) grad16(uint8_t hash, int16_t x) {
  106. hash = hash & 15;
  107. int16_t u,v;
  108. if(hash > 8) { u=x;v=x; }
  109. else if(hash < 4) { u=x;v=1; }
  110. else { u=1;v=x; }
  111. if(hash&1) { u = -u; }
  112. if(hash&2) { v = -v; }
  113. return AVG15(u,v);
  114. }
  115. // selectBasedOnHashBit performs this:
  116. // result = (hash & (1<<bitnumber)) ? a : b
  117. // but with an AVR asm version that's smaller and quicker than C
  118. // (and probably not worth including in lib8tion)
  119. static int8_t inline __attribute__((always_inline)) selectBasedOnHashBit(uint8_t hash, uint8_t bitnumber, int8_t a, int8_t b) {
  120. int8_t result;
  121. #if !defined(__AVR__)
  122. result = (hash & (1<<bitnumber)) ? a : b;
  123. #else
  124. asm volatile(
  125. "mov %[result],%[a] \n\t"
  126. "sbrs %[hash],%[bitnumber] \n\t"
  127. "mov %[result],%[b] \n\t"
  128. : [result] "=r" (result)
  129. : [hash] "r" (hash),
  130. [bitnumber] "M" (bitnumber),
  131. [a] "r" (a),
  132. [b] "r" (b)
  133. );
  134. #endif
  135. return result;
  136. }
  137. static int8_t inline __attribute__((always_inline)) grad8(uint8_t hash, int8_t x, int8_t y, int8_t z) {
  138. #if 0
  139. switch(hash & 0xF) {
  140. case 0: return (( x) + ( y))>>1;
  141. case 1: return ((-x) + ( y))>>1;
  142. case 2: return (( x) + (-y))>>1;
  143. case 3: return ((-x) + (-y))>>1;
  144. case 4: return (( x) + ( z))>>1;
  145. case 5: return ((-x) + ( z))>>1;
  146. case 6: return (( x) + (-z))>>1;
  147. case 7: return ((-x) + (-z))>>1;
  148. case 8: return (( y) + ( z))>>1;
  149. case 9: return ((-y) + ( z))>>1;
  150. case 10: return (( y) + (-z))>>1;
  151. case 11: return ((-y) + (-z))>>1;
  152. case 12: return (( y) + ( x))>>1;
  153. case 13: return ((-y) + ( z))>>1;
  154. case 14: return (( y) + (-x))>>1;
  155. case 15: return ((-y) + (-z))>>1;
  156. }
  157. #else
  158. hash &= 0xF;
  159. int8_t u, v;
  160. //u = (hash&8)?y:x;
  161. u = selectBasedOnHashBit( hash, 3, y, x);
  162. #if 1
  163. v = hash<4?y:hash==12||hash==14?x:z;
  164. #else
  165. // Verbose version for analysis; generates idenitical code.
  166. if( hash < 4) { // 00 01 02 03
  167. v = y;
  168. } else {
  169. if( hash==12 || hash==14) { // 0C 0E
  170. v = x;
  171. } else {
  172. v = z; // 04 05 06 07 08 09 0A 0B 0D 0F
  173. }
  174. }
  175. #endif
  176. if(hash&1) { u = -u; }
  177. if(hash&2) { v = -v; }
  178. return avg7(u,v);
  179. #endif
  180. }
  181. static int8_t inline __attribute__((always_inline)) grad8(uint8_t hash, int8_t x, int8_t y)
  182. {
  183. // since the tests below can be done bit-wise on the bottom
  184. // three bits, there's no need to mask off the higher bits
  185. // hash = hash & 7;
  186. int8_t u,v;
  187. if( hash & 4) {
  188. u = y; v = x;
  189. } else {
  190. u = x; v = y;
  191. }
  192. if(hash&1) { u = -u; }
  193. if(hash&2) { v = -v; }
  194. return avg7(u,v);
  195. }
  196. static int8_t inline __attribute__((always_inline)) grad8(uint8_t hash, int8_t x)
  197. {
  198. // since the tests below can be done bit-wise on the bottom
  199. // four bits, there's no need to mask off the higher bits
  200. // hash = hash & 15;
  201. int8_t u,v;
  202. if(hash & 8) {
  203. u=x; v=x;
  204. } else {
  205. if(hash & 4) {
  206. u=1; v=x;
  207. } else {
  208. u=x; v=1;
  209. }
  210. }
  211. if(hash&1) { u = -u; }
  212. if(hash&2) { v = -v; }
  213. return avg7(u,v);
  214. }
  215. #ifdef FADE_12
  216. uint16_t logfade12(uint16_t val) {
  217. return scale16(val,val)>>4;
  218. }
  219. static int16_t inline __attribute__((always_inline)) lerp15by12( int16_t a, int16_t b, fract16 frac)
  220. {
  221. //if(1) return (lerp(frac,a,b));
  222. int16_t result;
  223. if( b > a) {
  224. uint16_t delta = b - a;
  225. uint16_t scaled = scale16(delta,frac<<4);
  226. result = a + scaled;
  227. } else {
  228. uint16_t delta = a - b;
  229. uint16_t scaled = scale16(delta,frac<<4);
  230. result = a - scaled;
  231. }
  232. return result;
  233. }
  234. #endif
  235. static int8_t inline __attribute__((always_inline)) lerp7by8( int8_t a, int8_t b, fract8 frac)
  236. {
  237. // int8_t delta = b - a;
  238. // int16_t prod = (uint16_t)delta * (uint16_t)frac;
  239. // int8_t scaled = prod >> 8;
  240. // int8_t result = a + scaled;
  241. // return result;
  242. int8_t result;
  243. if( b > a) {
  244. uint8_t delta = b - a;
  245. uint8_t scaled = scale8( delta, frac);
  246. result = a + scaled;
  247. } else {
  248. uint8_t delta = a - b;
  249. uint8_t scaled = scale8( delta, frac);
  250. result = a - scaled;
  251. }
  252. return result;
  253. }
  254. int16_t inoise16_raw(uint32_t x, uint32_t y, uint32_t z)
  255. {
  256. // Find the unit cube containing the point
  257. uint8_t X = (x>>16)&0xFF;
  258. uint8_t Y = (y>>16)&0xFF;
  259. uint8_t Z = (z>>16)&0xFF;
  260. // Hash cube corner coordinates
  261. uint8_t A = P(X)+Y;
  262. uint8_t AA = P(A)+Z;
  263. uint8_t AB = P(A+1)+Z;
  264. uint8_t B = P(X+1)+Y;
  265. uint8_t BA = P(B) + Z;
  266. uint8_t BB = P(B+1)+Z;
  267. // Get the relative position of the point in the cube
  268. uint16_t u = x & 0xFFFF;
  269. uint16_t v = y & 0xFFFF;
  270. uint16_t w = z & 0xFFFF;
  271. // Get a signed version of the above for the grad function
  272. int16_t xx = (u >> 1) & 0x7FFF;
  273. int16_t yy = (v >> 1) & 0x7FFF;
  274. int16_t zz = (w >> 1) & 0x7FFF;
  275. uint16_t N = 0x8000L;
  276. u = EASE16(u); v = EASE16(v); w = EASE16(w);
  277. // skip the log fade adjustment for the moment, otherwise here we would
  278. // adjust fade values for u,v,w
  279. int16_t X1 = LERP(grad16(P(AA), xx, yy, zz), grad16(P(BA), xx - N, yy, zz), u);
  280. int16_t X2 = LERP(grad16(P(AB), xx, yy-N, zz), grad16(P(BB), xx - N, yy - N, zz), u);
  281. int16_t X3 = LERP(grad16(P(AA+1), xx, yy, zz-N), grad16(P(BA+1), xx - N, yy, zz-N), u);
  282. int16_t X4 = LERP(grad16(P(AB+1), xx, yy-N, zz-N), grad16(P(BB+1), xx - N, yy - N, zz - N), u);
  283. int16_t Y1 = LERP(X1,X2,v);
  284. int16_t Y2 = LERP(X3,X4,v);
  285. int16_t ans = LERP(Y1,Y2,w);
  286. return ans;
  287. }
  288. uint16_t inoise16(uint32_t x, uint32_t y, uint32_t z) {
  289. int32_t ans = inoise16_raw(x,y,z);
  290. ans = ans + 19052L;
  291. uint32_t pan = ans;
  292. // pan = (ans * 220L) >> 7. That's the same as:
  293. // pan = (ans * 440L) >> 8. And this way avoids a 7X four-byte shift-loop on AVR.
  294. // Identical math, except for the highest bit, which we don't care about anyway,
  295. // since we're returning the 'middle' 16 out of a 32-bit value anyway.
  296. pan *= 440L;
  297. return (pan>>8);
  298. // // return scale16by8(pan,220)<<1;
  299. // return ((inoise16_raw(x,y,z)+19052)*220)>>7;
  300. // return scale16by8(inoise16_raw(x,y,z)+19052,220)<<1;
  301. }
  302. int16_t inoise16_raw(uint32_t x, uint32_t y)
  303. {
  304. // Find the unit cube containing the point
  305. uint8_t X = x>>16;
  306. uint8_t Y = y>>16;
  307. // Hash cube corner coordinates
  308. uint8_t A = P(X)+Y;
  309. uint8_t AA = P(A);
  310. uint8_t AB = P(A+1);
  311. uint8_t B = P(X+1)+Y;
  312. uint8_t BA = P(B);
  313. uint8_t BB = P(B+1);
  314. // Get the relative position of the point in the cube
  315. uint16_t u = x & 0xFFFF;
  316. uint16_t v = y & 0xFFFF;
  317. // Get a signed version of the above for the grad function
  318. int16_t xx = (u >> 1) & 0x7FFF;
  319. int16_t yy = (v >> 1) & 0x7FFF;
  320. uint16_t N = 0x8000L;
  321. u = EASE16(u); v = EASE16(v);
  322. int16_t X1 = LERP(grad16(P(AA), xx, yy), grad16(P(BA), xx - N, yy), u);
  323. int16_t X2 = LERP(grad16(P(AB), xx, yy-N), grad16(P(BB), xx - N, yy - N), u);
  324. int16_t ans = LERP(X1,X2,v);
  325. return ans;
  326. }
  327. uint16_t inoise16(uint32_t x, uint32_t y) {
  328. int32_t ans = inoise16_raw(x,y);
  329. ans = ans + 17308L;
  330. uint32_t pan = ans;
  331. // pan = (ans * 242L) >> 7. That's the same as:
  332. // pan = (ans * 484L) >> 8. And this way avoids a 7X four-byte shift-loop on AVR.
  333. // Identical math, except for the highest bit, which we don't care about anyway,
  334. // since we're returning the 'middle' 16 out of a 32-bit value anyway.
  335. pan *= 484L;
  336. return (pan>>8);
  337. // return (uint32_t)(((int32_t)inoise16_raw(x,y)+(uint32_t)17308)*242)>>7;
  338. // return scale16by8(inoise16_raw(x,y)+17308,242)<<1;
  339. }
  340. int16_t inoise16_raw(uint32_t x)
  341. {
  342. // Find the unit cube containing the point
  343. uint8_t X = x>>16;
  344. // Hash cube corner coordinates
  345. uint8_t A = P(X);
  346. uint8_t AA = P(A);
  347. uint8_t B = P(X+1);
  348. uint8_t BA = P(B);
  349. // Get the relative position of the point in the cube
  350. uint16_t u = x & 0xFFFF;
  351. // Get a signed version of the above for the grad function
  352. int16_t xx = (u >> 1) & 0x7FFF;
  353. uint16_t N = 0x8000L;
  354. u = EASE16(u);
  355. int16_t ans = LERP(grad16(P(AA), xx), grad16(P(BA), xx - N), u);
  356. return ans;
  357. }
  358. uint16_t inoise16(uint32_t x) {
  359. return ((uint32_t)((int32_t)inoise16_raw(x) + 17308L)) << 1;
  360. }
  361. int8_t inoise8_raw(uint16_t x, uint16_t y, uint16_t z)
  362. {
  363. // Find the unit cube containing the point
  364. uint8_t X = x>>8;
  365. uint8_t Y = y>>8;
  366. uint8_t Z = z>>8;
  367. // Hash cube corner coordinates
  368. uint8_t A = P(X)+Y;
  369. uint8_t AA = P(A)+Z;
  370. uint8_t AB = P(A+1)+Z;
  371. uint8_t B = P(X+1)+Y;
  372. uint8_t BA = P(B) + Z;
  373. uint8_t BB = P(B+1)+Z;
  374. // Get the relative position of the point in the cube
  375. uint8_t u = x;
  376. uint8_t v = y;
  377. uint8_t w = z;
  378. // Get a signed version of the above for the grad function
  379. int8_t xx = ((uint8_t)(x)>>1) & 0x7F;
  380. int8_t yy = ((uint8_t)(y)>>1) & 0x7F;
  381. int8_t zz = ((uint8_t)(z)>>1) & 0x7F;
  382. uint8_t N = 0x80;
  383. u = EASE8(u); v = EASE8(v); w = EASE8(w);
  384. int8_t X1 = lerp7by8(grad8(P(AA), xx, yy, zz), grad8(P(BA), xx - N, yy, zz), u);
  385. int8_t X2 = lerp7by8(grad8(P(AB), xx, yy-N, zz), grad8(P(BB), xx - N, yy - N, zz), u);
  386. int8_t X3 = lerp7by8(grad8(P(AA+1), xx, yy, zz-N), grad8(P(BA+1), xx - N, yy, zz-N), u);
  387. int8_t X4 = lerp7by8(grad8(P(AB+1), xx, yy-N, zz-N), grad8(P(BB+1), xx - N, yy - N, zz - N), u);
  388. int8_t Y1 = lerp7by8(X1,X2,v);
  389. int8_t Y2 = lerp7by8(X3,X4,v);
  390. int8_t ans = lerp7by8(Y1,Y2,w);
  391. return ans;
  392. }
  393. uint8_t inoise8(uint16_t x, uint16_t y, uint16_t z) {
  394. // return scale8(76+(inoise8_raw(x,y,z)),215)<<1;
  395. int8_t n = inoise8_raw( x, y, z); // -64..+64
  396. n+= 64; // 0..128
  397. uint8_t ans = qadd8( n, n); // 0..255
  398. return ans;
  399. }
  400. int8_t inoise8_raw(uint16_t x, uint16_t y)
  401. {
  402. // Find the unit cube containing the point
  403. uint8_t X = x>>8;
  404. uint8_t Y = y>>8;
  405. // Hash cube corner coordinates
  406. uint8_t A = P(X)+Y;
  407. uint8_t AA = P(A);
  408. uint8_t AB = P(A+1);
  409. uint8_t B = P(X+1)+Y;
  410. uint8_t BA = P(B);
  411. uint8_t BB = P(B+1);
  412. // Get the relative position of the point in the cube
  413. uint8_t u = x;
  414. uint8_t v = y;
  415. // Get a signed version of the above for the grad function
  416. int8_t xx = ((uint8_t)(x)>>1) & 0x7F;
  417. int8_t yy = ((uint8_t)(y)>>1) & 0x7F;
  418. uint8_t N = 0x80;
  419. u = EASE8(u); v = EASE8(v);
  420. int8_t X1 = lerp7by8(grad8(P(AA), xx, yy), grad8(P(BA), xx - N, yy), u);
  421. int8_t X2 = lerp7by8(grad8(P(AB), xx, yy-N), grad8(P(BB), xx - N, yy - N), u);
  422. int8_t ans = lerp7by8(X1,X2,v);
  423. return ans;
  424. // return scale8((70+(ans)),234)<<1;
  425. }
  426. uint8_t inoise8(uint16_t x, uint16_t y) {
  427. //return scale8(69+inoise8_raw(x,y),237)<<1;
  428. int8_t n = inoise8_raw( x, y); // -64..+64
  429. n+= 64; // 0..128
  430. uint8_t ans = qadd8( n, n); // 0..255
  431. return ans;
  432. }
  433. // output range = -64 .. +64
  434. int8_t inoise8_raw(uint16_t x)
  435. {
  436. // Find the unit cube containing the point
  437. uint8_t X = x>>8;
  438. // Hash cube corner coordinates
  439. uint8_t A = P(X);
  440. uint8_t AA = P(A);
  441. uint8_t B = P(X+1);
  442. uint8_t BA = P(B);
  443. // Get the relative position of the point in the cube
  444. uint8_t u = x;
  445. // Get a signed version of the above for the grad function
  446. int8_t xx = ((uint8_t)(x)>>1) & 0x7F;
  447. uint8_t N = 0x80;
  448. u = EASE8( u);
  449. int8_t ans = lerp7by8(grad8(P(AA), xx), grad8(P(BA), xx - N), u);
  450. return ans;
  451. }
  452. uint8_t inoise8(uint16_t x) {
  453. int8_t n = inoise8_raw(x); //-64..+64
  454. n += 64; // 0..128
  455. uint8_t ans = qadd8(n,n); // 0..255
  456. return ans;
  457. }
  458. // struct q44 {
  459. // uint8_t i:4;
  460. // uint8_t f:4;
  461. // q44(uint8_t _i, uint8_t _f) {i=_i; f=_f; }
  462. // };
  463. // uint32_t mul44(uint32_t v, q44 mulby44) {
  464. // return (v *mulby44.i) + ((v * mulby44.f) >> 4);
  465. // }
  466. //
  467. // uint16_t mul44_16(uint16_t v, q44 mulby44) {
  468. // return (v *mulby44.i) + ((v * mulby44.f) >> 4);
  469. // }
  470. void fill_raw_noise8(uint8_t *pData, uint8_t num_points, uint8_t octaves, uint16_t x, int scale, uint16_t time) {
  471. uint32_t _xx = x;
  472. uint32_t scx = scale;
  473. for(int o = 0; o < octaves; o++) {
  474. for(int i = 0,xx=_xx; i < num_points; i++, xx+=scx) {
  475. pData[i] = qadd8(pData[i],inoise8(xx,time)>>o);
  476. }
  477. _xx <<= 1;
  478. scx <<= 1;
  479. }
  480. }
  481. void fill_raw_noise16into8(uint8_t *pData, uint8_t num_points, uint8_t octaves, uint32_t x, int scale, uint32_t time) {
  482. uint32_t _xx = x;
  483. uint32_t scx = scale;
  484. for(int o = 0; o < octaves; o++) {
  485. for(int i = 0,xx=_xx; i < num_points; i++, xx+=scx) {
  486. uint32_t accum = (inoise16(xx,time))>>o;
  487. accum += (pData[i]<<8);
  488. if(accum > 65535) { accum = 65535; }
  489. pData[i] = accum>>8;
  490. }
  491. _xx <<= 1;
  492. scx <<= 1;
  493. }
  494. }
  495. void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, q44 freq44, fract8 amplitude, int skip, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time) {
  496. if(octaves > 1) {
  497. fill_raw_2dnoise8(pData, width, height, octaves-1, freq44, amplitude, skip+1, x*freq44, freq44 * scalex, y*freq44, freq44 * scaley, time);
  498. } else {
  499. // amplitude is always 255 on the lowest level
  500. amplitude=255;
  501. }
  502. scalex *= skip;
  503. scaley *= skip;
  504. fract8 invamp = 255-amplitude;
  505. uint16_t xx = x;
  506. for(int i = 0; i < height; i++, y+=scaley) {
  507. uint8_t *pRow = pData + (i*width);
  508. xx = x;
  509. for(int j = 0; j < width; j++, xx+=scalex) {
  510. uint8_t noise_base = inoise8(xx,y,time);
  511. noise_base = (0x80 & noise_base) ? (noise_base - 127) : (127 - noise_base);
  512. noise_base = scale8(noise_base<<1,amplitude);
  513. if(skip == 1) {
  514. pRow[j] = scale8(pRow[j],invamp) + noise_base;
  515. } else {
  516. for(int ii = i; ii<(i+skip) && ii<height; ii++) {
  517. uint8_t *pRow = pData + (ii*width);
  518. for(int jj=j; jj<(j+skip) && jj<width; jj++) {
  519. pRow[jj] = scale8(pRow[jj],invamp) + noise_base;
  520. }
  521. }
  522. }
  523. }
  524. }
  525. }
  526. void fill_raw_2dnoise8(uint8_t *pData, int width, int height, uint8_t octaves, uint16_t x, int scalex, uint16_t y, int scaley, uint16_t time) {
  527. fill_raw_2dnoise8(pData, width, height, octaves, q44(2,0), 128, 1, x, scalex, y, scaley, time);
  528. }
  529. void fill_raw_2dnoise16(uint16_t *pData, int width, int height, uint8_t octaves, q88 freq88, fract16 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) {
  530. if(octaves > 1) {
  531. fill_raw_2dnoise16(pData, width, height, octaves-1, freq88, amplitude, skip, x *freq88 , scalex *freq88, y * freq88, scaley * freq88, time);
  532. } else {
  533. // amplitude is always 255 on the lowest level
  534. amplitude=65535;
  535. }
  536. scalex *= skip;
  537. scaley *= skip;
  538. fract16 invamp = 65535-amplitude;
  539. for(int i = 0; i < height; i+=skip, y+=scaley) {
  540. uint16_t *pRow = pData + (i*width);
  541. for(int j = 0,xx=x; j < width; j+=skip, xx+=scalex) {
  542. uint16_t noise_base = inoise16(xx,y,time);
  543. noise_base = (0x8000 & noise_base) ? noise_base - (32767) : 32767 - noise_base;
  544. noise_base = scale16(noise_base<<1, amplitude);
  545. if(skip==1) {
  546. pRow[j] = scale16(pRow[j],invamp) + noise_base;
  547. } else {
  548. for(int ii = i; ii<(i+skip) && ii<height; ii++) {
  549. uint16_t *pRow = pData + (ii*width);
  550. for(int jj=j; jj<(j+skip) && jj<width; jj++) {
  551. pRow[jj] = scale16(pRow[jj],invamp) + noise_base;
  552. }
  553. }
  554. }
  555. }
  556. }
  557. }
  558. int32_t nmin=11111110;
  559. int32_t nmax=0;
  560. void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, q44 freq44, fract8 amplitude, int skip, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) {
  561. if(octaves > 1) {
  562. fill_raw_2dnoise16into8(pData, width, height, octaves-1, freq44, amplitude, skip+1, x*freq44, scalex *freq44, y*freq44, scaley * freq44, time);
  563. } else {
  564. // amplitude is always 255 on the lowest level
  565. amplitude=255;
  566. }
  567. scalex *= skip;
  568. scaley *= skip;
  569. uint32_t xx;
  570. fract8 invamp = 255-amplitude;
  571. for(int i = 0; i < height; i+=skip, y+=scaley) {
  572. uint8_t *pRow = pData + (i*width);
  573. xx = x;
  574. for(int j = 0; j < width; j+=skip, xx+=scalex) {
  575. uint16_t noise_base = inoise16(xx,y,time);
  576. noise_base = (0x8000 & noise_base) ? noise_base - (32767) : 32767 - noise_base;
  577. noise_base = scale8(noise_base>>7,amplitude);
  578. if(skip==1) {
  579. pRow[j] = qadd8(scale8(pRow[j],invamp),noise_base);
  580. } else {
  581. for(int ii = i; ii<(i+skip) && ii<height; ii++) {
  582. uint8_t *pRow = pData + (ii*width);
  583. for(int jj=j; jj<(j+skip) && jj<width; jj++) {
  584. pRow[jj] = scale8(pRow[jj],invamp) + noise_base;
  585. }
  586. }
  587. }
  588. }
  589. }
  590. }
  591. void fill_raw_2dnoise16into8(uint8_t *pData, int width, int height, uint8_t octaves, uint32_t x, int scalex, uint32_t y, int scaley, uint32_t time) {
  592. fill_raw_2dnoise16into8(pData, width, height, octaves, q44(2,0), 171, 1, x, scalex, y, scaley, time);
  593. }
  594. void fill_noise8(CRGB *leds, int num_leds,
  595. uint8_t octaves, uint16_t x, int scale,
  596. uint8_t hue_octaves, uint16_t hue_x, int hue_scale,
  597. uint16_t time) {
  598. uint8_t V[num_leds];
  599. uint8_t H[num_leds];
  600. memset(V,0,num_leds);
  601. memset(H,0,num_leds);
  602. fill_raw_noise8(V,num_leds,octaves,x,scale,time);
  603. fill_raw_noise8(H,num_leds,hue_octaves,hue_x,hue_scale,time);
  604. for(int i = 0; i < num_leds; i++) {
  605. leds[i] = CHSV(H[i],255,V[i]);
  606. }
  607. }
  608. void fill_noise16(CRGB *leds, int num_leds,
  609. uint8_t octaves, uint16_t x, int scale,
  610. uint8_t hue_octaves, uint16_t hue_x, int hue_scale,
  611. uint16_t time, uint8_t hue_shift) {
  612. uint8_t V[num_leds];
  613. uint8_t H[num_leds];
  614. memset(V,0,num_leds);
  615. memset(H,0,num_leds);
  616. fill_raw_noise16into8(V,num_leds,octaves,x,scale,time);
  617. fill_raw_noise8(H,num_leds,hue_octaves,hue_x,hue_scale,time);
  618. for(int i = 0; i < num_leds; i++) {
  619. leds[i] = CHSV(H[i] + hue_shift,255,V[i]);
  620. }
  621. }
  622. void fill_2dnoise8(CRGB *leds, int width, int height, bool serpentine,
  623. uint8_t octaves, uint16_t x, int xscale, uint16_t y, int yscale, uint16_t time,
  624. uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time,bool blend) {
  625. uint8_t V[height][width];
  626. uint8_t H[height][width];
  627. memset(V,0,height*width);
  628. memset(H,0,height*width);
  629. fill_raw_2dnoise8((uint8_t*)V,width,height,octaves,x,xscale,y,yscale,time);
  630. fill_raw_2dnoise8((uint8_t*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time);
  631. int w1 = width-1;
  632. int h1 = height-1;
  633. for(int i = 0; i < height; i++) {
  634. int wb = i*width;
  635. for(int j = 0; j < width; j++) {
  636. CRGB led(CHSV(H[h1-i][w1-j],255,V[i][j]));
  637. int pos = j;
  638. if(serpentine && (i & 0x1)) {
  639. pos = w1-j;
  640. }
  641. if(blend) {
  642. leds[wb+pos] >>= 1; leds[wb+pos] += (led>>=1);
  643. } else {
  644. leds[wb+pos] = led;
  645. }
  646. }
  647. }
  648. }
  649. void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine,
  650. uint8_t octaves, uint32_t x, int xscale, uint32_t y, int yscale, uint32_t time,
  651. uint8_t hue_octaves, uint16_t hue_x, int hue_xscale, uint16_t hue_y, uint16_t hue_yscale,uint16_t hue_time, bool blend, uint16_t hue_shift) {
  652. uint8_t V[height][width];
  653. uint8_t H[height][width];
  654. memset(V,0,height*width);
  655. memset(H,0,height*width);
  656. fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,q44(2,0),171,1,x,xscale,y,yscale,time);
  657. // fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,x,xscale,y,yscale,time);
  658. // fill_raw_2dnoise8((uint8_t*)V,width,height,hue_octaves,x,xscale,y,yscale,time);
  659. fill_raw_2dnoise8((uint8_t*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time);
  660. int w1 = width-1;
  661. int h1 = height-1;
  662. hue_shift >>= 8;
  663. for(int i = 0; i < height; i++) {
  664. int wb = i*width;
  665. for(int j = 0; j < width; j++) {
  666. CRGB led(CHSV(hue_shift + (H[h1-i][w1-j]),196,V[i][j]));
  667. int pos = j;
  668. if(serpentine && (i & 0x1)) {
  669. pos = w1-j;
  670. }
  671. if(blend) {
  672. leds[wb+pos] >>= 1; leds[wb+pos] += (led>>=1);
  673. } else {
  674. leds[wb+pos] = led;
  675. }
  676. }
  677. }
  678. }
  679. FASTLED_NAMESPACE_END