import java.io.*; // NOTE: // the python script for the CIPIC conversion calculates also the FFT and pads the original data // to 256 bins; public class HRIRLoaderCIPIC implements IHRIRLoader { // reimplemented from hrir_data_documentation.pdf private final double[] azimuthDeg ={-80, -65, -55, -45, -40, -35, -30,-25,-20,-15,-10,-5,0,5,10, 15,20,25,30,35,40,45,55,65,80}; private static double elevForm(int i) { return -45.0+(5.625*i); } public double getAzimuthError() { return 0.0; } public double getElevationError() { return 0.0; } private String path; // private double az; // private double el; private int fftLen = 256; private int fftPow = 8; public int getFFTSize() { return this.fftLen; } public int getFFTPower() { return this.fftPow; } public HRIRLoaderCIPIC(String path) { this.path = path; } // 3d -> left/right each real, imag arrays public double[][][] getImpulseResponses(double azimuth, double elevation) { azimuth = azimuth *180.0; elevation = elevation*180.0; if(azimuth < -180.0) azimuth = 360.0+azimuth; if(elevation < -180.0) elevation = 360.0+elevation; System.err.println("AZ ELEV "+azimuth+" "+elevation); double[][] polarCoords = this.getNearestTwoPolarCoords(azimuth, elevation); System.err.println("AZ ELEV "+azimuth+" "+elevation+ " || "+polarCoords[0][0]+" v "+polarCoords[0][1]); System.err.println("AZ ELEV 2"+azimuth+" "+elevation+ " || "+polarCoords[1][0]+" v "+polarCoords[1][1]); double sL1[][] = this.loadIRFileCIPIC(polarCoords[0][0], polarCoords[0][1], true); double sR1[][] = this.loadIRFileCIPIC(polarCoords[0][0], polarCoords[0][1], false); double sL2[][] = this.loadIRFileCIPIC(polarCoords[1][0], polarCoords[1][1], true); double sR2[][] = this.loadIRFileCIPIC(polarCoords[1][0], polarCoords[1][1], false); double azDiff = Math.abs(polarCoords[1][0]-polarCoords[0][0]); double azDiffRatio = Math.abs(polarCoords[1][0])/azDiff; double l[][] = null; double r[][] = null; // Fixme: recheck! /*if(sL1 != null && sL2 != null && sR1 != null && sR2 != null) { l = interpolate(sL1, sL2, azDiffRatio); r = interpolate(sR1, sR2, azDiffRatio); } */ //return new double[][][]{l,r}; return new double[][][]{sL1,sR1}; } private double[][] interpolate(double[][] a, double[][] b, double ratio) { double[][] ret = new double[a.length][2]; double inratio = 1.0-ratio; for(int i = 0; i < ret.length; i++) { ret[i][0] = (a[i][0]*ratio)+(b[i][0]*inratio); ret[i][1] = (a[i][1]*ratio)+(b[i][1]*inratio); } return ret; } private double[][] loadIRFileCIPIC(double azi, double ele, boolean left) { double[][] ret = new double[2][fftLen]; String filename; if(left) { filename = "L_"; } else { filename = "R_"; } System.out.println("Open file for azimuth: "+azi+" elev: "+ele); filename = filename+((int)(azi*100.0))/100+"_"+ele+".txt"; System.out.print("Loading "+filename); // is this really the shortest way to do this? its fucking ugly but ought to be // x-platform File file = new File(this.path + filename); if(file.exists()) System.out.println("..."); try{ int i = 0; BufferedReader br = new BufferedReader(new FileReader(file)); for(i = 0; i < fftLen; i++) { String strLine; if((strLine = br.readLine()) != null) { String[] strings = strLine.split(" "); // real ret[0][i] = new Double(strings[0]); // imag ret[1][i] = new Double(strings[1]); } } br.close(); System.out.println("loaded "+i+" samples"); }catch (Exception e){ e.printStackTrace(); ret = null; } return ret; } private double[][] getNearestTwoPolarCoords(double az, double elev) { double azimuth = this.pValDeg(az) % 360; double elevation= this.pValDeg(elev)% 360; if(azimuth < -90.0 || azimuth > 90.0) { // FIXME change channels? do some mapping stuff?? azimuth = 80.0*Math.signum(azimuth); } double currDiff = Double.MAX_VALUE; double minAzOld = Double.MAX_VALUE; double minAz = Double.MAX_VALUE; for(double azDeg: azimuthDeg) { if(Math.signum(azDeg) == Math.signum(azimuth) || azDeg == 0 ) { double diff = Math.abs(azDeg-azimuth); if(diff <= currDiff) { minAzOld = minAz; minAz = azDeg; currDiff = diff; } } } if(minAzOld == Double.MAX_VALUE) { minAzOld = minAz; } double minElev = Double.MAX_VALUE; double minElevOld = Double.MAX_VALUE; currDiff = Double.MAX_VALUE; for(int i=0; i < 50; i++) { //System.out.println(elevation+" + "+minElev); double elevDeg = elevForm(i); if(Math.signum(elevDeg) == Math.signum(elevation)) { double diff = Math.abs(elevDeg -elevation); if(diff <= currDiff) { minElevOld = minElev; minElev = elevDeg; currDiff = diff; } } } if(minElevOld == Double.MAX_VALUE) { minElevOld = minElev; } return new double[][]{new double[]{minAz, minElev}, new double[]{minAzOld, minElevOld}}; } // ret angle private double pValDeg(double angle) { double dtr = Math.PI/180.0; double angleRet = Math.atan2(Math.sin(angle*dtr), Math.cos(angle*dtr))/dtr; if(angleRet < -90.0) { angleRet = angleRet+360; } return angleRet; } }