Carefree (looping) audio playback from DirectX in C #

I am currently using the following code (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); } } 

This code works, and the file I'm playing is a loop. But, obviously, there is a small gap between each reproduction.

  • I tried to reduce Thread.Sleep it to 10 or 5, but the gap remains.
  • I also tried to completely remove it, but then the processor load increased to 100%, and there is still a small gap.

Is there any (simple) way to make playback in DirectX indifferent? This is not very important, since this is only a personal project, but if I do something stupid or otherwise completely wrong, I'd love to know.

Thanks in advance.

+4
source share
2 answers

The problem with your approach is that you have a thread spinning while checking the position of the player. The longer you increase your sleep, the less it is depleted, but later it will see the end of the clip. The shorter the sleep, the faster it will notice the more the processor consumes your control thread.

I don’t see anything in the documents to pass the clip in a loop. The only thing I have is to use the Audio.Ending event to start playing the movie again. This will save you from having to use a separate monitoring thread, but I'm not sure if it will be fast enough to fill the gap.

You will also want to check that your sound clip does not start or end with a period of silence.

+2
source

Since you know the length of the song, simply use the timer to regularly call the “rewind” method and give the timer a gap that will be shorter than the actual duration of the song.

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

Of course, you need to stop the timer to make it an instance instead of the local variable of your method, so you can disable it using the Stop () method.

Hope this helps you. Manitra

0
source

Source: https://habr.com/ru/post/1304379/


All Articles