在Java中播放游戏音乐-如何停止数据流?

在Java中播放游戏音乐-如何停止数据流?,java,audio,Java,Audio,我在高中的入门课上为一个游戏上了音乐课。你可以看到我从哪里得到的代码 我最初使用的是剪辑,但发现它的缓冲区很小,不能很好地播放长歌(至少不能在学校的Mac电脑上播放)。据我所知,新的代码工作得很好,就是得到歌曲的“块”,播放它们,然后得到更多的块。问题是,当音乐改变时,歌曲有时会重叠,当我退出游戏时,可能会发出可怕的声音(至少在Mac电脑上),因为游戏结束前数据流被切断 除了每次将程序延迟几秒钟之外,还有其他方法可以解决这个问题吗? (注意:我不想使用external.jar或库,我希望严格遵守

我在高中的入门课上为一个游戏上了音乐课。你可以看到我从哪里得到的代码

我最初使用的是
剪辑
,但发现它的缓冲区很小,不能很好地播放长歌(至少不能在学校的Mac电脑上播放)。据我所知,新的代码工作得很好,就是得到歌曲的“块”,播放它们,然后得到更多的块。问题是,当音乐改变时,歌曲有时会重叠,当我退出游戏时,可能会发出可怕的声音(至少在Mac电脑上),因为游戏结束前数据流被切断

除了每次将程序延迟几秒钟之外,还有其他方法可以解决这个问题吗? (注意:我不想使用external.jar或库,我希望严格遵守JRE)


我不确定你会听到什么可怕的声音,但我想我知道如何解决你提到的重叠问题。看起来您对声音API的使用还不错,但我怀疑您可能存在并发问题。我注意到你播放的每个声音都有一个新的线索。这是一个好主意,但如果你不想让你的歌曲混音,你需要小心。我的理论是,您的代码如下所示:

Music songA = new Music();
Music songB = new Music();

//Start playing song A
songA.playMusic("path");

//Some stuff happens with your game...

//Some time later you want to change to song B
songA.stop();
songB.playMusic("other path");
乍一看,这看起来不错,毕竟你在开始songB之前很小心地阻止了songA,对吧?不幸的是,当涉及到并发时,很少有事情像我们希望的那样简单。让我们看一小段代码,特别是负责将数据馈送到音频流的
while
循环

//Inside run(), this is the interesting bit at the end

while(nBytesRead != -1 && play == true){
    //Feed the audio stream while there is still data 
}
stop()。如果我没有弄错的话,您的
while
循环的每次迭代都会将64k的数据发送到音频流中。64k是相当数量的音频数据,根据音频属性,它将持续一段时间。您真正想要做的是向线程发出退出信号(即将play设置为false),然后等待线程完成。我相信这将解决重叠的问题,如果你没有正确地杀死你的线程,这个问题也可能会导致退出时可怕的争吵。我谦恭地建议对你的音乐课进行以下更改(不保证正确性)


希望这能有所帮助,而且出于对所有善良和纯洁的爱,不要按原样使用我的代码,它在大约2分钟内就从我的脑海中消失了。我推荐。

1)我听说Java声音在Mac上有问题。2)
playMusic(stringloc)
String
表示
文件
对象的参数让我不寒而栗。如果需要
文件
,则不接受其他文件。3) 在这个主题上,在大多数情况下,
InputStream
作为参数胜过
文件
InputStream
可以来自内存中构造的
文件
URL
(可以包括存档中的资源)或
ByteArrayInputStream
。1。是的。总的来说,Clip并没有那个么好,而且对您可以向它提供多少数据有很小的限制,因为它将数据完全存储在内存中。我在电脑上没有问题,但在Mac电脑上,我遇到了与尺寸相关的问题。2.对不起,我仍然是一个初学者,17岁,没有受过正规教育(高中的入门课很难算),大部分我必须自学的东西,我会记住这一点。3.诚然,即使我不得不重新编写一个项目,我也会尽可能地提高效率,这绝对是一种更好的方式,尽管对游戏来说有些不必要。谢谢你的回答!该项目今天到期(必须在昨天完成),所以很遗憾,我没有尝试你的解决方案。通过刷新声音线(以及其他一些东西),我能够让音频停止。你说得对,为什么它是重叠的,在下一个开始播放之前,声音根本没有停止。关闭时的可怕声音,我认为是由于出口时音频未播放完造成的。有了更好的退出方式,并在结束时等待200毫秒,似乎一切正常,除非点击左上角的X按钮并强制关闭。
//Inside run(), this is the interesting bit at the end

while(nBytesRead != -1 && play == true){
    //Feed the audio stream while there is still data 
}
public class Music implements Runnable{
    private Thread t;    //Make the thread object a class field

    //Just about everything is the same as it was before...

    public void stop(){
        play = false;
        try{
            t.join()
        }catch(InterruptedException e){
            //Don't do anything, it doesn't matter
        }
   }
}