2010-06-21 58 views
2

我在Java中看到一些奇怪的行爲與Clip實例。音頻片段卡住

我正在處理的課程的目的是保持包含相同聲音樣本的Clip個實例的數量的計數(索引爲URI)。當應用程序請求播放一個片段並且已經有三個或更多片段通過PANframePosition加權和

  • 排序當前播放的剪輯:從相同的源已經在播放時,執行以下步驟。
  • 選擇具有最高值的剪輯作爲要停止並重新啓動的剪輯。
  • 重新啓動剪輯(下面的方法):

void restart(Clip clip, float gain, float pan) { 
    clip.stop(); 
    clip.flush(); 
    pan = Math.max(-1f, Math.min(pan, 1f)); 
    ((FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN)) 
         .setValue(gain); 
    ((FloatControl) clip.getControl(FloatControl.Type.PAN)) 
         .setValue(pan); 
    clip.setFramePosition(0); 
    clip.start(); 
} 
發生

奇怪的行爲,如果這種方法被稱爲快速連續多次(如20 1ms內次):

  • 剪輯播放
  • 剪輯觸發START事件以表示它已開始播放
  • 剪輯永遠不會觸發STOP事件。
  • stopstart後續調用沒有任何效果(但不要拋出異常。)
  • getFramePosition總是返回0,即使當夾子聽得見(最後一次)

任何想法可能造成這種情況?

我不認爲這是一個線程問題(至少在我的代碼。)只有一個線程調用我的類的公共方法(和他們都是​​反正)


可能與this bug有關。

+0

作爲一個快速測試,您可以嘗試在整個重新啓動方法的剪輯實例上同步,以排除任何線程問題。 – mdma 2010-06-25 20:22:09

+0

@mdma,我會嘗試,但如果它有所作爲,我會感到驚訝。 'restart'只能從另一個'synchronized'方法調用。 – finnw 2010-06-25 20:54:07

回答

1

DataLine.startDataLine.stop的呼叫已經內部AbstractDataLine同步DataLine的混頻器。

我強烈懷疑somewehere下來調用堆棧(以下implStart()/implStop()的任何DataLine化身你有,本地nStart/nstop內非常可能)至少一個異步調用時,從而導致競爭條件你觀察。

使用​​或任何其他Java構造來解決這類問題是不可能的,而不需要對被調用的本地實現有更深入的瞭解。

A 可行的即時解決方法可能是關閉舊剪輯並打開新實例而不是倒回舊剪輯。不是最佳的,但它可能會做一個更深入的調查。

爲了能夠執行上述深入調查,您需要知道您所在的平臺以及您的ClipMixer實例的實際類別名稱的確認。

UPDATE

同時,請用內省來設置com.sun.media.sound.Printer.trace = true(或提供自己實現com.sun.media.sound.PrinterCLASSPATH

本質DirectClip.open() spawns它訪問幾個volatile variables(特別感興趣的存在一個threaddoIO)以非線程安全的方式,這可能會導致主播放循環掛起。

可以確認(或體弱者)此(與Printer跡線一起)通過迫使thread dump在表觀掛起的時間,並檢查回放線程狀態/堆棧跟蹤(或使用調試器。)

如果doIO等訪問變成了不是成爲問題,那麼繼續挖掘本機實現仍然是要做的事情;如果doIO等訪問確實成爲問題,然後再次,有沒有簡單的修復(你可以嘗試使用自省抓住DirectClip.thread並定期發信號它的情況下,因爲doIO停止 - 再次,待確認)

+0

調音臺是'com.sun.media.sound.DirectAudioDevice',剪輯是'com.sun.media.sound.DirectAudioDevice.DirectClip'。 – finnw 2010-06-30 21:24:51

+0

...和平臺是...? :) – vladr 2010-07-01 13:48:07

+0

Romascanul,最初在Windows XP上。在Vista上覆制(但在Vista上發生的次數少於在XP上)。在Ubuntu上重現失敗,但是它只在一個只有一個處理器內核的上網本上運行(如果它是庫中的線程問題,可能會掩蓋問題。 ) – finnw 2010-07-01 17:14:21