0
$\begingroup$

I'm creating a program in order to perform Resample, Interpolation and Decimation Frequency.

Resample Method

  public static double[] getResampleFIR(int L, int M, String windowType, double freqPass, double sampleFreq) {
    double freqStop = 0.5 * sampleFreq;
    if (L > M) {
      freqStop = sampleFreq / (2.0);
      if (!(freqStop > freqPass)) {
        throw new IllegalArgumentException("Invalid value for fPass: fPass must be lower than 0.5*SamplingRate");
      }
    }
    if (M > L) {
      freqStop = 0.5 * (sampleFreq * L) / M;
      if (!(freqStop > freqPass)) {
        throw new IllegalArgumentException("Invalid value for fPass: fPass must be lower than 0.5*SamplingRate*L/M");
      }
    }

    Integer size = getIntUpOdd((int) Math.ceil(3.3 / ((freqStop - freqPass) / (sampleFreq * L))));
    double fc = (freqPass + freqStop) / 2.0;
    double auxSampleFreq = Math.max(sampleFreq, sampleFreq * L / M);
    double outSampleFreq = sampleFreq * L / M;
    System.out.println("L:" + L + ", M:" + M + ", sampleFreq:" + sampleFreq 
      + ", outSampleFreq:" + outSampleFreq + ", auxSampleFreq:" + auxSampleFreq 
      + ", freqPass:" + freqPass + ", freqStop:" + freqStop + ", fc:" + fc + ", size:" + size + "\n");

    return getLowPass(size, fc / auxSampleFreq); // <-- DOUBT HERE!!!
  }

Increment Method

  public static double[] getIncrementFIR(int L, double freqPass, double sampleFreq) {
    double freqStop = 0.5 * sampleFreq; //Min Value
    if (!(freqStop > freqPass)) {
      throw new IllegalArgumentException("Invalid value for fPass: fPass must be lower than 0.5*SamplingRate");
    }
    Integer size = getIntUpOdd((int) Math.ceil(3.3 / ((freqStop - freqPass) / (sampleFreq * L))));
    double fc = (freqPass + freqStop) / 2.0;
    return getLowPass(size, fc / (sampleFreq * L));
  }

Decrement Method

  public static double[] getDecrementFIR(int M, double freqPass, double sampleFreq) {
    double freqStop = 0.5 * sampleFreq / M; //Min Value
    if (!(freqStop > freqPass)) {
      throw new IllegalArgumentException("Invalid value for fPass: fPass must be lower than 0.5*SamplingRate/M");
    }
    Integer size = getIntUpOdd((int) Math.ceil(3.3 / ((freqStop - freqPass) / (sampleFreq))));
    double fc = (freqPass + freqStop) / 2.0;
    return getLowPass(size, fc / sampleFreq);
  }

Low Pass Filter Method

  public static double[] getLowPass(int size, String windowType, double normalizedFreqCut) {
    //Calculate Impulse Response Low Pass (High Stop) Filter
    if (!(normalizedFreqCut > 0.0) || !(size > 0)) {
      return null;
    }
    double[] hnCoefficients = new double[size];
    double[] wnCoefficients = getHammingWindow(size);
    int halfSize = (int) Math.floor((double) size / 2);
    double dWc = 2.0 * Math.PI * normalizedFreqCut;
    for (int infIndex = 0; infIndex < halfSize; infIndex++) {
      int supIndex = 2 * halfSize - infIndex;
      int Nn = infIndex - halfSize;
      int Np = halfSize - infIndex;
      double dHdnLP_n = Math.sin((double) Nn * dWc) / ((double) Nn * Math.PI);
      double dHdnLP_p = Math.sin((double) Np * dWc) / ((double) Np * Math.PI);
      hnCoefficients[infIndex] = dHdnLP_n * wnCoefficients[infIndex];
      hnCoefficients[supIndex] = dHdnLP_p * wnCoefficients[supIndex];
    }
    hnCoefficients[halfSize] = 2.0 * normalizedFreqCut;
    return hnCoefficients;
  }

Hamming Windows Method

  public static double[] getHammingWindow(int size) {
    double[] window = null;
    if (size > 0) {
      int halfSize;
      if (size % 2 == 0) {
        //Even
        halfSize = size / 2;
        //zero-phase version:
        window = new double[size];
        for (int i = 0; i < halfSize; i++) {
          int j = 2 * halfSize - i - 1;
          double Nn = (double) (i - halfSize) + 0.5;
          double Np = (double) (halfSize - i) - 0.5;
          double Pi2OnN = 2.0 * Math.PI / (size - 1);
          window[i] = 0.54 + 0.46 * Math.cos(Pi2OnN * Nn);
          window[j] = 0.54 + 0.46 * Math.cos(Pi2OnN * Np);
        }
      } else {
        //Odd
        halfSize = (int) Math.floor((double) size / 2);
        //zero-phase version:
        window = new double[size];
        for (int i = 0; i < halfSize; i++) {
          int j = 2 * halfSize - i;
          double Nn = (double) (i - halfSize);
          double Np = (double) (halfSize - i);
          double Pi2OnN = 2.0 * Math.PI / (size - 1);
          window[i] = 0.54 + 0.46 * Math.cos(Pi2OnN * Nn);
          window[j] = 0.54 + 0.46 * Math.cos(Pi2OnN * Np);
        }
        window[halfSize] = 1.0;
      }
    }
    return window;
  }

Integer Odd Up Method

  public static Integer getIntUpOdd(int X) {
    //Returns the Odd number, (next higher integer)
    if (X % 2 == 0) {
      return X + 1;
    } else {
      return X;
    }
  }

Testing Resample Method I have this output

L:2, M:1, sampleFreq:256.0, outSampleFreq:512.0, auxSampleFreq:512.0,    
freqPass:117.37651753019792, freqStop:128.0, fc:122.68825876509896, size:161

L:1, M:2, sampleFreq:512.0, outSampleFreq:256.0, auxSampleFreq:512.0,    
freqPass:117.37651753019792, freqStop:128.0, fc:122.68825876509896, size:161

enter image description here

Checking before image, the method is not implemented perfectly.

Question:

About the Resample method I have doubt about the argument normalizedFreqCut for Low Pass Filter.

I'm not clear on how to calculate it:

  1. fc / (sampleFreq * L / M)
  2. fc / (sampleFreq * L)
  3. fc / sampleFreq
$\endgroup$
2
  • $\begingroup$ I would love to help you but don't have the time to read through all that code and debug it. That is a lot of code for anyone to go through. It would be much more helpful if you simply and concisely listed the functional steps you use for interpolation and decimation and then include a final plot showing the issue and describe what is your concern with the plot specifically (you just said it is not implemented perfectly but not sure what that has to do with the plot you showed). $\endgroup$ – Dan Boschen Nov 27 '19 at 13:57
  • $\begingroup$ @QA_Col, to compute normalizedFreqCut use equation #3. Your normalized cutoff frequency is given as a fraction of the sampling rate (in the 0.0 to 0.5 range ) $\endgroup$ – dsp_user Nov 27 '19 at 20:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.