为了账号安全,请及时绑定邮箱和手机立即绑定

使音频循环更快

使音频循环更快

狐的传说 2023-03-09 14:01:05
简而言之,我在我的应用程序中使用 .ogg 文件,并且有几个背景音轨需要循环播放。但是,我循环播放音频文件的方法是简单地重新加载音频文件并再次播放。这种方法会在循环的每次播放之间产生延迟,这对于游戏所期望的无缝体验来说是不理想的。有没有一种方法我不必每次都重新加载文件?如有必要,我愿意将音频文件保存在内存中。这是我的 Sound 类,它的功能有所减少,可以解决问题的核心:以下库可能是播放某些文件类型所必需的,并且应该与上述文件一起编译:(链接)对于未来的读者,以防上述链接过期,使用的库如下:jl1.0.1.jarjogg-0.0.7.jarjorbis-0.0.17-1.jarmp3spi1.9.5.jarvorbisspi1.0.3.jar使用这个 Sound 类和这个 ogg 文件(来自 Undertale 的 Spear of Justice),这是一个显示问题的简单类:import javax.sound.sampled.UnsupportedAudioFileException;import java.io.IOException;public class Test {    public static void main(String[] args) throws IOException, UnsupportedAudioFileException, InterruptedException {        //Replace the path with the path to the downloaded soj.ogg file or another test file        Sound spearOfJustice = new Sound("C:\\Users\\gigibayte\\Desktop\\soj.ogg", true);        spearOfJustice.play();        //Ensure that this is greater than or equal than the length of the audio file chosen above in seconds.        int songSeconds = 240;        //Song is played twice to show looping issue        Thread.sleep(songSeconds * 2 * 1000);    }}
查看完整描述

1 回答

?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

实际上,解决方案比我想象的要容易得多。我只是将 do-while 循环移动到流方法并相应地进行了更改。


        PlayingSound() {

            Thread playingSound = new Thread(() -> {


                //REMOVED THE DO WHILE LOOP HERE

                try {

                    AudioInputStream in;

                    in = getAudioInputStream(new File(fileName));

                    final AudioFormat outFormat = getOutFormat(in.getFormat());

                    final Info info = new Info(SourceDataLine.class, outFormat);

                    try(final SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info)) {

                        if(line != null) {

                            line.open(outFormat);

                            line.start();

                            AudioInputStream inputMystream = AudioSystem.getAudioInputStream(outFormat, in);

                            stream(outFormat, inputMystream, line);

                            line.drain();

                            line.stop();

                        }

                    }

                }

                catch(UnsupportedAudioFileException | LineUnavailableException | IOException e) {

                    throw new IllegalStateException(e);

                }

                finally {

                    removeInternalSound(this);

                }

            });

            playingSound.start();

        }


        /**

         * Streams the audio to the mixer

         *

         * @param in   Input stream to audio file

         * @param line Where the audio data can be written to

         * @throws IOException Thrown if given file has any problems

         */

        private void stream(AudioFormat outFormat, AudioInputStream in, SourceDataLine line) throws IOException {

            byte[] buffer = new byte[32];

            do {

                for(int n = 0; n != -1 && !stop; n = in.read(buffer, 0, buffer.length)) {

                    byte[] bufferTemp = new byte[buffer.length];

                    for(int i = 0; i < bufferTemp.length; i += 2) {

                        short audioSample = (short) ((short) ((buffer[i + 1] & 0xff) << 8) | (buffer[i] & 0xff));

                        bufferTemp[i] = (byte) audioSample;

                        bufferTemp[i + 1] = (byte) (audioSample >> 8);

                    }

                    buffer = bufferTemp;

                    line.write(buffer, 0, n);

                }

                in = getAudioInputStream(new File(fileName));

                in = AudioSystem.getAudioInputStream(outFormat, in);

            } while(loopable && !stop);

        }



查看完整回答
反对 回复 2023-03-09
  • 1 回答
  • 0 关注
  • 117 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信