void SDROMnoiseblanker (NB nb) { int i; for (i = 0; i < CXBsize (nb->sigbuf); i++) { REAL cmag = Cmag (CXBdata (nb->sigbuf, i)); nb->average_sig = Cadd (Cscl (nb->average_sig, 0.75), Cscl (CXBdata (nb->sigbuf, i), 0.25)); nb->average_mag = (REAL) (0.999 * (nb->average_mag) + 0.001 * cmag); if (cmag > (nb->threshold * nb->average_mag)) CXBdata (nb->sigbuf, i) = nb->average_sig; } }
BOOLEAN SpotTone (SpotToneGen st) { int i, n = st->size; ComplexOSC (st->osc.gen); for (i = 0; i < n; i++) { // in an envelope stage? if (st->stage == SpotTone_RISE) { // still going? if (st->rise.have++ < st->rise.want) { st->curr += st->rise.incr; st->mul = (REAL) (st->scl * sin (st->curr * M_PI / 2.0)); } else { // no, assert steady-state, force level st->curr = 1.0; st->mul = st->scl; st->stage = SpotTone_STDY; // won't come back into envelopes // until FALL asserted from outside } } else if (st->stage == SpotTone_FALL) { // still going? if (st->fall.have++ < st->fall.want) { st->curr -= st->fall.incr; st->mul = (REAL) (st->scl * sin (st->curr * M_PI / 2.0)); } else { // no, assert trailing, force level st->curr = 0.0; st->mul = 0.0; st->stage = SpotTone_HOLD; // won't come back into envelopes hereafter } } // apply envelope // (same base as osc.gen internal buf) CXBdata (st->buf, i) = Cscl (CXBdata (st->buf, i), st->mul); } // indicate whether it's turned itself off // sometime during this pass return st->stage != SpotTone_HOLD; }
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; } } }
REAL normalize_vec_COMPLEX (COMPLEX * z, int n) { if (z && (n > 0)) { int i; REAL big = -(REAL) MONDO; for (i = 0; i < n; i++) { REAL a = Cabs (z[i]); big = max (big, a); } if (big > 0.0) { REAL scl = (REAL) (1.0 / big); for (i = 0; i < n; i++) z[i] = Cscl (z[i], scl); return scl; } else return 0.0; } else return 0.0; }
void blms_adapt (BLMS blms) { int sigsize = CXBhave (blms->signal); int sigidx = 0; // fputs("Inside\n",stderr),fflush(stderr); do { int j; memcpy (blms->delay_line, &blms->delay_line[128], sizeof (COMPLEX) * 128); // do overlap move memcpy (&blms->delay_line[128], &CXBdata (blms->signal, sigidx), sizeof (COMPLEX) * 128); // copy in new data fftwf_execute (blms->Xplan); // compute transform of input data for (j = 0; j < 256; j++) { blms->Yhat[j] = Cmul (blms->What[j], blms->Xhat[j]); // Filter new signal in freq. domain blms->Xhat[j] = Conjg (blms->Xhat[j]); // take input data's complex conjugate } fftwf_execute (blms->Yplan); //compute output signal transform for (j = 128; j < 256; j++) blms->y[j] = Cscl (blms->y[j], BLKSCL); memset (blms->y, 0, 128 * sizeof (COMPLEX)); for (j = 128; j < 256; j++) blms->error[j] = Csub (blms->delay_line[j], blms->y[j]); // compute error signal if (blms->filter_type) memcpy (&CXBdata (blms->signal, sigidx), &blms->y[128], 128 * sizeof (COMPLEX)); // if noise filter, output y else memcpy (&CXBdata (blms->signal, sigidx), &blms->error[128], 128 * sizeof (COMPLEX)); // if notch filter, output error fftwf_execute (blms->Errhatplan); // compute transform of the error signal for (j = 0; j < 256; j++) blms->Errhat[j] = Cmul (blms->Errhat[j], blms->Xhat[j]); // compute cross correlation transform fftwf_execute (blms->UPDplan); // compute inverse transform of cross correlation transform for (j = 0; j < 128; j++) blms->update[j] = Cscl (blms->update[j], BLKSCL); memset (&blms->update[128], 0, sizeof (COMPLEX) * 128); // zero the last block of the update, so we get // filter coefficients only at front of buffer fftwf_execute (blms->Wplan); for (j = 0; j < 256; j++) { blms->What[j] = Cadd (Cscl (blms->What[j], blms->leak_rate), // leak the W away Cscl (blms->Update[j], blms->adaptation_rate)); // update at adaptation rate } sigidx += 128; // move to next block in the signal buffer } while (sigidx < sigsize); // done? }
BOOLEAN CWTone (CWToneGen cwt) { int i, n = cwt->size; ComplexOSC (cwt->osc.gen); for (i = 0; i < n; i++) { // in an envelope stage? if (cwt->stage == CWTone_RISE) { // still going? if (cwt->rise.have++ < cwt->rise.want) { cwt->curr += cwt->rise.incr; cwt->mul = cwt->scl * (REAL) CWSIN (cwt->curr * M_PI / 2.0); } else { // no, assert steady-state, force level cwt->curr = 1.0; cwt->mul = cwt->scl; cwt->stage = CWTone_STDY; // won't come back into envelopes // until FALL asserted from outside } } else if (cwt->stage == CWTone_FALL) { // still going? if (cwt->fall.have++ < cwt->fall.want) { cwt->curr -= cwt->fall.incr; cwt->mul = cwt->scl * (REAL) CWSIN (cwt->curr * M_PI / 2.0); } else { // no, assert trailing, force level cwt->curr = 0.0; cwt->mul = 0.0; cwt->stage = CWTone_HOLD; // won't come back into envelopes hereafter } } // apply envelope // (same base as osc.gen internal buf) CXBdata (cwt->buf, i) = Cscl (CXBdata (cwt->buf, i), cwt->mul); } CXBhave(cwt->buf) = n; /* kd5tfd added - set have field of buf so correctIQ works */ // indicate whether it's turned itself off // sometime during this pass return cwt->stage != CWTone_HOLD; }
static void lmsr_adapt_i (LMSR lms) { int i, j, k; REAL sum_sq, scl1, scl2; COMPLEX accum, error; scl1 = (REAL) (1.0 - rate * leak); for (i = 0; i < ssiz; i++) { dlay (dptr) = CXBdata (lms->signal, i); accum = cxzero; sum_sq = 0; for (j = 0; j < asiz; j+=2) { k = wrap (j); sum_sq += Csqrmag (dlay (k)); accum.re += afil (j).re * dlay (k).re; accum.im += afil (j).im * dlay (k).im; k = wrap (j+1); sum_sq += Csqrmag (dlay (k)); accum.re += afil (j+1).re * dlay (k).re; accum.im += afil (j+1).im * dlay (k).im; } error = Csub(cssig(i),accum); cssig(i) = error; // ssig_i (i) = error.im; // ssig (i) = error.re; scl2 = (REAL) (rate / (sum_sq + 1.19e-7)); error = Cscl(error,scl2); for (j = 0; j < asiz; j+=2) { k = wrap (j); afil (j).re = afil (j).re * scl1 + error.re * dlay (k).re; afil (j).im = afil (j).im * scl1 + error.im * dlay (k).im; k = wrap (j+1); afil (j+1).re = afil (j+1).re * scl1 + error.re * dlay (k).re; afil (j+1).im = afil (j+1).im * scl1 + error.im * dlay (k).im; } dptr = bump (dptr); } }
void WSCompand (WSCompander wsc) { int i, n = CXBsize (wsc->buff); //if (wsc->fac != 0.0) { for (i = 0; i < n ; i++) { COMPLEX val = CXBdata (wsc->buff, i); REAL mag = Cmag (val), scl = WSCLookup (wsc, mag); CXBdata (wsc->buff, i) = Cscl (val,scl); } } }
// 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; }
DttSP_EXP void PolyPhaseFIR (ResSt resst) /****************************************************************************** * CALLING PARAMETERS: * Name Use Description * ____ ___ ___________ * *input pointer to input COMPLEX data array * *output pointer to output COMPLEX data array * RealFIR filter pointer to filter coefficients array * *filterMemoryBuff pointer to buffer used as filter memory. Initialized * all data to 0 before 1st call. length is calculated * from numFiltTaps * filterMemoryBuffLength length of filterMemoryBuff * inputArrayLength length of input array :note that "output" may differ * in length * numFiltTaps number of filter taps in array "filtcoeff": <filterMemoryBuffLength * indexfiltMemBuf index to where next input sample is to be stored in * "filterMemoryBuff",initalized 0 to before first call * interpFactor interpolation factor: output rate = input rate * * "interpFactor" / "deciFactor". * filterPhaseNum filter phase number (index), initialized to 0 before * first call * deciFactor decimation factor: * output rate = (input rate * "interpFactor"/"deciFactor") * numOutputSamples number of output samples placed in array "output" * * CALLED BY: * * RETURN VALUE: * Name Description * ____ ___________ * none * * DESCRIPTION: This function is used to change the sampling rate of the data. * The input is first upsampled to a multiple of the desired * sampling rate and then down sampled to the desired sampling rate. * * Ex. If we desire a 7200 Hz sampling rate for a signal that has * been sampled at 8000 Hz the signal can first be upsampled * by a factor of 9 which brings it up to 72000 Hz and then * down sampled by a factor of 10 which results in a sampling * rate of 7200 Hz. * * NOTES: * Also, the "*filterMemoryBuff" MUST be 2^N REALs long. This * routine uses circular addressing on this buffer assuming that * it is 2^N REALs in length. * ******************************************************************************/ { /****************************************************************************** * LOCAL VARIABLE DECLARATIONS ******************************************************************************* * Type Name Description * ____ ____ ___________ */ int i, j, k, jj; /* counter variables */ COMPLEX *outptr; resst->numOutputSamples = 0; for (i = 0; i < resst->inputArrayLength; i++) { /* * save data in circular buffer */ resst->filterMemoryBuff[resst->indexfiltMemBuf] = resst->input[i]; j = resst->indexfiltMemBuf; jj = j; /* * circular addressing */ resst->indexfiltMemBuf = (resst->indexfiltMemBuf + 1) & resst->MASK; /* * loop through each filter phase: interpolate then decimate */ while (resst->filterPhaseNum < resst->interpFactor) { j = jj; /* output[*numOutputSamples] = 0.0; */ outptr = resst->output + resst->numOutputSamples; *outptr = cxzero; /* * perform convolution */ for (k = resst->filterPhaseNum; k < resst->numFiltTaps; k += resst->interpFactor) { /* output[*numOutputSamples] += filtcoeff[k]*filterMemoryBuff[j]; */ //*outptr += resst->filtcoeff[k]* resst->filterMemoryBuff[j]; *outptr = Cadd (*outptr, Cscl (resst->filterMemoryBuff[j], FIRtap (resst->filter, k))); /* * circular adressing */ j = (j + resst->MASK) & resst->MASK; } /* * scale the data */ /* output[*numOutputSamples]*=(REAL)interpFactor; */ *outptr = Cscl (*outptr, (REAL) resst->interpFactor); resst->numOutputSamples += 1; /* * increment interpolation phase # by decimation factor */ resst->filterPhaseNum += (resst->deciFactor); } /* end while *filterPhaseNum < interpFactor */ resst->filterPhaseNum -= resst->interpFactor; } /* end for inputArrayLength */ } /* end PolyPhaseFir */
void DttSPAgc (DTTSPAGC a, int tick) { int i; int hangtime = (int) (uni[0].samplerate * a->hangtime); // hangtime in samples int fasthangtime = (int) (uni[0].samplerate * a->fasthangtime); // fast track hangtime in samples REAL hangthresh; // gate for whether to hang or not // if (a->hangthresh > 0) hangthresh = a->gain.top * a->hangthresh + a->gain.bottom * (REAL) (1.0 - a->hangthresh); // else // hangthresh = 0.; if (a->mode == 0) { for (i = 0; i < CXBsize (a->buff); i++) CXBdata (a->buff, i) = Cscl (CXBdata (a->buff, i), a->gain.fix); return; } for (i = 0; i < CXBsize (a->buff); i++) { REAL tmp; a->circ[a->slowindx] = CXBdata (a->buff, i); /* Drop sample into circular buffer */ // first, calculate slow gain tmp = Cmag (a->circ[a->slowindx]); if (tmp > 0.0f) tmp = a->gain.target / tmp; // if mag(sample) not too small, calculate putative gain // all the rest of the code which follows is running this // signal through the control laws. else tmp = a->gain.now; // sample too small, just use old gain if (tmp < hangthresh) a->hangindex = hangtime; // If the gain is less than the current hang threshold, then stop hanging. if (tmp >= a->gain.now) // If the putative gain is greater than the current gain then we are in decay. // That is, we need to "decay the ALC voltage", or increase the gain. { //a->gain.raw = a->one_m_decay * a->gain.now + a->decay * tmp; if (a->hangindex++ > hangtime) // Have we HUNG around long enough? { a->gain.now = // Compute the applicable slow channel gain through the decay control law. a->one_m_decay * a->gain.now + a->decay * min (a->gain.top, tmp); } } else // if the putative gain is greater than the current gain, we are in attack mode and need to decrease gain { a->hangindex = 0; // We don't need to hang, we need to attack so we reset the hang index to zero //a->gain.raw = a->one_m_attack * a->gain.now + a->attack * tmp; a->gain.now = // Compute the applicable slow channel gain through the attack control law. a->one_m_attack * a->gain.now + a->attack * max (tmp, a->gain.bottom); } // then, calculate fast gain // Fast channel to handle short duration events and not capture the slow channel decay tmp = Cmag (a->circ[a->fastindx]); if (tmp > 0.0f) tmp = a->gain.target / tmp; // if mag(sample) not too small, calculate putative gain // all the rest of the code which follows is running this // signal through the control laws. else tmp = a->gain.fastnow; // too small, just use old gain if (tmp > a->gain.fastnow) // If the putative gain is greater than the current gain then we are in decay. // That is, we need to "decay the ALC voltage", or increase the gain. { if (a->fasthang++ > fasthangtime) // Have we HUNG around long enough? { a->gain.fastnow = // Compute the applicable fast channel gain through the decay control law. a->one_m_fastdecay * a->gain.fastnow + a->fastdecay * min (a->gain.top, tmp); } } else { a->fasthang = 0; // We don't need to hang, we need to attack so we reset the hang index to zero a->gain.fastnow = // Compute the applicable fast channel gain through the fast attack control law. a->one_m_fastattack * a->gain.fastnow + a->fastattack * max (tmp, a->gain.bottom); } // Are these two lines necessary? I don't think so. Let's test that. tmp is bounded in the statements // above to be inside the gain limits // a->gain.fastnow = // max (min (a->gain.fastnow, a->gain.top), a->gain.bottom); // a->gain.now = max (min (a->gain.now, a->gain.top), a->gain.bottom); // Always apply the lower gain. CXBdata (a->buff, i) = Cscl (a->circ[a->out_indx], min (a->gain.fastnow, (a->slope * a->gain.now))); // Move the indices to prepare for the next sample to be processed a->slowindx = (a->slowindx + a->mask) & a->mask; a->out_indx = (a->out_indx + a->mask) & a->mask; a->fastindx = (a->fastindx + a->mask) & a->mask; } }
void DttSPAgc (DTTSPAGC a, int tick) { int i; int hangtime = (int) (uni[0].samplerate * a->hangtime); int fasthangtime = (int) (uni[0].samplerate * a->fasthangtime); REAL hangthresh; if (a->hangthresh > 0) hangthresh = a->gain.top * a->hangthresh + a->gain.bottom * (REAL) (1.0 - a->hangthresh); else hangthresh = 0.; if (a->mode == 0) { for (i = 0; i < CXBsize (a->buff); i++) CXBdata (a->buff, i) = Cscl (CXBdata (a->buff, i), a->gain.fix); return; } for (i = 0; i < CXBsize (a->buff); i++) { REAL tmp; a->circ[a->indx] = CXBdata (a->buff, i); /* Drop sample into circular buffer */ tmp = Cmag (a->circ[a->indx]); if (tmp > 0.00000005f) tmp = a->gain.limit / tmp; // if not zero sample, calculate gain else tmp = a->gain.now; // update. If zero, then use old gain if (tmp < hangthresh) a->hangindex = hangtime; if (tmp >= a->gain.now) { //a->gain.raw = a->one_m_decay * a->gain.now + a->decay * tmp; if (a->hangindex++ > hangtime) { a->gain.now = a->one_m_decay * a->gain.now + a->decay * min (a->gain.top, tmp); } } else { a->hangindex = 0; //a->gain.raw = a->one_m_attack * a->gain.now + a->attack * tmp; a->gain.now = a->one_m_attack * a->gain.now + a->attack * max (tmp, a->gain.bottom); } tmp = Cmag (a->circ[a->fastindx]); if (tmp > 0.00000005f) tmp = a->gain.limit / tmp; else tmp = a->gain.fastnow; if (tmp > a->gain.fastnow) { if (a->fasthang++ > fasthangtime) { a->gain.fastnow = min (a->one_m_fastdecay * a->gain.fastnow + a->fastdecay * min (a->gain.top, tmp), a->gain.top); } } else { a->fasthang = 0; a->gain.fastnow = max (a->one_m_fastattack * a->gain.fastnow + a->fastattack * max (tmp, a->gain.bottom), a->gain.bottom); } a->gain.fastnow = max (min (a->gain.fastnow, a->gain.top), a->gain.bottom); a->gain.now = max (min (a->gain.now, a->gain.top), a->gain.bottom); CXBdata (a->buff, i) = Cscl (a->circ[a->sndx], min (a->gain.fastnow, min (a->slope * a->gain.now, a->gain.top))); a->indx = (a->indx + a->mask) & a->mask; a->sndx = (a->sndx + a->mask) & a->mask; a->fastindx = (a->fastindx + a->mask) & a->mask; } }
DttSP_EXP void Audio_Callback2 (float **input, float **output, unsigned int nframes) { unsigned int thread; BOOLEAN b = reset_em; BOOLEAN return_empty=FALSE; unsigned int i; for(thread=0;thread<threadno;thread++) { if (top[thread].susp) return_empty = TRUE; } if (return_empty) { for(thread=0;thread<threadno;thread++) { memset (output[2*thread], 0, nframes * sizeof (float)); memset (output[2*thread+1], 0, nframes * sizeof (float)); } return; } if (b) { //fprintf(stderr, "reset_em!\n"); fflush(stderr); //fprintf(stdout,"Audio_Callback2: reset_em = TRUE\n"), fflush(stdout); reset_system_audio(nframes); for(thread=0;thread<threadno;thread++) { memset (output[2*thread], 0, nframes * sizeof (float)); memset (output[2*thread+1], 0, nframes * sizeof (float)); } return; } #if 0 if (diversity.flag) { // Deal with the transmitter first if ((ringb_float_read_space (top[1].jack.ring.o.l) >= nframes) && (ringb_float_read_space (top[1].jack.ring.o.r) >= nframes)) { ringb_float_read (top[1].jack.ring.o.l, output[2], nframes); ringb_float_read (top[1].jack.ring.o.r, output[3], nframes); } else { // rb pathology //reset_system_audio(nframes); for(thread=0;thread<threadno;thread++) { memset (output[thread], 0, nframes * sizeof (float)); memset (output[thread], 0, nframes * sizeof (float)); } return; } // input: copy from port to ring if ((ringb_float_write_space (top[1].jack.ring.i.l) >= nframes) && (ringb_float_write_space (top[1].jack.ring.i.r) >= nframes)) { ringb_float_write (top[1].jack.ring.i.l, input[2], nframes); ringb_float_write (top[1].jack.ring.i.r, input[3], nframes); } else { // rb pathology for(thread=0;thread<threadno;thread++) { memset (output[thread], 0, nframes * sizeof (float)); memset (output[thread], 0, nframes * sizeof (float)); } return; } // if enough accumulated in ring, fire dsp if ((ringb_float_read_space (top[1].jack.ring.i.l) >= top[1].hold.size.frames) && (ringb_float_read_space (top[1].jack.ring.i.r) >= top[1].hold.size.frames)) sem_post (&top[1].sync.buf.sem); // // Deal with the diversity channel next // if ((ringb_float_read_space (top[0].jack.ring.o.l) >= nframes) && (ringb_float_read_space (top[0].jack.ring.o.r) >= nframes)) { /*ringb_float_read (top[thread].jack.auxr.o.l, output[l], nframes); ringb_float_read (top[thread].jack.auxr.o.r, output[r], nframes);*/ ringb_float_read (top[0].jack.ring.o.l, output[2], nframes); ringb_float_read (top[0].jack.ring.o.r, output[3], nframes); } else { // rb pathology //reset_system_audio(nframes); for(thread=0;thread<threadno;thread++) { memset (output[thread], 0, nframes * sizeof (float)); memset (output[thread], 0, nframes * sizeof (float)); } return; } // Deal with the diversity/phased array channel next // input: copy from port to ring if ((ringb_float_write_space (top[0].jack.ring.i.l) >= nframes) && (ringb_float_write_space (top[0].jack.ring.i.r) >= nframes) && (ringb_float_write_space (top[2].jack.ring.i.l) >= nframes) && (ringb_float_write_space (top[2].jack.ring.i.r) >= nframes)) { REAL *l0 = input[0]; REAL *r0 = input[1]; REAL *l2 = input[4]; REAL *r2 = input[5]; for (i=0;i<nframes;i++) { COMPLEX A = Cmplx(l0[i],r0[i]); COMPLEX B = Cmplx(l2[i],r2[i]); A = Cscl(Cadd(A,Cmul(B,diversity.scalar)),diversity.gain); ringb_float_write (top[0].jack.ring.i.l, &A.re, 1); ringb_float_write (top[0].jack.ring.i.r, &A.im, 1); } /*ringb_float_write (top[thread].jack.auxr.i.l, input[l], nframes); ringb_float_write (top[thread].jack.auxr.i.r, input[r], nframes);*/ } else { // rb pathology //reset_system_audio(nframes); for(thread=0;thread<threadno;thread++) { memset (output[thread], 0, nframes * sizeof (float)); memset (output[thread], 0, nframes * sizeof (float)); } return; } // if enough accumulated in ring, fire dsp if ((ringb_float_read_space (top[0].jack.ring.i.l) >= top[0].hold.size.frames) && (ringb_float_read_space (top[0].jack.ring.i.r) >= top[0].hold.size.frames)) sem_post (&top[0].sync.buf.sem); // // Deal with 2nd receiver channel now // if ((ringb_float_read_space (top[2].jack.ring.o.l) >= nframes) && (ringb_float_read_space (top[2].jack.ring.o.r) >= nframes)) { /*ringb_float_read (top[thread].jack.auxr.o.l, output[l], nframes); ringb_float_read (top[thread].jack.auxr.o.r, output[r], nframes);*/ ringb_float_read (top[2].jack.ring.o.l, output[4], nframes); ringb_float_read (top[2].jack.ring.o.r, output[5], nframes); } else { // rb pathology //reset_system_audio(nframes); for(thread=0;thread<threadno;thread++) { memset (output[thread], 0, nframes * sizeof (float)); memset (output[thread], 0, nframes * sizeof (float)); } return; } // input: copy from port to ring if ((ringb_float_write_space (top[2].jack.ring.i.l) >= nframes) && (ringb_float_write_space (top[2].jack.ring.i.r) >= nframes)) { ringb_float_write (top[2].jack.ring.i.l, input[4], nframes); ringb_float_write (top[2].jack.ring.i.r, input[5], nframes); } else { // rb pathology for(thread=0;thread<threadno;thread++) { memset (output[thread], 0, nframes * sizeof (float)); memset (output[thread], 0, nframes * sizeof (float)); } return; } // if enough accumulated in ring, fire dsp if ((ringb_float_read_space (top[2].jack.ring.i.l) >= top[2].hold.size.frames) && (ringb_float_read_space (top[2].jack.ring.i.r) >= top[2].hold.size.frames)) sem_post (&top[2].sync.buf.sem); } else #endif for(thread=0; thread<threadno; thread++) { int l=2*thread, r = 2*thread+1; if ((ringb_float_read_space (top[thread].jack.ring.o.l) >= nframes) && (ringb_float_read_space (top[thread].jack.ring.o.r) >= nframes)) { /*ringb_float_read (top[thread].jack.auxr.o.l, output[l], nframes); ringb_float_read (top[thread].jack.auxr.o.r, output[r], nframes);*/ ringb_float_read (top[thread].jack.ring.o.l, output[l], nframes); ringb_float_read (top[thread].jack.ring.o.r, output[r], nframes); } else { // rb pathology //reset_system_audio(nframes); for(thread=0;thread<threadno;thread++) { memset (output[2*thread ], 0, nframes * sizeof (float)); memset (output[2*thread+1], 0, nframes * sizeof (float)); } return; } // input: copy from port to ring if ((ringb_float_write_space (top[thread].jack.ring.i.l) >= nframes) && (ringb_float_write_space (top[thread].jack.ring.i.r) >= nframes)) { if (diversity.flag && (thread == 0)) { if ((ringb_float_write_space (top[2].jack.ring.i.l) >= nframes) && (ringb_float_write_space (top[2].jack.ring.i.r) >= nframes)) { REAL *l0 = input[0]; REAL *r0 = input[1]; REAL *l2 = input[4]; REAL *r2 = input[5]; for (i=0;i<nframes;i++) { COMPLEX A = Cmplx(l0[i],r0[i]); COMPLEX B = Cmplx(l2[i],r2[i]); A = Cscl(Cadd(A,Cmul(B,diversity.scalar)),diversity.gain); ringb_float_write (top[0].jack.ring.i.l, &A.re, 1); ringb_float_write (top[0].jack.ring.i.r, &A.im, 1); } /*ringb_float_write (top[thread].jack.auxr.i.l, input[l], nframes); ringb_float_write (top[thread].jack.auxr.i.r, input[r], nframes);*/ } else { // rb pathology //reset_system_audio(nframes); for(thread=0;thread<threadno;thread++) { memset (output[2*thread ], 0, nframes * sizeof (float)); memset (output[2*thread+1], 0, nframes * sizeof (float)); } return; } } else { ringb_float_write (top[thread].jack.ring.i.l, input[l], nframes); ringb_float_write (top[thread].jack.ring.i.r, input[r], nframes); /*ringb_float_write (top[thread].jack.auxr.i.l, input[l], nframes); ringb_float_write (top[thread].jack.auxr.i.r, input[r], nframes);*/ } } else { // rb pathology //reset_system_audio(nframes); for(thread=0;thread<threadno;thread++) { memset (output[2*thread ], 0, nframes * sizeof (float)); memset (output[2*thread+1], 0, nframes * sizeof (float)); } return; } // if enough accumulated in ring, fire dsp if ((ringb_float_read_space (top[thread].jack.ring.i.l) >= top[thread].hold.size.frames) && (ringb_float_read_space (top[thread].jack.ring.i.r) >= top[thread].hold.size.frames)) sem_post (&top[thread].sync.buf.sem); } }