使音频循环更快

简而言之,我在我的应用程序中使用 .ogg 文件,并且有几个背景音轨需要循环播放。

但是,我循环播放音频文件的方法是简单地重新加载音频文件并再次播放。这种方法会在循环的每次播放之间产生延迟,这对于游戏所期望的无缝体验来说是不理想的。

有没有一种方法我不必每次都重新加载文件?如有必要,我愿意将音频文件保存在内存中。

这是我的 Sound 类,它的功能有所减少,可以解决问题的核心:

以下库可能是播放某些文件类型所必需的,并且应该与上述文件一起编译:(链接)

对于未来的读者,以防上述链接过期,使用的库如下:

  • jl1.0.1.jar

  • jogg-0.0.7.jar

  • jorbis-0.0.17-1.jar

  • mp3spi1.9.5.jar

  • vorbisspi1.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);

    }


}


狐的传说
浏览 118回答 1
1回答

犯罪嫌疑人X

实际上,解决方案比我想象的要容易得多。我只是将 do-while 循环移动到流方法并相应地进行了更改。&nbsp; &nbsp; &nbsp; &nbsp; PlayingSound() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread playingSound = new Thread(() -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //REMOVED THE DO WHILE LOOP HERE&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AudioInputStream in;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in = getAudioInputStream(new File(fileName));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final AudioFormat outFormat = getOutFormat(in.getFormat());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final Info info = new Info(SourceDataLine.class, outFormat);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try(final SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(line != null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; line.open(outFormat);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; line.start();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AudioInputStream inputMystream = AudioSystem.getAudioInputStream(outFormat, in);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stream(outFormat, inputMystream, line);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; line.drain();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; line.stop();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch(UnsupportedAudioFileException | LineUnavailableException | IOException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalStateException(e);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; finally {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; removeInternalSound(this);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; playingSound.start();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Streams the audio to the mixer&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param in&nbsp; &nbsp;Input stream to audio file&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param line Where the audio data can be written to&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @throws IOException Thrown if given file has any problems&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; &nbsp; &nbsp; private void stream(AudioFormat outFormat, AudioInputStream in, SourceDataLine line) throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; byte[] buffer = new byte[32];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; do {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(int n = 0; n != -1 && !stop; n = in.read(buffer, 0, buffer.length)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; byte[] bufferTemp = new byte[buffer.length];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(int i = 0; i < bufferTemp.length; i += 2) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; short audioSample = (short) ((short) ((buffer[i + 1] & 0xff) << 8) | (buffer[i] & 0xff));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bufferTemp[i] = (byte) audioSample;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bufferTemp[i + 1] = (byte) (audioSample >> 8);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buffer = bufferTemp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; line.write(buffer, 0, n);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in = getAudioInputStream(new File(fileName));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in = AudioSystem.getAudioInputStream(outFormat, in);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } while(loopable && !stop);&nbsp; &nbsp; &nbsp; &nbsp; }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java