[wdmaudiodev] Re: HD Audio WaveCyclic timing problems

  • From: Mike Pumford <mpumford@xxxxxxxxxxxxxx>
  • To: wdmaudiodev@xxxxxxxxxxxxx
  • Date: Tue, 12 Jan 2010 12:42:33 +0000

Lex Nahumury wrote:
Hello Mike,
t might be too small. I found I needed a larger buffer than this for
playback/record operations involving high sample rates, sample widths and
number of channels. In the end I ended up computing a size relative to
nAvgBytesPerSec.

Yes you are right of course.
However in this (testing) stage I only support 2 channel @44100hz.

Okay. I think PAGE_SIZE should be more than enough for that. In fact you need a buffer big enough for at least 2 * 10ms worth of samples. So that the codec can be transferring data from one part of the buffer while your DMA object is copying in the data to another part.

In SetNotificationFreq() I compute the needed 10msec FramingSize,
   FramingSize_in_bytes = nBlockAlign * sampleRate * Interval / 1000;

You might be better off using nAvgBytesPerSec here as well. Saves you having to adjust things later for different channel counts.

I use that FramingSize;
- to set the current buffersize via SetBufferSize(FramingSize_in_bytes)
- to program the length of the first (and only) BDL entry
- and in the call to SetupDmaEngineWithBdl() with LVI = 1

This is calling SetBufferSize in the IDMAChannelObject? You shouldn't do that. Windows will set the buffer size itself if necessary. In all my testing it always used all of the allocated buffer.


In GetPosition() I readout the address I obtained earlier via
GetLinkPositionRegister().

   *Position = READ_REGISTER_ULONG( pPositionRegister )

That's not quite right for a HD audio device (at least in my experience).
For GetPosition you need the position of the current sample actually being
played or recorded. To do this for HD Audio you need to to adjust the link
position register value using the FifoSize (you can get this from the HD
Audio interface). For Capture streams return LinkPosition - FifoSize, for
render streams return LinkPosition + FifoSize. Return 0 if the stream is
stopped.

Yes, I already tried something like this in GetPosition(),

        if(isRunning&&  pPositionRegister )
        {               
            ULONG pos =  READ_REGISTER_ULONG( pPositionRegister );
        
                pos += fifo_size;
                if(pos>  FramingSize_in_bytes)
                        pos =  pos - FramingSize_in_bytes; // wrap

You should be using the buffer size here. Not wrapping to the Framing Size. The wrap size should be the buffer size returned by the IDMAChannel::BufferSize API. For right now I'd try this without any wrap compensation at all.

Btw, I also noticed that if I readout the LinkPositionRegister in my
ISR routine it always reads 1576 as if the Interrupt fires too early
.I would expect it to be close around 1764 which is the
FramingSize_in_bytes for a 2 channel 44100hz stream.
That's quite deliberate on the part of windows it want's to fill in the next block of data in the data buffer before the codec starts transferring into the next frame.
It has probably something to do with the reported fifo size which is 191 bytes.
That is an weird fifo size. For 16bit samples I'd expect a power of 2 at least. In the Intel HDA codecs I used during testing I never got a value other than 16.

Mike
--
Mike Pumford, Senior Software Engineer
MPC Data Limited
e-mail: mpumford@xxxxxxxxxxxxxx     web: www.mpc-data.co.uk
tel: +44 (0) 1225 710600            fax: +44 (0) 1225 710601
ddi: +44 (0) 1225 710635


MPC Data Limited is a company registered in England and Wales with
company number 05507446
Registered Address: County Gate, County Way, Trowbridge, Wiltshire,
                    BA14 7FJ
VAT no: 850625238

The information in this email and in the attached documents is
confidential and may be legally privileged. Any unauthorized review,
copying, disclosure or distribution is prohibited and may be unlawful.
It is intended solely for the addressee. Access to this email by anyone
else is unauthorized. If you are not the intended recipient, please
contact the sender by reply email and destroy all copies of the original
message. When addressed to our clients any opinions or advice contained
in this email is subject to the terms and conditions expressed in the
governing contract.
******************

WDMAUDIODEV addresses:
Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx
Subscribe:    mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe
Unsubscribe:  mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe
Moderator:    mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx

URL to WDMAUDIODEV page:
http://www.wdmaudiodev.com/

Other related posts: