package nxm.sys.prim;
import nxm.sys.inc.*;
import nxm.sys.lib.*;
import nxm.sys.libm.Waveform;
/**
Creates signal waveforms of various shapes.
@author Jeff Schoen
@version $Id: waveform.java,v 1.15 2002/09/09 21:02:39 schoenj Exp $
@see <a href="../exp/waveform.exp">Explain</a>
@see <a href="waveform.java">Source</a>
*/
public final class waveform extends Primitive {
private Data data;
private DataFile hcb;
private double amp, freq, poff, phase, chirp, dt;
private int shape,throttle,mode;
public final static String shapeList =
"Sinusoid,Square,Triangle,Sawtooth,Pulse,Constant,Zero,White,Ramp";
private final static int
SIN=1,SQU=2,TRI=3,SAW=4,PUL=5,CON=6,ZER=7,WHI=8,RAM=9;
public final static String throttleList = "RealTime,Full,Block";
private final static int REALTIME=1,FULL=2,BLOCK=3;
public int open() {
// Get parameters
shape = MA.getChoice("SHAPE",shapeList,0);
freq = MA.getD("FREQ");
amp = MA.getD("AMP");
poff = MA.getD("PHASE");
chirp = MA.getD("CHIRP",0.0);
// Open output file
hcb = MA.getDataFile("OUT","1000","SF",0);
hcb.setFormat (MA.getFormat("FORM","S#,C#"));
hcb.setXStart (MA.getD("START"));
hcb.setXDelta (MA.getD("DELTA"));
hcb.setXUnits (Units.TIME);
hcb.setSize (MA.getD("ELEM"));
hcb.open();
// Setup processing
throttle = MA.getChoice("/RT",throttleList,FULL);
mode = hcb.spa;
xfer = MA.getL("/TL",4096);
data = hcb.getDataBuffer(xfer,FLOAT);
dt = hcb.getXDelta();
todo(hcb.size);
return (NORMAL);
}
public int process() {
double p, dp, ddp;
float[] fbuf;
if (throttle==BLOCK) return (NOOP);
int ndo = todo();
if (ndo==0) return (FINISH);
data.setSize(ndo); // size data object for this pass
fbuf = data.castF(false); // get array
p = phase+poff; // offset phase
dp = freq*dt; // delta phase
ddp = chirp*dt*dt; // delta phase delta
if (poff!=0) p -= Math.floor(p); // modulo 1.0 if necessary
if (dp<0 && shape!=SIN) dp = -dp; // no negative freqs except for SINs
switch (shape) { // branch on wave shape
case SIN: Waveform.sincos(fbuf,amp,p,dp,ndo,mode); break;
case SQU: Waveform.square(fbuf,amp,p,dp,ndo,mode); break;
case TRI: Waveform.triangle(fbuf,amp,p,dp,ndo,mode); break;
case SAW: Waveform.sawtooth(fbuf,amp,p,dp,ndo,mode); break;
case PUL: Waveform.pulse(fbuf,amp,p,dp,ndo,mode); break;
case CON: Waveform.constant(fbuf,amp,ndo,mode); break;
case ZER: Waveform.constant(fbuf,0.0,ndo,mode); break;
case WHI: Waveform.whitenoise(fbuf,amp,ndo,mode); break;
case RAM: Waveform.sawtooth(fbuf,amp,p,dp,ndo,mode); break;
}
data.uncast(fbuf,true);
if (throttle==REALTIME) Time.sleep( dt*ndo );
hcb.write(data,ndo);
phase += dp*ndo; // increment phase
phase -= Math.floor(phase); // modulo 1.0
return (NORMAL);
}
public int close() {
hcb.close();
return (NORMAL);
}
public int restart() {
hcb.close();
hcb = MA.getDataFile("OUT",hcb,0);
hcb.setFormat (MA.getS("FORM"),"S#,C#");
hcb.setSize (todo);
hcb.open();
data = hcb.getDataBuffer(xfer,FLOAT);
return (NORMAL);
}
/** set run-time properties */
public void setShape (String value) {
shape = Parser.find(shapeList,value,shape);
}
public void setAmp (double value) { amp = value; }
public void setFreq (double value) { freq = value; }
public void setChirp (double value) { chirp = value; }
public void setPhase (double value) { phase = value; }
public void setThrottle (String value) {
throttle = Parser.find(throttleList,value,throttle);
}
public void setFormat (String format) {
MA.put("FORM",format); setState(RESTART);
}
/** get run-time properties */
public String getShape () { return Parser.get(shapeList,shape); }
public double getAmp () { return amp; }
public double getFreq () { return freq; }
public double getChirp () { return chirp; }
public double getPhase () { return phase; }
public String getThrottle () { return Parser.get(throttleList,throttle); }
public String getFormat () { return MA.getS("FORM"); }
}