// 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