Memory management improv.

This commit is contained in:
Totoo
2026-04-30 15:00:19 +02:00
committed by GitHub
parent ab986a0378
commit 2bacbc80a8
26 changed files with 365 additions and 410 deletions
+29 -25
View File
@@ -131,35 +131,39 @@ void TVView::on_channel_spectrum(
// I was hoping that by doing this, I can have a longer buffer like 39936, then the frame will looks better vertically
// however this is useless until now.
for (size_t i = 0; i < 256; i++) {
// video_buffer[i+count*256] = spectrum_rgb4_lut[spectrum.db[i]];
video_buffer_int[i + count * 256] = 255 - spectrum.db[i];
// Left the original comment, but rewrote the function.
// Shift the last 128 pixels of the previous packet to the front
// This overlap handles an x_correction shift of up to 128 pixels seamlessly.
for (size_t i = 0; i < 128; i++) {
window_buffer[i] = window_buffer[i + 256];
}
count = count + 1;
if (count == 52 - 1) {
ui::Color line_buffer[128];
Coord line;
uint32_t bmp_px;
/*for (line = 0; line < 104; line++)
{
for (bmp_px = 0; bmp_px < 128; bmp_px++)
{
//line_buffer[bmp_px] = video_buffer[bmp_px+line*128];
line_buffer[bmp_px] = spectrum_rgb4_lut[video_buffer_int[bmp_px+line*128 + x_correction]];
}
// Load the new 256 pixels into the remainder of the buffer
for (size_t i = 0; i < 256; i++) {
window_buffer[i + 128] = 255 - spectrum.db[i];
}
display.render_line({ 0, line + 100 }, 128, line_buffer);
}*/
for (line = 0; line < 208; line = line + 2) {
for (bmp_px = 0; bmp_px < 128; bmp_px++) {
// line_buffer[bmp_px] = video_buffer[bmp_px+line*128];
line_buffer[bmp_px] = spectrum_rgb4_lut[video_buffer_int[bmp_px + line / 2 * 128 + x_correction]];
}
ui::Color line_buffer[128];
display.render_line({0, line + 100}, 128, line_buffer);
display.render_line({0, line + 101}, 128, line_buffer);
}
// Render the first line of this batch (matches original doubled-height behavior)
for (size_t bmp_px = 0; bmp_px < 128; bmp_px++) {
line_buffer[bmp_px] = spectrum_rgb4_lut[window_buffer[bmp_px + x_correction]];
}
display.render_line({0, (Coord)(count * 4 + 100)}, 128, line_buffer);
display.render_line({0, (Coord)(count * 4 + 101)}, 128, line_buffer);
// Render the second line of this batch
for (size_t bmp_px = 0; bmp_px < 128; bmp_px++) {
line_buffer[bmp_px] = spectrum_rgb4_lut[window_buffer[bmp_px + 128 + x_correction]];
}
display.render_line({0, (Coord)(count * 4 + 102)}, 128, line_buffer);
display.render_line({0, (Coord)(count * 4 + 103)}, 128, line_buffer);
count++;
// Reset at 52 (52 * 2 lines = 104 lines total)
if (count >= 52) {
count = 0;
}
}
+3 -2
View File
@@ -79,8 +79,9 @@ class TVView : public Widget {
void paint(Painter& painter) override;
void on_channel_spectrum(const ChannelSpectrum& spectrum);
void on_adjust_xcorr(uint8_t xcorr);
// ui::Color video_buffer[13312];
uint8_t video_buffer_int[13312 + 128]{0}; // 128 is for the over length caused by x_correction
// 256 samples from current callback + 128 overlap from the previous callback
uint8_t window_buffer[384]{0};
uint32_t count = 0;
uint8_t x_correction = 0;
@@ -77,6 +77,10 @@ void ExtSensorsView::on_any() {
has_data = true;
}
void ExtSensorsView::on_show() {
i2cdev::I2CDevManager::set_autoscan_interval(3);
}
void ExtSensorsView::on_gps(const GPSPosDataMessage* msg) {
on_any();
std::string tmp = to_string_decimal(msg->lat, 5);
@@ -78,6 +78,8 @@ class ExtSensorsView : public View {
void on_orientation(const OrientationDataMessage* msg);
void on_environment(const EnvironmentDataMessage* msg);
void on_show() override;
MessageHandlerRegistration message_handler_gps{
Message::ID::GPSPosData,
[this](Message* const p) {
+11 -10
View File
@@ -33,7 +33,7 @@ namespace ui::external_app::time_sink {
TimeSinkWaveformWidget::TimeSinkWaveformWidget(
Rect parent_rect,
const int16_t* data,
const int8_t* data,
size_t length,
Color color)
: Widget{parent_rect},
@@ -71,10 +71,10 @@ void TimeSinkWaveformWidget::set_persistence_frames(uint8_t frames) {
}
}
Coord TimeSinkWaveformWidget::sample_to_y(const Rect& r, int16_t sample) const {
Coord TimeSinkWaveformWidget::sample_to_y(const Rect& r, int8_t sample) const {
const int32_t y_center = r.top() + (r.height() / 2);
const int32_t y_span = std::max<int32_t>(1, r.height() - 1);
const int32_t y = y_center - (static_cast<int32_t>(sample) * y_span) / 65536;
const int32_t y = y_center - (static_cast<int32_t>(sample) * y_span) / 256;
return static_cast<Coord>(std::clamp<int32_t>(y, r.top(), r.bottom() - 1));
}
@@ -115,7 +115,6 @@ void TimeSinkWaveformWidget::paint(Painter& painter) {
current_y_[x] = sample_to_y(r, data_[src_index]);
}
// Draw first, then erase stale pixels so the trace never disappears mid-refresh.
for (size_t x = 0; x < columns; ++x) {
display.draw_pixel(
{static_cast<Coord>(r.left() + x), current_y_[x]},
@@ -126,13 +125,13 @@ void TimeSinkWaveformWidget::paint(Painter& painter) {
const size_t expired_slot = history_head_;
for (size_t x = 0; x < columns; ++x) {
const auto expired_y = history_y_[expired_slot][x];
const auto expired_y = sample_to_y(r, history_samples_[expired_slot][x]);
bool keep = (expired_y == current_y_[x]);
if (!keep) {
for (size_t i = 1; i < history_count_; ++i) {
const size_t slot = (history_head_ + i) % max_persistence_frames;
if (history_y_[slot][x] == expired_y) {
if (sample_to_y(r, history_samples_[slot][x]) == expired_y) {
keep = true;
break;
}
@@ -151,7 +150,10 @@ void TimeSinkWaveformWidget::paint(Painter& painter) {
}
const size_t tail_slot = (history_head_ + history_count_) % max_persistence_frames;
std::copy_n(current_y_.begin(), columns, history_y_[tail_slot].begin());
for (size_t x = 0; x < columns; ++x) {
const size_t src_index = (x * length_) / columns;
history_samples_[tail_slot][x] = data_[src_index];
}
++history_count_;
}
@@ -338,8 +340,7 @@ void TimeSinkView::on_channel_spectrum(const ChannelSpectrum& spectrum) {
const size_t src_index =
(trigger_index + offset) % source_count;
const int32_t centered = static_cast<int32_t>(spectrum.db[src_index]) - 128;
const int32_t scaled = centered * 256;
waveform_buffer[x] = static_cast<int16_t>(std::clamp<int32_t>(scaled, -32768, 32767));
waveform_buffer[x] = static_cast<int8_t>(std::clamp<int32_t>(centered, -128, 127));
}
waveform.set_dirty();
@@ -349,4 +350,4 @@ void TimeSinkView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
}
} // namespace ui::external_app::time_sink
} // namespace ui::external_app::time_sink
+6 -6
View File
@@ -40,7 +40,7 @@ constexpr size_t time_sink_waveform_points = 240;
class TimeSinkWaveformWidget : public Widget {
public:
TimeSinkWaveformWidget(Rect parent_rect, const int16_t* data, size_t length, Color color);
TimeSinkWaveformWidget(Rect parent_rect, const int8_t* data, size_t length, Color color);
TimeSinkWaveformWidget(const TimeSinkWaveformWidget&) = delete;
TimeSinkWaveformWidget(TimeSinkWaveformWidget&&) = delete;
TimeSinkWaveformWidget& operator=(const TimeSinkWaveformWidget&) = delete;
@@ -56,13 +56,13 @@ class TimeSinkWaveformWidget : public Widget {
static constexpr size_t max_persistence_frames = 16; // this is sad that we cant have 32 histories in ext app due to memory constraints
void reset_cache();
Coord sample_to_y(const Rect& r, int16_t sample) const;
Coord sample_to_y(const Rect& r, int8_t sample) const;
const int16_t* data_;
const int8_t* data_;
size_t length_;
Color color_;
std::array<Coord, max_columns> current_y_{};
std::array<std::array<Coord, max_columns>, max_persistence_frames> history_y_{};
std::array<std::array<int8_t, max_columns>, max_persistence_frames> history_samples_{};
size_t history_count_{0};
size_t history_head_{0};
uint8_t persistence_frames_{1};
@@ -120,7 +120,7 @@ class TimeSinkView : public View {
{"trigger_level"sv, &trigger_level},
}};
int16_t waveform_buffer[waveform_points]{0};
int8_t waveform_buffer[waveform_points]{0};
ChannelSpectrumFIFO* fifo = nullptr;
Labels labels{
@@ -235,4 +235,4 @@ class TimeSinkView : public View {
} // namespace ui::external_app::time_sink
#endif // __UI_TIME_SINK_APP_H__
#endif // __UI_TIME_SINK_APP_H__