2010-10-06 71 views
4

(道歉,如果這是一個重複的...我張貼,但並沒有發現它實際上是由它來論壇)播放聲音與SlimDX和DirectSound的(C#)

我一直試圖讓SlimDX的DirectSound加工。這是我的代碼。它從一個wav文件填充二級緩衝區,然後在一個線程循環中交替地填充緩衝區的下半部分或上半部分。

它播放緩衝區罰款的第一個負載。 AutoResetEvents在它們應該和下半部分然後填充上半部分時觸發(用Debug語句驗證)。但是在第一次加載緩衝區後播放不會繼續。所以不知怎的,緩衝區的重新填充不能正常工作。

想法?

(我用的DirectSound,因爲它是我發現設置,我想使用的音頻設備的GUID的唯一途徑。願意接受其他.NET友好的方式。)

private void PlaySound(Guid soundCardGuid, string audioFile) { 
     DirectSound ds = new DirectSound(soundCardGuid); 

     ds.SetCooperativeLevel(this.Handle, CooperativeLevel.Priority); 

     WaveFormat format = new WaveFormat(); 
     format.BitsPerSample = 16; 
     format.BlockAlignment = 4; 
     format.Channels = 2; 
     format.FormatTag = WaveFormatTag.Pcm; 
     format.SamplesPerSecond = 44100; 
     format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlignment; 

     SoundBufferDescription desc = new SoundBufferDescription(); 
     desc.Format = format; 
     desc.Flags = BufferFlags.GlobalFocus; 
     desc.SizeInBytes = 8 * format.AverageBytesPerSecond; 

     PrimarySoundBuffer pBuffer = new PrimarySoundBuffer(ds, desc); 

     SoundBufferDescription desc2 = new SoundBufferDescription(); 
     desc2.Format = format; 
     desc2.Flags = BufferFlags.GlobalFocus | BufferFlags.ControlPositionNotify | BufferFlags.GetCurrentPosition2; 
     desc2.SizeInBytes = 8 * format.AverageBytesPerSecond; 

     SecondarySoundBuffer sBuffer1 = new SecondarySoundBuffer(ds, desc2); 

     NotificationPosition[] notifications = new NotificationPosition[2]; 
     notifications[0].Offset = desc2.SizeInBytes/2 + 1; 
     notifications[1].Offset = desc2.SizeInBytes - 1; ; 

     notifications[0].Event = new AutoResetEvent(false); 
     notifications[1].Event = new AutoResetEvent(false); 
     sBuffer1.SetNotificationPositions(notifications); 

     byte[] bytes1 = new byte[desc2.SizeInBytes/2]; 
     byte[] bytes2 = new byte[desc2.SizeInBytes]; 

     Stream stream = File.Open(audioFile, FileMode.Open); 

     Thread fillBuffer = new Thread(() => { 
      int readNumber = 1; 
      int bytesRead; 

      bytesRead = stream.Read(bytes2, 0, desc2.SizeInBytes); 
      sBuffer1.Write<byte>(bytes2, 0, LockFlags.None); 
      sBuffer1.Play(0, PlayFlags.None); 
      while (true) { 
       if (bytesRead == 0) { break; } 
       notifications[0].Event.WaitOne(); 
       bytesRead = stream.Read(bytes1, 0, bytes1.Length); 
       sBuffer1.Write<byte>(bytes1, 0, LockFlags.None); 

       if (bytesRead == 0) { break; } 
       notifications[1].Event.WaitOne(); 
       bytesRead = stream.Read(bytes1, 0, bytes1.Length); 
       sBuffer1.Write<byte>(bytes1, desc2.SizeInBytes/2, LockFlags.None); 
      } 
      stream.Close(); 
      stream.Dispose(); 
     }); 
     fillBuffer.Start(); 
    } 
} 

回答

3

您尚未將其設置爲循環播放緩衝區。將代碼更改爲:

sBuffer1.Play(0, PlayFlags.Looping); 
+1

謝謝。就是這樣。在沒有任何關於這個主題的SlimDX文檔的時候,我誤解了這些標誌的含義。 – blearyeye 2010-10-07 18:19:04

+0

完成。忘了這麼做了。 – blearyeye 2011-01-06 20:16:15

+0

也適用於DirectSound。與blearyeye有同樣的問題。感謝您指點我... – 2011-02-15 10:48:06