1+ #include " lib/rgb.hpp"
2+ #include " effect.hpp"
3+
4+ void ClassicFFT::update (int16_t *buffer16, size_t sample_count) {
5+ int16_t * fft_array = &fft.sample_array [SAMPLES_PER_AUDIO_BUFFER * (BUFFERS_PER_FFT_SAMPLE - 1 )];
6+ memmove (fft.sample_array , &fft.sample_array [SAMPLES_PER_AUDIO_BUFFER], (BUFFERS_PER_FFT_SAMPLE - 1 ) * sizeof (uint16_t ));
7+
8+ for (auto i = 0u ; i < SAMPLES_PER_AUDIO_BUFFER; i++) {
9+ fft_array[i] = buffer16[i];
10+ }
11+
12+ fft.update ();
13+
14+ for (auto i = 0u ; i < display.WIDTH ; i++) {
15+ fix15 sample = std::min (float_to_fix15 (max_sample_from_fft), fft.get_scaled_as_fix15 (i + FFT_SKIP_BINS));
16+ uint8_t maxy = 0 ;
17+
18+ for (int j = 0 ; j < HISTORY_LEN; ++j) {
19+ if (eq_history[i][j] > maxy) {
20+ maxy = eq_history[i][j];
21+ }
22+ }
23+
24+ #ifdef SCALE_SQRT
25+ fix15 subtract = subtract_step;
26+ #endif
27+ for (auto y = 0 ; y < display.HEIGHT ; y++) {
28+ uint8_t r = 0 ;
29+ uint8_t g = 0 ;
30+ uint8_t b = 0 ;
31+ if (sample > int_to_fix15 (lower_threshold)) {
32+ r = (uint16_t )(palette[y].r );
33+ g = (uint16_t )(palette[y].g );
34+ b = (uint16_t )(palette[y].b );
35+ #ifdef SCALE_LOGARITHMIC
36+ sample = multiply_fix15_unit (multiple, sample);
37+ #else
38+ sample = std::max (1 , sample - subtract);
39+ #ifdef SCALE_SQRT
40+ subtract += subtract_step;
41+ #endif
42+ #endif
43+ }
44+ else if (sample > 0 ) {
45+ uint16_t int_sample = (uint16_t )fix15_to_int (sample);
46+ r = std::min ((uint16_t )(palette[y].r ), int_sample);
47+ g = std::min ((uint16_t )(palette[y].g ), int_sample);
48+ b = std::min ((uint16_t )(palette[y].b ), int_sample);
49+ eq_history[i][history_idx] = y;
50+ sample = 0 ;
51+ if (maxy < y) {
52+ maxy = y;
53+ }
54+ } else if (y < maxy) {
55+ r = (uint16_t )(palette[y].r ) >> 3 ;
56+ g = (uint16_t )(palette[y].g ) >> 3 ;
57+ b = (uint16_t )(palette[y].b ) >> 3 ;
58+ }
59+ display.set_pixel (i, display.HEIGHT - 1 - y, r, g, b);
60+ }
61+ if (maxy > 0 ) {
62+ RGB c = palette[display.HEIGHT - 1 ];
63+ display.set_pixel (i, display.HEIGHT - 1 - maxy, c.r , c.g , c.b );
64+ }
65+ }
66+ history_idx = (history_idx + 1 ) % HISTORY_LEN;
67+ }
68+
69+ void ClassicFFT::init (uint32_t sample_frequency) {
70+ printf (" ClassicFFT: %ix%i\n " , display.WIDTH , display.HEIGHT );
71+
72+ history_idx = 0 ;
73+
74+ fft.set_scale (display.HEIGHT * .318f );
75+
76+ for (auto i = 0u ; i < display.HEIGHT ; i++) {
77+ int n = floor (i / 4 ) * 4 ;
78+ float h = 0.4 * float (n) / display.HEIGHT ;
79+ h = 0.333 - h;
80+ palette[i] = RGB::from_hsv (h, 1 .0f , 1 .0f );
81+ }
82+
83+ max_sample_from_fft = 4000 .f + 130 .f * display.HEIGHT ;
84+ lower_threshold = 270 - 2 * display.HEIGHT ;
85+ #ifdef SCALE_LOGARITHMIC
86+ multiple = float_to_fix15 (pow (max_sample_from_fft / lower_threshold, -1 .f / (display.HEIGHT - 1 )));
87+ #elif defined(SCALE_SQRT)
88+ subtract_step = float_to_fix15 ((max_sample_from_fft - lower_threshold) * 2 .f / (display.HEIGHT * (display.HEIGHT - 1 )));
89+ #elif defined(SCALE_LINEAR)
90+ subtract = float_to_fix15 ((max_sample_from_fft - lower_threshold) / (display.HEIGHT - 1 ));
91+ #endif
92+ }
0 commit comments