Пример #1
0
DTTSPAGC
newDttSPAgc (AGCMODE mode,
			 COMPLEX * Vec,
			 int BufSize,
			 REAL Limit,
			 REAL attack,
			 REAL decay,
			 REAL slope,
			 REAL hangtime,
			 REAL samprate,
			 REAL MaxGain, REAL MinGain, REAL CurGain, char *tag)
{
	DTTSPAGC a;

	a = (DTTSPAGC) safealloc (1, sizeof (dttspagc), tag);
	a->mode = mode;

	a->attack = (REAL) (1.0 - exp (-1000.0 / (attack * samprate)));
	a->one_m_attack = (REAL) exp (-1000.0 / (attack * samprate));

	a->decay = (REAL) (1.0 - exp (-1000.0 / (decay * samprate)));
	a->one_m_decay = (REAL) exp (-1000.0 / (decay * samprate));

	a->fastattack = (REAL) (1.0 - exp (-1000.0 / (0.2 * samprate)));
	a->one_m_fastattack = (REAL) exp (-1000.0 / (0.2 * samprate));

	a->fastdecay = (REAL) (1.0 - exp (-1000.0 / (3.0 * samprate)));
	a->one_m_fastdecay = (REAL) exp (-1000.0 / (3.0 * samprate));

	strcpy (a->tag, tag);
	a->mask = 2 * BufSize;

	a->hangindex = a->indx = 0;
	a->hangtime = hangtime * 0.001f;
	a->hangthresh = 0.0;
	a->sndx = (int) (samprate * attack * 0.003f);
	a->fastindx = (int)(0.002f*samprate);
	a->gain.fix = 10.0;

	a->slope = slope;
	a->gain.top = MaxGain;
	a->hangthresh = a->gain.bottom = MinGain;
	a->gain.fastnow = a->gain.old = a->gain.now = CurGain;

	a->gain.limit = Limit;

	a->buff = newCXB (BufSize, Vec, "agc in buffer");
	a->circ = newvec_COMPLEX (a->mask, "circular agc buffer");
	a->mask -= 1;

	a->fasthang = 0;
	a->fasthangtime = 0.1f*a->hangtime;

	return a;
}
Пример #2
0
BLMS
new_blms (CXB signal, REAL adaptation_rate, REAL leak_rate, int filter_type,
	  int pbits)
{
  BLMS tmp;
  tmp = (BLMS) safealloc (1, sizeof (_blocklms), "block lms");
  tmp->delay_line = newvec_COMPLEX (256, "block lms delay line");
  tmp->y = newvec_COMPLEX (256, "block lms output signal");
  tmp->Yhat = newvec_COMPLEX (256, "block lms output transform");
  tmp->Errhat = newvec_COMPLEX (256, "block lms Error transform");
  tmp->error = newvec_COMPLEX (256, "block lms Error signal");
  tmp->Xhat = newvec_COMPLEX (256, "block lms signal transform");
  tmp->What = newvec_COMPLEX (256, "block lms filter transform");
  tmp->Update = newvec_COMPLEX (256, "block lms update transform");
  tmp->update = newvec_COMPLEX (256, "block lms update signal");
  tmp->adaptation_rate = adaptation_rate;
  tmp->leak_rate = 1.0f - leak_rate;
  tmp->signal = signal;
  tmp->filter_type = filter_type;
  tmp->Xplan = fftwf_plan_dft_1d (256,
				  (fftwf_complex *) tmp->delay_line,
				  (fftwf_complex *) tmp->Xhat,
				  FFTW_FORWARD, pbits);

  tmp->Yplan = fftwf_plan_dft_1d (256,
				  (fftwf_complex *) tmp->Yhat,
				  (fftwf_complex *) tmp->y,
				  FFTW_BACKWARD, pbits);

  tmp->Errhatplan = fftwf_plan_dft_1d (256,
				       (fftwf_complex *) tmp->error,
				       (fftwf_complex *) tmp->Errhat,
				       FFTW_FORWARD, pbits);
  tmp->UPDplan = fftwf_plan_dft_1d (256,
				    (fftwf_complex *) tmp->Errhat,
				    (fftwf_complex *) tmp->update,
				    FFTW_BACKWARD, pbits);
  tmp->Wplan = fftwf_plan_dft_1d (256,
				  (fftwf_complex *) tmp->update,
				  (fftwf_complex *) tmp->Update,
				  FFTW_FORWARD, pbits);
  return tmp;
}
Пример #3
0
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_COMPLEX (lms->size, "lmsr delay");
  lms->adaptation_rate = adaptation_rate;
  lms->leakage = leakage;
  lms->adaptive_filter_size = adaptive_filter_size;
  lms->adaptive_filter = newvec_COMPLEX (128, "lmsr filter");
  lms->filter_type = filter_type;
  lms->delay_line_ptr = 0;

  return lms;
}
Пример #4
0
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;
}
Пример #5
0
DTTSPAGC
newDttSPAgc (AGCMODE mode,
			 COMPLEX *Vec,
			 int BufSize,   // Size of the input buffer
			 REAL target,   // The target voltage
			 REAL attack,   // Attack time constant in msec
			 REAL decay,    // Decay time constant in msec
			 REAL slope,    // Rate of change of gain after agc threshold is exceeded
			 REAL hangtime, // Hang Time in msec where NO decay is allowed in the agc
			 REAL samprate, // Sample Rate so time can be turned into sample number
			 REAL MaxGain,  // Maximum allowable gain
			 REAL MinGain,  // Minimum gain (can be -dB / less than 1.0 as in ALC or strong signals on receive
			 REAL CurGain,  // The initial gain setting
			 char *tag)     // String to emit when error conditions occur
{
	DTTSPAGC a;

	a = (DTTSPAGC) safealloc (1, sizeof (dttspagc), tag);
	a->mode = mode;

	// Attack: decrease gain when input signal will produce an output signal above the target voltage
	// Decay:  increase gain when input signal will produce an output signal below the target voltage
	
	// Compute exponential attack rate per sample from attack time and sampler rate.
	a->attack = (REAL) (1.0 - exp (-1000.0 / (attack * samprate))); 
	// Compute 1.0 - attack time.
	a->one_m_attack = (REAL) (1.0 - a->attack);

	// Compute exponential decay rate per sample from attack time and sampler rate.
	a->decay = (REAL) (1.0 - exp (-1000.0 / (decay * samprate)));
	// Compute 1.0 - decay time.
	a->one_m_decay = (REAL) (1.0 - a->decay);

	// Our system has a two track agc response.  The normal one found in most receive
	// systems is the determined from the calculations we just made.
	// Ours has a fast track agc which is designed to prevent large pulse signals from pushing
	// us into serious attack and wait for a long decay when the signal is short duration < 3 time constants for attack

	// Compute exponential fast attack rate per sample from fast attack time and sampler rate.
	a->fastattack = (REAL) (1.0 - exp (-1000.0 / (0.2 * samprate)));
	// Compute 1.0 - fast attack time.
	a->one_m_fastattack = (REAL) (1.0 - a->fastattack);

	// Compute exponential fast decay rate per sample from fast attack time and sampler rate.
	a->fastdecay = (REAL) (1.0 - exp (-1000.0 / (3.0 * samprate)));
	// Compute 1.0 - fast decay time.
	a->one_m_fastdecay = (REAL) (1.0 - a->fastdecay);

	// Save the error identification message
	strcpy (a->tag, tag);

	// This computes the index max for our circular buffer
	a->mask = 2 * BufSize - 1;
	
	// Hangtime:  This is a period of NO allowed decay even though we need to increase gain to stay at target level
	// hangindex is used to compute how deep into the hang interval we are.
	a->hangindex = a->slowindx = 0;
	// Change hang time to hang length in samples using time and sample rate.
	a->hangtime = hangtime * 0.001f;
	//a->hangthresh = 0.0; // not neccessary?
	// We BEGIN applying decreasing gain 3 time constants ahead of the signals arrival to narrow the modulation
	// spread arising from modulating the signal with the agc gain.  The index to application of computed gain
	// sndx and it is computed as number of samples in 3 attack time constants
	a->out_indx = (int) (samprate * attack * 0.003f);

	// We do the same anticipation in the fast channel but we only do two time constants.
	a->fastindx = (int)(0.0027f*samprate);
	// see update.c:SetRAGC()
	a->gain.fix = 10000.0;

	// Slope:  The rate at which gain is decreased as signal strength increases after it exceeds the agc threshold
	// that is, after the required gain to reach the desired output level is LESS THAN the maximum allowable gain.
	a->slope = slope;

	// gain.top = Maxgain which is the maximum allowable gain.  This determines the agc threshold
	a->gain.top = MaxGain;
	// gain.bottom = MinGain is the minimum allowable gain.  If < 0dB or 1.0, then this is an attenuation.
	a->hangthresh = a->gain.bottom = MinGain;
	// Initialize the gain state to an initial value
	a->gain.fastnow = a->gain.old = a->gain.now = CurGain;

	// Set the target voltage.
	a->gain.target = target;

	// Given the vector of input samples,  make a local complex buffer (struct to handle metadata associated with
	// the vector or array of samples
	a->buff = newCXB (BufSize, Vec, "agc in buffer");
	// Use a circular buffer for efficiency in dealing with the anticipatory part of the agc algorithm
	a->circ = newvec_COMPLEX (2 * BufSize, "circular agc buffer");

	// intialize fast hang index to 0
	a->fasthang = 0;

	// Whatever the hangtime is for the slow channel, make the fast agc channel hangtime 10% of it
	a->fasthangtime = 0.1f*a->hangtime;

	return a;
}
Пример #6
0
FiltOvSv
newFiltOvSv(COMPLEX * coefs, int ncoef, int pbits) {
  int buflen, fftlen;
  FiltOvSv p;
  fftwf_plan pfwd, pinv;
  COMPLEX *zrvec, *zfvec, *zivec, *zovec;
  p = (FiltOvSv) safealloc(1, sizeof(filt_ov_sv), "new overlap/save filter");
  buflen = nblock2(ncoef - 1), fftlen = 2 * buflen;
  zrvec = newvec_COMPLEX_fftw(fftlen, "raw signal vec in newFiltOvSv");
  zfvec = newvec_COMPLEX_fftw(fftlen, "filter z vec in newFiltOvSv");
  zivec = newvec_COMPLEX_fftw(fftlen, "signal in z vec in newFiltOvSv");
  zovec = newvec_COMPLEX_fftw(fftlen, "signal out z vec in newFiltOvSv");

  /* prepare frequency response from filter coefs */
  {
    int i;
    COMPLEX *zcvec;
    fftwf_plan ptmp;

    zcvec = newvec_COMPLEX(fftlen, "temp filter z vec in newFiltOvSv");
    //ptmp = fftw_create_plan(fftlen, FFTW_FORWARD, pbits);
    ptmp =
      fftwf_plan_dft_1d(fftlen, (fftwf_complex *) zcvec,
			(fftwf_complex *) zfvec, FFTW_FORWARD, pbits);

#ifdef LHS
    for (i = 0; i < ncoef; i++)
      zcvec[i] = coefs[i];
#else
    for (i = 0; i < ncoef; i++)
      zcvec[fftlen - ncoef + i] = coefs[i];
#endif

    //fftw_one(ptmp, (fftw_complex *) zcvec, (fftw_complex *) zfvec);
    fftwf_execute(ptmp);
    fftwf_destroy_plan(ptmp);
    delvec_COMPLEX(zcvec);
  }

  /* prepare transforms for signal */
  //pfwd = fftw_create_plan(fftlen, FFTW_FORWARD, pbits);
  //pinv = fftw_create_plan(fftlen, FFTW_BACKWARD, pbits);
  pfwd = fftwf_plan_dft_1d(fftlen, (fftwf_complex *) zrvec,
			   (fftwf_complex *) zivec,
			   FFTW_FORWARD,
			   pbits);
  pinv = fftwf_plan_dft_1d(fftlen, (fftwf_complex *) zivec,
			   (fftwf_complex *) zovec,
			   FFTW_BACKWARD,
			   pbits);
  /* stuff values */
  p->buflen = buflen;
  p->fftlen = fftlen;
  p->zfvec = zfvec;
  p->zivec = zivec;
  p->zovec = zovec;
  p->zrvec = zrvec;
  p->pfwd = pfwd;
  p->pinv = pinv;
  p->scale = 1.0f / (REAL) fftlen;
  normalize_vec_COMPLEX (p->zfvec, p->fftlen, p->scale);
  return p;
}