Skip to content

Commit cf17cae

Browse files
author
Kevin J Walters
committed
Primitive filtering for audioscope x scaling.
Adding an inadequate window FIR filter for the x scaling on audioscope, this also deals with falling off the end of the buffer. Gadgetoid#14
1 parent 04b72d0 commit cf17cae

File tree

1 file changed

+63
-3
lines changed

1 file changed

+63
-3
lines changed

effect/effect_audioscope_tuner.cpp

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77

8+
#include <array>
89
#include <cmath>
910
#include <cstdint>
1011
#include <string>
@@ -17,6 +18,65 @@
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+
2080
void 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

Comments
 (0)