因此,我正在用 Java 制作游戏并使用以下代码来播放音效(枪声、爆炸等)。但是,有时,声音效果会以非常不规则的音量播放,比我预期的要响亮,即使它通常以标准音量播放。
当我同时播放很多声音时,这种情况更常见,有时一个声音片段的音量会比其他声音高得多,而且差异非常明显。
我已经录制了该问题的简短音频片段:Youtube 链接
任何帮助弄清楚为什么会发生这种情况将不胜感激。
这是我的声音类中使用的代码:
import java.io.File;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.*;
public class sound{
static File sound;
static boolean muted = false; // This should explain itself
static float volume = (float)100.0; // This is the volume that goes from 0 to 100
static float pan = (float)0.0; // The balance between the speakers 0 is both sides and it goes from -1 to 1
static double seconds = (double)0.0; // The amount of seconds to wait before the sound starts playing
static boolean looped_forever = false; // It will keep looping forever if this is true
static int loop_times = 0; // Set the amount of extra times you want the sound to loop (you don't need to have looped_forever set to true)
static int loops_done = 0; // When the program is running this is counting the times the sound has looped so it knows when to stop
final static Runnable playSound = new Runnable(){ //This Thread/Runnabe is for playing the sound
public void run(){
try{
// Check if the audio file is a .wav file
if (sound.getName().toLowerCase().contains(".wav")){
AudioInputStream stream = AudioSystem.getAudioInputStream(sound);
AudioFormat format = stream.getFormat();
if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED){
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
format.getSampleRate(),
format.getSampleSizeInBits() * 2,
format.getChannels(),
format.getFrameSize() * 2,
format.getFrameRate(),
true);
stream = AudioSystem.getAudioInputStream(format, stream);
}
SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class,stream.getFormat(),(int) (stream.getFrameLength() * format.getFrameSize()));
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
line.open(stream.getFormat());
line.start();
// Set Volume
FloatControl volume_control = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
volume_control.setValue((float) (Math.log(volume / 100.0f) / Math.log(10.0f) * 20.0f));
// Mute
BooleanControl mute_control = (BooleanControl) line.getControl(BooleanControl.Type.MUTE);
mute_control.setValue(muted);
FloatControl pan_control = (FloatControl) line.getControl(FloatControl.Type.PAN);
pan_control.setValue(pan);
long last_update = System.currentTimeMillis();
double since_last_update = (System.currentTimeMillis() - last_update) / 1000.0d;
// Wait the amount of seconds set before continuing
while (since_last_update < seconds){
since_last_update = (System.currentTimeMillis() - last_update) / 1000.0d;
}
int num_read = 0;
byte[] buf = new byte[line.getBufferSize()];
while ((num_read = stream.read(buf, 0, buf.length)) >= 0){
int offset = 0;
while (offset < num_read){
offset += line.write(buf, offset, num_read - offset);
}
}
line.drain();
line.stop();
line.close();
if (looped_forever){
new Thread(playSound).start();
}
else if (loops_done < loop_times){
loops_done++;
new Thread(playSound).start();
}
}
}
catch (Exception ex) { ex.printStackTrace(); }
}
};
}
我使用这段代码播放声音,每次武器射出子弹时我都会播放它:
sound.sound=new File("mySoundFile.wav");
new Thread(sound.playSound).start();