2016-07-27 116 views
3

我在做遊戲擴展來播放一些聲音。這些聲音可能會在隨機時間觸發,這意味着相同的聲音可能會以很短的時間間隔被觸發兩次。在這種情況下,即使聲音已經播放,聲音也應該開始播放(如果有意義的話)。如何啓動已播放的聲音?

我正在使用剪輯播放聲音。這意味着我必須在播放剪輯之前「倒回」剪輯。看起來,因爲它是相同的片段,所以它在重新開始之前停止播放。我想要的是讓它繼續播放,並在前一首中播放相同的剪輯。看到這個例子:

import java.io.File; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.Clip; 

public class JavaApplication { 

    public static void main(String[] args) throws Exception { 
     File file = new File(JavaApplication.class.getResource("1.wav").getPath()); 
     AudioInputStream inputStream = AudioSystem.getAudioInputStream(file); 

     Clip clip = AudioSystem.getClip(); 
     clip.open(inputStream); 
     clip.setFramePosition(0); 
     clip.start(); // The sound is 300 ms long 
     Thread.sleep(150); // Let it play for 150 ms 
     clip.setFramePosition(0); // Attempt to start it from the beginning, without stopping it 
     clip.start(); 
     Thread.sleep(1000); 
    } 
} 

回答

0

找到了解決方案:讀取聲音的原始字節,並在每次播放聲音時從數據創建一個輸入流。這使我可以在「自身之上」播放相同的聲音文件,而無需從磁盤載入多次。

package com.mysite.javaapplication; 

import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.Clip; 

public class JavaApplication { 

    private static void playSoundBytes(byte[] data) throws Exception { 
     AudioInputStream inputStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(data)); 
     AudioFormat format = inputStream.getFormat(); 
     Clip clip = AudioSystem.getClip(); 
     clip.open(inputStream); 
     clip.setFramePosition(0); 
     clip.start(); 
    } 

    private static byte[] getResourceAsBytes(String name, int bufferSize) throws IOException { 
     InputStream stream = JavaApplication.class.getResourceAsStream(name); 
     byte buffer[] = new byte[bufferSize]; 
     int b, i = 0; 
     while ((b = stream.read()) != -1) { 
      try { 
       buffer[i++] = (byte) b; 
      } catch (IndexOutOfBoundsException e) { 
       throw new IOException("Buffer of " + bufferSize + " bytes is too small to read resource \"" + name + "\""); 
      } 
     } 
     byte data[] = new byte[i + 1]; 
     while (i >= 0) { 
      data[i] = buffer[i]; 
      i--; 
     } 
     return data; 
    } 

    public static void main(String[] args) throws Exception { 

     byte[] soundData = getResourceAsBytes("/1.wav", 1000*1000); 
     playSoundBytes(soundData); 
     Thread.sleep(1000); 
     playSoundBytes(soundData); 
     Thread.sleep(2000); 
    } 
} 
0

你有沒有嘗試過創建一個重複的對象,當你需要它,並在它完成後摧毀它?一個新的剪輯對象或只是複製原始,並讓它與它一起玩。

Clip temp = clip; 
temp.start(); // The sound is 300 ms long 
Thread.sleep(150); // Let it play for 150 ms 
temp = null; 

只是一個建議,你也可以嘗試使用Clip []數組來處理在不同時間播放的幾個片段。

+0

謝謝,但沒有它不起作用。一組剪輯可以工作,但我似乎我不得不加載相同的文件兩次。我現在不是真的有多少相同聲音的「層」會相互「頂」,所以... – gromit190

+0

可能嘗試多線程?,每個線程都可以有一個關聯的Clip對象來處理,這樣你就可以將你的剪輯功能編碼一次,並在你每次需要播放時執行一個線程? – Aaron

+0

請參閱我的問題編輯 – gromit190

0

您需要創建兩個AudioInputStream實例。不需要在代碼中明確使用多線程。跳它會有所幫助。謝謝。

import java.io.File; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.Clip; 

public class JavaApplication { 

    public static void main(String[] args) throws Exception { 

     File file = new File(JavaApplication.class.getResource("1.wav").getPath()); 
     AudioInputStream inputStream1 = AudioSystem.getAudioInputStream(file); 
     AudioInputStream inputStream2 = AudioSystem.getAudioInputStream(file); 

     Clip clip = AudioSystem.getClip(); 
     clip.open(inputStream1); 
     clip.setFramePosition(0); 
     clip.start(); 

     // Clip is 2000 ms long. let it play for 1000 ms 
     Thread.sleep(1000); 

     Clip clip2 = AudioSystem.getClip(); 
     clip2.open(inputStream2); 
     clip2.setFramePosition(0); 
     clip2.start(); 

     Thread.sleep(2000); 

    } 
} 
+0

的狀態下運行,但這意味着我每次播放時都必須從系統加載聲音文件?如果是這樣,會傷害表現嗎? – gromit190

+0

@Birger。偉大的一點。我認爲這會傷害你的表現。也許你應該在整個遊戲應用程序上嘗試一下,看看性能問題是否可以容忍。 – Gearon

+0

它可能會正常運行,但每次從磁盤加載文件似乎都不正確。沒有其他辦法嗎? – gromit190