]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
OldProtocol: making feedback spectrum high resolution for all sample rates
authorc vw <dl1ycf@darc.de>
Thu, 18 Jul 2019 17:02:19 +0000 (19:02 +0200)
committerc vw <dl1ycf@darc.de>
Thu, 18 Jul 2019 17:02:19 +0000 (19:02 +0200)
hpsdrsim.c
radio.c
receiver.c
transmitter.c

index 881ea136677a9dd9c8117bb378d6e26b97701d81..59d5e6f74945c6bf3dc6299f565904f96367b8c9 100644 (file)
@@ -205,16 +205,30 @@ static double  last_q_sample=0.0;
 static int  txptr=0;
 static int  rxptr=0;
 
+//
+// Unfortunately, the code number of the gear
+// differes in old and new protocol
+//
 
-#define DEVICE_ATLAS      0
-#define DEVICE_HERMES     1
-#define DEVICE_HERMES2    2
-#define DEVICE_ANGELIA    3
-#define DEVICE_ORION      4
-#define DEVICE_ORION2     5
-#define DEVICE_HERMESLITE 6
-#define DEVICE_C25        100
-static int DEVICE=DEVICE_HERMES;
+#define DEVICE_ATLAS           0
+#define DEVICE_HERMES          1
+#define DEVICE_HERMES2         2
+#define DEVICE_ANGELIA         4
+#define DEVICE_ORION           5
+#define DEVICE_HERMES_LITE     6
+#define DEVICE_ORION2         10
+#define DEVICE_C25           100
+
+#define NEW_DEVICE_ATLAS       0
+#define NEW_DEVICE_HERMES      1
+#define NEW_DEVICE_HERMES2     2
+#define NEW_DEVICE_ANGELIA     3
+#define NEW_DEVICE_ORION       4
+#define NEW_DEVICE_ORION2      5
+#define NEW_DEVICE_HERMES_LITE 6
+
+static int OLDDEVICE=DEVICE_HERMES;
+static int NEWDEVICE=NEW_DEVICE_HERMES;
 
 int main(int argc, char *argv[])
 {
@@ -268,16 +282,16 @@ int main(int argc, char *argv[])
  */
 
         if (argc > 1) {
-           if (!strncmp(argv[1],"-atlas"  ,      6))  DEVICE=DEVICE_ATLAS;
-           if (!strncmp(argv[1],"-hermes" ,      7))  DEVICE=DEVICE_HERMES;
-           if (!strncmp(argv[1],"-hermes2" ,     8))  DEVICE=DEVICE_HERMES2;
-           if (!strncmp(argv[1],"-angelia" ,     8))  DEVICE=DEVICE_ANGELIA;
-           if (!strncmp(argv[1],"-orion" ,       6))  DEVICE=DEVICE_ORION;
-           if (!strncmp(argv[1],"-orion2" ,      7))  DEVICE=DEVICE_ORION2;
-           if (!strncmp(argv[1],"-hermeslite" , 11))  DEVICE=DEVICE_ORION2;
-           if (!strncmp(argv[1],"-c25"    ,      4))  DEVICE=DEVICE_C25;
+           if (!strncmp(argv[1],"-atlas"  ,      6))  {OLDDEVICE=DEVICE_ATLAS;       NEWDEVICE=NEW_DEVICE_ATLAS;}
+           if (!strncmp(argv[1],"-hermes" ,      7))  {OLDDEVICE=DEVICE_HERMES;      NEWDEVICE=NEW_DEVICE_HERMES;}
+           if (!strncmp(argv[1],"-hermes2" ,     8))  {OLDDEVICE=DEVICE_HERMES2;     NEWDEVICE=NEW_DEVICE_HERMES2;}
+           if (!strncmp(argv[1],"-angelia" ,     8))  {OLDDEVICE=DEVICE_ANGELIA;     NEWDEVICE=NEW_DEVICE_ANGELIA;}
+           if (!strncmp(argv[1],"-orion" ,       6))  {OLDDEVICE=DEVICE_ORION;       NEWDEVICE=NEW_DEVICE_ORION;}
+           if (!strncmp(argv[1],"-orion2" ,      7))  {OLDDEVICE=DEVICE_ORION2;      NEWDEVICE=NEW_DEVICE_ORION2;}
+           if (!strncmp(argv[1],"-hermeslite" , 11))  {OLDDEVICE=DEVICE_HERMES_LITE; NEWDEVICE=NEW_DEVICE_HERMES_LITE;}
+           if (!strncmp(argv[1],"-c25"    ,      4))  {OLDDEVICE=DEVICE_C25;         NEWDEVICE=NEW_DEVICE_HERMES;}
         }
-       switch (DEVICE) {
+       switch (OLDDEVICE) {
            case   DEVICE_ATLAS:   fprintf(stderr,"DEVICE is ATLASS\n");      break;
            case   DEVICE_HERMES:  fprintf(stderr,"DEVICE is HERMES\n");      break;
            case   DEVICE_HERMES2: fprintf(stderr,"DEVICE is HERMES (2)\n");  break;
@@ -286,7 +300,7 @@ int main(int argc, char *argv[])
            case   DEVICE_ORION2:  fprintf(stderr,"DEVICE is ORION-II\n");    break;
            case   DEVICE_C25:     fprintf(stderr,"DEVICE is STEMlab/C25\n"); break;
        }
-       reply[10]=DEVICE;
+       reply[10]=OLDDEVICE;
 
        if ((sock_udp = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        {
@@ -719,7 +733,7 @@ int main(int argc, char *argv[])
                                  buffer[ 8]=0xDD;
                                  buffer[ 9]=0xEE;
                                  buffer[10]=0xFF;
-                                 buffer[11]=DEVICE;
+                                 buffer[11]=NEWDEVICE;
                                  buffer[12]=38;
                                  buffer[13]=103;
                                  buffer[20]=2;
@@ -738,7 +752,7 @@ int main(int argc, char *argv[])
                                   buffer[ 8]=0xDD;
                                   buffer[ 9]=0xEE;
                                   buffer[10]=0xFF;
-                                  buffer[11]=DEVICE;
+                                  buffer[11]=NEWDEVICE;
                                   buffer[12]=38;
                                   buffer[13]=103;
                                   buffer[20]=2;
@@ -765,7 +779,7 @@ int main(int argc, char *argv[])
                                   buffer[ 9]=0xEE;
                                   buffer[10]=0xFF;
                                  buffer[11]=103;
-                                 buffer[12]=DEVICE;
+                                 buffer[12]=NEWDEVICE;
                                  buffer[13]=(checksum >> 8) & 0xFF;
                                  buffer[14]=(checksum     ) & 0xFF;
                                  sendto(sock_udp, buffer, 60, 0, (struct sockaddr *)&addr_from, sizeof(addr_from));
@@ -791,7 +805,7 @@ int main(int argc, char *argv[])
                                   buffer[ 8]=0xDD;
                                   buffer[ 9]=0xEE;
                                   buffer[10]=0xFF;
-                                  buffer[11]=DEVICE;
+                                  buffer[11]=NEWDEVICE;
                                   buffer[12]=38;
                                   buffer[13]=103;
                                   buffer[20]=2;
@@ -868,7 +882,7 @@ void process_ep2(uint8_t *frame)
           chk_data(((frame[4] >> 6) & 1), MicTS, "TimeStampMic");
           chk_data(((frame[4] >> 7) & 1), CommonMercuryFreq,"Common Mercury Freq");
 
-         if (DEVICE == DEVICE_C25) {
+         if (OLDDEVICE == DEVICE_C25) {
               // Charly25: has two 18-dB preamps that are switched with "preamp" and "dither"
               //           and two attenuators encoded in Alex-ATT
              //           Both only applies to RX1!
@@ -957,7 +971,7 @@ void process_ep2(uint8_t *frame)
           chk_data((frame[4] & 0x1F) >> 0, rx_att[0], "RX1 ATT");
           chk_data((frame[4] & 0x20) >> 5, rx1_attE, "RX1 ATT enable");
 
-          if (DEVICE != DEVICE_C25) {
+          if (OLDDEVICE != DEVICE_C25) {
             // Set RX amplification factors. No switchable preamps available normally.
              rxatt_dbl[0]=pow(10.0, -0.05*(10*AlexAtt+rx_att[0]));
              rxatt_dbl[1]=pow(10.0, -0.05*(rx_att[1]));
@@ -997,7 +1011,7 @@ void process_ep2(uint8_t *frame)
             chk_data((frame[2] & 0x30) >> 4, rx_adc[6], "RX7 ADC");
            chk_data((frame[3] & 0x1f), txatt, "TX ATT");
            txatt_dbl=pow(10.0, -0.05*(double) txatt);
-           if (DEVICE == DEVICE_C25) {
+           if (OLDDEVICE == DEVICE_C25) {
                // RedPitaya: Hard-wired ADC settings.
                rx_adc[0]=0;
                rx_adc[1]=1;
@@ -1128,7 +1142,7 @@ void *handler_ep6(void *arg)
                    memset(pointer, 0, 504);
                    for (j=0; j<n; j++) {
                        // ADC1: noise + weak tone on RX, feedback sig. on TX (except STEMlab)
-                       if (ptt && (DEVICE != DEVICE_C25)) {
+                       if (ptt && (OLDDEVICE != DEVICE_C25)) {
                          i1=isample[rxptr]*txdrv_dbl;
                          q1=qsample[rxptr]*txdrv_dbl;
                          fac=IM3a+IM3b*(i1*i1+q1*q1);
@@ -1141,7 +1155,7 @@ void *handler_ep6(void *arg)
                          adc1qsample += T0800Qtab[pt0800] * 83.886070 *rxatt_dbl[0];
                        }
                        // ADC2: noise + stronger tone on RX, feedback sig. on TX (only STEMlab)
-                       if (ptt && (DEVICE == DEVICE_C25)) {
+                       if (ptt && (OLDDEVICE == DEVICE_C25)) {
                          i1=isample[rxptr]*txdrv_dbl;
                          q1=qsample[rxptr]*txdrv_dbl;
                          fac=IM3a+IM3b*(i1*i1+q1*q1);
@@ -1176,17 +1190,17 @@ void *handler_ep6(void *arg)
                                myqsample=0;
                                break;
                            }
-                           if (DEVICE == DEVICE_ATLAS && ptt && (k==1)) {
+                           if (OLDDEVICE == DEVICE_ATLAS && ptt && (k==1)) {
                                // METIS: TX DAC signal goes to RX2 when TXing
                                myisample=dacisample;
                                myqsample=dacqsample;
                            }
-                           if ((DEVICE==DEVICE_HERMES || DEVICE==DEVICE_HERMES2 || DEVICE==DEVICE_C25) && ptt && (k==3)) {
+                           if ((OLDDEVICE==DEVICE_HERMES || OLDDEVICE==DEVICE_HERMES2 || OLDDEVICE==DEVICE_C25) && ptt && (k==3)) {
                                // HERMES: TX DAC signal goes to RX4 when TXing
                                myisample=dacisample;
                                myqsample=dacqsample;
                            }
-                           if ((DEVICE==DEVICE_ANGELIA || DEVICE == DEVICE_ORION || DEVICE== DEVICE_ORION2) && ptt && (k==4)) {
+                           if ((OLDDEVICE==DEVICE_ANGELIA || OLDDEVICE == DEVICE_ORION || OLDDEVICE== DEVICE_ORION2) && ptt && (k==4)) {
                                // ANGELIA and beyond: TX DAC signal goes to RX5 when TXing
                                myisample=dacisample;
                                myqsample=dacqsample;
diff --git a/radio.c b/radio.c
index 9017f1e1fb1289cc9e068af44590cbb43f9570dd..ce5caad308a51cb619b9e91482a2a30b3cd913c2 100644 (file)
--- a/radio.c
+++ b/radio.c
@@ -748,6 +748,9 @@ void radio_change_sample_rate(int rate) {
         for(i=0;i<receivers;i++) {
           receiver_change_sample_rate(receiver[i],rate);
         }
+#ifdef PURESIGNAL
+        receiver_change_sample_rate(receiver[PS_RX_FEEDBACK],rate);
+#endif
         old_protocol_set_mic_sample_rate(rate);
         old_protocol_run();
 #ifdef PURESIGNAL
index a888ba4dc1f78c436b2043d3049a948123001970..f96cbe3004ca5f6269b9db04c9a445e97bf60325 100644 (file)
@@ -751,7 +751,7 @@ fprintf(stderr,"receiver: waterfall_init: height=%d y=%d %p\n",height,y,rx->wate
 }
 
 #ifdef PURESIGNAL
-RECEIVER *create_pure_signal_receiver(int id, int buffer_size,int sample_rate,int pixels) {
+RECEIVER *create_pure_signal_receiver(int id, int buffer_size,int sample_rate,int width) {
 fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_size);
   RECEIVER *rx=malloc(sizeof(RECEIVER));
   rx->id=id;
@@ -766,7 +766,7 @@ fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_s
   rx->pixels=0;
   rx->fps=0;
 
-  rx->width=0;
+  rx->width=width;  // save for later use, e.g. when changing the sample rate
   rx->height=0;
   rx->display_panadapter=0;
   rx->display_waterfall=0;
@@ -779,7 +779,11 @@ fprintf(stderr,"create_pure_signal_receiver: id=%d buffer_size=%d\n",id,buffer_s
     // 192 kHz, we make a spectrum with four times the pixels and then
     // display only the central part.
     // 
-    rx->pixels = (protocol == ORIGINAL_PROTOCOL) ? pixels : 4*pixels;
+    if (protocol == ORIGINAL_PROTOCOL) {
+       rx->pixels=(sample_rate/48000) * width;
+    } else {
+      rx->pixels = 4*width;
+    }
   }
   // allocate buffers
   rx->iq_sequence=0;
@@ -1102,21 +1106,51 @@ void receiver_change_adc(RECEIVER *rx,int adc) {
 
 void receiver_change_sample_rate(RECEIVER *rx,int sample_rate) {
 
-  SetChannelState(rx->id,0,1);
+//
+// This must be done also for PS_RX_FEEDBACK to change
+// the number of pixels in the display (needed for
+// conversion from higher sample rates to 48K
+//
+// However, some of these operations must only be done
+// if this is a "normal" receiver
+//
+  int normal=(rx->id != PS_RX_FEEDBACK);
+  float *fp, *ofp;
 
   rx->sample_rate=sample_rate;
   int scale=rx->sample_rate/48000;
   rx->output_samples=rx->buffer_size/scale;
-  free(rx->audio_output_buffer);
-  rx->audio_output_buffer=malloc(sizeof(double)*2*rx->output_samples);
-  rx->audio_buffer=malloc(AUDIO_BUFFER_SIZE);
   rx->hz_per_pixel=(double)rx->sample_rate/(double)rx->width;
-  SetInputSamplerate(rx->id, sample_rate);
+
+  if (!normal) {
+    if (protocol == ORIGINAL_PROTOCOL) {
+      rx->pixels = scale * rx->width;
+    } else {
+      // We should never arrive here, since the sample rate of the
+      // PS feedback receiver is fixed.
+      rx->pixels = 4 * rx->width;
+    }
+    // make sure the pixel samples are always valid
+    // ... probably pure DL1YCF's paranoia
+    fp=malloc(sizeof(float)*rx->pixels);
+    ofp=rx->pixel_samples;
+    rx->pixel_samples=fp;
+    free(ofp);
+  }
   init_analyzer(rx);
-  SetEXTANBSamplerate (rx->id, sample_rate);
-  SetEXTNOBSamplerate (rx->id, sample_rate);
+
+  if (normal) {
+    SetChannelState(rx->id,0,1);
+    free(rx->audio_output_buffer);
+    rx->audio_output_buffer=malloc(sizeof(double)*2*rx->output_samples);
+    rx->audio_buffer=malloc(AUDIO_BUFFER_SIZE);
+    SetInputSamplerate(rx->id, sample_rate);
+    SetEXTANBSamplerate (rx->id, sample_rate);
+    SetEXTNOBSamplerate (rx->id, sample_rate);
+    SetChannelState(rx->id,1,0);
+  }
+
 fprintf(stderr,"receiver_change_sample_rate: id=%d rate=%d buffer_size=%d output_samples=%d\n",rx->id, rx->sample_rate, rx->buffer_size, rx->output_samples);
-  SetChannelState(rx->id,1,0);
 }
 
 void receiver_frequency_changed(RECEIVER *rx) {
index 890be41a91f5d0354b5d441a7dad8310859b2ea6..3f2a74523d23992668280596e29d9b8d508899fb 100644 (file)
@@ -324,60 +324,24 @@ static gboolean update_display(gpointer data) {
     // then obtain spectrum pixels from PS_RX_FEEDBACK,
     // that is, display the (attenuated) TX signal from the "antenna"
     //
-    // POSSIBLE MISMATCH OF SAMPLE RATES:
+    // POSSIBLE MISMATCH OF SAMPLE RATES IN ORIGINAL PROTOCOL:
     // TX sample rate is fixed 48 kHz, but RX sample rate can be
-    // 2*, 4*, or even 8* larger. In this case, the spectrum shown
-    // here is squeezed, so we have to extend the pixels.
-    // So the feedback spectrum is not nice to look at with 192000 Hz
-    // sample rate (low-res), but at least it is correct.
-    // For the sake of saving CPU cycles, we do not interpolate.
-    //
-    // This correction is applied her for the V1 protocol only, because
-    // there might be non-integer ratios using the new protocol.
+    // 2*, 4*, or even 8* larger. The analyzer has been set up to use
+    // more pixels in this case, so we just need to copy the
+    // inner part of the spectrum.
+    // If both spectra have the same number of pixels, this code
+    // just copies all of them
     //
     if(tx->puresignal && tx->feedback) {
       RECEIVER *rx_feedback=receiver[PS_RX_FEEDBACK];
       GetPixels(rx_feedback->id,0,rx_feedback->pixel_samples,&rc);
-      if (protocol == ORIGINAL_PROTOCOL && (active_receiver->sample_rate != 48000)) {
-        int ratio = active_receiver->sample_rate / 48000;
-        int width = tx->pixels / ratio;         // number of pixels to copy from the feedback spectrum
-        int start = (tx->pixels - width) >> 1;  // Copy from start ... (end-1) 
-        int end   = start + width;
-        int i;
-        float *tfp=tx->pixel_samples;
-       float *rfp=rx_feedback->pixel_samples+start;
-        switch (ratio) {
-          case 8:
-            for (i=start; i < end; i++) {
-               *tfp++ = *rfp;
-               *tfp++ = *rfp;
-               *tfp++ = *rfp;
-               *tfp++ = *rfp;
-               *tfp++ = *rfp;
-               *tfp++ = *rfp;
-               *tfp++ = *rfp;
-               *tfp++ = *rfp++;
-            }
-           break;
-          case 4:
-            for (i=start; i < end; i++) {
-               *tfp++ = *rfp;
-               *tfp++ = *rfp;
-               *tfp++ = *rfp;
-               *tfp++ = *rfp++;
-            }
-           break;
-          case 2:
-            for (i=start; i < end; i++) {
-               *tfp++ = *rfp;
-               *tfp++ = *rfp++;
-            }
-           break;
-       }
-      } else {
-       // TX and feedback sample rates are equal -- just copy
-        memcpy(tx->pixel_samples,rx_feedback->pixel_samples,sizeof(float)*tx->pixels);
-      }
+      int full  = rx_feedback->pixels;  // number of pixels in the feedback spectrum
+      int width = tx->pixels;           // number of pixels to copy from the feedback spectrum
+      int start = (full-width) /2;      // Copy from start ... (end-1) 
+      float *tfp=tx->pixel_samples;
+      float *rfp=rx_feedback->pixel_samples+start;
+      // if full == width, then we just copy all samples
+      memcpy(tfp, rfp, width*sizeof(float));
     } else {
 #endif
       GetPixels(tx->id,0,tx->pixel_samples,&rc);