Closed GoogleCodeExporter closed 9 years ago
That is correct. This is the corrected line 286:
fomega = lowp ? Math.sin(omega / 2.0) : Math.cos(omega/2.0);
I have developed a Butterworth testing suite using R results which I am
attaching below. The high pass filter is the one affected by the bug and it is
fixed by my patch above.
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.util.Arrays;
import org.junit.Test;
import de.fau.cs.jstk.sampled.AudioBuffer;
import de.fau.cs.jstk.sampled.filters.Butterworth;
import de.fau.cs.jstk.sampled.filters.IIRFilter;
public class TestJstk {
@Test
public void testButter_lp() throws IOException {
double[] x = new double[] { 16, 8, 12, 9, 3, 26, 20, 4, 112, 93, 80, 69, 68, 63, 58, 27, 25, 25, 18, 11, 22, 9, 5, 8, 16, 17, 17, 44, 63, 24, 47 };
double[] b = new double[] { 0.1550510, 0.3101021, 0.1550510 };
double[] a = new double[] { 1.0000000, -0.6202041, 0.2404082 };
final AudioBuffer audioBuffer = new AudioBuffer(x, 2);
final Butterworth butterworth = new Butterworth(audioBuffer, 2, 1.0 / 3.0, true);
final double[] bb = butterworth.getB();
final double[] aa = butterworth.getA();
assertArrayEquals(b, bb, 0.001);
assertArrayEquals(a, aa, 0.001);
}
@Test
public void testButter_hp() throws IOException {
double[] x = new double[] { 16, 8, 12, 9, 3, 26, 20, 4, 112, 93, 80, 69, 68, 63, 58, 27, 25, 25, 18, 11, 22, 9, 5, 8, 16, 17, 17, 44, 63, 24, 47 };
double[] b = new double[] { 0.3468218, -1.3872872, 2.0809308 ,-1.3872872, 0.3468218};
double[] a = new double[] { 1.0000000, -1.9684278, 1.7358607 ,-0.7244708, 0.1203896 };
double[] expected = new double[] {5.54914892555101,-8.49892230051391,-0.003607008408407,-0.309157749925311,0.549327031269458,12.3495446861587,-8.08187252527558,-10.2052018545226,42.7060615954128,-39.089626413168,-24.3177046211387,4.63980949957661,22.0464798879164,14.8012776797776,3.39742596116234,-13.9965761769389,2.71278575409631,1.87605737037402,-5.32246810936881,-4.53394312207378,5.16192117527652,-6.85997635444255,0.903951634058044,5.83406457378732,4.32350630835867,-3.60407519394749,-4.23879071781233,7.97239236467143,-1.93029751372985,-25.4779281018646,18.4450453439678};
final AudioBuffer audioBuffer = new AudioBuffer(x, 2);
final Butterworth butterworth = new Butterworth(audioBuffer, 4, 1.0 / 4.0, false);
final double[] bb = butterworth.getB();
final double[] aa = butterworth.getA();
assertArrayEquals(b, bb, 0.001);
assertArrayEquals(a, aa, 0.001);
double[] buf = new double[x.length];
butterworth.read(buf);
assertArrayEquals(expected,buf,0.001);
}
@Test
public void testButter_pass() throws IOException {
double[] x = new double[] { 16, 8, 12, 9, 3, 26, 20, 4, 112, 93, 80, 69, 68, 63, 58, 27, 25, 25, 18, 11, 22, 9, 5, 8, 16, 17, 17, 44, 63, 24, 47 };
double[] b = new double[] {0.0113248654051871,0,-0.0339745962155614,0,0.0339745962155614,0,-0.0113248654051871};
double[] a = new double[] {1,-4.4496959232013,8.65581123827227,-9.42446288516026,6.06410161513775,-2.18695422340435,0.346410161513775};
double[] expected = new double[] {0.181197846482994,0.896874242029731,2.01470814785898,2.73948388646281,2.27456568741899,0.61421917906726,-1.10462841953745,-1.93525406304157,-1.20621974366979,2.97278152595629,10.4303214872243,15.8822139387219,13.500760000539,2.38976099657175,-13.0801776390542,-26.72484049744,-34.2082480470628,-33.9079541732019,-26.2232727370073,-13.4714856847578,0.832951218316903,13.5117163981764,22.3047800227293,26.10958732738,25.5807316155666,22.6911775250397,19.1878576681426,15.9125835498727,13.4444260301878,11.4840807655145,7.8900683896338};
final AudioBuffer audioBuffer = new AudioBuffer(x, 2);
final Butterworth butterworth = new Butterworth(audioBuffer, 3, 1.0/12.0, 1.0 / 4.0, true);
final double[] bb = butterworth.getB();
final double[] aa = butterworth.getA();
assertArrayEquals(b, bb, 0.001);
assertArrayEquals(a, aa, 0.001);
double[] buf = new double[x.length];
butterworth.read(buf);
assertArrayEquals(expected,buf,0.001);
}
@Test
public void testButter_stop() throws IOException {
double[] x = new double[] { 16, 8, 12, 9, 3, 26, 20, 4, 112, 93, 80, 69, 68, 63, 58, 27, 25, 25, 18, 11, 22, 9, 5, 8, 16, 17, 17, 44, 63, 24, 47 };
double[] b = new double[] {0.588675134594813,-3.16675012051762,7.44448637286709,-9.72761279073067,7.44448637286709,-3.16675012051762,0.588675134594813};
double[] a = new double[] {1,-4.4496959232013,8.65581123827227,-9.42446288516026,6.06410161513775,-2.18695422340435,0.346410161513775};
double[] expected = new double[] {9.418802153517,-4.04779530757917,1.30305080730625,0.813444393440761,0.965738818071003,19.6437242012142,4.34025997546248,-5.19657906701005,70.0443383235965,4.92086998914045,-1.28503403301326,17.889553459591,44.7825129396512,54.6764469627152,55.1946954891815,36.2067494827069,49.6219341707565,54.3906737102908,50.2874318711772,49.6467626996213,61.0675149513866,47.3383697081128,47.5252796021205,48.7946668297596,46.0251122981386,33.6941987816225,24.7182348816676,35.7429020098952,29.4434367841126,-8.57798891169426,26.4753213522642};
final AudioBuffer audioBuffer = new AudioBuffer(x, 2);
final Butterworth butterworth = new Butterworth(audioBuffer, 3, 1.0/12.0, 1.0 / 4.0, false);
final double[] bb = butterworth.getB();
final double[] aa = butterworth.getA();
assertArrayEquals(b, bb, 0.001);
assertArrayEquals(a, aa, 0.001);
double[] buf = new double[x.length];
butterworth.read(buf);
assertArrayEquals(expected,buf,0.001);
}
@Test
public void testButter2() throws IOException {
double[] x = new double[] { 16, 8, 12, 9, 3, 26, 20, 4, 112, 93, 80, 69, 68, 63, 58, 27, 25, 25, 18, 11, 22, 9, 5, 8, 16, 17, 17, 44, 63, 24, 47 };
//
// double[] b = new double[] { 0.1550510, 0.3101021, 0.1550510 };
// double[] a = new double[] { 1.0000000, -0.6202041, 0.2404082 };
final AudioBuffer audioBuffer = new AudioBuffer(x, 2);
final Butterworth butterworth = new Butterworth(audioBuffer, 3, 1./12., 1.0 / 4.0, true);
final double[] bb = butterworth.getB();
final double[] aa = butterworth.getA();
System.out.println(Arrays.toString(bb));
System.out.println(Arrays.toString(aa));
// assertArrayEquals(b,bb,0.001);
// assertArrayEquals(a,aa,0.001);
}
@Test
public void testFilter() throws Exception {
double[] x = new double[] { 16, 8, 12, 9, 3, 26, 20, 4, 112, 93, 80, 69, 68, 63, 58, 27, 25, 25, 18, 11, 22, 9, 5, 8, 16, 17, 17, 44, 63, 24, 47 };
double[] expected = new double[] { 2.480816, 7.740654, 11.026622, 11.334931, 9.495764, 9.521394, 15.251175, 18.023392, 29.218818, 63.560039, 91.005041, 91.087775, 78.959247, 68.626275, 62.652705, 54.29965, 39.856636, 27.480371, 21.881322, 18.128053, 15.595807, 15.237716,
12.678430, 8.386320, 7.890119, 11.715253, 15.757417, 21.686219, 35.710242, 47.013993, 45.071298 };
double[] b = new double[] { 0.1550510, 0.3101021, 0.1550510 };
double[] a = new double[] { 1.0000000, -0.6202041, 0.2404082 };
final IIRFilter iirFilter = new IIRFilter(new AudioBuffer(x, 2), b, a);
double[] buf = new double[x.length + 1];
final int read = iirFilter.read(buf);
assertEquals(x.length, read);
assertArrayEquals(expected, Arrays.copyOfRange(buf, 0, x.length), 0.0001);
}
}
Original comment by pjfu...@gmail.com
on 27 Sep 2013 at 12:42
This JSTK project seems to be abandoned.
I have written another port of the Exstrom Butterworth IIR filter design module:
http://www.source-code.biz/dsp/java
Original comment by chdheu@gmail.com
on 27 Sep 2013 at 10:23
Thanks for your help, and sorry for the delay-- didn't get notified by gcode.
Fixed in r258.
Original comment by korbini...@gmail.com
on 10 Nov 2014 at 6:16
Already fixed.
Original issue reported on code.google.com by
chdheu@gmail.com
on 17 Jul 2013 at 10:44