import jass.render.*; import jass.engine.*; import jass.generators.*; import java.util.*; import java.net.*; /* Tones of the form: y = a*sin(2*pi*f*t) I(y) = a*a/2 db = 10*log(a*a/(2*I0)) = 10*log(a*a/2) - 10*log(I0) noise of the form: y = a * rnd(t), rnd white noise of bandwidth Fb I(y) = a*a/3 D(y) = I(y)/Fb Level l(y) = 10*log(a*a/(3*Fb*I0)) = 10*log(a*a/(3*Fb)) - 10*log(I0) A tone can be heard when its db level is 17 above the density level of white noise in these units. We've set I0 = 1, arbitrary. */ public class MaskingApplet extends AppletController { float dbMax=0,dbMin=-100,lMax = -50,lMin = -100; float f1=1200,f2=400,a1,a2,db1=dbMax,db2=dbMin,a_n,l_n=lMax; String sine50Hz44100 = "../data/sin20ms.wav"; float baseFreqWavFile = 50; float srate = 44100.f; SourcePlayer player; LoopBuffer tone1,tone2; RandOut randOut; Mixer mixer; int nSources = 3; // 2 tones + noise public void setNSliders() { nsliders = 5; } public void setNButtons() { nbuttons = 2; } // Convert db to amp for tone public double db2a(double db) { return Math.sqrt(2)*Math.exp(db*Math.log(10)/20); } // Convert density level to amp for white noise public double level2a(double lev) { return Math.sqrt(3*srate/2)*Math.exp(lev*Math.log(10)/20); } public void init() { super.init(); sine50Hz44100 = getParameter("wavfile"); } public void start() { int bufferSize = 1024; int bufferSizeJavaSound = 8*1024; URL codebase = getCodeBase(); URL wavurl = null; try { wavurl = new URL(codebase,sine50Hz44100); } catch(MalformedURLException e) { System.out.println(e+" Malformed URL: " +codebase+" "+ sine50Hz44100); } tone1 = new LoopBuffer(srate,bufferSize,wavurl); tone2 = new LoopBuffer(srate,bufferSize,wavurl); randOut = new RandOut(bufferSize); mixer = new Mixer(bufferSize,nSources); player = new SourcePlayer(bufferSize,bufferSizeJavaSound,srate); try { player.addSource(mixer); mixer.addSource(tone1); mixer.addSource(tone2); mixer.addSource(randOut); } catch(Exception e) { } // Add control panel String[] names = {"Freq 1 ", "Level (db) 1 ", "Freq. 2 ", "Level (db) 2 ", "Noise density level (db/Hz) " }; double[] val = {f1, db1, f2, db2, l_n }; double[] min = {50, dbMin, 50, dbMin, lMin }; double[] max = {srate/2, dbMax, srate/2, dbMax, lMax }; tone1.setSpeed(f1/baseFreqWavFile); tone2.setSpeed(f2/baseFreqWavFile); a1 = (float)db2a(db1); a2 = (float)db2a(db2); a_n = (float)level2a(l_n); mixer.setGain(0,a1); mixer.setGain(1,a2); mixer.setGain(2,a_n); setValues(val,min,max,names); jButton[0].setText ("Reset"); jButton[1].setText ("Mute"); //show(); player.start(); } protected void onSlider(int k) { switch(k) { case 0: f1 = (float)this.val[0]; tone1.setSpeed(f1/baseFreqWavFile); break; case 1: db1 = (float)this.val[1]; a1 = (float)db2a(db1); mixer.setGain(0,a1); break; case 2: f2 = (float)this.val[2]; tone2.setSpeed(f2/baseFreqWavFile); break; case 3: db2 = (float)this.val[3]; a2 = (float)db2a(db2); mixer.setGain(1,a2); case 4: l_n = (float)this.val[4]; a_n = (float)level2a(l_n); mixer.setGain(2,a_n); } } protected void jButtonMousePressed (int k,java.awt.event.MouseEvent evt) { 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; } } }