Invest limit bw ssb to 3 k (#2188)

* Adding_TX_BW_user_selection_to_the_Mic_SSB_mode

* TX_SSB_BW_adjustm_2k_3k_4k

* init_value_correction

* Comment_correction

* Leaving_only_OK_txbw_SSB_2K_3K

* Limti_SSB_TX_BW_2K_3K
This commit is contained in:
Brumi-2021 2024-07-06 13:34:09 +02:00 committed by GitHub
parent b53b5c70d3
commit 032168234a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 73 additions and 18 deletions

View File

@ -269,16 +269,24 @@ void MicTXView::set_rxbw_options(void) {
} }
} }
void MicTXView::set_rxbw_defaults(bool use_app_settings) { void MicTXView::set_rxbw_defaults(bool use_app_settings) { // Initially in that function we set up rxbw, but now also txbw.
if (use_app_settings) { if (use_app_settings) {
field_bw.set_value(transmitter_model.channel_bandwidth() / 1000); field_bw.set_value(transmitter_model.channel_bandwidth() / 1000);
field_rxbw.set_by_value(rxbw_index); field_rxbw.set_by_value(rxbw_index);
} else if (mic_mod_index == MIC_MOD_NFM) { } else if (mic_mod_index == MIC_MOD_NFM) {
field_bw.set_value(10); // NFM TX bw 10k, RX bw 16k (2) default field_bw.set_value(10); // NFM TX bw 10k, RX bw 16k (index 2) default
field_rxbw.set_by_value(2); field_bw.set_range(1, 60); // In NFM , FM , we are limitting index modulation range (0.08 ..5) ; (Ex max dev 60khz/12k = 5)
field_bw.set_step(1);
field_rxbw.set_by_value(2); // 16k from the three options (8k5,11k,16k)
} else if (mic_mod_index == MIC_MOD_WFM) { } else if (mic_mod_index == MIC_MOD_WFM) {
field_bw.set_value(75); // WFM TX bw 75K, RX bw 200k (0) default field_bw.set_value(75); // WFM TX bw 75K, RX bw 200k (index 0) default
field_bw.set_range(1, 150); // In our case Mod. Index range (1,67 ...12,5) ; 150k/12k=12,5
field_bw.set_step(1);
field_rxbw.set_by_value(0); field_rxbw.set_by_value(0);
} else if ((mic_mod_index == MIC_MOD_USB) | (mic_mod_index == MIC_MOD_LSB)) {
field_bw.set_value(3); // In SSB by default let's limit TX_BW to 3kHz.
field_bw.set_range(2, 3); // User range to modify that TX_BW. (TODO pending to investigate 4khz).
field_bw.set_step(1);
} }
// field_bw is hidden in other modulation cases // field_bw is hidden in other modulation cases
} }
@ -482,7 +490,11 @@ MicTXView::MicTXView(
field_bw.hidden(false); field_bw.hidden(false);
options_tone_key.hidden(false); options_tone_key.hidden(false);
} else { } else {
field_bw.hidden(true); if ((mic_mod_index == MIC_MOD_USB) || (mic_mod_index == MIC_MOD_LSB)) {
field_bw.hidden(false);
} else {
field_bw.hidden(true);
}
options_tone_key.set_selected_index(0); options_tone_key.set_selected_index(0);
options_tone_key.hidden(true); options_tone_key.hidden(true);
} }

View File

@ -148,10 +148,10 @@ class MicTXView : public View {
Labels labels_both{ Labels labels_both{
{{3 * 8, 1 * 8}, "MIC-GAIN:", Theme::getInstance()->fg_light->foreground}, {{3 * 8, 1 * 8}, "MIC-GAIN:", Theme::getInstance()->fg_light->foreground},
{{3 * 8, 3 * 8}, "F:", Theme::getInstance()->fg_light->foreground}, {{3 * 8, 3 * 8}, "F: MHz", Theme::getInstance()->fg_light->foreground},
{{15 * 8, 3 * 8}, "FM TXBW: kHz", Theme::getInstance()->fg_light->foreground}, // to be more symetric and consistent to the below FM RXBW {{18 * 8, 3 * 8}, "TXBW: kHz", Theme::getInstance()->fg_light->foreground}, // to be more symetric and consistent to the below FM RXBW
{{18 * 8, (5 * 8)}, "Mode:", Theme::getInstance()->fg_light->foreground}, // now, no need to handle GAIN, Amp here It is handled by ui_transmitter.cpp {{18 * 8, (5 * 8)}, "Mode:", Theme::getInstance()->fg_light->foreground}, // now, no need to handle GAIN, Amp here It is handled by ui_transmitter.cpp
{{4 * 8, 10 * 8}, "LVL:", Theme::getInstance()->fg_light->foreground}, // we delete { {11 * 8, 5 * 8 }, "Amp:", Theme::getInstance()->fg_light->foreground }, {{4 * 8, 10 * 8}, "LVL:", Theme::getInstance()->fg_light->foreground}, // we delete { {11 * 8, 5 * 8 }, "Amp:", Theme::getInstance()->fg_light->foreground },
{{12 * 8, 10 * 8}, "ATT:", Theme::getInstance()->fg_light->foreground}, {{12 * 8, 10 * 8}, "ATT:", Theme::getInstance()->fg_light->foreground},
{{20 * 8, 10 * 8}, "DEC:", Theme::getInstance()->fg_light->foreground}, {{20 * 8, 10 * 8}, "DEC:", Theme::getInstance()->fg_light->foreground},
{{3 * 8, (13 * 8) - 5}, "TONE KEY:", Theme::getInstance()->fg_light->foreground}, {{3 * 8, (13 * 8) - 5}, "TONE KEY:", Theme::getInstance()->fg_light->foreground},

View File

@ -27,6 +27,7 @@ namespace dsp {
HilbertTransform::HilbertTransform() { HilbertTransform::HilbertTransform() {
n = 0; n = 0;
sos_input.configure(half_band_lpf_config);
sos_i.configure(half_band_lpf_config); sos_i.configure(half_band_lpf_config);
sos_q.configure(half_band_lpf_config); sos_q.configure(half_band_lpf_config);
} }
@ -34,22 +35,26 @@ HilbertTransform::HilbertTransform() {
void HilbertTransform::execute(float in, float& out_i, float& out_q) { void HilbertTransform::execute(float in, float& out_i, float& out_q) {
float a = 0, b = 0; float a = 0, b = 0;
float in_filtered = sos_input.execute(in) * 1.0f; // Anti-aliasing LPF at fs/4 mic audio filter front-end.
// it is exactly matching with the usefull mic BW_cut_off =fs/4 of the following Hilbert Transf. implementation
// Ex. to TX SSB 3khz BW (3KHZ =fs/4) ,we need to run Hiblert_Trf fs = 12khz . And our anti-aliasing filter is also fcut =fs/4 when we use a half_band_LPF .
switch (n) { switch (n) {
case 0: case 0:
a = in; a = in_filtered;
b = 0; b = 0;
break; break;
case 1: case 1:
a = 0; a = 0;
b = -in; b = -in_filtered;
break; break;
case 2: case 2:
a = -in; a = -in_filtered;
b = 0; b = 0;
break; break;
case 3: case 3:
a = 0; a = 0;
b = in; b = in_filtered;
break; break;
} }

View File

@ -34,6 +34,7 @@ class HilbertTransform {
private: private:
uint8_t n = 0; uint8_t n = 0;
SOSFilter<5> sos_input = {};
SOSFilter<5> sos_i = {}; SOSFilter<5> sos_i = {};
SOSFilter<5> sos_q = {}; SOSFilter<5> sos_q = {};
}; };

View File

@ -81,6 +81,25 @@ SSB::SSB()
mode = Mode::LSB; mode = Mode::LSB;
} }
void SSB::set_fs_div_factor(float new_bw_ssb) {
switch ((int)new_bw_ssb / 1000) {
case 2:
fs_div_factor = 192; // TXBW_ssb = 2khz = fs/4 ; fs of Hilbert Transform => 8khz fs Hilbert = 1536.000/8000= 192
break;
case 3:
fs_div_factor = 128; // TXBW_ssb = 3khz = fs/4 ; fs of Hilbert Transform => 12khz fs Hilbert = 1536.000/12000= 128
break;
/* TODO pending to investigate 4khz, now is making aliasing folding with audio sweep .
case 4:
fs_div_factor = 96; // TXBW_ssb = 4khz = fs/4 ; fs of Hilbert Transform => 16khz fs Hilbert = 1536.000/16000= 96
break;
*/
default:
fs_div_factor = 128; // TXBW_ssb = 3khz = fs/4 ; fs of Hilbert Transform => 12khz fs Hilbert = 1536.000/12000= 128
break;
}
}
void SSB::execute(const buffer_s16_t& audio, const buffer_c8_t& buffer, bool& configured_in, uint32_t& new_beep_index, uint32_t& new_beep_timer, TXProgressMessage& new_txprogress_message, AudioLevelReportMessage& new_level_message, uint32_t& new_power_acc_count, uint32_t& new_divider) { void SSB::execute(const buffer_s16_t& audio, const buffer_c8_t& buffer, bool& configured_in, uint32_t& new_beep_index, uint32_t& new_beep_timer, TXProgressMessage& new_txprogress_message, AudioLevelReportMessage& new_level_message, uint32_t& new_power_acc_count, uint32_t& new_divider) {
// unused // unused
(void)configured_in; (void)configured_in;
@ -93,9 +112,10 @@ void SSB::execute(const buffer_s16_t& audio, const buffer_c8_t& buffer, bool& co
int8_t re = 0, im = 0; int8_t re = 0, im = 0;
for (size_t counter = 0; counter < buffer.count; counter++) { for (size_t counter = 0; counter < buffer.count; counter++) {
if (counter % 128 == 0) { if (counter % fs_div_factor == 0) { // Ex. TX bw_ssb 3khz =fs/4 Hilbert Transform sample rate, 128 = 1.536.000 hz / 12.000 hz (fs H.T.)
float i = 0.0, q = 0.0; float i = 0.0, q = 0.0;
// over = 1.536.000/24khz = 64 . (Mic audio has fixed SR in audio_p buffer[] = 24khz), but in tx mode , we are running Transceiver fs @tx = 1.536.000 Hz.
sample = audio.p[counter / over] >> audio_shift_bits_s16_AM_DSB_SSB; // originally fixed >> 2, now >>2 for AK, 0,1,2,3 for WM (boost off) sample = audio.p[counter / over] >> audio_shift_bits_s16_AM_DSB_SSB; // originally fixed >> 2, now >>2 for AK, 0,1,2,3 for WM (boost off)
sample *= audio_gain; // Apply GAIN Scale factor to the audio TX modulation. sample *= audio_gain; // Apply GAIN Scale factor to the audio TX modulation.

View File

@ -79,9 +79,12 @@ class SSB : public Modulator {
SSB(); SSB();
virtual void execute(const buffer_s16_t& audio, const buffer_c8_t& buffer, bool& configured_in, uint32_t& new_beep_index, uint32_t& new_beep_timer, TXProgressMessage& new_txprogress_message, AudioLevelReportMessage& new_level_message, uint32_t& new_power_acc_count, uint32_t& new_divider); virtual void execute(const buffer_s16_t& audio, const buffer_c8_t& buffer, bool& configured_in, uint32_t& new_beep_index, uint32_t& new_beep_timer, TXProgressMessage& new_txprogress_message, AudioLevelReportMessage& new_level_message, uint32_t& new_power_acc_count, uint32_t& new_divider);
void set_fs_div_factor(float new_bw_ssb);
private: private:
dsp::HilbertTransform hilbert; dsp::HilbertTransform hilbert;
float new_bw_ssb{3.0};
int fs_div_factor{128};
}; };
/// ///

View File

@ -113,13 +113,27 @@ void MicTXProcessor::on_message(const Message* const msg) {
} }
if (usb_enabled) { if (usb_enabled) {
modulator = new dsp::modulate::SSB(); dsp::modulate::SSB* ssb = new dsp::modulate::SSB();
modulator->set_mode(dsp::modulate::Mode::USB);
// Config fs_div_factor private var inside DSP modulate.cpp
ssb->set_fs_div_factor(config_message.deviation_hz); // we use same FM var deviation_hz , to set up also SSB BW
ssb->set_mode(dsp::modulate::Mode::USB);
modulator = ssb;
// modulator = new dsp::modulate::SSB(); // Keeping previous code as ref., when not passing deviation_hz parameter.
// modulator->set_mode(dsp::modulate::Mode::USB);
} }
if (lsb_enabled) { if (lsb_enabled) {
modulator = new dsp::modulate::SSB(); dsp::modulate::SSB* ssb = new dsp::modulate::SSB();
modulator->set_mode(dsp::modulate::Mode::LSB);
// Config fs_div_factor private var inside DSP modulate.cpp
ssb->set_fs_div_factor(config_message.deviation_hz); // we use same FM var deviation_hz , to set up also SSB BW
ssb->set_mode(dsp::modulate::Mode::LSB);
modulator = ssb;
// modulator = new dsp::modulate::SSB(); // Keeping previous code as ref., when not passing deviation_hz parameter.
// modulator->set_mode(dsp::modulate::Mode::LSB);
} }
if (am_enabled) { if (am_enabled) {
modulator = new dsp::modulate::AM(); modulator = new dsp::modulate::AM();