2012-08-23 273 views
1
的無縫繼承

我試圖做的是發揮循環WAV,但與特定的循環開始喜歡在音樂模塊文件(。它,S3M。的.mod等所使用的樣本位置)。 SoundPlayer沒有這個功能,所以我創建了兩個獨立的文件:原始的wav和wav,開頭切到循環開始的地方。我想連續播放這兩個文件,無縫地,首先是帶有PlaySync()的原始wav文件,然後是帶有PlayLooping()的循環部分。聲音播放和播放聲音

不幸的是我PlaySync()第一個wav後,有一個分裂秒它和PlayLooping()開始播放循環wav之間的中斷。打兩個獨立不同的聲音時

private static void PlayThread(SoundPlayer soundPlayer, byte[] wav, byte[] loop) 
    { 
     MemoryStream stream1 = new MemoryStream(wav); 
     MemoryStream stream2 = new MemoryStream(loop); 
     soundPlayer.Stream = stream1; 
     soundPlayer.PlaySync(); 
     // here is where the split second interruption occurs 
     soundPlayer.Stream = stream2; 
     soundPlayer.PlayLooping(); 
    } 

這可能不明顯,但是,試圖拉斷的循環機制我想的時候是非常明顯的。聲音波形是樂器樣本,非常小(通常不超過0x1000字節)。

回答

0

我不知道什麼聲音播放,但也許消除線3 + 4,而是寫你的第二次浪潮第一流而不是創建新流。這種方式實質上是將更多數據添加到流中以供播放。假設你可以寫得比它能播放它快,你應該可以。如果一個MemoryStream允許同時讀/寫,我不確定是否在我的頭頂。我做了類似的事情,但沒有手頭的代碼,而且可能略有不同。

另外,是Play()阻止?即直到完成播放,下一行纔會運行。如果是這樣,則在第3行讀取wav文件時暫停。所以你需要移動。播放到另一個線程,以便您可以在第一次播放時開始加載下一個wave。即使你發現你不能寫入第一個內存流,並且不得不創建一個新的內存流,至少你會將Wav文件加載到內存流中,並在第一次完成後立即開始播放。這將顯着減少暫停。

考慮具有MP3播放列表的媒體播放器。當一個MP3接近完成時,媒體播放器通常將繼續並從磁盤加載下一個mp3並在第一個播放完成之前將其加載到內存中。

0

這裏是我的測試看起來像:

 string sMediaPath = @"C:\Windows\Media"; 
     SoundPlayer soundPlayer = new SoundPlayer(); 

     soundPlayer.Stream = File.OpenRead(Path.Combine(sMediaPath, "chimes.wav")); 
     soundPlayer.PlaySync(); 

     soundPlayer.Stream = File.OpenRead(Path.Combine(sMediaPath, "chord.wav")); 
     soundPlayer.PlaySync(); 

我發現,這個測試工作完全一樣,你想要的 - 與文件之間沒有突然停止。這可能是由於其他原因,但最有可能與文件本身有關

  • 比特率:什麼是文件的採樣率?
  • 聲音文件是否交錯(立體聲)?
  • 聲音文件有多大?

也許你的預加載聲音播放他們可能會有所作爲之前?

 string sMediaPath = @"C:\Windows\Media"; 
     SoundPlayer soundPlayer = new SoundPlayer(); 

     List<Stream> oSoundStreams = new List<Stream>(); 
     oSoundStreams.Add(File.OpenRead(Path.Combine(sMediaPath, "chimes.wav"))); 
     oSoundStreams.Add(File.OpenRead(Path.Combine(sMediaPath, "chord.wav"))); 

     soundPlayer.Stream = oSoundStreams[0]; 
     soundPlayer.PlaySync(); 

     soundPlayer.Stream = oSoundStreams[1]; 
     soundPlayer.PlaySync(); 

編輯:

通過爲每個聲一片聲音播放對象中播放,似乎有可能搞垮您遇到的短間隔:

 string sMediaPath = @"C:\Users\Foogle\Desktop\"; 
     SoundPlayer soundPlayer1 = new SoundPlayer(); 
     SoundPlayer soundPlayer2 = new SoundPlayer(); 

     soundPlayer1.Stream = File.OpenRead(Path.Combine(sMediaPath, "W.wav")); 
     soundPlayer1.Load(); 

     soundPlayer2.Stream = File.OpenRead(Path.Combine(sMediaPath, "P.wav")); 
     soundPlayer2.Load(); 

     for (int i = 0; i < 10; i++) 
     { 
      soundPlayer1.PlaySync(); 
      soundPlayer2.PlaySync(); 
     } 

也許你可以創建一個SoundPlayer對象集合並根據需要播放它們?

希望這會有所幫助。

乾杯!

+0

我改變了我原來的職位描述完全是我想去完成。中斷很快,一秒鐘,但嘗試執行我想要的循環機制時非常明顯。我做了兩個獨立的流,但它仍然不起作用。 – giangurgolo

+0

@giangurgolo沒有問題,我編輯了我的答案,幷包含另一個場景供您測試。 – Rastus7

0

而不是試圖連續播放多個SoundPlayer對象,嘗試連接.wav文件,並將合併的.wav文件加載到一個SoundPlayer對象。

下載此WaveIO class,將其添加到您的項目,並嘗試下面的代碼要連續打無縫多的聲音:

string[] files = new string[3] { @"filepath1.wav", @"filepath2.wav", @"filepath3.wav" }; 

WaveIO wa = new WaveIO(); 
wa.Merge(files, @"tempfile.wav"); 

System.Media.SoundPlayer sp = new System.Media.SoundPlayer(@"tempfile.wav"); 
sp.Play();