Better error handling for Clip loading. (fixes #59)
Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
16ec6c5e23
commit
850a6c3882
|
@ -35,7 +35,6 @@ import javax.sound.sampled.Clip;
|
||||||
import javax.sound.sampled.DataLine;
|
import javax.sound.sampled.DataLine;
|
||||||
import javax.sound.sampled.LineListener;
|
import javax.sound.sampled.LineListener;
|
||||||
import javax.sound.sampled.LineUnavailableException;
|
import javax.sound.sampled.LineUnavailableException;
|
||||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
|
||||||
|
|
||||||
import org.newdawn.slick.SlickException;
|
import org.newdawn.slick.SlickException;
|
||||||
import org.newdawn.slick.util.ResourceLoader;
|
import org.newdawn.slick.util.ResourceLoader;
|
||||||
|
@ -89,7 +88,7 @@ public class SoundController {
|
||||||
|
|
||||||
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
|
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
|
||||||
return loadClip(ref, audioIn, isMP3);
|
return loadClip(ref, audioIn, isMP3);
|
||||||
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException | RuntimeException e) {
|
} catch (Exception e) {
|
||||||
ErrorHandler.error(String.format("Failed to load file '%s'.", ref), e, true);
|
ErrorHandler.error(String.format("Failed to load file '%s'.", ref), e, true);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -102,77 +101,72 @@ public class SoundController {
|
||||||
* @param isMP3 true if MP3, false if WAV
|
* @param isMP3 true if MP3, false if WAV
|
||||||
* @return the loaded and opened clip
|
* @return the loaded and opened clip
|
||||||
*/
|
*/
|
||||||
private static MultiClip loadClip(String ref, AudioInputStream audioIn, boolean isMP3) {
|
private static MultiClip loadClip(String ref, AudioInputStream audioIn, boolean isMP3)
|
||||||
try {
|
throws IOException, LineUnavailableException {
|
||||||
AudioFormat format = audioIn.getFormat();
|
AudioFormat format = audioIn.getFormat();
|
||||||
if (isMP3) {
|
if (isMP3) {
|
||||||
AudioFormat decodedFormat = new AudioFormat(
|
AudioFormat decodedFormat = new AudioFormat(
|
||||||
AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), 16,
|
AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), 16,
|
||||||
format.getChannels(), format.getChannels() * 2, format.getSampleRate(), false);
|
format.getChannels(), format.getChannels() * 2, format.getSampleRate(), false);
|
||||||
AudioInputStream decodedAudioIn = AudioSystem.getAudioInputStream(decodedFormat, audioIn);
|
AudioInputStream decodedAudioIn = AudioSystem.getAudioInputStream(decodedFormat, audioIn);
|
||||||
format = decodedFormat;
|
format = decodedFormat;
|
||||||
audioIn = decodedAudioIn;
|
audioIn = decodedAudioIn;
|
||||||
}
|
|
||||||
DataLine.Info info = new DataLine.Info(Clip.class, format);
|
|
||||||
if (AudioSystem.isLineSupported(info)) {
|
|
||||||
return new MultiClip(ref, audioIn);
|
|
||||||
} else {
|
|
||||||
// try to find closest matching line
|
|
||||||
Clip clip = AudioSystem.getClip();
|
|
||||||
AudioFormat[] formats = ((DataLine.Info) clip.getLineInfo()).getFormats();
|
|
||||||
int bestIndex = -1;
|
|
||||||
float bestScore = 0;
|
|
||||||
float sampleRate = format.getSampleRate();
|
|
||||||
if (sampleRate < 0)
|
|
||||||
sampleRate = clip.getFormat().getSampleRate();
|
|
||||||
float oldSampleRate = sampleRate;
|
|
||||||
while (true) {
|
|
||||||
for (int i = 0; i < formats.length; i++) {
|
|
||||||
AudioFormat curFormat = formats[i];
|
|
||||||
AudioFormat newFormat = new AudioFormat(
|
|
||||||
sampleRate, curFormat.getSampleSizeInBits(),
|
|
||||||
curFormat.getChannels(), true, curFormat.isBigEndian());
|
|
||||||
formats[i] = newFormat;
|
|
||||||
DataLine.Info newLine = new DataLine.Info(Clip.class, newFormat);
|
|
||||||
if (AudioSystem.isLineSupported(newLine) &&
|
|
||||||
AudioSystem.isConversionSupported(newFormat, format)) {
|
|
||||||
float score = 1
|
|
||||||
+ (newFormat.getSampleRate() == sampleRate ? 5 : 0)
|
|
||||||
+ (newFormat.getSampleSizeInBits() == format.getSampleSizeInBits() ? 5 : 0)
|
|
||||||
+ (newFormat.getChannels() == format.getChannels() ? 5 : 0)
|
|
||||||
+ (newFormat.isBigEndian() == format.isBigEndian() ? 1 : 0)
|
|
||||||
+ newFormat.getSampleRate() / 11025
|
|
||||||
+ newFormat.getChannels()
|
|
||||||
+ newFormat.getSampleSizeInBits() / 8;
|
|
||||||
if (score > bestScore) {
|
|
||||||
bestIndex = i;
|
|
||||||
bestScore = score;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bestIndex < 0) {
|
|
||||||
if (oldSampleRate < 44100) {
|
|
||||||
if (sampleRate > 44100)
|
|
||||||
break;
|
|
||||||
sampleRate *= 2;
|
|
||||||
} else {
|
|
||||||
if (sampleRate < 44100)
|
|
||||||
break;
|
|
||||||
sampleRate /= 2;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (bestIndex >= 0) {
|
|
||||||
return new MultiClip(ref, AudioSystem.getAudioInputStream(formats[bestIndex], audioIn));
|
|
||||||
} else
|
|
||||||
// still couldn't find anything, try the default clip format
|
|
||||||
return new MultiClip(ref, AudioSystem.getAudioInputStream(clip.getFormat(), audioIn));
|
|
||||||
}
|
|
||||||
} catch (IOException | LineUnavailableException | RuntimeException e) {
|
|
||||||
ErrorHandler.error(String.format("Failed to load file '%s'.", ref), e, true);
|
|
||||||
}
|
}
|
||||||
return null;
|
DataLine.Info info = new DataLine.Info(Clip.class, format);
|
||||||
|
if (AudioSystem.isLineSupported(info))
|
||||||
|
return new MultiClip(ref, audioIn);
|
||||||
|
|
||||||
|
// try to find closest matching line
|
||||||
|
Clip clip = AudioSystem.getClip();
|
||||||
|
AudioFormat[] formats = ((DataLine.Info) clip.getLineInfo()).getFormats();
|
||||||
|
int bestIndex = -1;
|
||||||
|
float bestScore = 0;
|
||||||
|
float sampleRate = format.getSampleRate();
|
||||||
|
if (sampleRate < 0)
|
||||||
|
sampleRate = clip.getFormat().getSampleRate();
|
||||||
|
float oldSampleRate = sampleRate;
|
||||||
|
while (true) {
|
||||||
|
for (int i = 0; i < formats.length; i++) {
|
||||||
|
AudioFormat curFormat = formats[i];
|
||||||
|
AudioFormat newFormat = new AudioFormat(
|
||||||
|
sampleRate, curFormat.getSampleSizeInBits(),
|
||||||
|
curFormat.getChannels(), true, curFormat.isBigEndian());
|
||||||
|
formats[i] = newFormat;
|
||||||
|
DataLine.Info newLine = new DataLine.Info(Clip.class, newFormat);
|
||||||
|
if (AudioSystem.isLineSupported(newLine) &&
|
||||||
|
AudioSystem.isConversionSupported(newFormat, format)) {
|
||||||
|
float score = 1
|
||||||
|
+ (newFormat.getSampleRate() == sampleRate ? 5 : 0)
|
||||||
|
+ (newFormat.getSampleSizeInBits() == format.getSampleSizeInBits() ? 5 : 0)
|
||||||
|
+ (newFormat.getChannels() == format.getChannels() ? 5 : 0)
|
||||||
|
+ (newFormat.isBigEndian() == format.isBigEndian() ? 1 : 0)
|
||||||
|
+ newFormat.getSampleRate() / 11025
|
||||||
|
+ newFormat.getChannels()
|
||||||
|
+ newFormat.getSampleSizeInBits() / 8;
|
||||||
|
if (score > bestScore) {
|
||||||
|
bestIndex = i;
|
||||||
|
bestScore = score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bestIndex < 0) {
|
||||||
|
if (oldSampleRate < 44100) {
|
||||||
|
if (sampleRate > 44100)
|
||||||
|
break;
|
||||||
|
sampleRate *= 2;
|
||||||
|
} else {
|
||||||
|
if (sampleRate < 44100)
|
||||||
|
break;
|
||||||
|
sampleRate /= 2;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (bestIndex >= 0)
|
||||||
|
return new MultiClip(ref, AudioSystem.getAudioInputStream(formats[bestIndex], audioIn));
|
||||||
|
|
||||||
|
// still couldn't find anything, try the default clip format
|
||||||
|
return new MultiClip(ref, AudioSystem.getAudioInputStream(clip.getFormat(), audioIn));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -327,7 +321,7 @@ public class SoundController {
|
||||||
* @param isMP3 true if MP3, false if WAV
|
* @param isMP3 true if MP3, false if WAV
|
||||||
* @param listener the line listener
|
* @param listener the line listener
|
||||||
* @return the MultiClip being played
|
* @return the MultiClip being played
|
||||||
* @throws SlickException if any error occurred (UnsupportedAudioFileException, IOException, RuntimeException)
|
* @throws SlickException if any error occurred
|
||||||
*/
|
*/
|
||||||
public static synchronized MultiClip playTrack(URL url, boolean isMP3, LineListener listener) throws SlickException {
|
public static synchronized MultiClip playTrack(URL url, boolean isMP3, LineListener listener) throws SlickException {
|
||||||
stopTrack();
|
stopTrack();
|
||||||
|
@ -336,7 +330,7 @@ public class SoundController {
|
||||||
currentTrack = loadClip(url.getFile(), audioIn, isMP3);
|
currentTrack = loadClip(url.getFile(), audioIn, isMP3);
|
||||||
playClip(currentTrack, Options.getMusicVolume() * Options.getMasterVolume(), listener);
|
playClip(currentTrack, Options.getMusicVolume() * Options.getMasterVolume(), listener);
|
||||||
return currentTrack;
|
return currentTrack;
|
||||||
} catch (UnsupportedAudioFileException | IOException | RuntimeException e) {
|
} catch (Exception e) {
|
||||||
throw new SlickException(String.format("Failed to load clip '%s'.", url.getFile(), e));
|
throw new SlickException(String.format("Failed to load clip '%s'.", url.getFile(), e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -498,7 +498,7 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
});
|
});
|
||||||
previewID = node.getID();
|
previewID = node.getID();
|
||||||
} catch (SlickException e) {
|
} catch (SlickException e) {
|
||||||
UI.sendBarNotification("Failed to load track preview.");
|
UI.sendBarNotification("Failed to load track preview. See log for details.");
|
||||||
Log.error(e);
|
Log.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user