package jass.generators; import jass.engine.*; import java.io.*; /** Vibration model of object, capable of playing sound. Extended to keep track of current excitation and capable of modes being turned on/off. @author Kees van den Doel (kvdoel@cs.ubc.ca) */ public class QuenchableModalObjectWithOneContact extends ModalObjectWithOneContact { /** True for the modes that are on */ protected boolean[] onBit; /** Create and initialize, but don't set any modal parameters. @param srate sampling rate in Hertz. @param nf number of modes. @param np number of locations. @param bufferSize Buffer size used for real-time rendering. */ public QuenchableModalObjectWithOneContact(float srate,int nf,int np,int bufferSize) { super(srate,nf,np,bufferSize); allocateonBit(nf); } /** Create and initialize with provided modal data. @param m modal model to load. @param srate sampling rate in Hertz. @param bufferSize Buffer size used for real-time rendering. */ public QuenchableModalObjectWithOneContact(ModalModel m,float srate,int bufferSize) { super(m,srate,bufferSize); allocateonBit(m.nf); } /** Allocate and turn on modes */ private void allocateonBit(int nf) { onBit = new boolean[nf]; for(int i=0;i<nf;i++) { onBit[i] = true; } } /** Turn mode on/off. @param mode mode number @param on true if turn on, fals if turn off */ public void setOnBit(int mode,boolean on) { if(on) { onBit[mode] = true; } else { if(onBit[mode]) { onBit[mode] = false; yt_1[mode] = yt_2[mode] = 0; } // else was off already } } /** Return current excitation of mode. Approximated as (y(t)^2 + (dy/dt)^2/(2pif)^2)/2). A pulse excitation of strength x should produce excitation of (ax)^2/2, with "a" gain of mode. @param k mode number @return excitation */ public float getModeExcitation(int k) { double y2term = yt_1[k]*yt_1[k]; double dy2term = (yt_1[k] - yt_2[k])*srate/(6.2831853*modalModel.fscale*modalModel.f[k]); dy2term *= dy2term; return (float)((y2term + dy2term)/2); } /** Apply external force[] and compute response through bank of modal filters. As in super class but skip off modes. @param output user provided output buffer. @param force input force. @param nsamples number of samples to compute. */ protected void computeModalFilterBank(float[] output, float[] force, int nsamples) { boolean isnul = true; for(int k=0;k<nsamples;k++) { output[k] = 0; if(Math.abs(force[k])>=eps) { isnul = false; } } int nf = modalModel.nfUsed; if(isnul) { for(int i=0;i<nf;i++) { if(Math.abs(yt_1[i]) >= eps || Math.abs(yt_2[i]) >= eps) { isnul = false; break; } } } if(isnul) { return; } for(int i=0;i<nf;i++) { if(onBit[i]) { float tmp_twoRCosTheta = twoRCosTheta[i]; float tmp_R2 = R2[i]; float tmp_a = ampR[i]; float tmp_yt_1 = yt_1[i]; float tmp_yt_2 = yt_2[i]; for(int k=0;k<nsamples;k++) { float ynew = tmp_twoRCosTheta * tmp_yt_1 - tmp_R2 * tmp_yt_2 + tmp_a * force[k]; // commenting out the force[k] changes performance 650->718 tmp_yt_2 = tmp_yt_1; tmp_yt_1 = ynew; output[k] += ynew; } yt_1[i] = tmp_yt_1; yt_2[i] = tmp_yt_2; } } } }