23kid wrote on Dec 1st, 2009, 4:01pm:Just an update: I've managed to get a realtime input and output with a delay by increasing the buffersize using some code I found here, but the output is played twice in succession. What do you think the cause of this is
On my system (MacOS 10.6, Processing 1.0.9), the system runs such that there are two calls to generate, then two calls to samples, then two calls to generate etc. So the first set of samples is overwritten by the second set, then that set is fed to the output twice on the two calls to generate. To fix this, you need to implement a FIFO in WaveformRenderer, e.g.
Code:
import ddf.minim.*;
Minim minim;
AudioInput in;
AudioOutput out;
WaveformRenderer waveform;
void setup()
{
size(512, 200);
minim = new Minim(this);
minim.debugOn();
// get a line in from Minim, default bit depth is 16
int buffer_size = 4096;
in = minim.getLineIn(Minim.STEREO, buffer_size);
out = minim.getLineOut(Minim.STEREO, buffer_size);
waveform = new WaveformRenderer(buffer_size);
in.addListener(waveform);
// adds the signal to the output
out.addSignal(waveform);
}
void draw()
{
background(0);
stroke(255);
}
void stop()
{
// always close Minim audio classes when you are done with them
in.close();
out.close();
minim.stop();
super.stop();
}
class WaveformRenderer implements AudioListener, AudioSignal
{
private float[] left;
private float[] right;
private int buffer_max;
private int inpos, outpos;
private int count;
// Assumes that samples will always enter and exit in blocks
// of buffer_size, so we don't have to worry about splitting
// blocks across the ring-buffer boundary
WaveformRenderer(int buffer_size)
{
int n_buffers = 4;
buffer_max = n_buffers * buffer_size;
left = new float[buffer_max];
right = new float[buffer_max];
inpos = 0;
outpos = 0;
count = 0;
}
synchronized void samples(float[] samp)
{
// handle mono by writing samples to both left and right
samples(samp, samp);
}
synchronized void samples(float[] sampL, float[] sampR)
{
System.arraycopy(sampL, 0, left, inpos, sampL.length);
System.arraycopy(sampR, 0, right, inpos, sampR.length);
inpos += sampL.length;
if (inpos == buffer_max) {
inpos = 0;
}
count += sampL.length;
// println("samples: count="+count);
}
void generate(float[] samp)
{
// println("generate: count="+count);
if (count > 0) {
System.arraycopy(left, outpos, samp, 0, samp.length);
outpos += samp.length;
if (outpos == buffer_max) {
outpos = 0;
}
count -= samp.length;
}
}
void generate(float[] sampL, float[] sampR)
{
// handle stereo by copying one channel, then passing the other channel
// to the mono handler which will update the pointers
if (count > 0) {
System.arraycopy(right, outpos, sampR, 0, sampR.length);
generate(sampL);
}
}
}