Re: PCI Audio Driver and takeTimeStamp
Re: PCI Audio Driver and takeTimeStamp
- Subject: Re: PCI Audio Driver and takeTimeStamp
- From: Jeff Moore <email@hidden>
- Date: Tue, 09 Dec 2008 09:35:17 -0800
Calling takeTimeStamp() from inside of performAudioEngineStart() is
generally not the right thing to do. The reason why is that
performAudioEngineStart() for most bits of hardware is not actually
connected to what the DMA engine is actually doing.
Remember, takeTimeStamp() is meant to be called from your _primary_
hardware interrupt that gets raised when your DMA wraps around the
ring buffer. By calling takeTimeStamp() from
performAudioEngineStart(), the first time stamp will have several
orders of magnitude more jitter in it than any other time stamp. If
you capture your time stamps and look at the succeeding differences
between the host times, you'd see that the difference between the
first and second time stamp will be very different from the
differences in later timestamps in such cases.
It kind of goes without saying, but the first time stamp a driver
gives to the HAL is the most important time stamp the driver delivers.
The reason why is that once the HAL sees the first time stamp, it will
anchor it's clock and begin doing IO. Any error in the first time
stamp is passed pretty much directly into the HAL's anchor time which
causes the HAL to start off already out of synch with the hardware in
an amount proportionate to the error in the first time stamp.
This is why drivers need to bend over backward to make the first time
stamp as accurate as possible. I touched on this topic briefly in a
recent thread where I was helping someone (Mr. Tan, I believe) with
their driver issues. One way I suggested in that thread to deal with
this issue is to do a small DMA transfer that causes the DMA to wrap
around the ring buffer, raise the interrupt, and cause takeTimeStamp()
to get called. I've worked with many different developers on putting
this into their drivers, and this has been the easiest way for most of
them to generate an accurate first time stamp.
BTW, the AudioReflectorDriver is written with this concept in mind,
which is why it never calls takeTimeStamp() except from it's simulated
hardware interrupt. The SamplePCIDriver (which is obsolete as sample
code BTW) does not do this and it's time stamps do in fact show the
kind of error I just described.
On Dec 9, 2008, at 1:59 AM, Peter Johnson wrote:
Hi David
You have to call takeTimeStamp periodically so that IOAudioFamily
knows where the engine currently is in the output buffer and to
predict where it will be in the future. Typically takeTimeStamp will
be called off of your hardware interrupt, e.g. when your hardware
buffer fills or wraps, or off a timer. takeTimeStamp also increments
a loop counter, effectively the number of times the buffer has cycled.
What's interesting me is why the AppleReflectorDriver doesn't call
takeTimeStamp from within performAudioEngineStart. It seems that the
"right thing to do" in performAudioEngineStart is to take an
AbsoluteTime and call takeTimeStamp(false, now). I can only guess
that this is so that IOAudioFamily can reset the loop count to zero
and record the starting time, otherwise I guess the first "real"
time stamp would anywhere in the buffer.....
cheers
peter
----- Original Message ----
From: David Tan <email@hidden>
To: Peter Johnson <email@hidden>; email@hidden
Sent: Tuesday, 9 December, 2008 17:47:05
Subject: RE: PCI Audio Driver and takeTimeStamp
Hi Peter,
Actually I'm also working on it now. As I understanding,
takeTimeStamp() can
be called anywhere in the driver. And in my audio driver, I even
have to
call it periodically based on the data I have processed.
Best Regards,
David Tan,
Software Engineer,
Dextrys Co., Ltd.
-----Original Message-----
From: coreaudio-api-bounces+david.tan=email@hidden
[mailto:coreaudio-api-bounces+david.tan=email@hidden]
On
Behalf Of Peter Johnson
Sent: Tuesday, December 09, 2008 2:11 PM
To: email@hidden
Subject: PCI Audio Driver and takeTimeStamp
Hi
I'm writing a PCI audio driver for an audio/video capture card. I'm
a little
confused by the usage of takeTimeStamp(). For instance, the
documentation
and the SamplePCIAudioDriver example calls takeTimeStamp(false) from
within
the audio engine performAudioEngineStart(), however, the
AudioReflectorDriver does not. Is there a reason for this?
This is further confusing me because the IOAudioFamily is reporting
"missed
samples" (I built a debug version the kext) when my own driver calls
takeTimeStamp(false) from my performAudioEngineStart().
So, is it necessary to call takeTimeStamp(false) when the engine
starts and
therefore reset the loop count and start the engine from the
beginning of
the sample buffer, and is the IOAudioFamily spuriously reporting
missed
samples because the buffer indices have jumped to the start? (in other
words, should I just ignore those messages).
cheers
peter
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
--
Jeff Moore
Core Audio
Apple
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden