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; } }
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); } } }
WSCompander newWSCompander (int npts, REAL fac, CXB buff) { WSCompander wsc; wsc = (WSCompander) safealloc (1, sizeof (WSCompanderInfo), "WSCompander struct"); wsc->npts = npts; wsc->nend = npts - 1; wsc->tbl = newvec_REAL (npts, "WSCompander table"); wsc->buff = newCXB (CXBsize (buff), CXBbase (buff), "WSCompander buff"); WSCReset (wsc, fac); return wsc; }
CXB newCXB (int size, COMPLEX * base, char *tag) { CXB p = (CXB) safealloc (1, sizeof (CXBuffer), tag); if (base) { CXBbase (p) = base; CXBmine (p) = FALSE; } else { CXBbase (p) = newvec_COMPLEX (size, "newCXB"); CXBmine (p) = TRUE; } CXBsize (p) = CXBwant (p) = size; CXBovlp (p) = CXBhave (p) = CXBdone (p) = 0; return p; }
void noiseblanker (NB nb) { int i; for (i = 0; i < CXBsize (nb->sigbuf); i++) { REAL cmag = Cmag (CXBdata (nb->sigbuf, i)); nb->delay[nb->sigindex] = CXBdata (nb->sigbuf, i); nb->average_mag = (REAL) (0.999 * (nb->average_mag) + 0.001 * cmag); if ((nb->hangtime == 0) && (cmag > (nb->threshold * nb->average_mag))) nb->hangtime = 7; if (nb->hangtime > 0) { CXBdata (nb->sigbuf, i) = Cmplx (0.0, 0.0); nb->hangtime--; } else CXBdata (nb->sigbuf, i) = nb->delay[nb->delayindex]; nb->sigindex = (nb->sigindex + 7) & 7; nb->delayindex = (nb->delayindex + 7) & 7; } }
LMSR new_lmsr (CXB signal, int delay, REAL adaptation_rate, REAL leakage, int adaptive_filter_size, int filter_type) { LMSR lms = (LMSR) safealloc (1, sizeof (_lmsstate), "new_lmsr state"); lms->signal = signal; lms->signal_size = CXBsize (lms->signal); lms->delay = delay; lms->size = 512; lms->mask = lms->size - 1; lms->delay_line = newvec_REAL (lms->size, "lmsr delay"); lms->adaptation_rate = adaptation_rate; lms->leakage = leakage; lms->adaptive_filter_size = adaptive_filter_size; lms->adaptive_filter = newvec_REAL (128, "lmsr filter"); lms->filter_type = filter_type; lms->delay_line_ptr = 0; return lms; }
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; } }