Java - звуки иногда играют на очень громком и нерегулярном уровне громкости
Итак, я делаю игру на 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();