Name: sl110371 Date: 06/21/2000
java version "1.3.0beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0beta-b07)
Java HotSpot(TM) Client VM (build 1.3.0beta-b04, mixed mode)
Operating System: Red Hat Linux 6.1 and 6.2
Environment (tried two different machines):
Machine 1: Dell Dimension XPS R400 running Red Hat Linux 6.1, with 256 MB ECC
SDRAM, Ensonic AudioPCI model es1371 sound card.
Machine 2: PC running Red Hat Linux 6.2, Intel 440BX-2 motherboard, Celeron 400
MHz, 384 MB SDRAM, with SB Live! (emu10k1) sound card.
Both sound cards support full-duplex operation.
Description:
Simultaneous capture/playback (full-duplex audio) appears to be broken in the
Linux release of JDK 1.3.0. I am able to run the Sun Java Sound demos, which do
not require full-duplex operation. The attached code illustrates the problem.
This program runs successfully under the Sun JDK 1.3 on Windows 2000, but does
not work under Linux. I have tried different formats, samples rates, buffers
sizes, but nothing works.
Error messages encountered: Program prints the following output and then hangs.
Opened playback line.
Opened capture line.
Capture started.
Playback started.
Trying to read data
More Java Sound examples that also require simultaneous capture/playback (and
also do not work) can be found at:
http://rupert.informatik.uni-stuttgart.de/~pfistere/jsexamples/
Example code: (Run it by typing javac Duplex1.java; java Duplex1)
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.AudioFileFormat;
/** Duplex1.java written by Brian K. Vogel (###@###.###)
* Purpose: Test full-duplex capture/playback. Capture from mic/line-in
* and play captured audio to speaker.
*/
public class Duplex1
{
public static void main(String[] args)
{
TargetDataLine targetLine;
SourceDataLine sourceLine;
AudioFormat audioFormat = new AudioFormat( 44100.0F, 16, 2, true, true);
try
{
DataLine.Info sourceDataLineInfo = new DataLine.Info(SourceDataLine.class,
audioFormat);
sourceLine = (SourceDataLine) AudioSystem.getLine(sourceDataLineInfo);
sourceLine.open(audioFormat);
System.out.println("Opened playback line.");
DataLine.Info targetDateLineInfo = new DataLine.Info(TargetDataLine.class,
audioFormat);
targetLine = (TargetDataLine) AudioSystem.getLine(targetDateLineInfo);
targetLine.open(audioFormat);
System.out.println("Opened capture line.");
// Start capture.
targetLine.start();
System.out.println("Capture started.");
// Start playback.
sourceLine.start();
System.out.println("Playback started.");
int buffSize = 4096;
byte[] sampleBuffer = new byte[buffSize];
int bytesRead;
while(true) {
System.out.println("Trying to read data");
bytesRead = targetLine.read(sampleBuffer, 0, buffSize);
System.out.println("Read data");
System.out.println("Trying to write data");
sourceLine.write(sampleBuffer, 0, bytesRead);
System.out.println("Wrote data");
System.out.println("************************");
}
}
catch (LineUnavailableException e)
{
e.printStackTrace();
System.exit(1);
}
}
}
(Review ID: 105809)
======================================================================
Name: krC82822 Date: 01/13/2001
13 Jan 2001, evall127@eng -- seems related to #'s 4257234 & 4347309 (one
of which should be closed as a duplicate of the other).
-----------------
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)
I swear I read that Java Sound API was supposed to be able to do full duplex if
the card supports it. I know my card supports it, but I cannot get it to work.
This may not be a bug; maybe I just don't know how to do it, but I haven't been
able to find any information on how to do simultaneous playback and record
correctly. Even though I'm using the same *instance* of AudioFormat to open
both lines, I consistently get the following exception:
javax.sound.sampled.LineUnavailableException: Requested format incompatible with
already established device format: PCM_SIGNED, 44100.0 Hz, 16 bit, stereo,
big-endian, audio data
at com.sun.media.sound.AbstractMixer.open(AbstractMixer.java:271)
at com.sun.media.sound.SimpleInputDevice.open(SimpleInputDevice.java:528)
at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:83)
at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:114)
at SimpleMultiTracker$TinyRecorder.fileRecord(SimpleMultiTracker.java:138)
at SimpleMultiTracker$TinyRecorder.run(SimpleMultiTracker.java:102)
at java.lang.Thread.run(Thread.java:484)
Here's the sample program I've written while trying to figure out how this
works. Please pardon the general crapiness of it; I'll design it right when I
figure out the details:
/******************************************************************************/
import java.io.*;
import javax.sound.sampled.*;
public class SimpleMultiTracker
{
protected AudioFormat _audioFormat;
public static void main(String[] args)
{
new SimpleMultiTracker().begin(args);
return;
}
protected static class TinyPlayer implements Runnable
{
protected SimpleMultiTracker _parent;
protected String _filename;
public TinyPlayer(SimpleMultiTracker parent, String filename)
{
_parent = parent;
_filename = filename;
}
public void run()
{
filePlayback(_filename);
}
protected void filePlayback(String filename)
{
SourceDataLine line = null;
File file = null;
AudioFileFormat fileFormat = null;
AudioFormat audioFormat = null;
DataLine.Info info = null;
try
{
file = new File(filename);
fileFormat = AudioSystem.getAudioFileFormat(file);
// this is the AudioFormat we expect to use for recording as
// well.
audioFormat = fileFormat.getFormat();
_parent.setAudioFormat(audioFormat);
System.out.println(audioFormat);
System.out.flush();
info = new DataLine.Info(SourceDataLine.class, audioFormat);
}
catch(Exception e)
{
e.printStackTrace();
}
if(!AudioSystem.isLineSupported(info))
{
System.err.println("Line not supported: " + info);
System.err.flush();
}
try
{
line = (SourceDataLine)AudioSystem.getLine(info);
line.open(audioFormat);
line.start();
int bytesRead = 0;
byte[] buf = new byte[1024];
FileInputStream in = new FileInputStream(file);
for(int total = 0; total < file.length() && bytesRead != -1;)
{
bytesRead = in.read(buf, 0, 1024);
total += bytesRead;
line.write(buf, 0, bytesRead);
}
line.drain();
line.stop();
line.close();
line = null;
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
protected static class TinyRecorder implements Runnable
{
protected SimpleMultiTracker _parent;
protected String _filename;
public TinyRecorder(SimpleMultiTracker parent, String filename)
{
_parent = parent;
_filename = filename;
}
public void run()
{
fileRecord(_filename);
}
protected void fileRecord(String filename)
{
TargetDataLine lineIn = null;
AudioInputStream in = null;
// clearly I'm using the same AudioFormat, because I'm referring
// to the same instance that the player is using. Naturally I
// I tried it with a separate instance initially, but when that
// didn't work, I tried this, which also didn't work.
AudioFormat format = null;
while(format == null)
{
format = _parent.getAudioFormat();
try{Thread.sleep(1000);}
catch(Exception e)
{}
}
DataLine.Info info =
new DataLine.Info(TargetDataLine.class, format);
File file = null;
try
{
file = new File(filename);
lineIn = (TargetDataLine)AudioSystem.getLine(info);
in = new AudioInputStream(lineIn);
}
catch(Exception e)
{
e.printStackTrace();
}
try
{
lineIn.open(format);
lineIn.start();
AudioSystem.write(in, AudioFileFormat.Type.WAVE, file);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
protected void begin(String[] args)
{
if(args.length != 2)
{
System.err.println("usage: " + getClass().getName() +
" fileToPlayback fileToRecord");
System.err.flush();
System.exit(1);
}
Thread player = new Thread(new TinyPlayer(this, args[0]));
Thread recorder = new Thread(new TinyRecorder(this, args[1]));
player.start();
recorder.start();
}
protected AudioFormat getAudioFormat()
{
return _audioFormat;
}
protected void setAudioFormat(AudioFormat audioFormat)
{
_audioFormat = audioFormat;
}
}
(Review ID: 114260)
======================================================================