From 849246b4ed4b16a8c276f360cdab68fe5915a09d Mon Sep 17 00:00:00 2001
From: DL1YCF <dl1ycf@darc.de>
Date: Sat, 5 Dec 2020 13:48:40 +0100
Subject: [PATCH] Correced the use of "RX filter edges" for TX

---
 receiver.c    | 28 +++++++++++++++++++++++++---
 transmitter.c | 26 ++++++++++++++++++--------
 tx_menu.c     | 43 ++++++++++++++++++++++++++++++-------------
 3 files changed, 73 insertions(+), 24 deletions(-)

diff --git a/receiver.c b/receiver.c
index 8562d2d..7b3e4e9 100644
--- a/receiver.c
+++ b/receiver.c
@@ -1300,8 +1300,8 @@ void receiver_filter_changed(RECEIVER *rx) {
   int m=vfo[rx->id].mode;
   if(m==modeFMN) {
     if(rx->deviation==2500) {
-      filter_low=-4000;
-      filter_high=4000;
+      filter_low=-5500;
+      filter_high=5500;
     } else {
       filter_low=-8000;
       filter_high=8000;
@@ -1316,10 +1316,32 @@ void receiver_filter_changed(RECEIVER *rx) {
     set_filter(rx,filter_low,filter_high);
   }
 
+  //
+  // tx_set_filter mirrors the filter edges for LSB, DIGL
+  //
   if(can_transmit && transmitter!=NULL) {
     if(transmitter->use_rx_filter) {
       if(rx==active_receiver) {
-        tx_set_filter(transmitter,filter_low,filter_high);
+        switch (m) {
+          case modeCWU:
+          case modeCWL:
+          case modeDSB:
+          case modeAM:
+          case modeSAM:
+          case modeFMN:
+          case modeDRM:
+          case modeSPEC:
+            tx_set_filter(transmitter,-filter_high,filter_high);
+            break;
+          case modeUSB:
+          case modeDIGU:
+            tx_set_filter(transmitter,filter_low,filter_high);
+            break;
+          case modeLSB:
+          case modeDIGL:
+            tx_set_filter(transmitter,-filter_high,-filter_low);
+            break;
+        }
       }
     }
   }
diff --git a/transmitter.c b/transmitter.c
index fe60549..443d182 100644
--- a/transmitter.c
+++ b/transmitter.c
@@ -956,24 +956,34 @@ void tx_set_filter(TRANSMITTER *tx,int low,int high) {
   int txmode=get_tx_mode();
 
   switch(txmode) {
-    case modeLSB:
+    //
+    // In CW TX, WDSP is not unused anyway but CW signals
+    // are sent at zero frequency, therefore
+    // TX filter should be centered around zero.
+    //
+    // FMN and DRM set fixed TX filter sizes.
+    //
+    // LSB/DIGL "mirror" filter edges
+    //
     case modeCWL:
+    case modeCWU:
+    case modeDSB:
+    case modeAM:
+    case modeSAM:
+    case modeSPEC:
+      tx->filter_low =-high;
+      tx->filter_high=high;
+      break;
+    case modeLSB:
     case modeDIGL:
       tx->filter_low=-high;
       tx->filter_high=-low;
       break;
     case modeUSB:
-    case modeCWU:
     case modeDIGU:
       tx->filter_low=low;
       tx->filter_high=high;
       break;
-    case modeDSB:
-    case modeAM:
-    case modeSAM:
-      tx->filter_low=-high;
-      tx->filter_high=high;
-      break;
     case modeFMN:
       if(tx->deviation==2500) {
         tx->filter_low=-5500;
diff --git a/tx_menu.c b/tx_menu.c
index 080363f..0211df6 100644
--- a/tx_menu.c
+++ b/tx_menu.c
@@ -130,21 +130,38 @@ static void use_rx_filter_cb(GtkWidget *widget, gpointer data) {
   transmitter->use_rx_filter=gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
   int filter_low,filter_high;
 
+  //
+  // The result is unreasonable if e.g. the RX mode is FM and the TX mode is USB
+  // but it is designed to do something useful if RX mode is USB and TX mode is LSB
+  // which may occur in cross-band QSOs
+  //
   if(transmitter->use_rx_filter) {
     int m=vfo[active_receiver->id].mode;
-    if(m==modeFMN) {
-      if(active_receiver->deviation==2500) {
-        filter_low=-5500;
-        filter_high=5500;
-      } else {
-        filter_low=-8000;
-        filter_high=8000;
-      }
-    } else {
-      FILTER *mode_filters=filters[m];
-      FILTER *filter=&mode_filters[vfo[active_receiver->id].filter];
-      filter_low=filter->low;
-      filter_high=filter->high;
+    FILTER *mode_filters=filters[m];
+    FILTER *filter=&mode_filters[vfo[active_receiver->id].filter];
+    switch (m) {
+      case modeFMN:
+      case modeDRM:
+      case modeCWU:
+      case modeCWL:
+      case modeAM:
+      case modeDSB:
+      case modeSAM:
+      case modeSPEC:
+        filter_low =-filter->high;
+        filter_high= filter->high;
+        break;
+      case modeLSB:
+      case modeDIGL:
+        // filter edges are in the IQ domain (negative)
+        filter_low=-filter->high;
+        filter_high=-filter->low;
+        break;
+      case modeUSB:
+      case modeDIGU:
+        filter_low=filter->low;
+        filter_high=filter->high;
+        break;
     }
   } else {
     filter_low=tx_filter_low;
-- 
2.45.2