package uk.co.mmscomputing.dsp.phone; import java.io.*; public class FSKTestUnit{ static private final int EOF = -1; static private final int QUIET = 0; static private final int MARK = 1; // 1300Hz static private final int SPACE = 2; // 2100Hz static private final int[] markAmps={ -8, 6784, 7296, 624,-6528,-7552,-1248, 6272, 7808, 1888,-5760,-7808,-2496, 5248, 8064, 3136,-4736,-8064,-3648, 4224, 8064, 4224,-3648,-8064,-4736, 3136, 8064, 5248,-2496,-7808,-5760, 1888, 7808, 6272,-1248,-7552,-6528, 624, 7296, 6784, 8,-6784,-7296, -624, 6528, 7552, 1248,-6272,-7808,-1888, 5760, 7808, 2496,-5248,-8064,-3136, 4736, 8064, 3648,-4224, -8064,-4224, 3648, 8064, 4736,-3136,-8064,-5248, 2496, 7808, 5760,-1888,-7808,-6272, 1248, 7552, 6528, -624,-7296,-6784, }; static private final int[] spaceAmps={ -8, 8064,-1248,-7808, 2496, 7552,-3648,-6784, 4736, 6272,-5760,-5248, 6528, 4224,-7296,-3136, 7808, 1888,-8064, -624, 8064, -624,-8064, 1888, 7808,-3136,-7296, 4224, 6528,-5248,-5760, 6272, 4736,-6784,-3648, 7552, 2496,-7808,-1248, 8064, 8,-8064, 1248, 7808,-2496,-7552, 3648, 6784,-4736,-6272, 5760, 5248,-6528,-4224, 7296, 3136,-7808,-1888, 8064, 624, -8064, 624, 8064,-1888,-7808, 3136, 7296,-4224,-6528, 5248, 5760,-6272,-4736, 6784, 3648,-7552,-2496, 7808, 1248,-8064, }; static private final int[] mark2space={ 0, 1,66,59,52,45,38,31,24,17,10,37,76,69,62,55,48,41,34,27, 20,13, 6,22,72,65,58,51,44,37,30,23,24, 9, 2,45,68,61,54,47, 40,41,26,19,12, 5,78,71,64,57,50,77,36,29,22,15, 8, 1,74,67, 60,53,46,62,32,25,18,11, 4,77,70,63,64,49,42, 5,28,21,14, 7, }; static private final int[] space2mark={ 0,57,34,11,68,45,22,79,56,33,10,67,44,21,78,55,32, 9,66,43, 20,77,54,31, 8,65,42,19,76,53,30, 7,64,41,18,45,52,29, 6,63, 40,17,74,51,28, 5,62,39,16,73,50,27, 4,61,38,15,72,49,26, 3, 60,37,14,71,48,25, 2,59,36,13,70,47,24, 1,58, 5,12,69,46,23, }; static protected final int max = 7; static private final double[][] retab = new double[max][max]; static private final double[][] imtab = new double[max][max]; static protected double[] au=new double[max]; // buffer audio static protected double[] re=new double[max]; // buffer: real part static protected double[] im=new double[max]; // buffer: imaginary part public FSKTestUnit(){ } static private int analyse(){ double maxmag=0,rev,imv; int maxfrq=0; for(int i=0;i<max;i++){ // evaluate amplitude rev=0;imv=0; for(int k=0;k<max;k++){ rev+=retab[i][k]*au[k]; imv-=imtab[i][k]*au[k]; } re[i]=rev; im[i]=imv; } for(int i=0;i<4;i++){ rev = (Math.abs(re[i])<0.00001)?0.0:re[i]; imv = (Math.abs(im[i])<0.001)?0.0:im[i]; double mag = rev*rev+imv*imv; if(mag>maxmag){ maxmag=mag; maxfrq=i; } } if(maxmag<1e6){ return QUIET;} if(maxfrq==3){ return QUIET;} return maxfrq; // QUIET(0Hz),MARK(1300Hz),SPACE(2100Hz) } static{ for(int i=0;i<max;i++){ for(int k=0;k<max;k++){ double tmp=2.0*Math.PI*((double)i)*((double)k)/((double)max); retab[i][k]=(1.0/(double)max)*Math.cos(tmp); imtab[i][k]=(1.0/(double)max)*Math.sin(tmp); } } } static void testm2s(int m,int testsym){ System.err.println("MARK -> SPACE "+m+" "+((testsym==MARK)?"MARK":"SPACE")); for(int i=0;i<markAmps.length;i++){ for(int j=m;j<au.length;j++){ au[j]=markAmps[(i-j+m-1+markAmps.length)%markAmps.length]; // System.err.println("au["+j+"]="+au[j]); } int k=mark2space[i]; // System.err.println("k="+k); for(int j=0;j<m;j++){ au[m-1-j]=spaceAmps[(k+j)%spaceAmps.length]; // System.err.println("au["+(m-1-j)+"]="+au[m-1-j]); } // System.err.println(); int res = analyse(); if(res!=testsym){ System.err.println("["+i+"] = "+res+" "+markAmps[i]+" k="+k); } } } static void tests2m(int m,int testsym){ System.err.println("SPACE -> MARK "+m+" "+((testsym==MARK)?"MARK":"SPACE")); for(int i=0;i<spaceAmps.length;i++){ for(int j=m;j<au.length;j++){ au[j]=spaceAmps[(i-j+m-1+spaceAmps.length)%spaceAmps.length];// System.err.println("au["+j+"]="+au[j]); } int k=space2mark[i]; // System.err.println("k="+k); for(int j=0;j<m;j++){ au[m-1-j]=markAmps[(k+j)%markAmps.length]; // System.err.println("au["+(m-1-j)+"]="+au[m-1-j]); } // System.err.println(); int res = analyse(); if(res!=testsym){ System.err.println("["+i+"] = "+res+" "+markAmps[i]+" k="+k); } } } public static void main(String[] argv){ try{ for(int i=0;i<markAmps.length;i++){ for(int j=0;j<au.length;j++){ au[j]=markAmps[(i-j+markAmps.length)%markAmps.length]; } int res = analyse(); if(res!=MARK){ System.err.println("["+i+"] = "+res+" "+markAmps[i]); } } for(int i=0;i<spaceAmps.length;i++){ for(int j=0;j<au.length;j++){ au[j]=spaceAmps[(i-j+spaceAmps.length)%spaceAmps.length]; } int res = analyse(); if(res!=SPACE){ System.err.println("["+i+"] = "+res+" "+spaceAmps[i]); } } System.err.println("\n\nSPACE -> MARK"); tests2m(2,SPACE); tests2m(3,SPACE); tests2m(4,MARK); tests2m(5,MARK); tests2m(6,MARK); System.err.println("\n\nMARK -> SPACE"); testm2s(2,MARK); testm2s(3,MARK); testm2s(4,SPACE); testm2s(5,SPACE); testm2s(6,SPACE); }catch(Exception e){ e.printStackTrace(); } } } // ETSI ES 201 912 v 1.2.1 (2004-06) // ETS 300 659-1/2 (1997-02)