我为游戏开发的声音处理程序可以处理迷糊和声音效果。从理论上讲,每个sfx和音乐应该有一个声音,并且每个声音只能同时播放一个音轨。
但是,在监视使用的资源的同时,跳过曲目时使用的RAM呈指数增长,一直到8Gb的参数限制-这意味着每次播放曲目时它都会再次将曲目加载到内存中,并且永远不会转储。
>在调试此代码时,我在类中的Clip上放置了数量不健康的.Drains和.Flushes,并将AudioInputStream重置为null,没有任何效果。
在旁注中,当快速跳过曲目时,偶尔会出现幻像声音,继续在受控音乐声音的不可控制的背景下播放-我觉得这可能密切相关。
下面是整个类,包括调试期间使用.Drain等的所有位置。歌曲跳过从NextTrack()
或PrevTrack()
开始,两者的结果相同。
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
public class SoundHandler {
private static Clip sfx = null, Music = null;
public static boolean MusicEnabled = true;
private static int STIndex = 0;
private static final int TrackCount = 41;
private static AudioInputStream audioInputStream;
//Channel true = sfx, else music
private static void PlayFile(String filename, boolean Chanel){
try {
audioInputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(new FileInputStream(filename)));
if (Chanel) {
try {sfx.stop(); sfx.drain();}catch (Exception e) {}
sfx = AudioSystem.getClip();
sfx.open(audioInputStream);
sfx.start();
} else {
if (!MusicEnabled) {return;}
try {Music.stop(); Music.drain();}catch (Exception e) {}
Music = AudioSystem.getClip();
Music.open(audioInputStream);
Music.start();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
//Music Handler for external
private static void PlayTrack() {
String Location = String.valueOf(Game.ResourcePath + "/Audio/Runtime/ST" + STIndex + ".wav");
PlayFile(Location, false);
}
public static void SFX(String Effect) {
String Location = String.valueOf(Game.ResourcePath + "/Audio/Runtime/" + Effect + ".wav");
PlayFile(Location, true);
}
public static void NextTrack() {
if (STIndex >= TrackCount) {STIndex = 0;} else {STIndex++;}
Music.stop();
Music.drain();
Music.flush();
try {audioInputStream.close();} catch (IOException e) {}
audioInputStream = null;
PlayTrack();
}
public static void PrevTrack() {
if (STIndex <= 0) {STIndex = TrackCount;} else {STIndex--;}
Music.stop();
Music.drain();
Music.flush();
try {audioInputStream.close();} catch (IOException e) {}
audioInputStream = null;
PlayTrack();
}
public static void StartMusic () {
MusicEnabled = true;
STIndex = 0;
String Location = String.valueOf(Game.ResourcePath + "/Audio/Runtime/ST" + STIndex + ".wav");
PlayFile(Location, false);
}
public static void PlayIndex(int index) {
MusicEnabled = true;
STIndex = 0;
String Location = String.valueOf(Game.ResourcePath + "/Audio/Runtime/ST" + index + ".wav");
PlayFile(Location, false);
}
public static void PlayStop() {
MusicEnabled = !MusicEnabled;
if (MusicEnabled) {
StartMusic();
} else {
try {Music.stop(); Music.drain(); Music.flush();}catch (Exception e) {}
}}
public static void Tick() {
try {if ((!Music.isActive()) && MusicEnabled){NextTrack();}} catch (Exception e) {}
if (!MusicEnabled) {
try {if (!Music.isActive()){Music.stop(); Music.drain();}} catch (Exception e) {}
}}
public static int getST() {
return STIndex;
}
}