package org.jcodec.audio;
import java.lang.IllegalArgumentException;
import java.nio.FloatBuffer;
/**
* This class is part of JCodec ( www.jcodec.org ) This software is distributed
* under FreeBSD License
*
* Base for all filters that use convolution with kernel
*
* @author The JCodec project
*
*/
public abstract class ConvolutionFilter implements AudioFilter {
private double[] kernel;
protected abstract double[] buildKernel();
@Override
public void filter(FloatBuffer[] _in, long[] pos, FloatBuffer[] out) {
if (_in.length != 1)
throw new IllegalArgumentException(this.getClass().getName()
+ " filter is designed to work only on one input");
if (out.length != 1)
throw new IllegalArgumentException(this.getClass().getName()
+ " filter is designed to work only on one output");
FloatBuffer in0 = _in[0];
FloatBuffer out0 = out[0];
if (kernel == null) {
kernel = buildKernel();
}
if (out0.remaining() < in0.remaining() - kernel.length)
throw new IllegalArgumentException("Output buffer is too small");
if (in0.remaining() <= kernel.length)
throw new IllegalArgumentException("Input buffer should contain > kernel lenght (" + kernel.length
+ ") samples.");
int halfKernel = kernel.length / 2;
int i;
for (i = in0.position() + halfKernel; i < in0.limit() - halfKernel; i++) {
double result = 0;
for (int j = 0; j < kernel.length; j++) {
result += kernel[j] * in0.get(i + j - halfKernel);
}
out0.put((float) result);
}
in0.position(i - halfKernel);
}
@Override
public int getDelay() {
if (kernel == null) {
kernel = buildKernel();
}
return kernel.length / 2;
}
@Override
public int getNInputs() {
return 1;
}
@Override
public int getNOutputs() {
return 1;
}
}