This project has moved. For the latest updates, please go here.

API for Position Reporting

Oct 9, 2012 at 12:23 PM

Mark,

I'm working on a position reporting patch for NAudio's wave player classes (and maybe the wave in stuff).  Do you want that functionality split to a separate interface (IWavePosition), or added to the existing IWavePlayer (and maybe IWaveIn) interfaces?

This API is basically so timestamps can be calculated to within a small margin of error.  This should be useful for anyone doing "sync" with the audio stream.  I'll use it for visualizations and a playback clock... :)

Coordinator
Oct 19, 2012 at 2:43 PM

Hi, sorry for slow response. It would be good to have a standardised approach to reporting position, but I would want it to be implemented on most if not all of the IWavePlayers if the method is to be introduced to IWavePlayer. Also, since IWavePlayer only takes an IWaveProvider, position really is just a function of how many samples have been played and cannot necessarily be related to the position within an input file. What was your proposed method signature for this feature?

Oct 19, 2012 at 6:00 PM
Edited Oct 19, 2012 at 6:08 PM

Agreed on the IWavePlayer stuff...  I'm not convinced it shouldn't live it its own interface at this point (IWavePosition?).  I have a fork that includes a POC implementation you can look at, but it isn't set in stone or anything.

Maybe we can do something like this (this is after using my POC version, which is a little bit different):

public interface IWavePosition
{
    long GetPosition();
    WaveFormat OutputWaveFormat { get; }
}

public static class Extensions
{
    public static TimeSpan GetPositionTimeSpan(this IWavePosition @this)
    {
        var pos = @this.GetPosition() / (@this.OutputWaveFormat.Channcels * @this.OutputWaveFormat.BitsPerSample / 8);
        return TimeSpan.FromMilliseconds(pos * 1000.0 / @this.OutputWaveFormat.SampleRate);
    }
}

As far as linking to the input, take the timestamp of playback before you start filling buffers and subtract that from the current value (at any given point).  That should tell you how much of the current source has been played through the hardware.  Likewise, after a seek, take the timestamp and adjust for the new position in the source.  Always let the buffers completely drain out before taking the timestamp, though...

I came up with all this because I have a project where decode and visualization prep is done well ahead of playback and I needed a way to sync the vis with the actual output from the hardware.  The logic above is how I implemented the sync and it's very close to exact (and doesn't "drift").

Coordinator
Jul 16, 2013 at 8:35 PM
hi, I've finally got round to accepting this. Your fork didn't actually have the IWavePosition and Extensions files in it, so I used the code above. (I also prefer the name OutputWaveFormat to RawWaveFormat).
Jul 17, 2013 at 2:19 PM
Works for me. :)

Thanks for taking the time to look at it.