Does anyone know of any tricks for reducing the latency of reading
from a TargetDataLine for Apple's "Built-in Input" mixer under
JavaSound?
I have the simplest possible application I could write. I create a
TargetDataLine (input) and SourceDataLine (output). I want to read
data on the input line and immediately write it to the output line
with the minimal amount of delay. I have tried all combinations of the
AudioFormat, and the best latency I can get is about 10.5 milliseconds
on the read. Ordinarily that would not be bad, but for audio it is not
good. I'm trying to play a musical instrument and hear it in real-
time, and that 10 milliseconds is noticeable. If I can just get it to
5 milliseconds, I will live with that.
Here's the inner loop of my app:
format = createAudioFormat();
SourceDataLine outputLine = createSourceDataLine(); //these
both use BUFFER_SIZE for the DataLine.Info and when opening the line
TargetDataLine inputLine = createTargetDataLine();
inputLine.start();
outputLine.start();
byte[] buffer = new byte[BUFFER_SIZE];
while (true)
{
int bytesRead = inputLine.read(buffer,0,BUFFER_SIZE);
int bytesWritten = outputLine.write(buffer,0, bytesRead);
}
private SourceDataLine createSourceDataLine() throws
LineUnavailableException
{
SourceDataLine line = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class,
format, BUFFER_SIZE);
Mixer mixer = AudioStreamUtil.getMixerByName(OUTPUT_MIXER_NAME);
line = (SourceDataLine) mixer.getLine(info);
line.open(format, BUFFER_SIZE);
return line;
}
private TargetDataLine createTargetDataLine() throws
LineUnavailableException
{
DataLine.Info info = new DataLine.Info(TargetDataLine.class,
format, BUFFER_SIZE);
TargetDataLine line = (TargetDataLine) mixer.getLine(info);
line.open(format, BUFFER_SIZE);
return line;
}
I've experimented with various sample rates, and it seems the faster
the better so I have been using 44100 or 48000. I'm using signed
samples, Big-endian, 1 channel, mono, normally 8 bits per sample (I've
experimented with a larger buffer and 16 bits per sample but that
doesn't help.)
With 8 bits per sample and a 512 byte buffer, the read takes on
average 10.5 milliseconds. (The write only takes about 80
microseconds) If I try a 256 byte buffer the read time is 9
milliseconds, but the sound is completely garbled, no doubt because
the output buffer completely drains before the next read can fill it
again.
I may have to finally dive in and learn some CoreAudio and write a
TargetDataLine implementation as a SPI in JNI, but I would really like
to avoid having to do that if at all possible. And I don't even know
if that will solve the problem either, since I don't know what the
inherent hardware capabilities are of the line-in port.
Does anyone have any suggestions? (This is on a modern dual-core
Intel, 2.6GHz, 64 bit, running Java 6, OS 10.5.7, all software up to
date.)
Rob
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden