import jass.render.*; import jass.engine.*; import jass.generators.*; import java.util.*; import java.awt.*; public class Masking extends Thread { static float dbMax=0,dbMin=-100,lMax = -50,lMin = -100; static float a_n,l_n=lMin; static float[] f; static int nfreq; static float[] a; static float[] db; static String sine50Hz44100 = "../data/sin20ms.wav"; static float baseFreqWavFile = 50; static float srate = 44100.f; static int nButtons = 4; static SourcePlayer player; static LoopBuffer[] tone; static RandOut randOut; static Mixer mixer; static int nSources; // Convert db to amp for tone public static double db2a(double db) { return Math.sqrt(2)*Math.exp(db*Math.log(10)/20); } // Convert density level to amp for white noise public static double level2a(double lev) { return Math.sqrt(3*srate/2)*Math.exp(lev*Math.log(10)/20); } public static void main (String args[]) throws Exception { if(args.length != 1) { System.out.println("Usage: java Masking nfrequencies"); return; } nfreq = Integer.parseInt(args[0]); int nsliders = nfreq*2+1; nSources = 1+nfreq; // nfreq tones 1 white noise a = new float[nfreq]; db = new float[nfreq]; f = new float[nfreq]; for(int i=0;i<nfreq;i++) { f[i] = 200 + i*20; } db[0] = dbMax; for(int i=1;i<nfreq;i++) { db[i] = dbMin; } int bufferSize = 1024; int bufferSizeJavaSound = 8*1024; tone = new LoopBuffer[nfreq]; for(int i=0;i<nfreq;i++) { tone[i] = new LoopBuffer(srate,bufferSize,sine50Hz44100); } randOut = new RandOut(bufferSize); mixer = new Mixer(bufferSize,nSources); player = new SourcePlayer(bufferSize,bufferSizeJavaSound,srate); try { player.addSource(mixer); for(int i=0;i<nfreq;i++) { mixer.addSource(tone[i]); } mixer.addSource(randOut); } catch(Exception e) { } // Add control panel String[] names = new String[nsliders]; double[] val = new double[nsliders]; double[] min = new double[nsliders]; double[] max = new double[nsliders]; for(int i=0;i<nsliders-2;i+=2) { names[i] = "f"+(i/2)+" "; val[i] = f[i/2]; min[i] = 50; max[i] = srate/2; names[i+1] = "dB"+(i/2)+" "; val[i+1] = db[i/2]; min[i+1] = dbMin; max[i+1] = dbMax; } names[nsliders-1] = "Noise density level (db/Hz) "; val[nsliders-1] = l_n; min[nsliders-1] = lMin; max[nsliders-1] = lMax; String[] button_names = {"Reset","Mute","Save","Load"}; for(int i=0;i<nfreq;i++) { //tone[i].setSpeed(f[i]/baseFreqWavFile); a[i] = (float)db2a(db[i]); //mixer.setGain(i,a[i]); } a_n = (float)level2a(l_n); //mixer.setGain(nfreq,a_n); Controller a_controlPanel = new Controller(new java.awt.Frame ("Masking"), false,val.length,nButtons) { public void onButton(int k) { switch(k) { case 0: player.resetAGC(); break; case 1: boolean muted = player.getMute(); player.setMute(!muted); if(muted) { jButton[1].setText ("Mute"); } else { jButton[1].setText ("Unmute"); } break; case 2: { FileDialog fd = new FileDialog(new Frame(),"Save"); fd.setMode(FileDialog.SAVE); fd.setVisible(true); saveToFile(fd.getFile()); } break; case 3: { FileDialog fd = new FileDialog(new Frame(),"Load"); fd.setMode(FileDialog.LOAD); fd.setVisible(true); loadFromFile(fd.getFile()); } break; } } public void onSlider(int k) { if(k==this.nsliders-1) { l_n = (float)this.val[k]; a_n = (float)level2a(l_n); mixer.setGain(nfreq,a_n); } else if(k%2 == 0) { f[k/2] = (float)this.val[k]; tone[k/2].setSpeed(f[k/2]/baseFreqWavFile); } else if(k%2 == 1) { db[(k-1)/2] = (float)this.val[k]; a[(k-1)/2] = (float)db2a(db[(k-1)/2]); mixer.setGain((k-1)/2,a[(k-1)/2]); } } }; a_controlPanel.setSliders(val,min,max,names); a_controlPanel.setVisible(true); player.start(); } }