Java – Implement a high-pass filter for audio signals

Implement a high-pass filter for audio signals… here is a solution to the problem.

Implement a high-pass filter for audio signals

I was able to write a program to capture an audio signal, remove background noise, apply window functions, and visualize that signal. So far, my program is working fine with no errors. Now I’m trying to implement a high-pass filter for my code. I’ve found the API for this part. But I can’t apply it based on my code. Here is my code :

private class RecordAudio extends AsyncTask<Void, double[], Void> {
    @Override
    protected Void doInBackground(Void... params) {
        started = true;
        try {
            DataOutputStream dos = new DataOutputStream(
                    new BufferedOutputStream(new FileOutputStream(
                            recordingFile)));
            int bufferSize = AudioRecord.getMinBufferSize(frequency,
                    channelConfiguration, audioEncoding);
            audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    frequency, channelConfiguration, audioEncoding,
                    bufferSize);

NoiseSuppressor.create(audioRecord.getAudioSessionId());
            short[] buffer = new short[blockSize];
            double[] toTransform = new double[blockSize];
            long t = System.currentTimeMillis();
            long end = t + 15000;
            audioRecord.startRecording();

while (started && System.currentTimeMillis() < end) {
                int bufferReadResult = audioRecord.read(buffer, 0,
                        blockSize);
                for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
                    toTransform[i] = (double) buffer[i] / 32768.0;
                    dos.writeShort(buffer[i]);
                }
                toTransform = hann(toTransform);
                transformer.ft(toTransform);
                publishProgress(toTransform);
            } 
            audioRecord.stop();
            dos.close();
        } catch (Throwable t) {
            Log.e("AudioRecord", "Recording Failed");
        }
        return null;
    }

This is an API link.

Can anyone help me with this feature? I really appreciate it! 🙂

Thanks in advance!

Solution

This is the class I converted from the library I found in C# to Java. I use it and it works great. You can also use this class for low-pass filters

public class Filter {

 <summary>
 rez amount, from sqrt(2) to ~ 0.1
 </summary>
private float resonance;

private float frequency;
private int sampleRate;
private PassType passType;

public float value;

private float c, a1, a2, a3, b1, b2;

 <summary>
 Array of input values, latest are in front
 </summary>
private float[] inputHistory = new float[2];

 <summary>
 Array of output values, latest are in front
 </summary>
private float[] outputHistory = new float[3];

public Filter(float frequency, int sampleRate, PassType passType, float resonance)
{
    this.resonance = resonance;
    this.frequency = frequency;
    this.sampleRate = sampleRate;
    this.passType = passType;

switch (passType)
    {
        case Lowpass:
            c = 1.0f / (float)Math.tan(Math.PI * frequency / sampleRate);
            a1 = 1.0f / (1.0f + resonance * c + c * c);
            a2 = 2f * a1;
            a3 = a1;
            b1 = 2.0f * (1.0f - c * c) * a1;
            b2 = (1.0f - resonance * c + c * c) * a1;
            break;
        case Highpass:
            c = (float)Math.tan(Math.PI * frequency / sampleRate);
            a1 = 1.0f / (1.0f + resonance * c + c * c);
            a2 = -2f * a1;
            a3 = a1;
            b1 = 2.0f * (c * c - 1.0f) * a1;
            b2 = (1.0f - resonance * c + c * c) * a1;
            break;
    }
}

public enum PassType
{
    Highpass,
    Lowpass,
}

public void Update(float newInput)
{
    float newOutput = a1 * newInput + a2 * this.inputHistory[0] + a3 * this.inputHistory[1] - b1 * this.outputHistory[0] - b2 * this.outputHistory[1];

this.inputHistory[1] = this.inputHistory[0];
    this.inputHistory[0] = newInput;

this.outputHistory[2] = this.outputHistory[1];
    this.outputHistory[1] = this.outputHistory[0];
    this.outputHistory[0] = newOutput;
}

public float getValue()
{
    return this.outputHistory[0];
}

}

That’s how I use it

    Filter filter = new Filter(15000,44100, Filter.PassType.Highpass,1);
    for (int i = 0; i < numSamples; i++)
    {
        filter. Update(floatArray[i]);
        floatArray[i] = filter.getValue();
    }

After you get the fft of the floatArray, you’ll see that it’s filtered.
Hope that helps

Related Problems and Solutions