This applet contains an implementation of a reverb as described by Steiglitz in his book
@book{Steiglitz96, title = {A Digital Signal Processing Primer with Applications to Digital Audio and Computer Music}, author = {Ken Steiglitz}, publisher = {Addison-Wesley}, address = {New York}, year = {1996}, pages = {290--295}}The input signal if filtered through 6 parallele comb filters with a lowpass each. Each comb filter is characterized by a feedback coefficient, a low-pass filter coefficient g, from the lowpass transfer function H(z) = 1/(1-g/z), and a delay time. The result of summingthe 6 comb filter outputs is fed through an allpass filter, which is characterized by a delay, and a coefficient a. The allpass transfer function is H(z) = (z^-{m}+a)/(1+a*z^{-m}). The final result is mixed with the original signal.
You can reverberate a set of impulses or a mike input. If you have no mike the AGC will boost the noise in your soundcard and reverberate that.
Latency is terrible. Download JASS and reduce the buffersizes if you have low latency JavaSound implementation like Tritonus, if youy can't live with it.
Source code:
import java.io.*; import jass.render.*; import jass.engine.*; import jass.generators.*; import jass.patches.*; /** CombReverb using Moorers reverb. See e.g. @book{Steiglitz96, title = {A Digital Signal Processing Primer with Applications to Digital Audio and Computer Music}, author = {Ken Steiglitz}, publisher = {Addison-Wesley}, address = {New York}, year = {1996}, pages = {290--295}} Defaults are for 25Khz sampling rate from Steiglitz book. @author Kees van den Doel (kvdoel@cs.ubc.ca) */ public class ReverbApplet extends AppletController { int bufferSize = 16; // no feedback loop can have smaller delay than this int bufferSizeJavaSound = 0; // use huge default latency float srate = 22050; // because I have model data for 25KHz sampling rate SourcePlayer player; AudioIn input; Impulse impulse; // alternate source boolean useImpulse = true; float impulseT = 1f; //second CombReverb reverb; int nReflections = 6; // Reverb parameters float[] combDelays = {.05f,.056f,.061f,.068f,.072f,.078f}; // delays in seonds float allpassDelay = .006f; // delay in seconds float a = .7071068f; // allpass parameter float[] R = {.4897f,.6142f,.5976f,.5893f,.581f,.5644f}; // feedback comb parameters float[] g = {.24f,.26f,.28f,.29f,.3f,.32f}; // low-pass comb parameters float dryToWet = .9f; // 1 is dry only double minDelay = 1.3*(bufferSize/srate); // smalles feedback delay possible public void setNSliders() { nsliders = nReflections*3 + 3; } public void setNButtons() { nbuttons = 3; } protected void createPatch() { player = new SourcePlayer(bufferSize,bufferSizeJavaSound,srate); if(useImpulse) { impulse = new Impulse(srate,bufferSize); impulse.setPeriod(impulseT); } else { input = new AudioIn(srate,bufferSize,bufferSizeJavaSound); } reverb = new CombReverb(bufferSize,srate,nReflections); try { if(useImpulse) { reverb.addSource(impulse); } else { reverb.addSource(input); } player.addSource(reverb); } catch(SinkIsFullException e) { System.out.println(e); System.exit(0); } for(int i=0;i