From c784c7218fac031973377cd3391c0dacda3dff58 Mon Sep 17 00:00:00 2001 From: c vw Date: Thu, 18 Jul 2019 19:02:19 +0200 Subject: [PATCH] OldProtocol: making feedback spectrum high resolution for all sample rates --- hpsdrsim.c | 76 ++++++++++++++++++++++++++++++--------------------- radio.c | 3 ++ receiver.c | 56 +++++++++++++++++++++++++++++-------- transmitter.c | 62 +++++++++-------------------------------- 4 files changed, 106 insertions(+), 91 deletions(-) diff --git a/hpsdrsim.c b/hpsdrsim.c index 881ea13..59d5e6f 100644 --- a/hpsdrsim.c +++ b/hpsdrsim.c @@ -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; jwate } #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) { diff --git a/transmitter.c b/transmitter.c index 890be41..3f2a745 100644 --- a/transmitter.c +++ b/transmitter.c @@ -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); -- 2.45.2