uni.mix.rx.flag = uni.mix.tx.flag = FALSE;
uni.mix.rx.gain = uni.mix.tx.gain = 1.0;
+ uni.cpdlen = loc.def.comp;
+
uni.tick = 0;
}
we just created */
rx[k].buf.i = newCXB(FiltOvSv_fetchsize(rx[k].filt.ovsv),
FiltOvSv_fetchpoint(rx[k].filt.ovsv),
- "init rx.buf.i");
+ "init rx[k].buf.i");
rx[k].buf.o = newCXB(FiltOvSv_storesize(rx[k].filt.ovsv),
FiltOvSv_storepoint(rx[k].filt.ovsv),
"init rx[k].buf.o");
uni.samplerate,
"SDR RX Oscillator");
- rx[k].agc.gen = newDigitalAgc(agcMED, // Mode
- 7, // Hang
- 7, // Size
- 48, // Ramp
- 3, // Over
- 3, // Rcov
- CXBsize(rx[k].buf.o), // BufSize
- 100.0, // MaxGain
- 0.707, // Limit
- 1.0, // CurGain
- CXBbase(rx[k].buf.o));
+ rx[k].agc.gen = newDigitalAgc(agcSLOW, // Mode
+ 7, // Hang
+ 48, // Ramp
+ 3, // Over
+ 3, // Rcov
+ CXBsize(rx[k].buf.o), // BufSize
+ 2500.0, // MaxGain
+ 0.707, // Limit
+ 1.0, // CurGain
+ CXBbase(rx[k].buf.o));
rx[k].agc.flag = TRUE;
/* demods */
rx[k].squelch.thresh = -30.0;
rx[k].squelch.power = 0.0;
rx[k].squelch.flag = rx[k].squelch.running = rx[k].squelch.set = FALSE;
- rx[k].squelch.num = (int) (0.0395 * uni.samplerate + 0.5);
+ rx[k].squelch.num = uni.buflen - 10;
+
+ rx[k].cpd.gen = newWSCompander(uni.cpdlen,
+ 0.0,
+ rx[k].buf.o);
+ rx[k].cpd.flag = FALSE;
rx[k].mode = uni.mode.sdr;
rx[k].bin.flag = FALSE;
FiltOvSv_storepoint(tx.filt.ovsv),
"init tx.buf.o");
+ tx.dcb.flag = FALSE;
+ tx.dcb.gen = newDCBlocker(DCB_MED, tx.buf.i);
+
/* conversion */
tx.osc.freq = 0.0;
tx.osc.phase = 0.0;
uni.samplerate,
"SDR TX Oscillator");
+
tx.agc.gen = newDigitalAgc(agcFAST, // Mode
3, // Hang
- 3, // Size
+ 48, // Ramp
3, // Over
3, // Rcov
- 48, // Ramp
CXBsize(tx.buf.o), // BufSize
1.0, // MaxGain
0.900, // Limit
CXBbase(tx.buf.o));
tx.agc.flag = TRUE;
- tx.spr.gen = newSpeechProc(0.4, 10.0, CXBbase(tx.buf.i), CXBsize(tx.buf.i));
+ tx.spr.gen = newSpeechProc(0.4, 10.0, CXBbase(tx.buf.o), CXBsize(tx.buf.o));
tx.spr.flag = FALSE;
+ tx.cpd.gen = newWSCompander(uni.cpdlen,
+ 0.0,
+ tx.buf.o);
+ tx.cpd.flag = FALSE;
+
tx.scl.dc = cxzero;
tx.scl.pre.val = 1.0;
tx.scl.pre.flag = FALSE;
delSpeechProc(tx.spr.gen);
delDigitalAgc(tx.agc.gen);
delOSC(tx.osc.gen);
+ delDCBlocker(tx.dcb.gen);
delvec_COMPLEX(tx.filt.save);
delFiltOvSv(tx.filt.ovsv);
delFIR_Bandpass_COMPLEX(tx.filt.coef);
uni.meter.rx.val[k][tap] = 0;
switch (uni.meter.rx.type) {
- case AVG_SIGNAL_STRENGTH:
- for (i = 0; i < len; i++)
- uni.meter.rx.val[k][tap] += Csqrmag(vec[i]);
- uni.meter.rx.val[k][tap] =
- uni.meter.rx.avg[k][tap] =
- 0.9 * uni.meter.rx.avg[k][tap] + log10(uni.meter.rx.val[k][tap] + 1e-20);
- break;
case SIGNAL_STRENGTH:
for (i = 0; i < len; i++)
uni.meter.rx.val[k][tap] += Csqrmag(vec[i]);
+ if (tap == 3) rx[k].norm = uni.meter.rx.val[k][tap] / len;
uni.meter.rx.avg[k][tap] =
uni.meter.rx.val[k][tap] =
10.0 * log10(uni.meter.rx.val[k][tap] + 1e-20);
break;
+ case AVG_SIGNAL_STRENGTH:
+ for (i = 0; i < len; i++)
+ uni.meter.rx.val[k][tap] += Csqrmag(vec[i]);
+ uni.meter.rx.val[k][tap] =
+ uni.meter.rx.avg[k][tap] =
+ 0.9 * uni.meter.rx.avg[k][tap] + log10(uni.meter.rx.val[k][tap] + 1e-20);
+ break;
case ADC_REAL:
for(i = 0; i < len; i++)
uni.meter.rx.val[k][tap] = max(fabs(vec[i].re), uni.meter.rx.val[k][tap]);
uni.meter.rx.val[k][tap] = max(fabs(vec[i].im), uni.meter.rx.val[k][tap]);
uni.meter.rx.val[k][tap] = 20.0 * log10(uni.meter.rx.val[k][tap] + 1e-10);
break;
+ case AGC_GAIN:
+ uni.meter.rx.val[k][tap] = 20.0 * log10(rx[k].agc.gen->gain.now + 1e-80);
+ break;
default:
break;
}
uni.meter.tx.val[tap] =
10.0 * log10(uni.meter.tx.val[tap] + 1e-20);
break;
- case ADC_REAL:
- for(i = 0; i < len; i++)
- uni.meter.tx.val[tap] = max(fabs(vec[i].re), uni.meter.tx.val[tap]);
- uni.meter.tx.val[tap] = 20.0 * log10(uni.meter.tx.val[tap] + 1e-10);
+ case ALC:
+ {
+ REAL tmp = 20.0 * log10(tx.agc.gen->gain.now);
+ uni.meter.tx.val[tap] =
+ tmp < 0.0 ? tmp : min(20.0, 20.0 * log10(tx.agc.gen->gain.raw));
+ }
break;
- case ADC_IMAG:
- for(i = 0; i < len; i++)
- uni.meter.tx.val[tap] = max(fabs(vec[i].im), uni.meter.tx.val[tap]);
- uni.meter.tx.val[tap] = 20.0 * log10(uni.meter.tx.val[tap] + 1e-10);
+ case PWR:
+ for(i = 0, uni.meter.tx.val[tap] = 1e-20; i < CXBhave(tx.buf.o); i++)
+ uni.meter.tx.val[tap] += Csqrmag(CXBdata(tx.buf.o, i));
+ uni.meter.tx.val[tap] /= 2048.0;
+ break;
+ case PKPWR:
+ for(i = 0, uni.meter.tx.val[tap] = 1e-20; i < CXBhave(tx.buf.o); i++)
+ uni.meter.tx.val[tap] = max(uni.meter.tx.val[tap],
+ Csqrmag(CXBdata(tx.buf.o,i)));
break;
default:
break;
}
}
-PRIVATE BOOLEAN
+PRIVATE void
do_rx_spectrum(int k, CXB buf, int type) {
if (uni.spec.flag && k == uni.spec.rxk && type == uni.spec.type) {
memcpy((char *) &CXBdata(uni.spec.accum, uni.spec.fill),
(char *) CXBbase(buf),
- CXBhave(buf));
- uni.spec.fill = (uni.spec.fill + uni.spec.buflen) % uni.spec.size;
+ CXBsize(buf) * sizeof(COMPLEX));
+ uni.spec.fill = (uni.spec.fill + CXBsize(buf)) % uni.spec.size;
}
}
do_tx_spectrum(CXB buf) {
memcpy((char *) &CXBdata(uni.spec.accum, uni.spec.fill),
(char *) CXBbase(buf),
- CXBhave(buf));
- uni.spec.fill = (uni.spec.fill + uni.spec.buflen) % uni.spec.size;
+ CXBsize(buf) * sizeof(COMPLEX));
+ uni.spec.fill = (uni.spec.fill + CXBsize(buf)) % uni.spec.size;
}
//========================================================================
if (rx[k].squelch.flag) {
int i, n = CXBhave(rx[k].buf.o);
rx[k].squelch.power = 0.0;
+
for (i = 0; i < n; i++)
rx[k].squelch.power += Csqrmag(CXBdata(rx[k].buf.o, i));
- return rx[k].squelch.thresh > 10.0 * log10(rx[k].squelch.power);
+
+ return
+ 10.0 * log10(rx[k].squelch.power) < rx[k].squelch.thresh;
+
} else
return rx[k].squelch.set = FALSE;
}
PRIVATE void
do_squelch(int k) {
rx[k].squelch.set = TRUE;
+
if (!rx[k].squelch.running) {
- int i, m = rx[k].squelch.num, n = CXBhave(rx[k].buf.o) - m;
+ int i,
+ m = rx[k].squelch.num,
+ n = CXBhave(rx[k].buf.o) - m;
+
for (i = 0; i < m; i++)
- CXBdata(rx[k].buf.o, i) = Cscl(CXBdata(rx[k].buf.o, i), 1.0 - (REAL) i / m);
- memset((void *) (CXBbase(rx[k].buf.o) + m), 0, n * sizeof(COMPLEX));
+ CXBdata(rx[k].buf.o, i) =
+ Cscl(CXBdata(rx[k].buf.o, i), 1.0 - (REAL) i / m);
+
+ memset((void *) (CXBbase(rx[k].buf.o) + m),
+ 0,
+ n * sizeof(COMPLEX));
rx[k].squelch.running = TRUE;
+
} else
- memset((void *) CXBbase(rx[k].buf.o), 0, CXBhave(rx[k].buf.o) * sizeof(COMPLEX));
+ memset((void *) CXBbase(rx[k].buf.o),
+ 0,
+ CXBhave(rx[k].buf.o) * sizeof(COMPLEX));
}
// lift squelch
no_squelch(int k) {
if (rx[k].squelch.running) {
int i, m = rx[k].squelch.num;
+
for (i = 0; i < m; i++)
- CXBdata(rx[k].buf.o, i) = Cscl(CXBdata(rx[k].buf.o, i), (REAL) i / m);
+ CXBdata(rx[k].buf.o, i) =
+ Cscl(CXBdata(rx[k].buf.o, i), (REAL) i / m);
+
rx[k].squelch.running = FALSE;
}
}
do_rx_meter(k, rx[k].buf.o, RXMETER_POST_FILT);
do_rx_spectrum(k, rx[k].buf.o, SPEC_POST_FILT);
+ if (rx[k].cpd.flag)
+ WSCompand(rx[k].cpd.gen);
+
if (should_do_rx_squelch(k))
do_squelch(k);
else if (rx[k].agc.flag)
DigitalAgc(rx[k].agc.gen, rx[k].tick);
-
+
+ do_rx_spectrum(k, rx[k].buf.o, SPEC_POST_AGC);
}
}
PRIVATE void
do_tx_pre(void) {
-if (tx.scl.pre.flag) {
-int i, n = CXBhave(tx.buf.i);
+ if (tx.scl.pre.flag) {
+ int i, n = CXBhave(tx.buf.i);
for (i = 0; i < n; i++)
CXBdata(tx.buf.i, i) = Cmplx(CXBreal(tx.buf.i, i) * tx.scl.pre.val, 0.0);
}
correctIQ(tx.buf.i, tx.iqfix);
- if (tx.spr.flag) SpeechProcessor(tx.spr.gen);
+ if (tx.dcb.flag) DCBlock(tx.dcb.gen);
if (tx.tick == 0) reset_OvSv(tx.filt.ovsv);
filter_OvSv(tx.filt.ovsv);
+
}
PRIVATE void
CXBdata(tx.buf.o, i) = Cscl(CXBdata(tx.buf.o, i), tx.scl.post.val);
}
+ if (tx.spr.flag) SpeechProcessor(tx.spr.gen);
+ if (tx.cpd.flag) WSCompand(tx.cpd.gen);
+
if (uni.spec.flag)
do_tx_spectrum(tx.buf.o);
do_rx(k), rx[k].tick++;
// mix
for (i = 0; i < n; i++)
- bufl[i] += CXBimag(rx[k].buf.o, i),
- bufr[i] += CXBreal(rx[k].buf.o, i);
+ bufl[i] += (float) CXBimag(rx[k].buf.o, i),
+ bufr[i] += (float) CXBreal(rx[k].buf.o, i);
CXBhave(rx[k].buf.o) = n;
}
// late mixing of aux buffers
if (uni.mix.rx.flag)
for (i = 0; i < n; i++)
- bufl[i] += auxl[i] * uni.mix.rx.gain,
- bufr[i] += auxr[i] * uni.mix.rx.gain;
+ bufl[i] += (float) (auxl[i] * uni.mix.rx.gain),
+ bufr[i] += (float) (auxr[i] * uni.mix.rx.gain);
break;
// early mixing of aux buffers
if (uni.mix.tx.flag)
for (i = 0; i < n; i++)
- bufl[i] += auxl[i] * uni.mix.tx.gain,
- bufr[i] += auxr[i] * uni.mix.tx.gain;
+ bufl[i] += (float) (auxl[i] * uni.mix.tx.gain),
+ bufr[i] += (float) (auxr[i] * uni.mix.tx.gain);
for (i = 0; i < n; i++)
CXBimag(tx.buf.i, i) = bufl[i], CXBreal(tx.buf.i, i) = bufr[i];