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