Morse rx cleanings (#2962)

* fix ui overlap, align with log box
* bring back enum inside the class as a simple enum
* correctly restore saved setting whatever the modulation was at exit
* set squelch / field_squelch / receiver model in one go, add audio/receiver model stop and start
This commit is contained in:
gullradriel
2026-02-04 14:01:29 +01:00
committed by GitHub
parent a44a00acf0
commit 927e3b11e7
2 changed files with 48 additions and 64 deletions
+25 -48
View File
@@ -34,46 +34,44 @@ MorseRadioView::MorseRadioView(ui::NavigationView& nav)
logger->init_daily_log(logs_dir);
};
audio::output::start();
receiver_model.set_sampling_rate(3072000);
receiver_model.set_baseband_bandwidth(1750000);
receiver_model.enable();
field_squelch.on_change = [this](int32_t v) {
receiver_model.set_squelch_level(v);
};
options_mode.on_change = [this](size_t, int32_t value) {
current_mode = static_cast<ModulationMode>((uint8_t)value);
options_mode.on_change = [this](size_t, int32_t mode) {
audio::output::stop();
receiver_model.disable();
morse_decoder_.resetLearning();
if (current_mode == ModulationMode::FM) {
if (mode == MORSE_NFM) {
receiver_model.set_am_configuration(4);
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
field_squelch.set_style(Theme::getInstance()->option_active);
field_squelch.set_focusable(true);
receiver_model.set_squelch_level(field_squelch.value());
field_squelch.set_value(receiver_model.squelch_level());
audio::set_rate(audio::Rate::Hz_24000);
} else {
audio::set_rate(audio::Rate::Hz_12000);
receiver_model.set_modulation(ReceiverModel::Mode::AMAudio);
if (current_mode == ModulationMode::AM || current_mode == ModulationMode::DSB)
if (mode == MORSE_AM_CW || mode == MORSE_AM_DSB)
receiver_model.set_am_configuration(7);
else if (current_mode == ModulationMode::USB)
else if (mode == MORSE_AM_USB)
receiver_model.set_am_configuration(9);
else // LSB
receiver_model.set_am_configuration(10);
receiver_model.set_squelch_level(0);
field_squelch.set_style(Theme::getInstance()->fg_dark);
field_squelch.set_focusable(false);
}
baseband::set_moreserx_config(static_cast<uint8_t>(current_mode));
};
field_squelch.set_value(receiver_model.squelch_level(), false); // will be sent later, no need to send 2x
field_squelch.on_change = [this](int32_t v) {
if (current_mode == ModulationMode::FM)
receiver_model.set_squelch_level(v);
};
options_mode.set_selected_index(static_cast<int32_t>(current_mode), true);
baseband::set_moreserx_config(mode);
saved_mode = mode;
auto vol = field_volume.value(); // audio volume fix
field_volume.set_value(0);
field_volume.set_value(vol);
audio::output::start();
receiver_model.set_headphone_volume(receiver_model.headphone_volume()); // WM8731 hack.
receiver_model.set_sampling_rate(3072000);
receiver_model.set_baseband_bandwidth(1750000);
receiver_model.enable();
};
options_mode.set_selected_index(saved_mode);
logger = std::make_unique<MorseLogger>();
chk_log.on_select = [this](Checkbox&, bool save) {
@@ -109,42 +107,21 @@ void MorseLogger::init_daily_log(const std::filesystem::path& log_dir) {
}
}
void MorseLogger::radio_set_log(uint8_t current_mode) {
void MorseLogger::radio_set_log(const std::string& morse_mode) {
int64_t freq = receiver_model.target_frequency();
std::string mode_str;
switch (static_cast<MorseRadioView::ModulationMode>(current_mode)) {
case MorseRadioView::ModulationMode::AM:
mode_str = "AM";
break;
case MorseRadioView::ModulationMode::FM:
mode_str = "FM";
break;
case MorseRadioView::ModulationMode::DSB:
mode_str = "DSB";
break;
case MorseRadioView::ModulationMode::USB:
mode_str = "USB";
break;
case MorseRadioView::ModulationMode::LSB:
mode_str = "LSB";
break;
default:
mode_str = "???";
break;
}
std::string header = "Freq:" + to_string_rounded_freq(freq, 4);
header += "MHz, ";
header += "RX MODE:" + mode_str;
header += "RX MODE:" + morse_mode;
header += "\r\nMessage:";
log_file.write_raw(header);
}
bool MorseLogger::on_packet(const std::string& content, bool time, uint8_t current_mode) {
bool MorseLogger::on_packet(const std::string& content, bool time, const std::string& morse_mode) {
if (!time) {
log_file.write_raw_no_newline("\r\n\r\n");
auto timestamp = to_string_datetime(rtc_time::now(), YMDHMS);
log_file.write_raw("[" + timestamp + "] ");
radio_set_log(current_mode);
radio_set_log(morse_mode);
char_count = 0;
time = true;
}
@@ -243,7 +220,7 @@ void MorseRadioView::on_data(const MorseRXDataMessage* message) {
last_activity_time = chTimeNow(); // start reset timer on valid input
writeCharToConsole(result.text, result.confidence);
if (logger && save_log) {
time_stamp = logger->on_packet(result.text, time_stamp, static_cast<uint8_t>(current_mode));
time_stamp = logger->on_packet(result.text, time_stamp, options_mode.selected_index_name());
}
float dah_time = morse_decoder_.getCurrentTimeUnit() * 3.0f;
if (dah_time > 0) {
+23 -16
View File
@@ -54,8 +54,8 @@ class MorseLogger {
}
void init_daily_log(const std::filesystem::path& log_dir);
bool on_packet(const std::string& content, bool time, uint8_t current_mode);
void radio_set_log(uint8_t current_mode);
bool on_packet(const std::string& content, bool time, const std::string& morse_mode);
void radio_set_log(const std::string& morse_mode);
private:
LogFile log_file{};
@@ -64,14 +64,6 @@ class MorseLogger {
class MorseRadioView : public ui::View {
public:
enum class ModulationMode : uint8_t {
AM = 0,
FM = 1,
DSB = 2,
USB = 3,
LSB = 4
};
MorseRadioView(ui::NavigationView& nav);
~MorseRadioView();
std::string title() const override {
@@ -91,12 +83,21 @@ class MorseRadioView : public ui::View {
RxRadioState radio_state_{};
std::unique_ptr<MorseLogger> logger{};
ModulationMode current_mode = ModulationMode::AM;
enum morse_modes : uint8_t {
MORSE_AM_CW = 0,
MORSE_NFM,
MORSE_AM_DSB,
MORSE_AM_USB,
MORSE_AM_LSB,
};
uint8_t saved_mode = MORSE_AM_CW;
app_settings::SettingsManager settings_{
"rx_morese_radio",
"rx_morse_radio",
app_settings::Mode::RX,
{{"cwmode"sv, reinterpret_cast<uint8_t*>(&current_mode)}}};
{
{"cwmode"sv, &saved_mode},
}};
RxFrequencyField field_frequency{
{UI_POS_X(0), UI_POS_Y(0)},
@@ -134,9 +135,15 @@ class MorseRadioView : public ui::View {
{{UI_POS_X(27), UI_POS_Y(2)}, "Hz", Theme::getInstance()->fg_light->foreground}};
ui::OptionsField options_mode{
{UI_POS_X(9), UI_POS_Y(2)},
5,
{{"AM", 0}, {"FM", 1}, {"DSB", 2}, {"USB", 3}, {"LSB", 4}}};
{UI_POS_X(8), UI_POS_Y(2) + 4}, // +4 to align with 'Log' checkbox text
6,
{
{"AM/CW", MORSE_AM_CW},
{"NFM", MORSE_NFM},
{"AM/DSB", MORSE_AM_DSB},
{"AM/USB", MORSE_AM_USB},
{"AM/LSB", MORSE_AM_LSB},
}};
Checkbox chk_log{{UI_POS_X(0), UI_POS_Y(2)}, 12, "Log", false};
ui::Button btn_clear{{UI_POS_X(0), UI_POS_Y_BOTTOM(2), UI_POS_WIDTH(6), UI_POS_HEIGHT(1)}, "CLR"};