2010-03-17 102 views
4

我目前使用下面的代碼(C#):無縫(循環)音頻播放支持DirectX在C#

private static void PlayLoop(string filename) 
    { 
     Audio player = new Audio(filename); 
     player.Play(); 
     while (player.Playing) 
     { 
      if (player.CurrentPosition >= player.Duration) 
      { 
       player.SeekCurrentPosition(0, SeekPositionFlags.AbsolutePositioning); 
      } 
      System.Threading.Thread.Sleep(100); 
     } 
    } 

此代碼的工作,和我打的循環的文件。但是,顯然,每個回放之間有一個小的差距。

  • 我試着減少Thread.Sleep到10或5,但差距仍然存在。
  • 我也嘗試完全刪除它,但CPU使用率提高到100%,並且還有一個小差距。

是否有任何(簡單)方法在DirectX無間隙中進行回放?這不是一個大問題,因爲它只是一個個人項目,但如果我做了一些愚蠢的或其他完全錯誤的事情,我很想知道。

在此先感謝。

回答

2

你的方法的問題是你有一個線程旋轉,檢查玩家的位置。您增加睡眠的時間越長,排出的CPU越少,但稍後它會注意到剪輯的結束。睡眠越短,它會注意到的越快,但檢查器線程消耗的CPU越多。

我可以在文檔中看到任何內容來告訴剪輯循環。我唯一的建議是使用Audio.Ending事件再次開始剪輯播放。這將消除您對單獨監控線程的需求,但我不確定這是否會足夠快以消除差距。

您還需要檢查以確保您的音頻剪輯不會以沉默期開始或結束。

0

由於您知道歌曲的持續時間,只需使用定時器定期調用您的「倒帶」方法,並使定時器的間隔略短於真實歌曲持續時間。

private static void PlayLoop(string filename) 
{ 
    Audio player = new Audio(filename); 
    player.Play(); 

    //System.Timers.Timer (i reduce the length by 100 ms to try to avoid blank) 
    var timer = new Timer((player.Duration - TimeSpan.FromMilliseconds(100)).TotalMilliseconds()); 
    timer.Elapsed += (sender, arg) => 
    { 
     player.SeekCurrentPosition(0, SeekPositionFlags.AbsolutePositioning); 
    }; 
    timer.Start(); 
} 

當然,你需要停止計時器,以便使它成爲一個實例成員,而不是你的方法的局部變量,這樣你就可以用stop()方法禁用它。

我希望這會幫助你。 Manitra