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;
    }
}
Exemple #2
0
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);
		}
	}
}
Exemple #3
0
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;
}
Exemple #7
0
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;
	}
}