Java Sound crash fixes for Linux. (issue #1)
- Explicitly supply the AudioFormat when creating a Clip. - Disable Master Gain if unsupported (e.g. in PulseAudio). - Do not try to play uninitialized sounds (e.g. LineUnavailableException during creation, seems to happen regularly with PulseAudio). Other changes: - Errors replaced with debugs in 'getTrackLength()' if audio fields inaccessible. - Do not log ThreadDeath exceptions (it's a known issue, and only clutters the log file). Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
a9cc7a3deb
commit
83c475cdc1
|
@ -246,7 +246,7 @@ public class MusicController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the length of the track, in milliseconds.
|
* Gets the length of the track, in milliseconds.
|
||||||
* Returns 0f if no file is loaded or an MP3 is currently being converted.
|
* Returns 0 if no file is loaded or an MP3 is currently being converted.
|
||||||
* @author bdk (http://slick.ninjacave.com/forum/viewtopic.php?t=2699)
|
* @author bdk (http://slick.ninjacave.com/forum/viewtopic.php?t=2699)
|
||||||
*/
|
*/
|
||||||
public static int getTrackLength() {
|
public static int getTrackLength() {
|
||||||
|
@ -265,7 +265,8 @@ public class MusicController {
|
||||||
length.setAccessible(true);
|
length.setAccessible(true);
|
||||||
duration = (float) (length.get(audio));
|
duration = (float) (length.get(audio));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.error("Could not get track length.", e);
|
Log.debug("Could not get track length.");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return (int) (duration * 1000);
|
return (int) (duration * 1000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,7 @@ public class Opsu extends StateBasedGame {
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void uncaughtException(Thread t, Throwable e) {
|
public void uncaughtException(Thread t, Throwable e) {
|
||||||
|
if (!(e instanceof ThreadDeath)) // TODO: see MusicController
|
||||||
Log.error("** Uncaught Exception! **", e);
|
Log.error("** Uncaught Exception! **", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,9 +23,11 @@ import itdelatrisu.opsu.states.Options;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
import javax.sound.sampled.AudioFormat;
|
||||||
import javax.sound.sampled.AudioInputStream;
|
import javax.sound.sampled.AudioInputStream;
|
||||||
import javax.sound.sampled.AudioSystem;
|
import javax.sound.sampled.AudioSystem;
|
||||||
import javax.sound.sampled.Clip;
|
import javax.sound.sampled.Clip;
|
||||||
|
import javax.sound.sampled.DataLine;
|
||||||
import javax.sound.sampled.FloatControl;
|
import javax.sound.sampled.FloatControl;
|
||||||
import javax.sound.sampled.LineUnavailableException;
|
import javax.sound.sampled.LineUnavailableException;
|
||||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||||
|
@ -154,7 +156,13 @@ public class SoundController {
|
||||||
try {
|
try {
|
||||||
URL url = ResourceLoader.getResource(ref);
|
URL url = ResourceLoader.getResource(ref);
|
||||||
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
|
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
|
||||||
Clip clip = AudioSystem.getClip();
|
|
||||||
|
// GNU/Linux workaround
|
||||||
|
// Clip clip = AudioSystem.getClip();
|
||||||
|
AudioFormat format = audioIn.getFormat();
|
||||||
|
DataLine.Info info = new DataLine.Info(Clip.class, format);
|
||||||
|
Clip clip = (Clip) AudioSystem.getLine(info);
|
||||||
|
|
||||||
clip.open(audioIn);
|
clip.open(audioIn);
|
||||||
return clip;
|
return clip;
|
||||||
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
|
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
|
||||||
|
@ -218,6 +226,9 @@ public class SoundController {
|
||||||
* @param volume the volume [0, 1]
|
* @param volume the volume [0, 1]
|
||||||
*/
|
*/
|
||||||
private static void playClip(Clip clip, float volume) {
|
private static void playClip(Clip clip, float volume) {
|
||||||
|
if (clip == null) // clip failed to load properly
|
||||||
|
return;
|
||||||
|
|
||||||
if (volume > 0f) {
|
if (volume > 0f) {
|
||||||
// stop clip if running
|
// stop clip if running
|
||||||
if (clip.isRunning()) {
|
if (clip.isRunning()) {
|
||||||
|
@ -225,10 +236,13 @@ public class SoundController {
|
||||||
clip.flush();
|
clip.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PulseAudio does not support Master Gain
|
||||||
|
if (clip.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
|
||||||
// set volume
|
// set volume
|
||||||
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
|
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
|
||||||
float dB = (float) (Math.log(volume) / Math.log(10.0) * 20.0);
|
float dB = (float) (Math.log(volume) / Math.log(10.0) * 20.0);
|
||||||
gainControl.setValue(dB);
|
gainControl.setValue(dB);
|
||||||
|
}
|
||||||
|
|
||||||
// play clip
|
// play clip
|
||||||
clip.setFramePosition(0);
|
clip.setFramePosition(0);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user