C# NAudio - Changing audio playback position still plays a small buffer of old position
Asked Answered
O

1

7

I am trying to make a basic MP3 player in C# and WPF, along with NAudio. I recently added a slider that tracks the current position in the song as well as allows you to drag it to a different position and upon Thumb.DragCompleted it will set the song's position to where you dragged it.

This all works fine and all, except when I make it jump to the new position, it still plays the old position 1/5th or so of a second before changing. This is most noticeable e.g. while the singer is in the middle of singing "aaa", you pause, drag to a point where he sings "ooo", then play again, you will hear "aa-ooo". This just results in it sounding pretty horrible.

So I suppose the audio playback simply has a small 'buffer' remaining that it insists on playing before moving on. Is there any way to clear this buffer? Or am I setting the position wrong?

I am using a WaveOut waveOutDevice and an AudioFileReader audioFileReader. The slider is called sldrPlaybackProgress.
I tried to change position in the song in two different ways already:

First method:

audioFileReader.CurrentTime = new TimeSpan(0, (int)(Math.Floor(sldrPlaybackProgress.Value / 60)), (int)(Math.Floor(sldrPlaybackProgress.Value % 60))); 

Second method:

audioFileReader.Position = (long)(sldrPlaybackProgress.Value * audioFileReader.WaveFormat.AverageBytesPerSecond);

Both of these individually or even both combined still result in the problem persisting.

Oder answered 19/8, 2015 at 16:6 Comment(3)
Try to pause, set position, play again.Foothold
I have tried this, still won't work. I even desperately tried to re-initialize both the WaveOut and AudioFileReader, but this produced some weird bugs with the song playing twice - not to mention it's probably not very efficient to do that.Oder
Just found that WaveOut.Stop(), setting AudioFileReader's position, then starting WaveOut.Play() again WILL fix it. I think this could make for some annoying bugs later in the code if I have some WaveOut.PlaybackStopped event handler, but that's something I'll just have to work around. Thanks for the pause/play idea, got me on the right track :)Oder
M
7

You should call Stop when a reposition happens during pause. This will flush any outstanding buffers and. Under the hood Stop calls waveOutStop and Pause calls waveOutPause, which doesn't clear any in progress playing buffers.

Mesopotamia answered 20/8, 2015 at 10:22 Comment(1)
Wow, directly from the horse's mouth.Thanks, this helped me keep going...Probably this should be more clear from the demo program (used WinForms)Poppo

© 2022 - 2024 — McMap. All rights reserved.