gtk_container_remove(GTK_CONTAINER(fixed), transmitter->panel);
}
if(!duplex) {
+ //
+ // Set parameters for the "silence first RXIQ samples after TX/RX transition" feature
+ // the default is "no silence", that is, fastest turnaround
+ //
+ int do_silence=0;
+ if (protocol == ORIGINAL_PROTOCOL && (device == DEVICE_HERMES_LITE2 || device == DEVICE_STEMLAB)) {
+ //
+ // These systems get a significant "tail" of the RX feedback signal into the RX after TX/RX,
+ // leading to AGC pumping. The problem is most severe if there is a carrier until the end of
+ // the TX phase (TUNE, AM, FM), the problem is virtually non-existent for CW, and of medium
+ // importance in SSB. On the other hand, one want a very fast turnaround in CW.
+ // So there is no "muting" for CW, 31 msec off "muting" for TUNE/AM/FM, and 16 msec for other modes.
+ //
+ switch(get_tx_mode()) {
+ case modeCWU:
+ case modeCWL:
+ do_silence=0; // no "silence"
+ break;
+ case modeAM:
+ case modeFMN:
+ do_silence=5; // leads to 31 ms "silence"
+ break;
+ default:
+ do_silence=6; // leads to 16 ms "silence"
+ break;
+ }
+ if (tune) do_silence=5; // 31 ms "silence" for TUNEing in any mode
+ }
+
for(i=0;i<receivers;i++) {
gtk_fixed_put(GTK_FIXED(fixed),receiver[i]->panel,receiver[i]->x,receiver[i]->y);
SetChannelState(receiver[i]->id,1,0);
set_displaying(receiver[i],1);
- receiver[i]->rxcount=0;
- receiver[i]->maxcount=-1;
- // if not duplex, clear RX iq buffer
+ //
+ // There might be some left-over samples in the RX buffer that were filled in
+ // *before* going TX, delete them
+ //
receiver[i]->samples=0;
+ if (do_silence) {
+ receiver[i]->txrxmax = receiver[i]->sample_rate >> do_silence;
+ } else {
+ receiver[i]->txrxmax = 0;
+ }
+ receiver[i]->txrxcount = 0;
}
}
}
// defer set_agc until here, otherwise the AGC threshold is not computed correctly
set_agc(rx, rx->agc);
- rx->rxcount=99999;
+ rx->txrxcount=0;
+ rx->txrxmax=0;
return rx;
}
g_mutex_lock(&rx->mutex);
rx->sample_rate=sample_rate;
- rx->samples=0; // clear RX iq buffer
int scale=rx->sample_rate/48000;
rx->output_samples=rx->buffer_size/scale;
rx->hz_per_pixel=(double)rx->sample_rate/(double)rx->width;
void add_iq_samples(RECEIVER *rx, double i_sample,double q_sample) {
- if (rx->rxcount <= 20000) {
- if (i_sample*i_sample + q_sample*q_sample > 0.01) rx->maxcount=rx->rxcount;
- if (rx->rxcount < (int)(rx->sample_rate >> 5)) {
- i_sample=0.0;
- q_sample=0.0;
- }
- if (rx->rxcount == 20000) {
- fprintf(stderr,"ID=%d MAXCOUNT=%d\n", rx->id, rx->maxcount);
- rx->rxcount = 99999;
- }
- rx->rxcount++;
+ //
+ // At the end of a TX/RX transition, txrxcount is set to zero,
+ // and txrxmax to some suitable value.
+ // Then, the first txrxmax RXIQ samples are "silenced"
+ // This is necessary on systems where RX feedback samples
+ // from cross-talk at the TRX relay arrive with some delay.
+ //
+ // If txrxmax is zero, no "silencing" takes place here,
+ // this is the case for radios not showing this problem,
+ // and generally if in CW mode or using duplex.
+ //
+ if (rx->txrxcount < rx->txrxmax) {
+ i_sample=0.0;
+ q_sample=0.0;
+ rx->txrxcount++;
}
rx->iq_input_buffer[rx->samples*2]=i_sample;
// Note that we sum the second channel onto the first one.
//
void add_div_iq_samples(RECEIVER *rx, double i0, double q0, double i1, double q1) {
- rx->iq_input_buffer[rx->samples*2] = i0 + (div_cos*i1 - div_sin*q1);
- rx->iq_input_buffer[(rx->samples*2)+1]= q0 + (div_sin*i1 + div_cos*q1);
+ double i_sample=i0 + (div_cos*i1 - div_sin*q1);
+ double q_sample=q0 + (div_sin*i1 + div_cos*q1);
+ //
+ // The rest of the code is copied from add_iq_samples()
+ //
+ if (rx->txrxcount < rx->txrxmax) {
+ i_sample=0.0;
+ q_sample=0.0;
+ rx->txrxcount++;
+ }
+
+ rx->iq_input_buffer[rx->samples*2]=i_sample;
+ rx->iq_input_buffer[(rx->samples*2)+1]=q_sample;
rx->samples=rx->samples+1;
if(rx->samples>=rx->buffer_size) {
full_rx_buffer(rx);
gint x;
gint y;
- int rxcount; int maxcount;
+ // two variables that implement the new
+ // "mute first RX IQ samples after TX/RX transition"
+ // feature that is relevant for HermesLite-II and STEMlab
+ // (and possibly some other radios)
+ //
+ guint txrxcount;
+ guint txrxmax;
} RECEIVER;
extern RECEIVER *create_pure_signal_receiver(int id, int buffer_size,int sample_rate,int pixels);