Skip to content

IIR Filter #2704

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions AudioFilters/IIRFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package AudioFilters;

/**
* N-Order IIR Filter
* Assumes inputs are normalized to [-1, 1]
*
* Based on the difference equation from https://en.wikipedia.org/wiki/Infinite_impulse_response
*/
public class IIRFilter {
private final int order;
private final double[] coeffsA;
private final double[] coeffsB;
private final double[] historyX;
private final double[] historyY;

/**
* Construct an IIR Filter
*
* @param order the filter's order
* @throws IllegalArgumentException if order is zero or less
*/
public IIRFilter(int order) throws IllegalArgumentException {
if (order < 1) {
throw new IllegalArgumentException("order must be greater than zero");
}

this.order = order;
coeffsA = new double[order+1];
coeffsB = new double[order+1];

// Sane defaults
coeffsA[0] = 1.0;
coeffsB[0] = 1.0;

historyX = new double[order];
historyY = new double[order];
}

/**
* Set coefficients
* @param aCoeffs Denominator coefficients
* @param bCoeffs Numerator coefficients
* @throws IllegalArgumentException if {@code aCoeffs} or {@code bCoeffs} is not of size {@code order},
* or if {@code aCoeffs[0]} is 0.0
*/
public void setCoeffs(double[] aCoeffs, double[] bCoeffs) throws IllegalArgumentException {
if (aCoeffs.length != order) {
throw new IllegalArgumentException("aCoeffs must be of size " + order + ", got " + aCoeffs.length);
}

if (aCoeffs[0] == 0.0) {
throw new IllegalArgumentException("aCoeffs.get(0) must not be zero");
}

if (bCoeffs.length != order) {
throw new IllegalArgumentException("bCoeffs must be of size " + order + ", got " + bCoeffs.length);
}

for (int i = 0; i <= order; i++) {
coeffsA[i] = aCoeffs[i];
coeffsB[i] = bCoeffs[i];
}
}

/**
* Process a single sample
*
* @param sample the sample to process
* @return the processed sample
*/
public double process(double sample) {
double result = 0.0;

// Process
for (int i = 1; i <= order; i++) {
result += (coeffsB[i] * historyX[i-1] - coeffsA[i] * historyY[i-1]);
}
result = (result + coeffsB[0] * sample) / coeffsA[0];

// Feedback
for (int i = order-1; i > 0; i--) {
historyX[i] = historyX[i-1];
historyY[i] = historyY[i-1];
}

historyX[0] = sample;
historyY[0] = result;

return result;
}
}
3 changes: 3 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

## Audio Filters
* [IIRFilter](https://github.com/TheAlgorithms/Java/blob/master/AudioFilters/IIRFilter.java)

## Backtracking
* [NQueens](https://github.com/TheAlgorithms/Java/blob/master/Backtracking/NQueens.java)
* [PowerSum](https://github.com/TheAlgorithms/Java/blob/master/Backtracking/PowerSum.java)
Expand Down