|
Quick Lists
|
|
Bug ID:
|
4347309
|
|
Votes
|
10
|
|
Synopsis
|
Simultaneous capture/playback of audio does not work on Linux.
|
|
Category
|
java:classes_sound
|
|
Reported Against
|
1.3
, ladybird-rc1
|
|
Release Fixed
|
1.4.2(mantis)
|
|
State
|
10-Fix Delivered,
bug
|
|
Priority:
|
4-Low
|
|
Related Bugs
|
|
|
Submit Date
|
21-JUN-2000
|
|
Description
|
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: customer 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, customer 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 ( xxxxx@xxxxx )
* 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)
======================================================================
13 Jan 2001, xxxxx@xxxxx -- 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)
======================================================================
|
|
Work Around
|
N/A
|
|
Evaluation
|
xxxxx@xxxxx 2002-11-02
Changed synopsis to include Linux, since this is a linux-specific bug. This bug should be fixed with ALSA support in 1.4.2 (of course, ALSA 0.9 needs to be installed on the Linux system).
|
|
Comments
|
Submitted On 28-NOV-2000
oligold
I ran into the same problem and didn't know if it was
something wrong with the sound card.
Olivier.
Submitted On 09-MAY-2001
insaar
I have the same problem... and I don't want to hurt anybody, but it seems to be a
Java problem, that Java cannot implement sound fullduplex...
Submitted On 03-AUG-2001
jallonzyn
i tried the latter program again on my winME+jdk1.3.0.02.
the results are same:
C:\>javac SimpleMultiTracker.java
C:\>java SimpleMultiTracker
usage: SimpleMultiTracker fileToPlayback fileToRecord
C:\>java SimpleMultiTracker setup0.wav tst1.wav
PCM_UNSIGNED, 22050.0 Hz, 8 bit, stereo, audio data
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(Unknown
Source)
at com.sun.media.sound.SimpleInputDevice.open
(Unknown Source)
at com.sun.media.sound.AbstractDataLine.open
(Unknown Source)
at com.sun.media.sound.AbstractDataLine.open
(Unknown Source)
at SimpleMultiTracker$TinyRecorder.fileRecord
(SimpleMultiTracker.java:13
7)
at SimpleMultiTracker$TinyRecorder.run
(SimpleMultiTracker.java:100)
at java.lang.Thread.run(Unknown Source)
Submitted On 15-OCT-2001
basashi
add more things.
now I'm downloading IBM jdk1.3 and installing.
and run same program is work!!
Submitted On 15-OCT-2001
basashi
I have the same problem too. on Vine linux 2.1 & Ess1968
maestro2 sound card & build 1.4.0-beta2-b77, mixed mode (
same if use jdk1.3.1 )...but If I get rebooting to windows
98,
no problems happen. I can start TargetDataLine,
SourceDataLine smooth.
Submitted On 06-NOV-2001
shahr00z
me too, I have ran my app on Win2000 prof,but there was an
Exception UnavailableFileFormat even when I have opened it
on network streams.
Submitted On 19-MAR-2002
rasmuskjellman
Same problem as jallonzyn... Really annoying.
Submitted On 09-JAN-2003
jmccaughey
how is this closed or fixed?
Submitted On 09-FEB-2004
beltdar
I've got the same problem!!!...i'm doing an Audio
Conferencing Aplication and I cannot open
SourceDataLine (speakers for incoming sound from
the network) and TargetDataLine (microphone for
sending sound to the network).....
I've read the entire Java Sound User's Guide and it
doesn't make any reference to simoultaneous
playback and recording or something like that.
I really believe it doesn't work and it's not hardware
problem.
P.D: I'm using WinXP
Submitted On 02-SEP-2004
JavaInstruments
Well, I wrote a code similar to Duplex1.java (see (Review ID: 105809) ), where input is mike and output is speaker, and I get the buffer size from mike.getBufferSize()/5 (or /25, /55, /10) and although is plays on Windows 2000, java 1.4.2.04 SE, it does it with a "fixed" delay of about a second, without losing frames. I know that Java may not be the fastest language and I expected to have problems with continuous data stream from device to device, specially for long buffering or delay between reads and writes from and to streams. However, because I don't seem to observe loss of sound, I wonder what could be the problem?
Please, contact me at luizcosta@sbcglobal.net
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |