void CLMS::processNoise() { float scl1 = 1.0F - m_adaptationRate * m_leakage; unsigned int n = CXBhave(m_signal); for (unsigned int i = 0; i < n; i++) { m_delayLine[m_delayLinePtr] = CXBreal(m_signal, i); float accum = 0.0F; float sum_sq = 0.0F; unsigned int j; for (j = 0; j < m_adaptiveFilterSize; j++) { unsigned int k = (j + m_delay + m_delayLinePtr) & m_mask; sum_sq += m_delayLine[k] * m_delayLine[k]; accum += m_adaptiveFilter[j] * m_delayLine[k]; } float error = CXBreal(m_signal, i) - accum; CXBreal(m_signal, i) = accum; CXBimag(m_signal, i) = accum; float scl2 = m_adaptationRate / (sum_sq + 1e-10); error *= scl2; for (j = 0; j < m_adaptiveFilterSize; j++) { unsigned int k = (j + m_delay + m_delayLinePtr) & m_mask; m_adaptiveFilter[j] = m_adaptiveFilter[j] * scl1 + error * m_delayLine[k]; } m_delayLinePtr = (m_delayLinePtr + m_mask) & m_mask; } }
void correctIQ (CXB sigbuf, IQ iq, BOOLEAN isTX, int subchan) { int i; REAL doit; if (IQdoit == 0) return; if (subchan == 0) doit = iq->mu; else doit = 0; if(!isTX) { // if (subchan == 0) // removed so that sub rx's will get IQ correction for (i = 0; i < CXBhave (sigbuf); i++) { iq->del[iq->index] = CXBdata(sigbuf,i); iq->y[iq->index] = Cadd(iq->del[iq->index],Cmul(iq->w[0],Conjg(iq->del[iq->index]))); iq->y[iq->index] = Cadd(iq->y[iq->index],Cmul(iq->w[1],Conjg(iq->y[iq->index]))); iq->w[1] = Csub(iq->w[1], Cscl(Cmul(iq->y[iq->index],iq->y[iq->index]), doit)); // this is where the adaption happens CXBdata(sigbuf,i)=iq->y[iq->index]; iq->index = (iq->index+iq->MASK)&iq->MASK; } //fprintf(stderr, "w1 real: %g, w1 imag: %g\n", iq->w[1].re, iq->w[1].im); fflush(stderr); } else { for (i = 0; i < CXBhave (sigbuf); i++) { CXBimag (sigbuf, i) += iq->phase * CXBreal (sigbuf, i); CXBreal (sigbuf, i) *= iq->gain; } } }
/* ---------------------------------------------------------------------------- */ void FMDemod(FMD fm) { int i; for (i = 0; i < CXBhave(fm->ibuf); i++) { pll(fm, CXBdata(fm->ibuf, i)); fm->afc = (REAL) (0.9999 * fm->afc + 0.0001 * fm->pll.freq.f); CXBreal(fm->obuf, i) = CXBimag(fm->obuf, i) = (fm->pll.freq.f - fm->afc) * fm->cvt; } }
// snapshot of current signal void snap_spectrum (SpecBlock * sb, int label) { int i, j; // where most recent signal started j = sb->fill; // copy starting from there in circular fashion, // applying window as we go if (!sb->polyphase) { for (i = 0; i < sb->size; i++) { CXBdata (sb->timebuf, i) = Cscl (CXBdata (sb->accum, j), sb->window[i]); j = (++j & sb->mask); } } else { int k; for (i = 0; i < sb->size; i++) { CXBreal (sb->timebuf, i) = CXBreal (sb->accum, j) * sb->window[i]; CXBimag (sb->timebuf, i) = CXBimag (sb->accum, j) * sb->window[i]; for (k = 1; k < 8; k++) { int accumidx = (j + k * sb->size) & sb->mask; int winidx = i + k * sb->size; CXBreal (sb->timebuf, i) += CXBreal (sb->accum, accumidx) * sb->window[winidx]; CXBimag (sb->timebuf, i) += CXBimag (sb->accum, accumidx) * sb->window[winidx]; } j = (++j & sb->mask); } } sb->label = label; }
void CFMDemod::demodulate() { unsigned int n = CXBhave(m_ibuf); for (unsigned int i = 0; i < n; i++) { pll(CXBdata(m_ibuf, i)); m_afc = float(0.9999 * m_afc + 0.0001F * m_pllFreqF); CXBreal(m_obuf, i) = CXBimag(m_obuf, i) = (m_pllFreqF - m_afc) * m_cvt; } CXBhave(m_obuf) = n; }
// generated tone -> output ringbuffer void send_tone (void) { if (ringb_float_write_space (lring) < TONE_SIZE) { cw_ring_reset = TRUE; } else { int i; EnterCriticalSection (cs_cw); correctIQ(gen->buf, tx[1].iqfix); for (i = 0; i < gen->size; i++) { float r = (float) CXBreal (gen->buf, i), l = (float) CXBimag (gen->buf, i); ringb_float_write (lring, (float *) &l, 1); ringb_float_write (rring, (float *) &r, 1); } LeaveCriticalSection (cs_cw); } }
void correctIQ (CXB sigbuf, IQ iq) { int i; // SV1EIA AIR if (CXBhave (sigbuf)!= DEFSPEC) // SV1EIA AIR { // SV1EIA AIR if (iq->buffer_counter>DEFSPEC-1) iq->buffer_counter = 0; // SV1EIA AIR iq->buffer_length[iq->buffer_counter] = CXBhave (sigbuf); // SV1EIA AIR iq->buffer_counter++; // SV1EIA AIR } // SV1EIA AIR iq->im_max_actual = 0; // SV1EIA AIR iq->im_max_test = 0; // SV1EIA AIR iq->im_min_actual = 0; // SV1EIA AIR iq->im_min_test = 0; // SV1EIA AIR iq->re_max_actual = 0; // SV1EIA AIR iq->re_max_test = 0; // SV1EIA AIR iq->re_min_actual = 0; // SV1EIA AIR iq->re_min_test = 0; // SV1EIA AIR for (i = 0; i < CXBhave (sigbuf); i++) // SV1EIA AIR { // SV1EIA AIR if (CXBimag (sigbuf, i) >= iq->im_max_actual) // SV1EIA AIR { // SV1EIA AIR iq->im_max_actual = CXBimag (sigbuf, i); // SV1EIA AIR iq->im_max_bin_actual = i; // SV1EIA AIR } // SV1EIA AIR if (CXBreal (sigbuf, i) >= iq->re_max_actual) // SV1EIA AIR { // SV1EIA AIR iq->re_max_actual = CXBreal (sigbuf, i); // SV1EIA AIR iq->re_max_bin_actual = i; // SV1EIA AIR } // SV1EIA AIR if (CXBimag (sigbuf, i) <= iq->im_min_actual) // SV1EIA AIR { // SV1EIA AIR iq->im_min_actual = CXBimag (sigbuf, i); // SV1EIA AIR iq->im_min_bin_actual = i; // SV1EIA AIR } // SV1EIA AIR if (CXBreal (sigbuf, i) <= iq->re_min_actual) // SV1EIA AIR { // SV1EIA AIR iq->re_min_actual = CXBreal (sigbuf, i); // SV1EIA AIR iq->re_min_bin_actual = i; // SV1EIA AIR } // SV1EIA AIR iq->im_actual[i] = CXBimag (sigbuf, i); // SV1EIA AIR iq->re_actual[i] = CXBreal (sigbuf, i); // SV1EIA AIR CXBimag (sigbuf, i) += iq->phase[i] * CXBreal (sigbuf, i); // SV1EIA AIR CXBreal (sigbuf, i) *= iq->gain[i]; // SV1EIA AIR iq->im_test[i] = CXBimag (sigbuf, i); // SV1EIA AIR iq->re_test[i] = CXBreal (sigbuf, i); // SV1EIA AIR if (CXBimag (sigbuf, i) >= iq->im_max_test) // SV1EIA AIR { // SV1EIA AIR iq->im_max_test = CXBimag (sigbuf, i); // SV1EIA AIR iq->im_max_bin_test = i; // SV1EIA AIR } // SV1EIA AIR if (CXBreal (sigbuf, i) >= iq->re_max_test) // SV1EIA AIR { // SV1EIA AIR iq->re_max_test = CXBreal (sigbuf, i); // SV1EIA AIR iq->re_max_bin_test = i; // SV1EIA AIR } // SV1EIA AIR if (CXBimag (sigbuf, i) <= iq->im_min_test) // SV1EIA AIR { // SV1EIA AIR iq->im_min_test = CXBimag (sigbuf, i); // SV1EIA AIR iq->im_min_bin_test = i; // SV1EIA AIR } // SV1EIA AIR if (CXBreal (sigbuf, i) <= iq->re_min_test) // SV1EIA AIR { // SV1EIA AIR iq->re_min_test = CXBreal (sigbuf, i); // SV1EIA AIR iq->re_min_bin_test = i; // SV1EIA AIR } // SV1EIA AIR } // SV1EIA AIR // if (iq->spec > 0) // { // } }
void CTX::process(float* bufi, float* bufq, unsigned int n) { for (unsigned int i = 0U; i < n; i++) { CXBreal(m_iBuf, i) = bufi[i]; CXBimag(m_iBuf, i) = bufq[i]; } CXBhave(m_iBuf) = n; CXBscl(m_iBuf, m_micGain); /* unsigned int n = CXBhave(m_iBuf); for (unsigned int i = 0; i < n; i++) CXBdata(m_iBuf, i) = Cmplx(CXBimag(m_iBuf, i), 0.0F); */ if (m_dcBlockFlag && (m_mode == USB || m_mode == LSB)) m_dcBlock->block(); spectrum(m_iBuf, SPEC_TX_MIC); meter(m_iBuf, TX_MIC); if (m_equaliserFlag && (m_mode == USB || m_mode == LSB || m_mode == AM || m_mode == SAM || m_mode == FMN)) m_equaliser->process(); if (m_speechProcFlag && (m_mode == USB || m_mode == LSB)) m_speechProc->process(); spectrum(m_iBuf, SPEC_TX_POST_COMP); meter(m_iBuf, TX_COMP); m_alc->process(); spectrum(m_iBuf, SPEC_TX_POST_ALC); meter(m_iBuf, TX_ALC); m_modulator->modulate(); if (m_tick == 0UL) m_filter->reset(); // Only active for the third method and zero-IF m_oscillator2->mix(); m_filter->filter(); CXBhave(m_oBuf) = CXBhave(m_iBuf); spectrum(m_oBuf, SPEC_TX_POST_FILT); m_oscillator1->mix(); m_iq->process(); CXBscl(m_oBuf, m_power); meter(m_oBuf, TX_PWR); n = CXBhave(m_oBuf); if (m_swapIQ) { for (unsigned int i = 0U; i < n; i++) { bufq[i] = CXBreal(m_oBuf, i); bufi[i] = CXBimag(m_oBuf, i); } } else { for (unsigned int i = 0U; i < n; i++) { bufi[i] = CXBreal(m_oBuf, i); bufq[i] = CXBimag(m_oBuf, i); } } m_tick++; }