2010-10-06 25 views
4

(excuses si cela est un doublon ... je l'ai vu affiché, mais aucune preuve qu'il en fait sur le forum)jouer son avec SlimDX et DirectSound (C#)

J'ai essayé d'obtenir SlimDX DirectSound travail. Voici le code que j'ai. Il remplit le tampon secondaire à partir d'un fichier wav puis, dans une boucle de thread, remplit alternativement les moitiés inférieure ou supérieure du tampon.

Il lit la première charge du tampon. L'AutoResetEvents se déclenche quand ils le devraient et la moitié inférieure puis la moitié supérieure du tampon sont remplies (vérifiées avec les instructions de débogage). Mais le jeu ne continue pas après le premier chargement du tampon. Donc, d'une manière ou d'une autre, le repeuplement du tampon ne fonctionne pas comme il le devrait.

Des idées?

(j'utilise DirectSound parce que c'est la seule façon que j'ai trouvé pour régler le guid de l'appareil audio que je veux utiliser. Suis ouvert à d'autres approches .NET de l'environnement.)

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(); 
    } 
} 

Répondre

3

Vous ne l'avez pas configuré en boucle sur le tampon de lecture. Changez votre code pour:

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

Merci. C'était ça. En l'absence de tout document SlimDX sur le sujet, j'avais mal compris la signification des drapeaux. – blearyeye

+0

Terminé. J'ai oublié de le faire plus tôt. – blearyeye

+0

Fonctionne également pour DirectSound. Avait le même problème que blearyeye. Merci de m'avoir indiqué ... –