class WaveformRenderer implements AudioListener { private float[] left; private float[] right; private float offsetA,offsetB; private int calibrate; private long numCalibrate; private float[] channelA; private float[] channelB; private int sizeX,sizeY; private float scaleX,scaleY; private float startX,startY; private float oldX,oldY; private float absMax,absMaxA,absMaxB; private float gainOld; private float gain,gainA,gainB; private boolean gainCommon; private boolean displayA,displayB; private float old; private boolean hasTriggerd; private boolean autoTrigger; private boolean dataReady; private int triggerSource; private int numChannel; private long numRead; private float rate; private float samplerate; private int skip; private float LevelTrigger; private float slopeTrigger; private float posChannelA; private float posChannelB; private float alphaValue; private final int maxChannel=512; private PFont font; WaveformRenderer(float samplerate_) { samplerate=samplerate_; left = null; right = null; channelA = new float[maxChannel]; channelB = new float[maxChannel]; old=0.0; //trigger vars numChannel=0; numRead=0; skip=1; rate=samplerate; LevelTrigger=0.00001; hasTriggerd=false; autoTrigger=true; dataReady=false; slopeTrigger=1.0; triggerSource=0; gainCommon=false; offsetA=0.0; offsetB=0.0; displayA=true; displayB=true; //frameRate(30); sizeX=width; sizeY=height; scaleX=1.0; scaleY=1.0; startX=0.0; startY=0.0; numCalibrate=0; calibrate=0; posChannelA=(float)2*height/4; posChannelB=(float)2*height/4; alphaValue=255.0; absMax=0.0; gainOld=1.0; //gain=1.0; font=loadFont("Arial.vlw"); textFont(font,12); } public void setDisplayA(boolean val){ displayA=val; } public void setDisplayB(boolean val){ displayB=val; } public void setSize(int x,int y){ sizeX=x; sizeY=y; scaleX=(float)sizeX/(float)width; scaleY=(float)sizeY/(float)height; } public void setCorner(int x,int y){ startX=x; startY=y; } public float getTriggerLevel(){ return LevelTrigger; } public void setTriggerLevel(float level){ LevelTrigger=level; } public void setTriggerSource(int src){ triggerSource=src; } public void setTriggerSlope(float slope){ if(slope>0.0)slopeTrigger=1.0; else slopeTrigger=-1.0; } public void setSkip(int skp){ skip=skp; rate=samplerate/skip; } public float getRate(){ return rate; } public void calibrate(){ calibrate=400; numCalibrate=0; offsetA=0.0; offsetB=0.0; } void setRate(float rate_){ rate=rate_; skip=constrain(round(samplerate/(float)rate),1,100000); } public int getSkip(){ return skip; } public void setGainCommon(boolean GC){ gainCommon=GC; } private synchronized int waitTrigger(float[] samp){ float offset,current; int i; offset=0.0; switch(triggerSource){ case 0: offset=offsetA; break; case 1: offset=offsetB; break; } if((!hasTriggerd)&&(autoTrigger)){ for(i=0;islopeTrigger*LevelTrigger)&&(slopeTrigger*oldabsMaxA)absMaxA=abs(l); if(abs(r)>absMaxB)absMaxB=abs(r); channelA[numChannel]=l; //rot channelB[numChannel]=r; //gruen numChannel++; if(numChannel==maxChannel){ hasTriggerd=false; dataReady=true; break; } } numRead++; } } } else{ for(i=0;istartX)&&(mouseXstartY)&&(mouseYgainB)gainA=gainB; } stroke(255,0,0,alphaValue); for ( int i = 0; i < numChannel; i++ ) { powA+=channelA[i]*channelA[i]; if(displayA){ float Y=posChannelA - channelA[i]*((height/2)*gainA); if(i==0)oldY=Y; line(i,oldY,i+1,Y); oldY=Y; } } stroke(0,255,0,alphaValue); for ( int i = 0; i < numChannel-1; i++ ) { powB+=channelB[i]*channelB[i]; if(displayB){ float Y=posChannelB - channelB[i+1]*((height/2)*gainB); float oldY=posChannelB - channelB[i]*((height/2)*gainB); line(i,oldY,i+1,Y); oldY=Y; } } if(dataReady){ autoTrigger=true; dataReady=false; } if(slopeTrigger>0.0)sign="+"; else sign="-"; fill(255); text(nfs(LevelTrigger,1,5)+" [V] "+sign,20,20); text(nfs(samplerate/skip,5,1)+" [Hz]",20,40); //fill(255,0,0); //text(nfs(offsetA,1,5)+" [V]",100,20); //fill(0,255,0); //text(nfs(offsetB,1,5)+" [V]",100,40); noStroke(); fill(255,0,0); rect(width-260,15,250,10); fill(0,0,0,128); rect(width-10,15,log(sqrt(powA/numChannel))*20,10); fill(0); rect(width-10,15,log(sqrt(absMaxA))*20,10); float r=15.0; float s=1.0; float tt=10.0; fill(190); rect(width-10+20*log(1.0),r,s,tt); fill(90); rect(width-10+20*log(0.1),r,s,tt); rect(width-10+20*log(0.01),r,s,tt); fill(190); rect(width-10+20*log(0.001),r,s,tt); fill(90); rect(width-10+20*log(0.0001),r,s,tt); rect(width-10+20*log(0.00001),r,s,tt); if(LevelTrigger>=0.0) fill(255,255,0); else fill(0,0,256); t=20*log(abs(LevelTrigger)); rect(width-10+t,15,2,10); noStroke(); fill(0,255,0); rect(width-260,30,250,10); fill(0,0,0,128); rect(width-10,30,log(sqrt(powB/numChannel))*20,10); fill(0); rect(width-10,30,log(sqrt(absMaxB))*20,10); r=30.0; s=1.0; tt=10.0; fill(190); rect(width-10+20*log(1.0),r,s,tt); fill(90); rect(width-10+20*log(0.1),r,s,tt); rect(width-10+20*log(0.01),r,s,tt); fill(190); rect(width-10+20*log(0.001),r,s,tt); fill(90); rect(width-10+20*log(0.0001),r,s,tt); rect(width-10+20*log(0.00001),r,s,tt); if(calibrate>0){ fill(64,64,64,190); rect(0,0,width,height); stroke(0); fill(0); rect(width/2-200,height/2+30,400,10); fill(255,255,0); text("calibrating...",width/2-200,height/2+20); rect(width/2-200,height/2+30,400-calibrate,10); } if(isInside()&&(calibrate==0)){ float x=skip*(mouseX-startX)/(scaleX*samplerate); float y=-1000.0*((mouseY-startY)*2/sizeY-1)*scaleY*sqrt(absMaxA); float tx=constrain(mouseX+20,0,width-80); float ty=constrain(mouseY-40,60,height); if(gainCommon)fill(255); else fill(255,160,160); text(nf(y,3,2)+" [mV]\n"+nf(x,1,5)+" [s]",tx,ty); } popMatrix(); } } //class