[wdmaudiodev] Re: Need help in Passing a test case from KS-Position test

  • From: Matthew van Eerde <Matthew.van.Eerde@xxxxxxxxxxxxx>
  • To: "wdmaudiodev@xxxxxxxxxxxxx" <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Mon, 5 May 2014 16:24:04 +0000

There are two problems with this:

1) Relatively minor: your reported position is a little bit slow

> ULONGLONG bytesDisplaceMent = (ULONGLONG)( (ULONGLONG)m_ulDmaMovementRate * 
> (ULONGLONG)timeElapsedInNS ) / 10000000;

This always rounds down, which means your reported position falls behind the 
KeQueryInterruptTime() clock by (on average) half a byte per GetPosition() 
call. That is, your reported audio clock will run a little bit slow compared to 
the system time.

2) Rather more severe: your reported position ignores the layer below you

You’re sending data over the network; I presume that something on the other 
side is reading it and feeding a digital-to-analog converter. This converter 
has a clock.

http://msdn.microsoft.com/en-us/library/windows/hardware/ff536716(v=vs.85).aspx

> IMiniportWaveCyclicStream::GetPosition method
…

> For a render stream, the GetPosition method retrieves the play position, 
> which is the byte offset of the sample that is currently being played through 
> the DAC and transmitted through the speaker jack.
…

> Audio hardware that internally buffers a portion of a playback or capture 
> stream might make a precise position reading more difficult to obtain. In 
> this case, the driver should estimate the current position as accurately as 
> possible. For example, if an audio device prefetches the playback stream into 
> an internal buffer, the driver might need to take both the buffer size and 
> timing information into account in order to properly estimate the play 
> position.
…

> The WaveCyclic port driver implements a property handler for 
> KSPROPERTY_AUDIO_POSITION. This property handler calls the GetPosition method 
> to obtain the current play or record position from the miniport driver. For 
> more information, see Audio Position Property.

http://msdn.microsoft.com/en-us/library/windows/hardware/ff536211(v=vs.85).aspx
> Audio Position Property
…

> The play position is the byte offset of the sample that is currently being 
> played (that is, the sample that is latched at the input of the 
> digital-to-analog converter, or DAC). The write position is the position 
> beyond which the client can safely write to the buffer. As the stream plays, 
> the play and write positions move from left to right in the preceding figure. 
> The client's writes must stay ahead of the write position. In addition, if 
> the buffer is looped, the client's writes must never overtake the play 
> position.
…

> Although the WaveCyclic or WavePci port driver relies on the miniport driver 
> to keep track of the play position, the port driver keeps track of the write 
> position. The WaveCyclic and WavePci port drivers update the write position 
> as follows:
…

> WaveCyclic
…

> Each time the WaveCyclic port driver calls IDmaChannel::CopyTo to copy a new 
> block of data to the cyclic buffer (from the client buffer), the write 
> position advances to the location (in the client buffer) of the last byte in 
> the data block
…

Can you go into more detail as to how exactly you’re sending data over the 
network? If you send data too slowly, you’ll starve the DAC on the other side; 
if you send data too quickly, you’ll overflow the buffer on the other side. 
What mechanism exists at that layer to allow you to feed the DAC at the right 
speed?

Other related posts: