2011-08-18 49 views
0

我正在使用AudioInputStream將字節傳送到SourceDataLine以播放PCM文件。我想讓用戶能夠將滑塊移動到文件中的某個點。跳轉到使用Java Sound API的音頻文件中的位置

問題我有:

  • markSupported()回報falseAudioInputStream。所以我 不能使用我最初的方法調用reset()然後skip()(其中 我已經認爲是一種醜陋的...)
  • 我真的不想推倒InputStrea米,並創建一個新的剛跳到在我目前的商標之前的位置。
  • SourceLineData.getLongFramePosition()似乎並不十分可靠......我知道它有一個緩衝區,但即使考慮爲byte的左在緩衝區中,我不理解的行爲

我已經考慮使用一個Memory-Mapped File將字節提供給線路,以便我可以隨意跳到任何地方,但是如果我不需要,我不想增加函數的複雜性。有沒有一種好方法可以做到這一點,我錯過了?任何人都可以解釋getLongFramePosition()返回的幀號實際上是什麼意思?是通過揚聲器傳遞的幀數(看起來不是)?

+0

爲什麼不使用'Clip'? –

+0

,因爲我正在播放的文件可能是未指定的長度。我的理解是剪輯適用於非常短的聲音。 – sethro

+0

'未指定'或'大'?區別非常重要。例如。 [BigClip](http://stackoverflow.com/questions/5667454/playing-audio-file-in-java-application/5668510#5668510)可以處理**大**剪輯。 (是的,你對'Clip'的理解是正確的。) –

回答

0

我能想出最徹底的方法是使用一個FileChannel基於用戶讀取字節到SourceDataLine這樣移動滑塊我可以確定文件中的字節位置(確保將其調整或舍入爲與一個幀對齊),然後在FileChannel中設置該位置,然後繼續播放。當發生這種情況時,我不會播放剩餘的字節。

1

BigClip是否適合您?

如果不是,這是可以工作的東西。警告,這是一個錯綜複雜。 http://hexara.com/VSL/VSL2.htm

有了這個Applet,你可以加載一個wav - 我已經加載了超過5分鐘的wavs,它工作正常,但音頻數據佔用了大量的RAM。

加載WAV後,您可以將鼠標移動到任意位置,然後通過向下拖動鼠標進行回放。顯然,這不是你想要做的,因爲你想從某個角度回放,而不必擔心拖拽或拖拽速度。但是爲了讓數據處於可播放狀態而採取的路徑仍然適用於您。

如果您有一個可用的AudioInputStream和AudioFileFormat,您可以設置一個內部數組並直接讀取數據。音頻文件格式爲您提供了可用於計算陣列維度的幀編碼和幀長度。

然後,製作一個TargetDataLine,從您製作的數組中獲取音頻數據。 TDL必須有一個變量來標記下一次讀取的開始位置。您可以使用JSlider來更改該變量的內容,以指向您想要的任何框架。

如果您沒有工作的AudioInputStream,有辦法得到一個...但它更復雜,涉及ByteArrayOutput &輸入流對象。可能不需要去那裏。 (我用它們來讀取上面的Applet中的客戶端數據。)

至於你關於當前幀位置的問題,關鍵問題是JVM處理塊中的音頻數據,它傾向於超前在陣陣中聽到。我撞了我的頭靠在這個問題了半晌,然後想出了這個: http://www.java-gaming.org/index.php/topic,24605.0.html

+0

感謝這個例子,我實際上已經想出了一個解決方案,我忘了發佈它。 – sethro