mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-04-18 06:56:03 -04:00
Fixes
This commit is contained in:
parent
37082a7f20
commit
9ef8811f72
107
firmware/application/external/rf3d/ui_rf3d.cpp
vendored
107
firmware/application/external/rf3d/ui_rf3d.cpp
vendored
@ -11,8 +11,8 @@ using namespace portapack;
|
||||
namespace ui::external_app::rf3d {
|
||||
|
||||
RF3DView::RF3DView(NavigationView& nav)
|
||||
: nav_{nav}, spectrum_data(SCREEN_WIDTH, std::vector<uint8_t>(MAX_RENDER_DEPTH, 0)) {
|
||||
baseband::run_image(portapack::spi_flash::image_tag_wfm_audio);
|
||||
: nav_{nav}, bar_heights(NUM_BARS, 0), prev_bar_heights(NUM_BARS, 0) {
|
||||
baseband::run_image(spi_flash::image_tag_wfm_audio);
|
||||
add_children({&rssi, &channel, &audio, &field_frequency, &field_lna, &field_vga,
|
||||
&options_modulation, &field_volume, &text_ctcss, &record_view, &dummy});
|
||||
|
||||
@ -24,10 +24,11 @@ RF3DView::RF3DView(NavigationView& nav)
|
||||
receiver_model.set_sampling_rate(3072000);
|
||||
receiver_model.set_baseband_bandwidth(40000);
|
||||
receiver_model.set_target_frequency(93100000);
|
||||
receiver_model.set_rf_amp(true);
|
||||
receiver_model.enable();
|
||||
|
||||
field_lna.set_value(32);
|
||||
field_vga.set_value(40);
|
||||
field_lna.set_value(40);
|
||||
field_vga.set_value(62);
|
||||
|
||||
options_modulation.set_by_value(toUType(ReceiverModel::Mode::WidebandFMAudio));
|
||||
options_modulation.on_change = [this](size_t, OptionsField::value_t v) {
|
||||
@ -58,72 +59,54 @@ void RF3DView::focus() {
|
||||
|
||||
void RF3DView::start() {
|
||||
if (!running) {
|
||||
baseband::spectrum_streaming_start();
|
||||
running = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RF3DView::stop() {
|
||||
if (running) {
|
||||
baseband::spectrum_streaming_stop();
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RF3DView::update_spectrum(const ChannelSpectrum& spectrum) {
|
||||
for (int x = 0; x < SCREEN_WIDTH; x++) {
|
||||
int index = x * 256 / SCREEN_WIDTH;
|
||||
uint8_t new_value = spectrum.db[index];
|
||||
if (new_value > 50) {
|
||||
spectrum_data[x][0] = new_value;
|
||||
} else {
|
||||
spectrum_data[x][0] = 0;
|
||||
void RF3DView::update_spectrum(const AudioSpectrum& spectrum) {
|
||||
const int bins_per_bar = 128 / NUM_BARS; // Simple linear grouping
|
||||
for (int bar = 0; bar < NUM_BARS; bar++) {
|
||||
int start_bin = bar * bins_per_bar;
|
||||
uint8_t max_db = 0;
|
||||
for (int bin = start_bin; bin < start_bin + bins_per_bar; bin++) {
|
||||
if (spectrum.db[bin] > max_db) {
|
||||
max_db = spectrum.db[bin];
|
||||
}
|
||||
}
|
||||
int height = (max_db * RENDER_HEIGHT) / 255;
|
||||
bar_heights[bar] = height;
|
||||
}
|
||||
sampling_rate = spectrum.sampling_rate;
|
||||
}
|
||||
|
||||
void RF3DView::render_3d_waterfall(Painter& painter) {
|
||||
static bool background_drawn = false;
|
||||
static std::vector<int> prev_segments(SCREEN_WIDTH / (12 + 2), 0);
|
||||
|
||||
if (!background_drawn) {
|
||||
painter.fill_rectangle({0, header_height, SCREEN_WIDTH, RENDER_HEIGHT}, Color(20, 0, 40));
|
||||
for (int x = 0; x < SCREEN_WIDTH; x += 20) {
|
||||
painter.fill_rectangle({x, header_height, 1, RENDER_HEIGHT}, Color(80, 0, 160));
|
||||
}
|
||||
for (int y = header_height; y < SCREEN_HEIGHT; y += 20) {
|
||||
painter.fill_rectangle({0, y, SCREEN_WIDTH, 1}, Color(80, 0, 160));
|
||||
}
|
||||
background_drawn = true;
|
||||
}
|
||||
|
||||
const int bar_width = 12;
|
||||
const int bar_spacing = 2;
|
||||
const int num_bars = SCREEN_WIDTH / (bar_width + bar_spacing);
|
||||
const int segment_height = 10;
|
||||
const int num_segments = RENDER_HEIGHT / segment_height;
|
||||
void RF3DView::render_equalizer(Painter& painter) {
|
||||
const int num_bars = SCREEN_WIDTH / (BAR_WIDTH + BAR_SPACING);
|
||||
const int num_segments = RENDER_HEIGHT / SEGMENT_HEIGHT;
|
||||
|
||||
for (int bar = 0; bar < num_bars; bar++) {
|
||||
int x = bar * (bar_width + bar_spacing);
|
||||
uint8_t intensity = spectrum_data[bar * SCREEN_WIDTH / num_bars][0];
|
||||
int active_segments = (intensity * num_segments) / 255;
|
||||
int x = bar * (BAR_WIDTH + BAR_SPACING);
|
||||
int active_segments = (bar_heights[bar] * num_segments) / RENDER_HEIGHT;
|
||||
|
||||
if (prev_segments[bar] > active_segments) {
|
||||
int clear_height = (prev_segments[bar] - active_segments) * segment_height;
|
||||
int clear_y = SCREEN_HEIGHT - prev_segments[bar] * segment_height;
|
||||
painter.fill_rectangle({x, clear_y, bar_width, clear_height}, Color(20, 0, 40));
|
||||
if (prev_bar_heights[bar] > active_segments) {
|
||||
int clear_height = (prev_bar_heights[bar] - active_segments) * SEGMENT_HEIGHT;
|
||||
int clear_y = SCREEN_HEIGHT - prev_bar_heights[bar] * SEGMENT_HEIGHT;
|
||||
painter.fill_rectangle({x, clear_y, BAR_WIDTH, clear_height}, Color(0, 0, 0));
|
||||
}
|
||||
|
||||
for (int seg = 0; seg < active_segments; seg++) {
|
||||
int y = SCREEN_HEIGHT - (seg + 1) * segment_height;
|
||||
int y = SCREEN_HEIGHT - (seg + 1) * SEGMENT_HEIGHT;
|
||||
if (y < header_height) break;
|
||||
|
||||
Color segment_color = (seg >= active_segments - 2 && seg < active_segments) ? Color(255, 255, 255) : Color(255, 0, 255);
|
||||
painter.fill_rectangle({x, y, bar_width, segment_height - 1}, segment_color);
|
||||
painter.fill_rectangle({x, y, BAR_WIDTH, SEGMENT_HEIGHT - 1}, segment_color);
|
||||
}
|
||||
|
||||
prev_segments[bar] = active_segments;
|
||||
prev_bar_heights[bar] = active_segments;
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,25 +114,16 @@ void RF3DView::paint(Painter& painter) {
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
start();
|
||||
painter.fill_rectangle({0, header_height, SCREEN_WIDTH, RENDER_HEIGHT}, Color(0, 0, 0));
|
||||
}
|
||||
render_3d_waterfall(painter);
|
||||
}
|
||||
|
||||
void RF3DView::frame_sync() {
|
||||
if (running && channel_fifo) {
|
||||
ChannelSpectrum channel_spectrum;
|
||||
while (channel_fifo->out(channel_spectrum)) {
|
||||
update_spectrum(channel_spectrum);
|
||||
}
|
||||
set_dirty();
|
||||
}
|
||||
render_equalizer(painter);
|
||||
}
|
||||
|
||||
void RF3DView::on_modulation_changed(ReceiverModel::Mode modulation) {
|
||||
baseband::spectrum_streaming_stop();
|
||||
stop();
|
||||
update_modulation(modulation);
|
||||
on_show_options_modulation();
|
||||
baseband::spectrum_streaming_start();
|
||||
start();
|
||||
}
|
||||
|
||||
void RF3DView::on_show_options_frequency() {
|
||||
@ -229,32 +203,33 @@ void RF3DView::update_modulation(ReceiverModel::Mode modulation) {
|
||||
record_view.stop();
|
||||
baseband::shutdown();
|
||||
|
||||
portapack::spi_flash::image_tag_t image_tag;
|
||||
spi_flash::image_tag_t image_tag;
|
||||
switch (modulation) {
|
||||
case ReceiverModel::Mode::AMAudio:
|
||||
image_tag = portapack::spi_flash::image_tag_am_audio;
|
||||
image_tag = spi_flash::image_tag_am_audio;
|
||||
break;
|
||||
case ReceiverModel::Mode::NarrowbandFMAudio:
|
||||
image_tag = portapack::spi_flash::image_tag_nfm_audio;
|
||||
image_tag = spi_flash::image_tag_nfm_audio;
|
||||
break;
|
||||
case ReceiverModel::Mode::WidebandFMAudio:
|
||||
image_tag = portapack::spi_flash::image_tag_wfm_audio;
|
||||
image_tag = spi_flash::image_tag_wfm_audio;
|
||||
break;
|
||||
case ReceiverModel::Mode::SpectrumAnalysis:
|
||||
image_tag = portapack::spi_flash::image_tag_wideband_spectrum;
|
||||
image_tag = spi_flash::image_tag_wideband_spectrum;
|
||||
break;
|
||||
default:
|
||||
image_tag = portapack::spi_flash::image_tag_wfm_audio;
|
||||
image_tag = spi_flash::image_tag_wfm_audio;
|
||||
break;
|
||||
}
|
||||
|
||||
baseband::run_image(image_tag);
|
||||
if (modulation == ReceiverModel::Mode::SpectrumAnalysis) {
|
||||
baseband::set_spectrum(sampling_rate, 63);
|
||||
baseband::set_spectrum(receiver_model.sampling_rate(), 63);
|
||||
}
|
||||
|
||||
receiver_model.set_modulation(modulation);
|
||||
receiver_model.set_sampling_rate(modulation == ReceiverModel::Mode::SpectrumAnalysis ? sampling_rate : 3072000);
|
||||
receiver_model.set_sampling_rate(3072000);
|
||||
receiver_model.set_rf_amp(true);
|
||||
receiver_model.enable();
|
||||
|
||||
size_t record_sampling_rate = 0;
|
||||
|
44
firmware/application/external/rf3d/ui_rf3d.hpp
vendored
44
firmware/application/external/rf3d/ui_rf3d.hpp
vendored
@ -8,6 +8,7 @@
|
||||
#include "baseband_api.hpp"
|
||||
#include "portapack.hpp"
|
||||
#include "ui_record_view.hpp"
|
||||
#include "ui_spectrum.hpp"
|
||||
|
||||
namespace ui::external_app::rf3d {
|
||||
|
||||
@ -23,41 +24,40 @@ public:
|
||||
std::string title() const override { return "RF3D"; }
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
void frame_sync();
|
||||
|
||||
private:
|
||||
static constexpr ui::Dim header_height = 3 * 16;
|
||||
static constexpr int SCREEN_WIDTH = 240;
|
||||
static constexpr int SCREEN_HEIGHT = 320;
|
||||
static constexpr int RENDER_HEIGHT = 280;
|
||||
static constexpr int HALF_WIDTH = SCREEN_WIDTH / 2;
|
||||
static constexpr int HALF_HEIGHT = RENDER_HEIGHT / 2;
|
||||
static constexpr int MAX_RENDER_DEPTH = 12;
|
||||
static constexpr int NUM_BARS = 16;
|
||||
static constexpr int BAR_WIDTH = SCREEN_WIDTH / NUM_BARS;
|
||||
static constexpr int BAR_SPACING = 2;
|
||||
static constexpr int SEGMENT_HEIGHT = 10;
|
||||
|
||||
NavigationView& nav_;
|
||||
bool initialized{false};
|
||||
std::vector<std::vector<uint8_t>> spectrum_data;
|
||||
uint32_t sampling_rate{3072000};
|
||||
double angle{0.0};
|
||||
std::vector<int> bar_heights;
|
||||
std::vector<int> prev_bar_heights;
|
||||
bool running{false};
|
||||
|
||||
RSSI rssi{{21 * 8, 0, 6 * 8, 4}};
|
||||
Channel channel{{21 * 8, 5, 6 * 8, 4}};
|
||||
Audio audio{{21 * 8, 10, 6 * 8, 4}};
|
||||
FrequencyField field_frequency{{5 * 8, 0 * 16}};
|
||||
LNAGainField field_lna{{15 * 8, 0 * 16}};
|
||||
VGAGainField field_vga{{18 * 8, 0 * 16}};
|
||||
FrequencyField field_frequency{Point{5 * 8, 0 * 16}};
|
||||
LNAGainField field_lna{Point{15 * 8, 0 * 16}};
|
||||
VGAGainField field_vga{Point{18 * 8, 0 * 16}};
|
||||
OptionsField options_modulation{
|
||||
{0 * 8, 0 * 16},
|
||||
4,
|
||||
{
|
||||
{"AM", toUType(ReceiverModel::Mode::AMAudio)},
|
||||
{"NFM", toUType(ReceiverModel::Mode::NarrowbandFMAudio)},
|
||||
{"WFM", toUType(ReceiverModel::Mode::WidebandFMAudio)},
|
||||
{"AM ", toUType(ReceiverModel::Mode::AMAudio)},
|
||||
{"NFM ", toUType(ReceiverModel::Mode::NarrowbandFMAudio)},
|
||||
{"WFM ", toUType(ReceiverModel::Mode::WidebandFMAudio)},
|
||||
{"SPEC", toUType(ReceiverModel::Mode::SpectrumAnalysis)}
|
||||
}
|
||||
};
|
||||
AudioVolumeField field_volume{{28 * 8, 0 * 16}};
|
||||
AudioVolumeField field_volume{Point{28 * 8, 0 * 16}};
|
||||
Text text_ctcss{{16 * 8, 1 * 16, 14 * 8, 1 * 16}, ""};
|
||||
RecordView record_view{
|
||||
{0 * 8, 2 * 16, 30 * 8, 1 * 16},
|
||||
@ -73,8 +73,8 @@ private:
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void update_spectrum(const ChannelSpectrum& spectrum);
|
||||
void render_3d_waterfall(Painter& painter);
|
||||
void update_spectrum(const AudioSpectrum& spectrum);
|
||||
void render_equalizer(Painter& painter);
|
||||
void on_modulation_changed(ReceiverModel::Mode modulation);
|
||||
void on_show_options_frequency();
|
||||
void on_show_options_rf_gain();
|
||||
@ -88,13 +88,14 @@ private:
|
||||
|
||||
MessageHandlerRegistration message_handler_frame_sync{
|
||||
Message::ID::DisplayFrameSync,
|
||||
[this](const Message* const) { this->frame_sync(); }
|
||||
[this](const Message* const) { }
|
||||
};
|
||||
MessageHandlerRegistration message_handler_channel_spectrum{
|
||||
Message::ID::ChannelSpectrumConfig,
|
||||
MessageHandlerRegistration message_handler_audio_spectrum{
|
||||
Message::ID::AudioSpectrum,
|
||||
[this](const Message* const p) {
|
||||
const auto message = *reinterpret_cast<const ChannelSpectrumConfigMessage*>(p);
|
||||
this->channel_fifo = message.fifo;
|
||||
const auto message = *reinterpret_cast<const AudioSpectrumMessage*>(p);
|
||||
this->update_spectrum(*message.data);
|
||||
this->set_dirty();
|
||||
}
|
||||
};
|
||||
MessageHandlerRegistration message_handler_coded_squelch{
|
||||
@ -104,7 +105,6 @@ private:
|
||||
this->handle_coded_squelch(message.value);
|
||||
}
|
||||
};
|
||||
ChannelSpectrumFIFO* channel_fifo{nullptr};
|
||||
};
|
||||
|
||||
} // namespace ui::external_app::rf3d
|
||||
|
Loading…
x
Reference in New Issue
Block a user