import jass.render.*;
import jass.engine.*;
import jass.generators.*;
import java.util.*;
import java.net.*;
import java.io.*;
public class BellApplet extends AppletController {
SourcePlayer player;
ModalModel mm,mmOrg;
ModalObjectWithOneContact bell;
OneShotBuffer force;
double hitFreq = .333;
BellToller bellToller;
float[] w; // warp direction
String syfile = "../data/bell4.sy";
public void setNSliders() {
nsliders = 5;
}
public void setNButtons() {
nbuttons = 2;
}
void randWarp() {
for(int i=0;i<w.length;i++) {
w[i] = (float)(2*Math.random()-1);
}
}
public void warp(double x) {
int nf = w.length;
for(int i=0;i<nf;i++) {
mm.f[i] = (float)(mmOrg.f[i]*(1 + w[i]*x ));
}
}
public void init() {
super.init();
syfile = getParameter("syfile");
}
public void start() {
float srate = 44100.f;
int bufferSize = 128;
int bufferSizeJavaSound = 8*1024;
player = new SourcePlayer(bufferSize,bufferSizeJavaSound,srate);
URL codebase = getCodeBase();
URL syurl = null;
try {
syurl = new URL(codebase,syfile);
} catch(MalformedURLException e) {
System.out.println(e+" Malformed URL: " +codebase+" "+ syfile);
}
try {
mm = new ModalModel(syurl); // warp this one
mmOrg = new ModalModel(syurl); // don't change this one
} catch(IOException e) {
System.out.println(e);
}
w = new float[mm.f.length];
bell = new ModalObjectWithOneContact(mm,srate,bufferSize);
float dur = .002f; // 2 ms
int nsamples = (int)(srate * dur);
float[] cosForce = new float[nsamples];
for(int i=0;i<nsamples;i++) {
cosForce[i] = (float)(.5*(1.-Math.cos(2*Math.PI*(i+1)/(1+nsamples))));
}
force = new OneShotBuffer(srate,bufferSize,cosForce);
try {
bell.addSource(force);
player.addSource(bell);
} catch(SinkIsFullException e) {
System.out.println(this+ " " + e);
}
int nModes0 = 30;
bell.setNf(nModes0);
float hardNess0 = 10f;
force.setSpeed(hardNess0);
force.setVolume(hardNess0);
String[] names = {"Hardness ",
"No. modes ",
"Bell freq. ",
"Toll speed ",
"Warp modes "
};
double[] val = {hardNess0,
nModes0,
1,
hitFreq,
0
};
double[] min = {0.1,
1,
.25,
.1,
-.1
};
double[] max = {hardNess0,
mm.f.length,
3,
1,
.1
};
setValues(val,min,max,names);
jButton[0].setText ("Stop");
jButton[1].setText ("Generate Warp Direction");
player.start();
bellToller = new BellToller();
bellToller.hitFreq = hitFreq;
bellToller.force = force;
bellToller.start();
bellToller.isRunning = true;
randWarp();
}
protected void onSlider(int k) {
switch(k) {
case 0:
force.setSpeed((float)this.val[0]);
force.setVolume((float)this.val[0]);
break;
case 1:
int nf = (int)this.val[1];
bell.setNf(nf);
break;
case 2:
bell.setFrequencyScale((float)this.val[2]);
break;
case 3:
bellToller.hitFreq = this.val[3];
break;
case 4:
warp(this.val[4]);
bell.computeFilter();
break;
}
}
protected void jButtonMousePressed (int k,java.awt.event.MouseEvent evt) {
switch(k) {
case 0:
if(bellToller.isRunning) {
jButton[0].setText("Start");
bellToller.isRunning = false;
bell.clearHistory();
force.clearBuffer();
player.resetAGC();
} else {
jButton[0].setText("Stop");
bellToller.isRunning = true;
}
break;
case 1:
randWarp();
warp(this.val[4]);
bell.computeFilter();
break;
}
}
class BellToller extends Thread {
public double hitFreq = .33;
public OneShotBuffer force;
public boolean isRunning = false;
public void run() {
try {
while(true) {
if(isRunning) {
force.hit();
}
sleep((int)(1000/hitFreq));
}
} catch(InterruptedException e) {
System.out.println(this+" "+e);
}
}
}
}