]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Some "brain-storming" on setting a new frequency
authorc vw <dl1ycf@darc.de>
Thu, 15 Dec 2022 17:10:03 +0000 (18:10 +0100)
committerc vw <dl1ycf@darc.de>
Thu, 15 Dec 2022 17:10:03 +0000 (18:10 +0100)
radio.c
radio.h
receiver.c
receiver.h
vfo.c
vfo.h

diff --git a/radio.c b/radio.c
index 6c9193a5b792772e705bcc32a9446b9c35007fbb..2537c36b40a511f0fe3f31f5393247c9ad3a01d1 100644 (file)
--- a/radio.c
+++ b/radio.c
@@ -1368,7 +1368,7 @@ void start_radio() {
     soapy_protocol_set_gain(rx);
 
     if(vfo[0].ctun) {
-      setFrequency(vfo[0].ctun_frequency);
+      receiver_set_frequency(rx,vfo[0].ctun_frequency);
     }
     soapy_protocol_start_receiver(rx);
 
@@ -1845,52 +1845,6 @@ int isTransmitting() {
   return mox | vox | tune;
 }
 
-void setFrequency(long long f) {
-  int v=active_receiver->id;
-  vfo[v].band=get_band_from_frequency(f);
-
-  if(vfo[v].ctun) {
-    //
-    // If new frequency is within "window", change the CTUN frequency and
-    // update the offset. If it is outside, deactivate CTUN and fall
-    // through
-    //
-    long long minf=vfo[v].frequency-(long long)(active_receiver->sample_rate/2);
-    long long maxf=vfo[v].frequency+(long long)(active_receiver->sample_rate/2);
-    if(f > minf && f < maxf) {
-      vfo[v].ctun_frequency=f;
-      vfo[v].offset=f-vfo[v].frequency;
-      set_offset(active_receiver,vfo[v].offset);
-      return;
-    }
-    vfo[v].ctun=0;
-    vfo[v].ctun_frequency=0;
-    vfo[v].offset=0;
-    set_offset(active_receiver,vfo[v].offset);
-  }
-  vfo[v].frequency=f;
-
-  switch(protocol) {
-    case NEW_PROTOCOL:
-      schedule_high_priority();
-      break;
-    case ORIGINAL_PROTOCOL:
-      break;
-#ifdef SOAPYSDR
-    case SOAPYSDR_PROTOCOL:
-      if(!vfo[v].ctun) {
-        soapy_protocol_set_rx_frequency(active_receiver,v);
-        vfo[v].offset=0;
-      }
-      break;
-#endif
-  }
-}
-
-long long getFrequency() {
-    return vfo[active_receiver->id].frequency;
-}
-
 double getDrive() {
     return transmitter->drive;
 }
@@ -2041,6 +1995,10 @@ void set_alex_attenuation(int v) {
     }
 }
 
+void radio_split_toggle() {
+  radio_set_split(!split);
+}
+
 void radio_set_split(int val) {
   //
   // "split" *must only* be set through this interface,
diff --git a/radio.h b/radio.h
index af7647b3950abb67189e77f7b56947e8f6ed59a8..3e6294a5e08cb1181b1ea5feec9407258da77e97 100644 (file)
--- a/radio.h
+++ b/radio.h
@@ -338,6 +338,7 @@ extern void radio_change_receivers(int r);
 extern void radio_change_sample_rate(int rate);
 extern void set_alex_antennas(void);
 extern void tx_vfo_changed(void);
+extern void radio_split_toggle();
 extern void radio_set_split(int v);
 extern void setMox(int state);
 extern int getMox(void);
@@ -360,9 +361,6 @@ extern void set_alex_attenuation(int v);
 
 extern int isTransmitting(void);
 
-extern void setFrequency(long long f);
-extern long long getFrequency(void);
-
 extern void radioRestoreState(void);
 extern void radioSaveState(void);
 
index 8fa91758a4e5f2cb2d804eb290524e0d5ee619e9..d043d895df5ffa2f335c68a7be9c94ac2c6ae414 100644 (file)
@@ -1322,20 +1322,46 @@ g_print("%s: id=%d rate=%d scale=%d buffer_size=%d output_samples=%d\n",__FUNCTI
 g_print("%s: id=%d rate=%d buffer_size=%d output_samples=%d\n",__FUNCTION__,rx->id, rx->sample_rate, rx->buffer_size, rx->output_samples);
 }
 
+void receiver_set_frequency(RECEIVER *rx, long long f) {
+  int id=rx->id;
+
+  //
+  // update VFO, and let receiver_frequency_changed do the rest
+  //
+  vfo[id].band=get_band_from_frequency(f);
+  if(vfo[id].ctun) {
+    vfo[id].ctun_frequency=f;
+  } else {
+    vfo[id].frequency=f;
+  }
+  receiver_frequency_changed(rx);
+}
+
 void receiver_frequency_changed(RECEIVER *rx) {
   int id=rx->id;
 
   if(vfo[id].ctun) {
+    int ctun_ok=1;
+    long long frequency=vfo[id].frequency;
+    long long half=(long long)rx->sample_rate/2LL;
+    long long rx_low=vfo[id].ctun_frequency+rx->filter_low;
+    long long rx_high=vfo[id].ctun_frequency+rx->filter_high;
+    if (rx_low < frequency - half || rx_high > frequency+half) {
+      //
+      // Perhaps this is paranoia, but a "legal" VFO might turn
+      // into an "illegal" when when reducing the sample rate,
+      // thus narrowing the CTUN window
+      //
+      g_print("%s: CTUN freq out of range\n", __FUNCTION__);
+      vfo[id].frequency=vfo[id].ctun_frequency;
+      ctun_ok=0;
+    }
 
     if(rx->zoom>1) {
       //
       // Adjust PAN if new filter width has moved out of
       // current display range
       //
-      long long frequency=vfo[id].frequency;
-      long long half=(long long)rx->sample_rate/2LL;
-      long long rx_low=vfo[id].ctun_frequency+rx->filter_low;
-      long long rx_high=vfo[id].ctun_frequency+rx->filter_high;
       long long min_display=frequency-half+(long long)((double)rx->pan*rx->hz_per_pixel);
       long long max_display=min_display+(long long)((double)rx->width*rx->hz_per_pixel);
       if(rx_low<=min_display) {
@@ -1350,28 +1376,31 @@ void receiver_frequency_changed(RECEIVER *rx) {
     }
 
     //
-    // The (HPSDR) frequency does not change in CTUN,
-    // so simply compute new offset and tell WDSP about it
+    // Compute new offset and tell WDSP about it
     //
     vfo[id].offset=vfo[id].ctun_frequency-vfo[id].frequency;
     if(vfo[id].rit_enabled) {
       vfo[id].offset+=vfo[id].rit;
     }
     set_offset(rx,vfo[id].offset);
-  } else {
-    switch(protocol) {
-      case ORIGINAL_PROTOCOL:
-       // P1 does this automatically
-        break;
-      case NEW_PROTOCOL:
-        schedule_high_priority(); // send new frequency
-        break;
+    //
+    // If we have changed the CTUN center frequency,
+    // we cannot return but must tell the radio about it
+    //
+    if (ctun_ok) return;
+  }
+  switch(protocol) {
+    case ORIGINAL_PROTOCOL:
+      // P1 does this automatically
+      break;
+    case NEW_PROTOCOL:
+      schedule_high_priority(); // send new frequency
+      break;
 #if SOAPYSDR
-      case SOAPYSDR_PROTOCOL:
-        soapy_protocol_set_rx_frequency(rx,id);
-        break;
+    case SOAPYSDR_PROTOCOL:
+      soapy_protocol_set_rx_frequency(rx,id);
+      break;
 #endif
-    }
   }
 }
 
@@ -1390,9 +1419,12 @@ void receiver_mode_changed(RECEIVER *rx) {
 }
 
 void receiver_vfo_changed(RECEIVER *rx) {
+  //
+  // Called when the VFO controlling rx has changed,
+  // e.g. after a "swap VFO" action
+  //
   receiver_frequency_changed(rx);
   receiver_mode_changed(rx);
-  //receiver_filter_changed(rx);
 }
 
 static void process_rx_buffer(RECEIVER *rx) {
index 41d580cc9d66732719191af9b3d314368ee3572c..c596b7d622252cb2ab5b5196024ec3f650aeec19 100644 (file)
@@ -180,6 +180,7 @@ extern RECEIVER *create_pure_signal_receiver(int id, int buffer_size,int sample_
 extern RECEIVER *create_receiver(int id, int buffer_size, int fft_size, int pixels, int fps, int width, int height);
 extern void receiver_change_sample_rate(RECEIVER *rx,int sample_rate);
 extern void receiver_change_adc(RECEIVER *rx,int adc);
+extern void receiver_set_frequency(RECEIVER *rx, long long frequency);
 extern void receiver_frequency_changed(RECEIVER *rx);
 extern void receiver_mode_changed(RECEIVER *rx);
 extern void receiver_filter_changed(RECEIVER *rx);
diff --git a/vfo.c b/vfo.c
index 79d948ffa88914c8e4bd1e27524e6aa5a99ef166..ea7c726e9625351b30470758b727917a7ee64e11 100644 (file)
--- a/vfo.c
+++ b/vfo.c
@@ -1533,22 +1533,78 @@ void vfo_set_frequency(int v,long long f) {
   if (b != vfo[v].band) {
     vfo_band_changed(v, b);
   }
-  if(active_receiver->id==v) {
-    setFrequency(f);
-  } else {
-    // change VFO frequency of the non-active receiver
-    vfo[v].frequency=f;
-    if (vfo[v].ctun) {
-      vfo[v].ctun=FALSE;
-      vfo[v].offset=0;
-      vfo[v].ctun_frequency=vfo[v].frequency;
-    }
+  if (v == VFO_A) receiver_set_frequency(receiver[0], f);
+  if (v == VFO_B) {
+    //
+    // If there is only one receiver, there is no RX running that
+    // is controlled by VFO_B, so just update the frequency of the
+    // VFO without telling WDSP about it.
+    // If VFO_B controls a (running) receiver, do the "full job".
+    //
     if (receivers == 2) {
-      // VFO v controls a running  WDSP receiver,
-      // need to "manually change" it.
-      // DO NOT DO IT HERE. Better add a "RECEIVER *rx" argument
-      // to setFrequency in radio.c
+      receiver_set_frequency(receiver[1], f);
+    } else {
+      vfo[v].frequency=f;
+      if (vfo[v].ctun) {
+        vfo[v].ctun=FALSE;
+        vfo[v].offset=0;
+        vfo[v].ctun_frequency=vfo[v].frequency;
+      }
     }
   }
   g_idle_add(ext_vfo_update, NULL);
 }
+
+//
+// Set CTUN state of a VFO
+//
+void vfo_ctun_update(int id,int state) {
+  long long f;
+  if (vfo[id].ctun == state) return;  // no-op if no change
+  vfo[id].ctun=state;
+  if(vfo[id].ctun) {
+    // CTUN turned OFF->ON
+    vfo[id].ctun_frequency=vfo[id].frequency;
+    vfo[id].offset=0;
+    if (id < receivers) receiver_set_frequency(receiver[id],vfo[id].ctun_frequency);
+  } else {
+    // CTUN turned ON->OFF: keep frequency
+    vfo[id].frequency=vfo[id].ctun_frequency;
+    vfo[id].offset=0;
+    if (id < receivers) receiver_set_frequency(receiver[id],vfo[id].ctun_frequency);
+  }
+}
+
+//
+// helper function for numerically entering a new VFO frequency
+//
+void num_pad(int val) {
+  //
+  // The numpad may be difficult to use since the frequency has to be given in Hz
+  // TODO: add a multiplier button like "kHz"
+  // TODO: display the current "entered_frequency" somewhere 
+  //       (not all of us are good in typing blind)
+  //
+  RECEIVER *rx=active_receiver;
+  if(!vfo[rx->id].entering_frequency) {
+    vfo[rx->id].entered_frequency=0;
+    vfo[rx->id].entering_frequency=TRUE;
+  }
+  switch(val) {
+    case -1: // clear
+      vfo[rx->id].entered_frequency=0;
+      vfo[rx->id].entering_frequency=FALSE;
+      break;
+    case -2: // enter
+      if(vfo[rx->id].entered_frequency!=0) {
+        receiver_set_frequency(rx, vfo[rx->id].entered_frequency);
+        g_idle_add(ext_vfo_update, NULL);
+      }
+      vfo[rx->id].entering_frequency=FALSE;
+      break;
+    default:
+      vfo[rx->id].entered_frequency=(vfo[rx->id].entered_frequency*10)+val;
+      break;
+  }
+}
+
diff --git a/vfo.h b/vfo.h
index 859eab7e5630edf99522a4f1c86bb8691f57a113..76ed8d61b123e9e0944b9162da09b9888358c855 100644 (file)
--- a/vfo.h
+++ b/vfo.h
@@ -74,11 +74,6 @@ struct _mode_settings {
 
 extern struct _mode_settings mode_settings[];
 
-typedef struct _set_frequency {
-  int vfo;
-  long long frequency;
-} SET_FREQUENCY;
-
 #define STEPS 15
 extern char *step_labels[];
 
@@ -118,4 +113,8 @@ extern void vfo_rit_clear(int rx);
 extern void vfo_rit(int rx,int i);
 extern void vfo_set_frequency(int vfo, long long f);
 
+extern void vfo_ctun_update(int id, int state);
+
+extern void num_pad(int val);
+
 #endif