Merge branch 'next' into tetris-updates

This commit is contained in:
RocketGod 2025-03-23 21:50:45 -07:00 committed by GitHub
commit 8c93e9fd2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 152 additions and 34 deletions

View File

@ -303,7 +303,7 @@ set(CPPSRC
apps/ui_rds.cpp
apps/ui_recon_settings.cpp
apps/ui_recon.cpp
apps/ui_scanner.cpp
# apps/ui_scanner.cpp
apps/ui_sd_over_usb.cpp
apps/ui_search.cpp
apps/ui_settings.cpp

View File

@ -40,6 +40,7 @@ namespace ui {
/* AMOptionsView *********************************************************/
AMOptionsView::AMOptionsView(
AnalogAudioView* view,
Rect parent_rect,
const Style* style)
: View{parent_rect} {
@ -48,12 +49,23 @@ AMOptionsView::AMOptionsView(
add_children({
&label_config,
&options_config,
&zoom_config,
});
zoom_config.on_change = [this, view](size_t, OptionsField::value_t n) {
receiver_model.set_am_configuration(previous_filter_array_index + n);
view->set_zoom_factor(AM_MODULATION, n);
};
// restore zoom selection
zoom_config.set_by_value(view->get_zoom_factor(AM_MODULATION));
freqman_set_bandwidth_option(AM_MODULATION, options_config); // adding the common message from freqman.cpp to the options_config
options_config.set_by_value(receiver_model.am_configuration());
options_config.on_change = [this](size_t, OptionsField::value_t n) {
options_config.on_change = [this, view](size_t, OptionsField::value_t n) {
receiver_model.set_am_configuration(n);
previous_filter_array_index = n;
zoom_config.set_by_value(view->get_zoom_factor(AM_MODULATION));
};
}
@ -105,6 +117,7 @@ WFMOptionsView::WFMOptionsView(
/* AMFMAptOptionsView *********************************************************/
AMFMAptOptionsView::AMFMAptOptionsView(
AnalogAudioView* view,
Rect parent_rect,
const Style* style)
: View{parent_rect} {
@ -113,11 +126,20 @@ AMFMAptOptionsView::AMFMAptOptionsView(
add_children({
&label_config,
&options_config,
&zoom_config,
});
freqman_set_bandwidth_option(AMFM_MODULATION, options_config); // adding the common message from freqman.cpp to the options_config
receiver_model.set_amfm_configuration(5); // Fix index 5 manually, not from freqman: set to RX AM (USB+FM) mode to demod audio tone, and get Wefax_APT signal.
options_config.set_by_value(receiver_model.amfm_configuration());
zoom_config.on_change = [this, view](size_t, OptionsField::value_t n) {
receiver_model.set_amfm_configuration(5 + n);
view->set_zoom_factor(AMFM_MODULATION, n);
};
// restore zoom selection
zoom_config.set_by_value(view->get_zoom_factor(AMFM_MODULATION));
}
/* SPECOptionsView *******************************************************/
@ -245,11 +267,26 @@ void AnalogAudioView::set_spec_bw(size_t index, uint32_t bw) {
receiver_model.set_baseband_bandwidth(bw / 2);
}
uint8_t AnalogAudioView::get_spec_iq_phase_calibration_value() { // define accessor functions inside AnalogAudioView to read & write real iq_phase_calibration_value
uint8_t AnalogAudioView::get_zoom_factor(uint8_t mode) { // define accessor functions inside AnalogAudioView to read zoom value
if (mode == AM_MODULATION)
return zoom_factor_am;
else if (mode == AMFM_MODULATION)
return zoom_factor_amfm;
return 0; // default if unsupported mode
}
void AnalogAudioView::set_zoom_factor(uint8_t mode, uint8_t zoom) { // define accessor functions inside AnalogAudioView to write zoom value
if (mode == AM_MODULATION)
zoom_factor_am = zoom;
else if (mode == AMFM_MODULATION)
zoom_factor_amfm = zoom;
}
uint8_t AnalogAudioView::get_spec_iq_phase_calibration_value() { // define accessor functions inside AnalogAudioView to read iq_phase_calibration_value
return iq_phase_calibration_value;
}
void AnalogAudioView::set_spec_iq_phase_calibration_value(uint8_t cal_value) { // define accessor functions
void AnalogAudioView::set_spec_iq_phase_calibration_value(uint8_t cal_value) { // define accessor functions inside AnalogAudioView to write iq_phase_calibration_value
iq_phase_calibration_value = cal_value;
radio::set_rx_max283x_iq_phase_calibration(iq_phase_calibration_value);
}
@ -345,7 +382,7 @@ void AnalogAudioView::on_show_options_modulation() {
const auto modulation = receiver_model.modulation();
switch (modulation) {
case ReceiverModel::Mode::AMAudio:
widget = std::make_unique<AMOptionsView>(options_view_rect, Theme::getInstance()->option_active);
widget = std::make_unique<AMOptionsView>(this, options_view_rect, Theme::getInstance()->option_active);
waterfall.show_audio_spectrum_view(false);
text_ctcss.hidden(true);
break;
@ -363,7 +400,7 @@ void AnalogAudioView::on_show_options_modulation() {
break;
case ReceiverModel::Mode::AMAudioFMApt:
widget = std::make_unique<AMFMAptOptionsView>(options_view_rect, Theme::getInstance()->option_active);
widget = std::make_unique<AMFMAptOptionsView>(this, options_view_rect, Theme::getInstance()->option_active);
waterfall.show_audio_spectrum_view(false);
text_ctcss.hidden(true);
break;

View File

@ -35,9 +35,12 @@
namespace ui {
class AnalogAudioView;
class AMOptionsView : public View {
public:
AMOptionsView(Rect parent_rect, const Style* style);
AMOptionsView(AnalogAudioView* view, Rect parent_rect, const Style* style);
int16_t previous_filter_array_index = 0;
private:
Text label_config{
@ -51,11 +54,18 @@ class AMOptionsView : public View {
{
// Using common messages from freqman_ui.cpp
}};
OptionsField zoom_config{
{23 * 8, 0 * 16},
7,
{{"ZOOM x1", 0},
{"ZOOM x2", 6}} // offset index array filters.
};
};
class AMFMAptOptionsView : public View {
public:
AMFMAptOptionsView(Rect parent_rect, const Style* style);
AMFMAptOptionsView(AnalogAudioView* view, Rect parent_rect, const Style* style);
private:
Text label_config{
@ -65,10 +75,17 @@ class AMFMAptOptionsView : public View {
OptionsField options_config{
{3 * 8, 0 * 16},
6, // Max option length
6, // Max option length chars
{
// Using common messages from freqman_ui.cpp In HF USB , Here we only need USB Audio demod, + post-FM demod fsubcarrier FM tone to get APT signal.
}};
OptionsField zoom_config{
{23 * 8, 0 * 16},
7,
{{"ZOOM x1", 0},
{"ZOOM x2", 6}} // offset index array filters.
};
};
class NBFMOptionsView : public View {
@ -116,8 +133,6 @@ class WFMOptionsView : public View {
}};
};
class AnalogAudioView;
class SPECOptionsView : public View {
public:
SPECOptionsView(AnalogAudioView* view, Rect parent_rect, const Style* style);
@ -182,17 +197,24 @@ class AnalogAudioView : public View {
uint8_t get_spec_iq_phase_calibration_value();
void set_spec_iq_phase_calibration_value(uint8_t cal_value);
uint8_t get_zoom_factor(uint8_t mode);
void set_zoom_factor(uint8_t mode, uint8_t zoom);
private:
static constexpr ui::Dim header_height = 3 * 16;
NavigationView& nav_;
RxRadioState radio_state_{};
uint8_t iq_phase_calibration_value{15}; // initial default RX IQ phase calibration value , used for both max2837 & max2839
uint8_t zoom_factor_am{0}; // initial zoom factor in AM mode
uint8_t zoom_factor_amfm{0}; // initial zoom factor in AMFM mode
app_settings::SettingsManager settings_{
"rx_audio",
app_settings::Mode::RX,
{
{"iq_phase_calibration"sv, &iq_phase_calibration_value}, // we are saving and restoring that CAL from Settings.
{"zoom_factor_am"sv, &zoom_factor_am}, // we are saving and restoring AM ZOOM factor from Settings.
{"zoom_factor_amfm"sv, &zoom_factor_amfm}, // we are saving and restoring AMFM ZOOM factor from Settings.
}};
const Rect options_view_rect{0 * 8, 1 * 16, 30 * 8, 1 * 16};

View File

@ -66,12 +66,13 @@ static void send_message(const Message* const message) {
void AMConfig::apply() const {
const AMConfigureMessage message{
taps_6k0_decim_0, // common FIR filter taps pre-decim_0 to all 6 x AM mod types.(AM-9K, AM-6K, USB, LSB, CW, AMFM-WFAX)
taps_6k0_decim_1, // common FIR filter taps pre-decim_1 to all 6 x AM mod. types. (")
decim_2, // var decim_2 FIR taps filter , variable values, depending selected AM mod(AM 9k / 6k and all rest AM modes)
channel, // var channel FIR taps filter , variable values, depending selected AM mode, each one different (DSB-9K, DSB-6K, USB-3K, LSB-3K,CW,AMFM-WFAX)
modulation, // var parameter . enum class Modulation : int32_t {DSB = 0, SSB = 1, SSB_FM = 2}
audio_12k_iir_filter_config}; // var parameter , 300 Hz hpf all except Wefax (1.500Hz lpf)
taps_6k0_decim_0, // common FIR filter taps pre-decim_0 to all 6 x AM mod types.(AM-9K, AM-6K, USB, LSB, CW, AMFM-WFAX)
decim_1, // var decim_1 FIR taps filter , variable values , to handle two spectrum decim factor 1 and 2 (zoom) and more APT LPF filtered .
decim_2, // var decim_2 FIR taps filter , variable values, depending selected AM mod(AM 9k / 6k and all rest AM modes)
channel, // var channel FIR taps filter , variable values, depending selected AM mode, each one different (DSB-9K, DSB-6K, USB-3K, LSB-3K,CW,AMFM-WFAX)
modulation, // var parameter . enum class Modulation : int32_t {DSB = 0, SSB = 1, SSB_FM = 2}
audio_12k_iir_filter_config, // var parameter , 300 Hz hpf all except Wefax (1.500Hz lpf)
spectrum_decimation_factor}; // var parameter , waterfall no zoom : 1 ,for zoom x 2 : 2
send_message(&message);
audio::set_rate(audio::Rate::Hz_12000);
}

View File

@ -36,10 +36,12 @@
namespace baseband {
struct AMConfig {
const fir_taps_real<32> decim_1; // added to handle two var LPF in AMFM to avoid aliasing when spectrum zoom factor 2.
const fir_taps_real<32> decim_2; // added to handle two var types decim_2 9k, 6k
const fir_taps_complex<64> channel;
const AMConfigureMessage::Modulation modulation;
const iir_biquad_config_t audio_12k_iir_filter_config; // added to handle two var IIR filter types : 300 hpf(as before) , 1500Hz lpf for Wefax.
const size_t spectrum_decimation_factor; // used to handle LCD AM waterfall zoom x1 / zoom x2.
void apply() const;
};

View File

@ -39,14 +39,22 @@ using namespace portapack;
namespace {
static constexpr std::array<baseband::AMConfig, 6> am_configs{{
static constexpr std::array<baseband::AMConfig, 12> am_configs{{
// we config here all the non COMMON parameters to each AM modulation type in RX.
{taps_9k0_decim_2, taps_9k0_dsb_channel, AMConfigureMessage::Modulation::DSB, audio_12k_hpf_300hz_config}, // AM DSB-C BW 9khz (+-4k5) commercial EU bandwidth .
{taps_6k0_decim_2, taps_6k0_dsb_channel, AMConfigureMessage::Modulation::DSB, audio_12k_hpf_300hz_config}, // AM DSB-C BW 6khz (+-3k0) narrow AM , ham equipments.
{taps_6k0_decim_2, taps_2k8_usb_channel, AMConfigureMessage::Modulation::SSB, audio_12k_hpf_300hz_config}, // SSB USB BW 2K8 (+ 2K8) SSB ham equipments.
{taps_6k0_decim_2, taps_2k8_lsb_channel, AMConfigureMessage::Modulation::SSB, audio_12k_hpf_300hz_config}, // SSB LSB BW 2K8 (- 2K8) SSB ham equipments.
{taps_6k0_decim_2, taps_0k7_usb_channel, AMConfigureMessage::Modulation::SSB, audio_12k_hpf_300hz_config}, // SSB USB BW 0K7 (+ 0K7) To get audio tone from CW Morse, assuming tx shifted +700hz aprox
{taps_6k0_decim_2, taps_2k6_usb_wefax_channel, AMConfigureMessage::Modulation::SSB_FM, audio_12k_lpf_1500hz_config}, // SSB USB+FM to demod. Subcarrier FM Audio Tones to get APT Weather Fax.
{taps_6k0_decim_1, taps_9k0_decim_2, taps_9k0_dsb_channel, AMConfigureMessage::Modulation::DSB, audio_12k_hpf_300hz_config, (int)AMConfigureMessage::Zoom_waterfall::ZOOM_x_1}, // AM DSB-C BW 9khz (+-4k5) commercial EU bandwidth .
{taps_6k0_decim_1, taps_6k0_decim_2, taps_6k0_dsb_channel, AMConfigureMessage::Modulation::DSB, audio_12k_hpf_300hz_config, (int)AMConfigureMessage::Zoom_waterfall::ZOOM_x_1}, // AM DSB-C BW 6khz (+-3k0) narrow AM , ham equipments.
{taps_6k0_decim_1, taps_6k0_decim_2, taps_2k8_usb_channel, AMConfigureMessage::Modulation::SSB, audio_12k_hpf_300hz_config, (int)AMConfigureMessage::Zoom_waterfall::ZOOM_x_1}, // SSB USB BW 2K8 (+ 2K8) SSB ham equipments.
{taps_6k0_decim_1, taps_6k0_decim_2, taps_2k8_lsb_channel, AMConfigureMessage::Modulation::SSB, audio_12k_hpf_300hz_config, (int)AMConfigureMessage::Zoom_waterfall::ZOOM_x_1}, // SSB LSB BW 2K8 (- 2K8) SSB ham equipments.
{taps_6k0_decim_1, taps_6k0_decim_2, taps_0k7_usb_channel, AMConfigureMessage::Modulation::SSB, audio_12k_hpf_300hz_config, (int)AMConfigureMessage::Zoom_waterfall::ZOOM_x_1}, // SSB USB BW 0K7 (+ 0K7) To get audio tone from CW Morse, assuming tx shifted +700hz aprox
{taps_6k0_decim_1, taps_6k0_decim_2, taps_2k6_usb_wefax_channel, AMConfigureMessage::Modulation::SSB_FM, audio_12k_lpf_1500hz_config, (int)AMConfigureMessage::Zoom_waterfall::ZOOM_x_1}, // SSB USB+FM to demod. Subcarrier FM Audio Tones to get APT Weather Fax.
// below options for Waterfall zoom x 2
{taps_6k0_narrow_decim_1, taps_9k0_decim_2, taps_9k0_dsb_channel, AMConfigureMessage::Modulation::DSB, audio_12k_hpf_300hz_config, (int)AMConfigureMessage::Zoom_waterfall::ZOOM_x_2}, // AM DSB-C BW 9khz (+-4k5) commercial EU bandwidth .
{taps_6k0_narrow_decim_1, taps_6k0_decim_2, taps_6k0_dsb_channel, AMConfigureMessage::Modulation::DSB, audio_12k_hpf_300hz_config, (int)AMConfigureMessage::Zoom_waterfall::ZOOM_x_2}, // AM DSB-C BW 6khz (+-3k0) narrow AM , ham equipments.
{taps_6k0_narrow_decim_1, taps_6k0_decim_2, taps_2k8_usb_channel, AMConfigureMessage::Modulation::SSB, audio_12k_hpf_300hz_config, (int)AMConfigureMessage::Zoom_waterfall::ZOOM_x_2}, // SSB USB BW 2K8 (+ 2K8) SSB ham equipments.
{taps_6k0_narrow_decim_1, taps_6k0_decim_2, taps_2k8_lsb_channel, AMConfigureMessage::Modulation::SSB, audio_12k_hpf_300hz_config, (int)AMConfigureMessage::Zoom_waterfall::ZOOM_x_2}, // SSB LSB BW 2K8 (- 2K8) SSB ham equipments.
{taps_6k0_narrow_decim_1, taps_6k0_decim_2, taps_0k7_usb_channel, AMConfigureMessage::Modulation::SSB, audio_12k_hpf_300hz_config, (int)AMConfigureMessage::Zoom_waterfall::ZOOM_x_2}, // SSB USB BW 0K7 (+ 0K7) To get audio tone from CW Morse, assuming tx shifted +700hz aprox
{taps_6k0_narrow_decim_1, taps_6k0_decim_2, taps_2k6_usb_wefax_channel, AMConfigureMessage::Modulation::SSB_FM, audio_12k_lpf_1500hz_config, (int)AMConfigureMessage::Zoom_waterfall::ZOOM_x_2}, // SSB USB+FM to demod. Subcarrier FM Audio Tones to get APT Weather Fax with waterfall zoom x 2 (we need taps_6k0_narrow_decim_1 to minimize aliasing)
}};
static constexpr std::array<baseband::NBFMConfig, 3> nbfm_configs{{

View File

@ -52,7 +52,7 @@
#include "ui_pocsag_tx.hpp"
#include "ui_rds.hpp"
#include "ui_recon.hpp"
#include "ui_scanner.hpp"
//#include "ui_scanner.hpp"
#include "ui_sd_over_usb.hpp"
#include "ui_search.hpp"
#include "ui_settings.hpp"
@ -139,7 +139,7 @@ const NavigationView::AppList NavigationView::appList = {
{"level", "Level", RX, Color::green(), &bitmap_icon_options_radio, new ViewFactory<LevelView>()},
{"pocsag", "POCSAG", RX, Color::green(), &bitmap_icon_pocsag, new ViewFactory<POCSAGAppView>()},
{"radiosonde", "Radiosnde", RX, Color::green(), &bitmap_icon_sonde, new ViewFactory<SondeView>()},
{"scanner", "Scanner", RX, Color::green(), &bitmap_icon_scanner, new ViewFactory<ScannerView>()},
// {"scanner", "Scanner", RX, Color::green(), &bitmap_icon_scanner, new ViewFactory<ScannerView>()},
{"search", "Search", RX, Color::yellow(), &bitmap_icon_search, new ViewFactory<SearchView>()},
{"subghzd", "SubGhzD", RX, Color::yellow(), &bitmap_icon_remote, new ViewFactory<SubGhzDView>()},
{"weather", "Weather", RX, Color::green(), &bitmap_icon_thermometer, new ViewFactory<WeatherView>()},

View File

@ -113,13 +113,8 @@ void NarrowbandAMAudio::configure(const AMConfigureMessage& message) {
channel_filter_high_f = message.channel_filter.high_frequency_normalized * channel_filter_input_fs;
channel_filter_transition = message.channel_filter.transition_normalized * channel_filter_input_fs;
// modulation_ssb = (message.modulation == AMConfigureMessage::Modulation::SSB); // originally we had just 2 AM types of demod. (DSB , SSB)
modulation_ssb = (int)message.modulation; // now sending by message , 3 types of AM demod : enum class Modulation : int32_t {DSB = 0, SSB = 1, SSB_FM = 2}
if (modulation_ssb == (int)(AMConfigureMessage::Modulation::SSB_FM)) {
channel_spectrum.set_decimation_factor(6.0f); // zooming for better tuning {SSB_FM = 2}
} else {
channel_spectrum.set_decimation_factor(1.0f); // no zooming .{DSB = 0, SSB = 1,}
}
channel_spectrum.set_decimation_factor(message.channel_spectrum_decimation_factor);
audio_output.configure(message.audio_hpf_lpf_config); // hpf in all AM demod modes (AM-6K/9K, USB/LSB,DSB), except Wefax (lpf there).
configured = true;

View File

@ -512,6 +512,51 @@ constexpr fir_taps_real<32> taps_6k0_decim_1{
}},
};
// IFIR prototype filter: fs=384000, pass=3000, stop=33000, decim=8, fout=48000
// Narrower taps_6k0_decim_1IFIR version to avoid LCD waterfall aliasing in AMFM Wefax in ZOOM X 2 (means spectrum decimation factor x2)
// It has BW -3dB's of +-9Khz, Stop band from 33khz onwards -60 dB's , then we can use in all AM modes (DSB, SSB,CW )
constexpr fir_taps_real<32> taps_6k0_narrow_decim_1{
.low_frequency_normalized = -3000.0f / 384000.0f,
.high_frequency_normalized = 3000.0f / 384000.0f,
.transition_normalized = 30000.0f / 384000.0f,
.taps = {{
58,
80,
138,
219,
326,
461,
622,
807,
1011,
1224,
1438,
1640,
1820,
1966,
2069,
2122,
2122,
2069,
1966,
1820,
1640,
1438,
1224,
1011,
807,
622,
461,
326,
219,
138,
80,
58,
}},
};
// IFIR prototype filter: fs=48000, pass=3000, stop=6700, decim=4, fout=12000
constexpr fir_taps_real<32> taps_6k0_decim_2{
.low_frequency_normalized = -3000.0f / 48000.0f,

View File

@ -591,6 +591,10 @@ class AMConfigureMessage : public Message {
SSB = 1,
SSB_FM = 2, // Added new for RX Wefax mode, to demodulate APT signal ,FM modulated inside audio subcarrier tones, and then up broadcasted in SSB USB .
};
enum class Zoom_waterfall : size_t {
ZOOM_x_1 = 1,
ZOOM_x_2 = 2,
};
constexpr AMConfigureMessage(
const fir_taps_real<24> decim_0_filter,
@ -598,14 +602,17 @@ class AMConfigureMessage : public Message {
const fir_taps_real<32> decim_2_filter,
const fir_taps_complex<64> channel_filter,
const Modulation modulation,
const iir_biquad_config_t audio_hpf_lpf_config)
const iir_biquad_config_t audio_hpf_lpf_config,
const size_t channel_spectrum_decimation_factor)
: Message{ID::AMConfigure},
decim_0_filter(decim_0_filter),
decim_1_filter(decim_1_filter),
decim_2_filter(decim_2_filter),
channel_filter(channel_filter),
modulation{modulation},
audio_hpf_lpf_config(audio_hpf_lpf_config) {
audio_hpf_lpf_config(audio_hpf_lpf_config),
channel_spectrum_decimation_factor(channel_spectrum_decimation_factor) {
}
const fir_taps_real<24> decim_0_filter;
@ -614,6 +621,7 @@ class AMConfigureMessage : public Message {
const fir_taps_complex<64> channel_filter;
const Modulation modulation;
const iir_biquad_config_t audio_hpf_lpf_config;
const size_t channel_spectrum_decimation_factor;
};
// TODO: Put this somewhere else, or at least the implementation part.