From cd7c412aa40be3a1af0ce693af3690b308ca922a Mon Sep 17 00:00:00 2001 From: stafur Date: Wed, 25 Feb 2026 03:29:21 -0500 Subject: [PATCH] Improve low band signal reception (FM Radio Station Audio tests) (#3048) * Added PRO button to analog_audio.cpp for debugging metallic ringing sounds in Audio app. Ensured consitency to 4MHz in analog_audio.cpp * Restored blutooth after loss. * Added several sampling rates to analog_audio for testing. * Ran format-code.sh --- .../application/apps/analog_audio_app.cpp | 52 ++++++++++++++++++- .../application/apps/analog_audio_app.hpp | 32 ++++++++++++ firmware/baseband/proc_wfm_audio.hpp | 4 ++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/firmware/application/apps/analog_audio_app.cpp b/firmware/application/apps/analog_audio_app.cpp index a5c51f4a5..1fd64c114 100644 --- a/firmware/application/apps/analog_audio_app.cpp +++ b/firmware/application/apps/analog_audio_app.cpp @@ -199,6 +199,33 @@ SPECOptionsView::SPECOptionsView( view->set_spec_iq_phase_calibration_value(view->get_spec_iq_phase_calibration_value()); // initialize iq_phase_calibration in radio } +/* PralineOptionsView *******************************************************/ + +#ifdef PRALINE +PralineOptionsView::PralineOptionsView(Rect parent_rect, const Style* style) { + set_parent_rect(parent_rect); + add_children({&label_sr, &options_sr, &label_dc, &options_dc, + &label_qi, &options_qi, &label_qs, &options_qs, + &label_dec, &options_dec}); + + options_sr.set_by_value(receiver_model.sampling_rate()); + options_dc.set_by_value(1); + options_qi.set_by_value(1); + options_qs.set_by_value(0); + options_dec.set_by_value(0); + + options_sr.on_change = [this](size_t, OptionsField::value_t v) { receiver_model.set_sampling_rate(v); }; + options_dc.on_change = [this](size_t, OptionsField::value_t v) { if (v) fpga_reg_1 |= 0x01; else fpga_reg_1 &= ~0x01; update_fpga_ctrl(); }; + options_qi.on_change = [this](size_t, OptionsField::value_t v) { if (v) fpga_reg_1 |= 0x02; else fpga_reg_1 &= ~0x02; update_fpga_ctrl(); }; + options_qs.on_change = [this](size_t, OptionsField::value_t v) { if (v) fpga_reg_1 |= 0x04; else fpga_reg_1 &= ~0x04; update_fpga_ctrl(); }; + options_dec.on_change = [this](size_t, OptionsField::value_t v) { radio::debug::fpga::register_write(2, v); }; +} + +void PralineOptionsView::update_fpga_ctrl() { + radio::debug::fpga::register_write(1, fpga_reg_1); +} +#endif + /* AnalogAudioView *******************************************************/ AnalogAudioView::AnalogAudioView( @@ -217,7 +244,14 @@ AnalogAudioView::AnalogAudioView( &field_volume, &text_ctcss, &record_view, - &waterfall}); +#ifdef PRALINE + &waterfall, + &button_pro +#else + &waterfall + +#endif + }); // Filename Datetime and Frequency record_view.set_filename_date_frequency(true); @@ -256,6 +290,10 @@ AnalogAudioView::AnalogAudioView( field_frequency.set_value(receiver_model.target_frequency() + offset); }; +#ifdef PRALINE + button_pro.on_select = [this](Button&) { this->on_show_options_praline(); }; +#endif + audio::output::start(); // This call starts the correct baseband image to run @@ -511,8 +549,13 @@ void AnalogAudioView::update_modulation(ReceiverModel::Mode modulation) { const auto is_wideband_spectrum_mode = (modulation == ReceiverModel::Mode::SpectrumAnalysis); receiver_model.set_modulation(modulation); +#ifdef PRALINE + receiver_model.set_sampling_rate(is_wideband_spectrum_mode ? spec_bw : 4000000); + receiver_model.set_baseband_bandwidth(is_wideband_spectrum_mode ? spec_bw / 2 : 2000000); +#else receiver_model.set_sampling_rate(is_wideband_spectrum_mode ? spec_bw : 3072000); receiver_model.set_baseband_bandwidth(is_wideband_spectrum_mode ? spec_bw / 2 : 1750000); +#endif receiver_model.set_hidden_offset(modulation == ReceiverModel::Mode::AMAudioFMApt ? -2200 : 0); // wefax needs to be shifted, see wefax rx app. @@ -553,4 +596,11 @@ void AnalogAudioView::handle_coded_squelch(uint32_t value) { void AnalogAudioView::on_freqchg(int64_t freq) { field_frequency.set_value(freq); } + +#ifdef PRALINE +void AnalogAudioView::on_show_options_praline() { + set_options_widget(std::make_unique(options_view_rect, Theme::getInstance()->option_active)); +} +#endif + } /* namespace ui */ diff --git a/firmware/application/apps/analog_audio_app.hpp b/firmware/application/apps/analog_audio_app.hpp index 33d7b41d0..95dbb6c4b 100644 --- a/firmware/application/apps/analog_audio_app.hpp +++ b/firmware/application/apps/analog_audio_app.hpp @@ -37,6 +37,33 @@ namespace ui { class AnalogAudioView; +#ifdef PRALINE +class PralineOptionsView : public View { + public: + PralineOptionsView(Rect parent_rect, const Style* style); + + private: + // Layout: SR (Sample Rate), DC (DC Block), QI (Q-Invert), QS (Quarter Shift), D (Decim) + Text label_sr{{UI_POS_X(0), UI_POS_Y(0), UI_POS_WIDTH(2), UI_POS_HEIGHT(1)}, "SR"}; + OptionsField options_sr{{UI_POS_X(3), UI_POS_Y(0)}, 4, {{"0.25M", 250000}, {"0.5M", 500000}, {"0.75M", 750000}, {"1.0M", 1000000}, {"1.25M", 1250000}, {"1.5M", 1500000}, {"1.75M", 1750000}, {"2.0M", 2000000}, {"2.25M", 2250000}, {"2.5M", 2500000}, {"2.75M", 2750000}, {"3.0M", 3000000}, {"3.05M", 3050000}, {"3.072M", 3072000}, {"3.10M", 3100000}, {"3.15M", 3150000}, {"3.20M", 3200000}, {"3.25M", 3250000}, {"3.30M", 3300000}, {"3.35M", 3350000}, {"3.40M", 3400000}, {"3.45M", 3450000}, {"3.5M", 3500000}, {"3.51M", 3510000}, {"3.52M", 3520000}, {"3.53M", 3530000}, {"3.54M", 3540000}, {"3.55M", 3550000}, {"3.56M", 3560000}, {"3.57M", 3570000}, {"3.58M", 3580000}, {"3.59M", 3590000}, {"3.60M", 3600000}, {"3.61M", 3610000}, {"3.62M", 3620000}, {"3.63M", 3630000}, {"3.64M", 3640000}, {"3.65M", 3650000}, {"3.66M", 3660000}, {"3.67M", 3670000}, {"3.68M", 3680000}, {"3.69M", 3690000}, {"3.70M", 3700000}, {"3.71M", 3710000}, {"3.72M", 3720000}, {"3.73M", 3730000}, {"3.74M", 3740000}, {"3.75M", 3750000}, {"3.76M", 3760000}, {"3.77M", 3770000}, {"3.78M", 3780000}, {"3.79M", 3790000}, {"3.80M", 3800000}, {"3.81M", 3810000}, {"3.82M", 3820000}, {"3.83M", 3830000}, {"3.84M", 3840000}, {"3.85M", 3850000}, {"3.86M", 3860000}, {"3.87M", 3870000}, {"3.88M", 3880000}, {"3.89M", 3890000}, {"3.90M", 3900000}, {"3.91M", 3910000}, {"3.92M", 3920000}, {"3.93M", 3930000}, {"3.94M", 3940000}, {"3.95M", 3950000}, {"3.96M", 3960000}, {"3.97M", 3970000}, {"3.98M", 3980000}, {"3.99M", 3990000}, {"4.0M", 4000000}, {"5.0M", 5000000}}}; + + Text label_dc{{UI_POS_X(8), UI_POS_Y(0), UI_POS_WIDTH(2), UI_POS_HEIGHT(1)}, "DC"}; + OptionsField options_dc{{UI_POS_X(11), UI_POS_Y(0)}, 2, {{"Of", 0}, {"On", 1}}}; + + Text label_qi{{UI_POS_X(14), UI_POS_Y(0), UI_POS_WIDTH(2), UI_POS_HEIGHT(1)}, "QI"}; + OptionsField options_qi{{UI_POS_X(17), UI_POS_Y(0)}, 2, {{"Of", 0}, {"On", 1}}}; + + Text label_qs{{UI_POS_X(20), UI_POS_Y(0), UI_POS_WIDTH(2), UI_POS_HEIGHT(1)}, "QS"}; + OptionsField options_qs{{UI_POS_X(23), UI_POS_Y(0)}, 2, {{"Of", 0}, {"On", 1}}}; + + Text label_dec{{UI_POS_X(26), UI_POS_Y(0), UI_POS_WIDTH(1), UI_POS_HEIGHT(1)}, "D"}; + OptionsField options_dec{{UI_POS_X(28), UI_POS_Y(0)}, 2, {{" 1", 0}, {" 2", 1}, {" 4", 2}, {" 8", 3}, {"16", 4}}}; + + uint8_t fpga_reg_1{0x03}; // Tracks DC, QI, QS bits + void update_fpga_ctrl(); +}; +#endif + class AMOptionsView : public View { public: AMOptionsView(AnalogAudioView* view, Rect parent_rect, const Style* style); @@ -222,6 +249,11 @@ class AnalogAudioView : public View { uint8_t get_previous_zoom_option(); void set_previous_zoom_option(uint8_t zoom); +#ifdef PRALINE + Button button_pro{{UI_POS_X(12), UI_POS_Y(2), UI_POS_WIDTH(3), UI_POS_HEIGHT(1)}, "PRO"}; + void on_show_options_praline(); +#endif + private: static constexpr ui::Dim header_height = 3 * 16; diff --git a/firmware/baseband/proc_wfm_audio.hpp b/firmware/baseband/proc_wfm_audio.hpp index a9ebd87d5..00abd5bc1 100644 --- a/firmware/baseband/proc_wfm_audio.hpp +++ b/firmware/baseband/proc_wfm_audio.hpp @@ -81,7 +81,11 @@ class WidebandFMAudio : public BasebandProcessor { void on_message(const Message* const message) override; private: +#ifdef PRALINE + static constexpr size_t baseband_fs = 2000000; +#else static constexpr size_t baseband_fs = 3072000; +#endif static constexpr auto spectrum_rate_hz = 50.0f; std::array dst{};