Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NAudio - seeking and navigation to play from the specified position

Tags:

c#

audio

naudio

I'm using NAudio library in a C# application. I'm trying to seek an audio (*.mp3 file) to the position I want. However I didn't figure out how to do it.

//Play the file starting from 16th second
waveStream.Seek(16, SeekOrigin.Begin);

And ... It played starting almost from the beginning, but not from the 16th second. I also found a solution I thought true:

waveStream.Seek(waveStream.WaveFormat.AverageBytesPerSecond * 16, SeekOrigin.Begin);

It seems it's closer the truth. Is my resolving true or not? If not what should I do?

like image 637
Alexandre Avatar asked Apr 29 '12 11:04

Alexandre


3 Answers

You can set Position directly on a WaveStream, which must be converted into a byte offset - so yes, multiplying the average bytes per second by the number of seconds will get you to the right place (at least with regular PCM WAV files). WaveStream also has a helper property called CurrentTime allowing you to use a TimeSpan and it does the same calculation for you.

audioFile.Position += audioFile.WaveFormat.AverageBytesPerSecond * 15;

like image 58
Mark Heath Avatar answered Nov 12 '22 01:11

Mark Heath


If someone still has this problem and can not figure it out. Then here is an example:

myWaveStream.CurrentTime = myWaveStream.CurrentTime.Add(new TimeSpan(0, hours, minutes, seconds, milliseconds));

myWaveStream.CurrentTime = myWaveStream.CurrentTime.Subtract(new TimeSpan(0, hours, minutes, seconds, milliseconds));
like image 29
Tanel Avatar answered Nov 12 '22 01:11

Tanel


I created a navigation using a trackBar with 4 ticks per second (1 tick at 250ms):

trackBar1.Maximum = (int)stream.TotalTime.TotalSeconds * 4;

In a timer tick handler, called at each 250ms, an update of the trackbar is done as following:

double ms = stream.Position * 1000.0 / output.OutputWaveFormat.BitsPerSample / output.OutputWaveFormat.Channels * 8.0 / output.OutputWaveFormat.SampleRate;
trackBar1.Value = (int) (4 * ms / 1000);

In order to set the position (after scrolling), this formula worked:

double ms = trackBar1.Value * 1000.0 / 4.0;
stream.Position = (long)(ms * output.OutputWaveFormat.SampleRate * output.OutputWaveFormat.BitsPerSample * output.OutputWaveFormat.Channels / 8000.0) & ~1;
like image 23
Tavy Avatar answered Nov 12 '22 01:11

Tavy