1

因此,我正在用 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();
4

0 回答 0