LineUnavailableException when loading audio clip with Java on RPi - java

My RPi is Zero W and using Raspbian Jessie 4.9.35 / Oracle JDK8 1.8.0_65.
I'm having problem with loading audio clips on Java Program with RPi.
I have two audio files named "piano_0.wav" and "piano_1.wav" and they are different audio files.
I used this to load the clip:
Clip loadClip(String path) {
Clip clip = null;
try {
clip = AudioSystem.getClip();
AudioInputStream stream = AudioSystem.getAudioInputStream(new File(path));
clip.open(stream);
} catch (Exception e) {
Logger.getLogger(MusicManager.class.getName()).log(Level.SEVERE, null, e);
}
return clip;
}
When I try to load piano_0.wav, there's no error logs and can play returned Clip. but When I try to load piano_1.wav program throws exception:
javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian not supported.
at com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:513)
at com.sun.media.sound.DirectAudioDevice$DirectClip.implOpen(DirectAudioDevice.java:1304)
at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:121)
at com.sun.media.sound.DirectAudioDevice$DirectClip.open(DirectAudioDevice.java:1085)
at com.sun.media.sound.DirectAudioDevice$DirectClip.open(DirectAudioDevice.java:1175)
at beatstairscmd.BeatStairsCMD.testMusicClip(BeatStairsCMD.java:81)
at beatstairscmd.BeatStairsCMD.main(BeatStairsCMD.java:42)
But when I used this code on my Desktop there's no problem to load more clips.
I already tried solutions with init the clip with other ways instead of AudioSystem.getClip() and there's no changes.
How should I fix this problem?

Related

Ubuntu 16.4, Java, WAV file playback

This is a weird thing. I'm trying to playback some sounds via Java AudioSystem and AudioSystem.getClip(). The files are all "PCM_SIGNED, 22.050.0 Hz, 16 bit, mono, 2 bytes/frame, little endian".
On several Ubuntu 16.4 LTS Linux boxes this format is rejected by PulseAudio with an Invalid Format Exception, because the only accepted format is seemingly "PCM_SIGNED, unknown sample rate, 16 bit, stereo, 4 bytes/frame, big endian".
I already tried to re-sample my WAVs in order to match this strange constraint, to no avail. Those are not even accepted anymore by AudioSystem.getAudioInputStream()
Needless to say, that the same works fine on Mac OS and Windows. And there is also no problem to playback these files using the sox library and play file.wav
OK, solved.
Usually if one asks, how to playback WAV using Java, this is the most common answer:
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(DragonflyApp.class.getResource("/resources/" + soundFile));
clip = AudioSystem.getClip();
clip.addLineListener(e -> {
if (e.getType() == LineEvent.Type.STOP) {
// Do something on end of playback
}
});
clip.open(audioInputStream);
clip.start();
Unfortunately on some Linux systems this ends up in an "Invalid Format" exception, thrown by PulseAudio, which claims to be unable to playback the simplest WAV file (see above).
The workaround is to use this sequence under Linux instead. It generally does also work on MacOS, but the final "STOP" indication comes very late (roughly 5s after playback end), so I make a conditional execution here:
This works on Linux (at least on Ubunutu 16.04) with clips, which have formerly been rejected by PulseAudio:
DataPusher datapusher = null;
DataLine.Info lineinfo = null;
SourceDataLine sourcedataline = null;
lineinfo = new DataLine.Info(SourceDataLine.class, audioInputStream.getFormat());
if (!(AudioSystem.isLineSupported(lineinfo))) {
return;
}
sourcedataline = (SourceDataLine) AudioSystem.getLine(lineinfo);
sourcedataline.addLineListener(e -> {
if (e.getType() == LineEvent.Type.STOP) {
// Do something on end of playback
}
});
datapusher = new DataPusher(sourcedataline, audioInputStream);
datapusher.start();
Both code snippets are used conditionally:
if (System.getProperty("os.name").equals("Mac OS X")) {
// The clip solution
}
else {
// The datapusher solution
}
Hope, that helps others, who will also have this problem.

Java does not play multi channel wave file

I am unable to play a multi channel wave file in java using javax.sound.sampled package.
I am using an external USB 7.1 surround sound card from logilink.
The wave file is generated by myself. If I generate a stereo track, I am able to play the file. If I use the 6 channel track, I get the following error message:
javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 48000.0 Hz, 16 bit, 6 channels, 12 bytes/frame, little-endian not supported.
I checked if the line is supported and it is by using this code
AudioFormat format = new AudioFormat(48000, 16, 6, true, false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
if (info.isFormatSupported(format)) {
// is supported
}
I play the wave file as follows:
AudioListener listener = new AudioListener();
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(clipFile);
Clip clip = null;
clip = AudioSystem.getClip();
clip.addLineListener(listener);
clip.open(audioInputStream);
clip.start();
Any idea what is wrong?

Issues with SourceDataLine format support

I have an application written in Java in which I need to play audio. I used OpenAL (with java-openal library) for the task however I would like to use WSOLA which is not supported by OpenAL directly. I found a nice java-native library called TarsosDSP which has support for WSOLA.
The library uses standard Java APIs for audio output. The issue occurs during the SourceDataLine setup:
IllegalArgumentException: No line matching interface SourceDataLine supporting format PCM_UNSIGNED 16000.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian is supported.
I made sure the issue is not caused by the lack of permissions (ran it as root on Linux + tried it on Windows 10) and there are no other SourceDataLines used in the project.
After tinkering with the format I found out that the format is accepted when it's changed from PCM_UNSIGNED to PCM_SIGNED. It seems like a minor issue since only moving the byte range form unsigned to signed should be pretty easy. However it's weird that it's not supported natively.
So, is there some solution in which I wouldn't have to modify the source data?
Thanks, Jan
You don't have to move the byte range by hand. After you've created an AudioInputStream, you create another AudioInputStream, with a signed format and that is connected to the first unsigned stream. If you then read the data using the signed stream, the Sound API automatically converts the format. This way you don't need to modify the source data.
File fileWithUnsignedFormat;
AudioInputStream sourceInputStream;
AudioInputStream targetInputStream;
AudioFormat sourceFormat;
AudioFormat targetFormat;
SourceDataLine sourceDataLine;
sourceInputStream = AudioSystem.getAudioInputStream(fileWithUnsignedFormat);
sourceFormat = sourceInputStream.getFormat();
targetFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
sourceFormat.getSampleRate(),
sourceFormat.getSampleSizeInBits(),
sourceFormat.getChannels(),
sourceFormat.getFrameSize(),
sourceFormat.getFrameRate(),
false);
targetInputStream = AudioSystem.getAudioInputStream(targetFormat, sourceInputStream);
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, targetFormat);
sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
sourceDataLine.open(targetFormat);
sourceLine.start();
// schematic
targetInputStream.read(byteArray, 0, byteArray.length);
sourceDataLine.write(byteArray, 0, byteArray.length);

Java - Sound Won't Load - AudioInputStream [duplicate]

The message on the shell is:
Exception in thread "main" java.lang.IllegalArgumentException: Invalid format
at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.createStream(PulseAudioDataLine.java:142)
at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.open(PulseAudioDataLine.java:99)
at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.open(PulseAudioDataLine.java:283)
at org.classpath.icedtea.pulseaudio.PulseAudioClip.open(PulseAudioClip.java:402)
at org.classpath.icedtea.pulseaudio.PulseAudioClip.open(PulseAudioClip.java:453)
at reprod.ReproducirFichero(reprod.java:16)
at reprod.main(reprod.java:44)
I try to download new drivers for audio, i try to reinstall openJDK 7 and openJRE 7 and also i try to install java 7.
I have proved my code in another computer and it works, the desktop board that i use is an intel d525mw, the audio format that i´m trying to play is .wav.The version of linux that I use is Ubuntu 12.04.3.Please I need help.Thanks
here is party of my code, and i try to play a .wav audio format
import javax.sound.sampled.*;
public class reprod {
public static void play(){
try {
Clip cl = AudioSystem.getClip();
File f = new File("/home/usr/Desktop/d.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(f);
cl.open(ais);
cl.start();
System.out.println("playing...");
while (cl.isRunning())
Thread.sleep(4000);
cl.close();
the version of linux that I use is Ubuntu 12.04.3
I solved the problem by simply passing the parameter null into AudioSystem.getClip().
I don't know why this exception occured, I run this project before on Windows, and it worked... After on Linux and here, it didn't work.
I had the same problem and found this code to work:
File soundFile = new File("/home/usr/Desktop/d.wav");
AudioInputStream soundIn = AudioSystem.getAudioInputStream(soundFile);
AudioFormat format = soundIn.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
Clip clip = (Clip)AudioSystem.getLine(info);
clip.open(soundIn);
clip.start();
while(clip.isRunning())
{
Thread.yield();
}
The key is in soundIn.getFormat(). To quote the docs:
Obtains the audio format of the sound data in this audio input stream.
Source: http://ubuntuforums.org/showthread.php?t=1469572
The error message says that the input file format is wrong somehow.
If you gave us more information (file format, maybe where you got it, code that you use to open the file and how you configured the audio drivers), we might be able to help.
See this question for some code that you can try: How to play .wav files with java

Error while playing sound in Java

I'm trying to play a sound in my Java Application, but every time I call the method I get this exception: javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 48000.0 Hz, 24 bit, mono, 3 bytes/frame, little-endian not supported.
Here's the code:
AudioInputStream audio = AudioSystem.getAudioInputStream(new File("src/media/ding2.wav"));
Clip clip = AudioSystem.getClip();
clip.open(audio);
clip.start();
I tried to play a file by passing a URL and it works fine, but with my "ding2.wav" nothing works.
Thanks in advance for your help.
By looking over HERE in Documention, the LineUnavailableException arises when the line is not Available, or the requested resource is in use by Another Application,
Make Sure that your audio file is not open in any other application.
EDIT
As the error message says :line with format PCM_SIGNED 48000.0 Hz, 24 bit, mono, 3 bytes/frame
the file format you are providing is not supported.
and as you said I tried to play a file by passing a URL and it works fine,
put the Old file back and check the file format by using
System.out.println(audio.getFormat());
and check what was the file format of that file , whether that was same to the above _line with format PCM_SIGNED 48000.0 Hz, 24 bit, mono, 3 _ or not,

Categories