55 */
66
77
8+ #include < array>
89#include < cmath>
910#include < cstdint>
1011#include < string>
1718#include " uad/display.hpp"
1819
1920
21+ static const std::array win5_32{3 , 7 , 12 , 7 , 3 }; // TODO ponder symmetry
22+ static constexpr uint32_t win5_32_shift = 5 ;
23+
24+ static inline int16_t window_win5_32 (std::vector <int16_t > data1, int32_t idx) {
25+ int32_t value = 0 ;
26+
27+ size_t half_win_len = std::size (win5_32) / 2 ;
28+ int32_t d_idx = idx - half_win_len;
29+ size_t data1_len = data1.size ();
30+ if (d_idx >= 0 && d_idx < data1_len - std::size (win5_32)) {
31+ // More efficient version for most cases
32+ for (const auto weight : win5_32) {
33+ value += weight * int32_t (data1[d_idx++]);
34+ }
35+ value = value >> win5_32_shift;
36+ } else {
37+ int32_t weights = 0 ;
38+ for (const auto weight : win5_32) {
39+ if (d_idx >= 0 && d_idx < data1_len) {
40+ value += weight * data1[d_idx];
41+ weights += weight;
42+ };
43+ ++d_idx;
44+ }
45+ if (weights != 0 ) {
46+ value /= weights;
47+ }
48+ }
49+
50+ return int16_t (value);
51+ }
52+
53+ static inline int16_t window_win3_4 (std::vector <int16_t > data1, int32_t idx) {
54+
55+ if (idx >= 1 && idx < data1.size () - 1 ) {
56+ int32_t value = 0 ;
57+ // These are 1/4 2/4 1/4 weights
58+ value = data1[idx - 1 ] + (data1[idx] << 1 ) + data1[idx + 1 ];
59+ value = value >> 2 ;
60+ return int16_t (value);
61+ } else {
62+ return data1[idx];
63+ }
64+ }
65+
66+ static inline int16_t window (std::vector <int16_t > data1, int32_t window, int32_t idx) {
67+ int32_t value = 0 ;
68+
69+ if (window == 5 ) {
70+ value = window_win5_32 (data1, idx);
71+ } else if (window == 3 ) {
72+ value = window_win3_4 (data1, idx);
73+ } else {
74+ value = data1[idx];
75+ }
76+
77+ return int16_t (value);
78+ }
79+
2080void EffectAudioscopeTuner::updateDisplay (void ) {
2181 float frequency = tuner.latest_frequency ;
2282 auto signal = tuner.getSamples ();
@@ -35,11 +95,11 @@ void EffectAudioscopeTuner::updateDisplay(void) {
3595 }
3696 }
3797
38- // TODO ensure tuner.sample_array access does not go beyond buffer
3998 // TODO add multiple fading passes
4099 for (uint8_t x=0 ; x < Display::WIDTH; x++) {
41- int32_t y = Y_MID_POS - int32_t (roundf (signal[waveform_idx] * y_scale));
42- waveform_idx += 10 ; // TODO proper (fast) reasmpling
100+ int32_t value = window (signal, 5 , waveform_idx); // returns 0 beyond end of buffer
101+ int32_t y = Y_MID_POS - int32_t (roundf (value * y_scale));
102+ waveform_idx += 10 ;
43103 if (y >=0 && y < Display::HEIGHT) {
44104 display.set_pixel (x, y,
45105 0u , 128u , 0u );
0 commit comments