// Copyright (c) 2011, XMOS Ltd, All rights reserved // This software is freely distributable under a derivative of the // University of Illinois/NCSA Open Source License posted in // LICENSE.txt and at import java.lang.Math; import java.io.*; import java.util.*; class MakeCoeffs { final double pi = Math.PI; int FRACTIONALBITS = 24; final int hzCnt = 42; final int maxDbs = 41; double [][]gain = new double[maxDbs][hzCnt]; double [][]igain = new double[maxDbs][hzCnt]; double []freqs = new double[hzCnt]; int thedb; PrintStream fdH, fdXC, fdCSV; static int errorValue = 0; int R(double x) { if (x >= (1<<(31-FRACTIONALBITS)) || x < -(1<<(31-FRACTIONALBITS))) { System.err.print("Overflow: constant " + x + " too large, maximum with " + FRACTIONALBITS + " fractional bits is " + (1<<(31-FRACTIONALBITS))); errorValue++; } return (int) Math.floor((1< filters = new Vector(); for(int i = 0; i < args.length; i++) { if (args[i].equals( "-low") ) { filters.add(new F(LOW, Double.parseDouble(args[++i]), 0)); filterCnt++; } else if (args[i].equals( "-high") ) { filters.add(new F(HIGH, Double.parseDouble(args[++i]) , 0)); filterCnt++; } else if (args[i].equals( "-peaking") ) { filters.add(new F(PEAKING, Double.parseDouble(args[i+1]), Double.parseDouble(args[i+2]))); i += 2; filterCnt++; } else if (args[i].equals( "-fs") ) { Fs = Double.parseDouble(args[++i]); } else if (args[i].equals( "-bits") ) { FRACTIONALBITS = Integer.parseInt(args[++i]); } else if (args[i].equals( "-min") ) { mindb = Double.parseDouble(args[++i]); } else if (args[i].equals( "-max") ) { maxdb = Double.parseDouble(args[++i]); } else if (args[i].equals( "-step") ) { stepdb = Double.parseDouble(args[++i]); } else if (args[i].equals( "-h") ) { includeFile = args[++i] ; } else if (args[i].equals( "-xc") ) { sourceFile = args[++i] ; } else if (args[i].equals( "-csv") ) { responseCurve = args[++i]; } else { usage(); } } dbcnt = (int) Math.floor((maxdb-mindb+stepdb/4)/stepdb) + 1; if (mindb > maxdb) { System.err.print("Mindb should be less than or equal to maxdb\n"); System.exit(1); } if (dbcnt > maxDbs) { System.err.println("Too many steps in db (>= " + maxDbs + "), recompile the source\n"); System.exit(1); } fdH = fopen_save(includeFile); fdXC = fopen_save(sourceFile); fdCSV = fopen_save(responseCurve); f = 10; for(int i = 0; i < hzCnt; i++, f *= 1.18920711500272106671) { freqs[i] = f; } fdH.print( "//Generated code - do not edit.\n\n" + "#define BANKS " + filterCnt + "\n" + "#define DBS "+ dbcnt + " \n" + "#define FRACTIONALBITS " + FRACTIONALBITS + "\n" ); fdXC.print( "//Generated code - do not edit.\n\n" + "// First index is the dbLevel, in steps of " + stepdb + " db, first entry is " + mindb + " db\n" + "// Second index is the filter number - this filter has " + filterCnt + " banks\n" + "// Each structure instantiation contains the five coefficients for each biquad:\n" + "// b0/a0, b1/a0, b2/a0, -a1/a0, -a2/a0; all numbers are stored in 2.30 fixed point\n" + "#include \"" + includeFile + "\"\n" + "#include \"biquadCascade.h\"\n" + "struct coeff biquads[DBS][BANKS] = {\n"); thedb = 0; fdCSV.print("\"\",\"\","); for(f = mindb; f <= maxdb+stepdb/1000; f+=stepdb) { fdCSV.print("\"" + f + " dB\","); fdXC.print(" { //Db: " + f + "\n"); for(F ff: filters) { switch(ff.type) { case LOW: lowShelf(ff.freq, f); break; case HIGH: highShelf(ff.freq, f); break; case PEAKING: peakingEQ(ff.freq, f, ff.bw); break; } } thedb++; fdXC.print(" },\n"); } fdXC.print("};\n"); fdCSV.print("\n"); for(int i = 0; i < hzCnt; i++) { fdCSV.print( "\""+freqs[i]+"\",\"Hz\","); for(j = 0; j