Coder Social home page Coder Social logo

berndporr / iirj Goto Github PK

View Code? Open in Web Editor NEW
132.0 8.0 36.0 2.43 MB

An efficient IIR filter library written in JAVA

License: Apache License 2.0

Java 94.60% Python 5.36% Shell 0.04%
signal-processing iir filter filters filter-plugin highpass lowpass-filter highpass-filter bandstop bandstop-filter

iirj's Introduction

iirj

An IIR filter library written in JAVA.

Highpass, lowpass, bandpass and bandstop as Butterworth, Bessel and Chebyshev Type I/II.

You can also calculate the filter coefficients with Python's scipy and then create your custom IIR filter. See the python-design subdirectory.

It's based on the IIR1 library [https://github.com/berndporr/iir1] which in turn is based on Vinnie Falco's DSPFilters [https://github.com/vinniefalco/DSPFilters].

alt tag

Usage

import uk.me.berndporr.iirj.*;

Constructor

Butterworth butterworth = new Butterworth();

Initialisation

  1. Bandstop

    butterworth.bandStop(order,Samplingfreq,Center freq,Width in frequ);

  2. Bandpass

    butterworth.bandPass(order,Samplingfreq,Center freq,Width in frequ);

  3. Lowpass

    butterworth.lowPass(order,Samplingfreq,Cutoff frequ);

  4. Highpass

    butterworth.highPass(order,Samplingfreq,Cutoff frequ);

Filtering

Sample by sample for realtime processing:

v = butterworth.filter(v)

Coding examples

See the *Test.java files for complete examples for all filter types. Run them with mvn test. These test programs write the different impulse responses of the filters to text files.

Installation

Local install

  • Clone this repository
  • Run mvn install to add it to your local maven respository

Maven central

At Maven Central click on the iirj version number and then choose the appropriate installation option, for example for Android studio.

Android Studio

dependencies {
    implementation group: 'uk.me.berndporr', name:'iirj', version: '1.7'
}

Android studio will automatically notify you if a new IIR library is available.

Documentation

  • Online: https://berndporr.github.io/iirj/
  • mvn javadoc:javadoc generates the JavaDocs
  • mvn site generates the web pages containing the documentation under target/site describing all commands in detail.

Testing

mvn test creates impulse responses in the subdirectories for the different filters: target/surefire-reports.

To see the impulse and frequency responses run:

python3 ./plot_impulse_fresponse.py <filter>

where is is butterworth, bessel, chebyshevI or chebyshevII.

The script DetectorTest uses a bandpass filter to detect the heartbeats of an ECG recording faking a matched filter which could be also seen as a 1st approximation of a wavelet. The heartrate is stored in hr.txt.

Have fun

/Bernd Porr [http://www.berndporr.me.uk]

iirj's People

Contributors

berndporr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iirj's Issues

Question on Butterworth highPass, cutoff==Nyquist, coefficients are NaN?

Hi and thanks for this wonderful library - I am learning a lot!

I wanted to run this by you to see if you had any thoughts. Perhaps I am doing something wrong - would not be the first time in history =). I am trying to filter seismic time series data so we generally work in the sub-100 Hz realm. Much of the time, 20 samples per sec.

For a low-pass Butterworth filter order 4, sampling rate 20/sec and cutoff frequencies 1 through 10, all is fine.

For the high-pass case however, I run into trouble right at the Nyquist barrier with cutoff = 10.

Stepping thru the call to filter(), with a breakpoint in the Cascade class, ~line 70, I can see that the m_biquads array (index 0) has NaN for the 3 "b" coefficients (m_b0, m_b1, m_b2). This leads to all NaNs for my data after the filter call.

So then I had a go at stepping into the initialization of the filter:

butterworth.highPass(4, rate, freqCutoff); // 4, 20.0, 10.0

and to me things seem OK in highPass() and setupHighPass(). I did manage to step a little further, into the Biquad initialization. But in the setCoefficients() method, I don't detect any NaNs or div by zero or anything really obvious a mortal like me might spot.

So finally my question to you: Are there particular cases where I might need to make additional checks of my web service user's inputs in which I can predict that things are going to get unstable, or catch the exception and return no data?

Thanks for your patience and have a wonderful day!
Mick Van Fossen
Seattle

Applying butterworth bandpass filter on a wav file

I want to filter an already saved audio in the form of wav file. I know that the filter needs a double array for filtering. So, I have read the audio in a byte array and then converted that byte array to a double array. After applying the filter on the double array with a for loop, I have converted the double array to bytes and then wav file again but the resulting audio file is choppy and doesn't look filtered in a audio spectrum analyzer.

I can provide the code if anyone interested!

voice filter

Hello!

I've tried to use your library to filter voice using bandPass(2, 16000, 1850, 1550) and it seems not working. Voice has a freqency from 300 up to 3000 and it should exclute music or with bandStop( same args ) exclude voice. But non of it seems working.

It is a bug, or voice filtering way more complicated?

BTW it is open-source android audio recrorder https://gitlab.com/axet/android-audio-recorder

Returns NaN when filtering.

I have setup a filter with the parameters (4, 30, 140, 200) for heartbeat filtering from camera brightness variation. However the returned value is NaN for each of the numbers I feed into it.
Butterworth butter = new Butterworth(); butter.bandPass(2, 29, 140, 200); for (Double val: brightness){ processed.add(butter.filter(val)); }

Changing target Frequency while feeding in new Samples

Hi!
I have a .csv file containing target frequencies that need to be filtered out with a band stop filter.
These frequencies change over time. Is it possible to do that? Because I tried it the obvious way by calling the butterworth.bandStop function with the new frequency before feeding the next sample, but that doesn't seem to work.
Thanks
Bastian

Error when setting up lowpass filter

java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
                                                                          at uk.me.berndporr.iirj.LayoutBase.add(LayoutBase.java:57)
                                                                          at uk.me.berndporr.iirj.Butterworth$AnalogLowPass.design(Butterworth.java:58)
                                                                          at uk.me.berndporr.iirj.Butterworth.setupLowPass(Butterworth.java:66)
                                                                          at uk.me.berndporr.iirj.Butterworth.lowPass(Butterworth.java:87)
                                                                          at sg.edu.sutd.syncbeat.utilities.Adaptiv.<init>(Adaptiv.java:17)
                                                                          at sg.edu.sutd.syncbeat.MainActivity.onCreate(MainActivity.java:56)
                                                                          at android.app.Activity.performCreate(Activity.java:5411)
                                                                          at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
                                                                          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2270)
                                                                          at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2396) 
                                                                          at android.app.ActivityThread.access$800(ActivityThread.java:139) 
                                                                          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1293) 
                                                                          at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                          at android.os.Looper.loop(Looper.java:149) 
                                                                          at android.app.ActivityThread.main(ActivityThread.java:5257) 
                                                                          at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                          at java.lang.reflect.Method.invoke(Method.java:515) 
                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609) 
                                                                          at dalvik.system.NativeStart.main(Native Method)

Looking at https://github.com/berndporr/iirj/blob/master/src/main/java/uk/me/berndporr/iirj/LayoutBase.java#L45 and https://github.com/berndporr/iirj/blob/master/src/main/java/uk/me/berndporr/iirj/LayoutBase.java#L57, it seems like there will always be an array out of bounds error. Is this a bug?

Input for butterworth filter on audio signal

I have an array of audio signal ranging from nearly -5000 to 5000 and I want to apply a bandpass filter on it. Its a heartbeat audio but I have to filter it .
The array when plotted on a graph looks something like this

When I apply filter on this , the result comes out distorted and the frequencies are not filtered. I am suspecting that the array range should be in range of -1 to 1 instead of -5000 to 5000.
Can anyone tell me what should be the input on the butterworth algo!?

Question about the arguments

Is the sample rate the same as the frequency which the signal was sampled or is it something else?
The frequencies specified are normalized (Nyquist frequency) or raw?

A querstion about HighPass

I'm trying to transform a java UDF from python code. In python, it use scipy.signal as highpass filter, i'm searching a lot time and found this project. But i can't get the same result, so i wanna know what's difference between Butterworth.highpass() and scipy.signal.butter?

Some help converting code from Matlab

Hello,
Are you familiar with Matlab by any change?
If so, would you mind helping me convert a few lines of Matlab code to Java using IIRJ.
This is the code in question:

tempo = 100
fs = 44100

% Butterworth 3rd order bandpass
[b_but, a_but] = butter(3, [20 140+tempo]/(0.5*fs), 'bandpass');
filtered_pulse = filter(b_but, a_but, pulse);

% Peaking filter
[b_peak, a_peak] = iirpeak(110/(fs/2), 120/(0.5*fs));
filtered_pulse = filter(b_peak, a_peak, filtered_pulse);

For the 1st part I already have this:

private int fs = 44100;
private int temp = 100;

public double[] applyBandpass(double[] pulse) {
	double filteredPulse = new double[pulse.length];
	Butterworth butter = new Butterworth();
	butter.bandPass(3, 44100, ?centerFrequency?, ?widthFrequency?);
	for(int i = 0; i < pulse.length; i++)
		filteredPulse[i] = filter.filter(pulse[i]);
	return filteredPulse;
}

I'm not sure how to compute the centerFrequency and widthFrequency.
In the Matlab code there is just [20 140+tempo]/(0.5*fs), and sample rate is not passed separately.

For the 2nd part I don't have any java code yet because I'm not sure which class of your library to use for the iirpeak() filter.

Thanks in advance for any help.

about sampling rate and cut off frequency

Hi! Great work and very helpful.I want to use it but i don't know what to give for sampling rate and cut off frequency.i measure the Brightness of Frame and i what to use it to find the heart rate but first i want a low-pass filter.

what i want in Matlab is this

BPM_L = 40; % Heart rate lower limit [beats per minute]
BPM_H = 230; % Heart rate higher limit [beats per minute]
v.Framerte=30;
f1=((BPM_L / 60) / v.FrameRate * 2); // f1=0.01
f2=((BPM_H / 60) / v.FrameRate * 2) ;// f2=0.06
[b, a] = butter(2, [f1 f2]);
//the two-element vector [f1 f2], where f1 < f2, then butter designs a bandpass filter with lower cutoff frequency f1 and higher cutoff frequency f2
filtBrightness = filter(b, a, brightness);

what i have to give for sampling rate (?1) and cut off frequency (?2) in the filter you wrote?
butterworth.lowPass(2,?1,?2);
double butterDouble = butterworth.filter(imgAvg); // this is ok

Basic question on applying the filter

Hi,

I am trying to understand the library for EEG plotting. I am not a signal processing student by any means and was trying to understand it for my needs.

In EEG these are the recommendations:
https://sapienlabs.org/pitfalls-of-filtering-the-eeg-signal/

In the first paragraph, I need "to apply a high-pass filter to filter out slow frequencies less than 0.1 Hz or often even 1 Hz". My sampling frequency is 250Hz.

Does this mean I use

butterworth.highPass(order: 3, sampling frequency: 250, cutoff: 1);

Would appreciate some clarification.

Forward-Backward Filter

Great implementation! I've been trying to compare the results with those obtained using Scipy.

With an example of low-pass Butterworth filter, I'm getting the same results as what sosfilt produces.

I'm trying to get the same behaviour as sosfiltfilt ("A forward-backward digital filter using cascaded second-order sections").

As far as I can tell, sosfiltfilt:

  • Pads the input array by copying the signal in a symmetric way to the first point and last point, at the beginning and the end, respectively.
  • "Computes an initial state zi for the sosfilt function that corresponds to the steady state of the step response." (sosfilt_zi) and set those initial values in the filter.
  • Runs the filter forward (after scaling the initial values)
  • Runs the filter backwards (after scaling the initial values using the fist forward results)

Using some examples and looking at iirj's m_biquads values and Scipy's sos coefficients seem to be the same values (arranged differently).

Is there a way to compute and set the initial zi values required for forward-backward processing with iirj?

Thank you.

A querstion about HighPass with value

First, i'm sorry i didn't discuss my question clearly. I mean that i used the same sample rate, cutofFrequency and order on concstructor. But i found that I get different B, A. I don't know the reason of this question.
Java:
image

Python:
image

image

Maybe something wrong with param in ?

Real-time filtering vs array filtering

Hi! This library is very useful for my android project, thank you for doing this! My project actually does not need real-time filtering, but I can't find any reliable array filtering library. May I know the difference in result between real-time filtering vs array filtering?

Issue with Odd-Order Highpass Filters

After introducing new tests, it was observed that highpass filters of odd order produce incorrect results. This issue has already been reported in the original library, as seen in this issue.

The proposed fix appears to be effective. Both tbrunsch and I have tested the fix, and it seems to work without introducing any other issues. Additionally, upon reviewing the code, we've verified that the changes exclusively affect the highpass filter and do so correctly.

We will be submitting a PR that includes both the unit tests and the fix for this problem.

Bandpass filter frequency settings

It looks as if the Bandpass Filter sets upper and lower frequencies symmetrically (arithmetic mean) around the centre frequency, width defined by the widthFrequency - is that correct?
For an Octave Band Filter I need a Geometric Mean centre frequency - the upper frequency cut-off to be further away from the centre frequency than the lower frequency cut-off
Does the IIRS filter library allow for this type of bandpass filter? Thank you, Michael

Unusual results when using Bessel filters of higher orders

We've observed that the results from IIRJ align closely with Scipy for most filters. However, for Bessel Filters of order greater than 1, there are significant differences. Visually, the Bessel results from IIRJ appear inconsistent. Given that other filters produce similar results to Scipy, we suspect this isn't a configuration issue, though we can't be entirely certain. Any insights or guidance on this matter would be highly appreciated.

Compare.zip

How would this be linked in Android Studio?

I am doing a project which needs butterworth filtering, and can't seem to find libraries for DSP in android.
Do you have any directions as to how I can use this in my project?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.