Beispiel #1
0
/* ----------------------------------------------------------------------- */
float *downsample(float *input, int samsin, int state_idx, double freq,
                  int *samsout, int decimate, int first_time, int last_time)
{
  static float	b[2048];
  static float *foutput = NULL;
  float	beta = 0.0f;
  static int	ncoeff = 127, ncoefft = 0;
  int init;

  if(input && (samsin > 0) && (decimate > 0) && *samsout) {
    if(decimate == 1) {
      return(input);
    }

    if(first_time){
      int nbuff = (samsin/decimate) + (2*ncoeff);

      ncoeff = ((int)(freq * .005)) | 1;
      beta = .5f/decimate;
      foutput =
          (float *) realloc((void *) foutput, sizeof(float) * nbuff);
      for( ; nbuff > 0 ;)
	foutput[--nbuff] = 0.0;

      if( !lc_lin_fir(beta,&ncoeff,b)) {
	fprintf(stderr,"\nProblems computing interpolation filter\n");
	free((void *) foutput);
	return(NULL);
      }
      ncoefft = (ncoeff/2) + 1;
    }		    /*  endif new coefficients need to be computed */

    if(first_time) init = 1;
    else if (last_time) init = 2;
    else init = 0;

    if(downsamp(input,foutput,samsin,samsout,state_idx,decimate,ncoefft,b,init)) {
      return(foutput);
    } else
      Fprintf(stderr,"Problems in downsamp() in downsample()\n");
  }

  return(NULL);
}
Beispiel #2
0
/* ----------------------------------------------------------------------- */
void FdFilter::FdFilterInitialize(float inFreq, float cFreq, int doHp, float fDur, int convertF,
			char *specShape, float *specArray, int nMagnitudes)
{
  float	beta = 0.0, *b = NULL;
  float  ratio_t, ratio, freq1=inFreq;
  int pow2, i;

  insert = 1;
  decimate = 1;
  state = 1;
  arrayLeftover = 0;
  arrayIndex = 0;
  arraySamplesUsed = 0;
  trueOutputFreq = inFreq;

  if(specShape || (specArray && (nMagnitudes > 1))) {
    doHp = -1; /* flag that this is an equalization filtering */
  } else {
    if(convertF) {
      freq1 = inFreq;
    } else {			/* it is just a symmetric FIR */
      if(cFreq >= (freq1 = inFreq)/2.0) {
	fprintf(stderr,"Unreasonable corner frequency specified to filter() (%f)\n",cFreq);
      }
    }
  }

  if(specShape) {
    FILE *specStream = fopen(specShape, "r");

    if(specStream) {
      int nSpect, ind;
      char line[500];
      float fs;
      if(fgets(line,500, specStream)) {
	int nItems = sscanf(line,"%d %d %f", &pow2, &nSpect, &fs);
	if((nItems == 3) && (fs != inFreq)) { // This should be a fatal error
	  fprintf(stderr,"Filter spec (%f) does not match input frequency (%f)\n",fs,inFreq);
	  fprintf(stderr,"The filtering results will probably not be what you want!\n");
	}
	b = new float [nSpect];
	nCoeff = (nSpect - 1); /* represents actual filter-kernel length,
				  instead of half filter length
				  when using externsl filter. */
	for(i=0; i < nSpect; i++) {
	  if((! fgets(line,500,specStream)) ||
	     (sscanf(line,"%d %f", &ind, &(b[i])) != 2)) {
	    fprintf(stderr, "Parsing error in spect ratio file %s\n",specShape);
	  }
	}
      } else {
	fprintf(stderr,"Bad format in spectrum file %s\n", specShape);
      }
      fclose(specStream);
    } else {
      fprintf(stderr,"Can't open %s as a spectrum file\n",specShape);
    }
  } else
    if( specArray && (nMagnitudes > 1)) { // Note: nMagnitudes MUST be ((2^k)+1) for k > 1.
      nCoeff = nMagnitudes - 1;
      int nft = nCoeff * 2;
      pow2 = 1;
      while( (1 << pow2) < nft) {
	pow2++;
      }
      b = specArray; // Note: b must not be deleted in this case!
    } else { /* it is not an eq filter */
      if(convertF) {
	/* get a ratio of integers close to desired freq. ratio. */
	ratio = cFreq/freq1;
	ratprx(ratio,&insert,&decimate,FD_MAX_DECIMATE);
	ratio_t = ((float)insert)/((float)decimate);
    
	if(fabs(1.0-ratio_t) < .01) {
	  fprintf(stderr,"Input and output frequencies are essentially equal!\n");
	}
    
	trueOutputFreq = ratio_t * freq1;
	//	if(cFreq != trueOutputFreq) {
	//	  fprintf(stderr,
	//		  "Warning: The output frequency obtained (%f) is not the frequency requested (%f)\n",
	//		  trueOutputFreq, cFreq);
	//	}
	cFreq = trueOutputFreq;
	nCoeff = ((int)(freq1 * insert * fDur)) | 1;
	if(cFreq < freq1)
	  beta = (.5 * cFreq)/(insert * freq1);
	else
	  beta = .5/insert;
      } else {
	beta = cFreq/freq1;
	nCoeff = ((int)(freq1 * fDur)) | 1;
      }

      /* Generate the symmetric FIR filter coefficients. */
      b = new float [1 + nCoeff/2];
      lc_lin_fir(beta,&nCoeff,b);

      if(insert > 1) { /* scale up filter coeffs. to maintain precision in output */
	float fact = (float)insert;
	for(i=nCoeff/2; i>=0; i--) b[i] *= fact;
      }
    } /* end else it is not an eq filter */

  nCoeffBy2 = nCoeff/2;

  if(doHp >= 0) { /* Is it a simple high- or low-pass filter? */
    mirror_filter(b,doHp);
    int nf2 = nCoeff << 1;
    nFFT = 128;
    pow2 = 7;
    while(nf2 > nFFT) {
      nFFT *= 2;
      pow2++;
    }
  } else { /* it is a filter with the magnitude response specified in b. */
    nFFT = nCoeff * 2;
    pow2 = 2;
    while((1 << pow2) < nFFT)
      pow2++;
  }

  nFFTBy2 = nFFT/2;

  x = new float [nFFT];
  y = new float [nFFT];
  xf = new float [nFFT];
  yf = new float [nFFT];

  leftovers = new short [nFFT];
  maxInput = FD_FBUF_SIZE/insert;
  outputDelayed = new float [FD_FBUF_SIZE+nCoeff+nFFT];

  float ftscale = 1.0/(float)nFFT;
  ft = new FFT(pow2);
  if(doHp >= 0) {
    /* position the filter kernel to be symmetric about time=0 */
    /* Note that this assumes an odd number of symmetric filter coefficients. */
    for(i=0; i <= nCoeffBy2; i++) {
      xf[i] = ftscale * fCoeff[i+nCoeffBy2];
      yf[i] = 0.0;
    }
    for( ; i < nCoeff; i++) {
      xf[nFFT - nCoeff + i] = ftscale * fCoeff[i-nCoeffBy2-1];
      yf[nFFT - nCoeff + i] = 0.0;
    }
    for(i=nCoeffBy2 ;i < (nFFT-nCoeffBy2);i++)
      xf[i] = yf[i] = 0.0;
    ft->fft(xf,yf);
  } else { /* Install the magnitude response symmetrically. */
    for(i=0; i <= nCoeff; i++) {
      xf[i] = ftscale * b[i];
      yf[i] = 0.0;
    }
    for( ; i < nFFT; i++) {
      xf[i] = xf[nFFT - i];
      yf[i] = 0.0;
    }
  }
  /* The filter, regardless of origin, is now in the frequency domain. */

  if(specShape && !( specArray && (nMagnitudes > 1)))
    delete b;

  b = NULL;
  filterMode = doHp;
}