Support loading MP3 sound effects.
Also some minor formatting changes from #22. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
d268008d7a
commit
96e27171e9
|
@ -23,6 +23,7 @@ import itdelatrisu.opsu.Options;
|
||||||
import itdelatrisu.opsu.OsuHitObject;
|
import itdelatrisu.opsu.OsuHitObject;
|
||||||
import itdelatrisu.opsu.audio.HitSound.SampleSet;
|
import itdelatrisu.opsu.audio.HitSound.SampleSet;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -67,54 +68,59 @@ public class SoundController {
|
||||||
/**
|
/**
|
||||||
* Loads and returns a Clip from a resource.
|
* Loads and returns a Clip from a resource.
|
||||||
* @param ref the resource name
|
* @param ref the resource name
|
||||||
|
* @param isMP3 true if MP3, false if WAV
|
||||||
* @return the loaded and opened clip
|
* @return the loaded and opened clip
|
||||||
*/
|
*/
|
||||||
private static Clip loadClip(String ref) {
|
private static Clip loadClip(String ref, boolean isMP3) {
|
||||||
try {
|
try {
|
||||||
URL url = ResourceLoader.getResource(ref);
|
URL url = ResourceLoader.getResource(ref);
|
||||||
//check for 0 length wav files
|
|
||||||
|
// check for 0 length files
|
||||||
InputStream in = url.openStream();
|
InputStream in = url.openStream();
|
||||||
if(in.available()==0){
|
if (in.available() == 0) {
|
||||||
in.close();
|
in.close();
|
||||||
return AudioSystem.getClip();
|
return AudioSystem.getClip();
|
||||||
}
|
}
|
||||||
in.close();
|
in.close();
|
||||||
|
|
||||||
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
|
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
|
||||||
|
|
||||||
// GNU/Linux workaround
|
// GNU/Linux workaround
|
||||||
// Clip clip = AudioSystem.getClip();
|
// Clip clip = AudioSystem.getClip();
|
||||||
AudioFormat format = audioIn.getFormat();
|
AudioFormat format = audioIn.getFormat();
|
||||||
|
if (isMP3) {
|
||||||
|
AudioFormat decodedFormat = new AudioFormat(
|
||||||
|
AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), 16,
|
||||||
|
format.getChannels(), format.getChannels() * 2, format.getSampleRate(), false);
|
||||||
|
AudioInputStream decodedAudioIn = AudioSystem.getAudioInputStream(decodedFormat, audioIn);
|
||||||
|
format = decodedFormat;
|
||||||
|
audioIn = decodedAudioIn;
|
||||||
|
}
|
||||||
DataLine.Info info = new DataLine.Info(Clip.class, format);
|
DataLine.Info info = new DataLine.Info(Clip.class, format);
|
||||||
if(AudioSystem.isLineSupported(info)){
|
if (AudioSystem.isLineSupported(info)) {
|
||||||
Clip clip = (Clip) AudioSystem.getLine(info);
|
Clip clip = (Clip) AudioSystem.getLine(info);
|
||||||
clip.open(audioIn);
|
clip.open(audioIn);
|
||||||
return clip;
|
return clip;
|
||||||
}else{
|
} else {
|
||||||
//Try to find closest matching line
|
// try to find closest matching line
|
||||||
Clip clip = AudioSystem.getClip();
|
Clip clip = AudioSystem.getClip();
|
||||||
AudioFormat[] formats = ((DataLine.Info) clip.getLineInfo())
|
AudioFormat[] formats = ((DataLine.Info) clip.getLineInfo()).getFormats();
|
||||||
.getFormats();
|
|
||||||
int bestIndex = -1;
|
int bestIndex = -1;
|
||||||
float bestScore = 0;
|
float bestScore = 0;
|
||||||
float sampleRate = format.getSampleRate();
|
float sampleRate = format.getSampleRate();
|
||||||
if (sampleRate < 0) {
|
if (sampleRate < 0)
|
||||||
sampleRate = clip.getFormat().getSampleRate();
|
sampleRate = clip.getFormat().getSampleRate();
|
||||||
}
|
|
||||||
float oldSampleRate = sampleRate;
|
float oldSampleRate = sampleRate;
|
||||||
while (true) {
|
while (true) {
|
||||||
for (int i = 0; i < formats.length; i++) {
|
for (int i = 0; i < formats.length; i++) {
|
||||||
AudioFormat curFormat = formats[i];
|
AudioFormat curFormat = formats[i];
|
||||||
AudioFormat newFormat = new AudioFormat(sampleRate,
|
AudioFormat newFormat = new AudioFormat(
|
||||||
curFormat.getSampleSizeInBits(),
|
sampleRate, curFormat.getSampleSizeInBits(),
|
||||||
curFormat.getChannels(), true,
|
curFormat.getChannels(), true, curFormat.isBigEndian());
|
||||||
curFormat.isBigEndian());
|
|
||||||
formats[i] = newFormat;
|
formats[i] = newFormat;
|
||||||
DataLine.Info newLine = new DataLine.Info(Clip.class,
|
DataLine.Info newLine = new DataLine.Info(Clip.class, newFormat);
|
||||||
newFormat);
|
if (AudioSystem.isLineSupported(newLine) &&
|
||||||
if (AudioSystem.isLineSupported(newLine)
|
AudioSystem.isConversionSupported(newFormat, format)) {
|
||||||
&& AudioSystem.isConversionSupported(newFormat,
|
|
||||||
format)) {
|
|
||||||
float score = 1
|
float score = 1
|
||||||
+ (newFormat.getSampleRate() == sampleRate ? 5 : 0)
|
+ (newFormat.getSampleRate() == sampleRate ? 5 : 0)
|
||||||
+ (newFormat.getSampleSizeInBits() == format.getSampleSizeInBits() ? 5 : 0)
|
+ (newFormat.getSampleSizeInBits() == format.getSampleSizeInBits() ? 5 : 0)
|
||||||
|
@ -143,12 +149,10 @@ public class SoundController {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (bestIndex >= 0) {
|
if (bestIndex >= 0) {
|
||||||
clip.open(AudioSystem.getAudioInputStream(
|
clip.open(AudioSystem.getAudioInputStream(formats[bestIndex], audioIn));
|
||||||
formats[bestIndex], audioIn));
|
|
||||||
} else
|
} else
|
||||||
// still couldn't find anything, try the default clip format
|
// still couldn't find anything, try the default clip format
|
||||||
clip.open(AudioSystem.getAudioInputStream(clip.getFormat(),
|
clip.open(AudioSystem.getAudioInputStream(clip.getFormat(), audioIn));
|
||||||
audioIn));
|
|
||||||
return clip;
|
return clip;
|
||||||
}
|
}
|
||||||
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException | RuntimeException e) {
|
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException | RuntimeException e) {
|
||||||
|
@ -157,6 +161,26 @@ public class SoundController {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the sound file name, with extension, by first looking through
|
||||||
|
* the skins directory and then the default images.
|
||||||
|
* @param filename the base file name
|
||||||
|
* @return the full file name, or null if no file found
|
||||||
|
*/
|
||||||
|
private static String getSoundFileName(String filename) {
|
||||||
|
String wav = String.format("%s.wav", filename), mp3 = String.format("%s.mp3", filename);
|
||||||
|
File skinWAV = new File(Options.getSkinDir(), wav), skinMP3 = new File(Options.getSkinDir(), mp3);
|
||||||
|
if (skinWAV.isFile())
|
||||||
|
return skinWAV.getAbsolutePath();
|
||||||
|
if (skinMP3.isFile())
|
||||||
|
return skinMP3.getAbsolutePath();
|
||||||
|
if (ResourceLoader.resourceExists(wav))
|
||||||
|
return wav;
|
||||||
|
if (ResourceLoader.resourceExists(mp3))
|
||||||
|
return mp3;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads all sound files.
|
* Loads all sound files.
|
||||||
*/
|
*/
|
||||||
|
@ -164,21 +188,27 @@ public class SoundController {
|
||||||
if (Options.isSoundDisabled())
|
if (Options.isSoundDisabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: support MP3 sounds?
|
|
||||||
currentFileIndex = 0;
|
currentFileIndex = 0;
|
||||||
|
|
||||||
// menu and game sounds
|
// menu and game sounds
|
||||||
for (SoundEffect s : SoundEffect.values()) {
|
for (SoundEffect s : SoundEffect.values()) {
|
||||||
currentFileName = String.format("%s.wav", s.getFileName());
|
if ((currentFileName = getSoundFileName(s.getFileName())) == null) {
|
||||||
s.setClip(loadClip(currentFileName));
|
ErrorHandler.error(String.format("Could not find sound file '%s'.", s.getFileName()), null, false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
s.setClip(loadClip(currentFileName, currentFileName.endsWith(".mp3")));
|
||||||
currentFileIndex++;
|
currentFileIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// hit sounds
|
// hit sounds
|
||||||
for (SampleSet ss : SampleSet.values()) {
|
for (SampleSet ss : SampleSet.values()) {
|
||||||
for (HitSound s : HitSound.values()) {
|
for (HitSound s : HitSound.values()) {
|
||||||
currentFileName = String.format("%s-%s.wav", ss.getName(), s.getFileName());
|
String filename = String.format("%s-%s", ss.getName(), s.getFileName());
|
||||||
s.setClip(ss, loadClip(currentFileName));
|
if ((currentFileName = getSoundFileName(filename)) == null) {
|
||||||
|
ErrorHandler.error(String.format("Could not find hit sound file '%s'.", filename), null, false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
s.setClip(ss, loadClip(currentFileName, false));
|
||||||
currentFileIndex++;
|
currentFileIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user