# resample interpolation decimation filters algorithm

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


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
• 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). – Dan Boschen Nov 27 '19 at 13:57
• @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 ) – dsp_user Nov 27 '19 at 20:50