[wdmaudiodev] AW: Re: AW: Re: AW: Re: AW: external audio driver clocking

  • From: "Johannes Freyberger" <jfreyberger@xxxxxxxxxxxxxxxxxxxx>
  • To: <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Thu, 23 Aug 2018 19:39:09 +0200

Yes, I think you've got my idea - and btw. thanks for all your answers and
for thinking with me and helping me.

 

My app logs the current size of the jitter buffer of the audio data returned
from each driver instance every minute. Here I can see a very slow drift to
different directions from the different driver instances. It's no sudden
event just a slow increase or decrease of the jitter buffer of about up to
500 samples per hour, for some driver instances it even looks stable. So I
don't think it's starving. On my system here (Core i7, W10 pro) it's stable
all the time although my PTP to QueryPerformanceCounter skew number is more
different to 1.0 than the skew number on our customers system. I'm also
logging the skew number each minute and it looks stable also on the
customers system.

 

Von: wdmaudiodev-bounce@xxxxxxxxxxxxx <wdmaudiodev-bounce@xxxxxxxxxxxxx> Im
Auftrag von Matthew van Eerde (Redacted sender "Matthew.van.Eerde" for
DMARC)
Gesendet: Donnerstag, 23. August 2018 19:13
An: wdmaudiodev@xxxxxxxxxxxxx
Betreff: [wdmaudiodev] Re: AW: Re: AW: Re: AW: external audio driver
clocking

 

OK, so your app is calculating a skew number between PTP and
QueryPerformanceCounter and conveying this to every instance of your driver.

 

Each instance of your driver then applies this common skew number to
KeQueryPerformanceCounter and uses that to calculate the answer to the
portcls GetPosition query.

 

And yet your app ends up pulling data from different instances of the driver
and different rates.

 

Confusing.

 

Is Windows actually delivering data to all instances of your driver on time?
Or are you being starved?

 

From: Johannes Freyberger <mailto:jfreyberger@xxxxxxxxxxxxxxxxxxxx
Sent: Thursday, August 23, 2018 10:01 AM
To: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] AW: Re: AW: Re: AW: external audio driver clocking

 

How are you calculating the relation between PTP and
KeQueryPerformanceCounter?

-> once a PTP messages arrives I take the QueryPerformanceCounter timestamp
and put this pair into a vector. After about 100 measurement points I start
to build a regression line through this points and the gradient angle gives
the PTP to KeQueryPerformanceCounter factor. This happens inside my app and
the factor is then given to all driver instances. The regression line and
the factor are constantly updated.

 

Do different instances of your driver feed the same network stream, or does
each instance have its own stream?

-> the audio data from all driver instances is returned to my app and there
it's combined into a single network stream. Due to the PTP clock I know how
many samples to send to the stream at which time. The very interesting thing
is that the number of samples I'm retrieving from the WDM driver instances
is not identical and seems to drift to different directions.

 

Is the workstation in question multihomed?

-> no, I don't think it's multihomed but I'll ask the customer

 

Von: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > Im Auftrag von Matthew van Eerde
(Redacted sender "Matthew.van.Eerde" for DMARC)
Gesendet: Donnerstag, 23. August 2018 17:44
An: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Betreff: [wdmaudiodev] Re: AW: Re: AW: external audio driver clocking

 

PTP is this? https://en.wikipedia.org/wiki/Precision_Time_Protocol
<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fen.wikiped
ia.org%2Fwiki%2FPrecision_Time_Protocol&data=02%7C01%7CMatthew.van.Eerde%40m
icrosoft.com%7C12d59791e5c8493a8f7508d60919fcf1%7C72f988bf86f141af91ab2d7cd0
11db47%7C1%7C0%7C636706404609504675&sdata=tC9hAVJY0dPSvIbeb%2FKAd6tbukx2DG2s
OPRjDfz%2FPvU%3D&reserved=0> 

 

Different processors on the system share the same clock.
KeQueryPerformanceCounter is not specific to a particular processor.

 

How are you calculating the relation between PTP and
KeQueryPerformanceCounter? Do different instances of your driver feed the
same network stream, or does each instance have its own stream? Is the
workstation in question multihomed?

 



From: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > on behalf of Johannes Freyberger
<jfreyberger@xxxxxxxxxxxxxxxxxxxx <mailto:jfreyberger@xxxxxxxxxxxxxxxxxxxx>


Sent: Thursday, August 23, 2018 8:31:07 AM
To: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] AW: Re: AW: external audio driver clocking 

 

Yes, I have the external clock (it's PTP) and thus I have the relation to my
internal clock taken from KeQueryPerformanceCounter(). As expected this is
very close to 1 normally something between 0.99995 and 1.00005. This factor
is adjusted in intervals and I'm using it to compute the desired number of
samples. This method normally works stable on many installations. But here
on this customers workstation I see different drifts for different instances
of the driver. I could imagine this happens if my "PTP to
KeQueryPerformanceCounter()" factor is computed on one Xeon, while the
driver runs on the other Xeon and their performance counters are not
identical or in perfect sync. The "PTP to KeQueryPerformanceCounter()"
factor is computed inside my app and then given to all drivers.

 

So that's the background of my question: Is it guaranteed that
KeQueryPerformanceCounter() is identical or synced exactly between the two
Xeons?

 

Von: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > Im Auftrag von Matthew van Eerde
(Redacted sender "Matthew.van.Eerde" for DMARC)
Gesendet: Donnerstag, 23. August 2018 16:43
An: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Betreff: [wdmaudiodev] Re: AW: external audio driver clocking

 

DACs have a clock in them. Audio usually is driven from that clock.

 

Your driver doesn't have a DAC. You feed something downstream of you. So you
don't have a clock yourself; you're just ratelessly copying bits.

 

But the thing downstream of you has a clock. or at least, there is
eventually a clock.

 

To avoid drift, you need to let the clock downstream of you drive your
answers to the Windows position query.

 

If the clock downstream of you runs slow, Windows will feed data to you
slow. If it runs fast, Windows will feed data to you fast. No drift.

 

If you lie to Windows about how fast you need data, or just make up an
answer using KeQueryPerformanceCounter, Windows will believe you, but you
will drift.

 



From: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > on behalf of Johannes Freyberger
<jfreyberger@xxxxxxxxxxxxxxxxxxxx <mailto:jfreyberger@xxxxxxxxxxxxxxxxxxxx>

Sent: Thursday, August 23, 2018 5:38:27 AM
To: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] AW: external audio driver clocking 

 

Hmm . my ideas about IMiniportWaveCyclicStream::GetPosition() and
IDmaChannel::CopyTo() meanwhile seem to be the wrong direction for me and
I'm thinking if the dual Xeon system could be a problem and this arises a
lot of questions. Is it guaranteed that KeQueryPerformanceCounter() is
synced exactly between the Xeons? Did this sync change in different Windows
OS versions? Could there be a difference in this when using TSC_INVARIANT or
HPET as base for KeQueryPerformanceCounter()? Can I ensure somehow my
drivers are running on the same cores (in the same Xeon) as my application.
I know how to assign my application to certain cores but is this possible
for drivers?

 

Von: Johannes Freyberger <jfreyberger@xxxxxxxxxxxxxxxxxxxx
<mailto:jfreyberger@xxxxxxxxxxxxxxxxxxxx> > 
Gesendet: Donnerstag, 23. August 2018 13:17
An: 'wdmaudiodev@xxxxxxxxxxxxx' <wdmaudiodev@xxxxxxxxxxxxx
<mailto:wdmaudiodev@xxxxxxxxxxxxx> >
Betreff: Re: external audio driver clocking

 

OK, thanks. 

 

So now I'm trying to understand the correlation between
IMiniportWaveCyclicStream::GetPosition() which reports my current DAC
position and IDmaChannel::CopyTo() which gives me access to the next bunch
of samples played by an application. Could it be this drifts apart? Do I
have to keep track of the number of samples delivered in
IDmaChannel::CopyTo() and match this value against my current DMA and thus
sample position in IMiniportWaveCyclicStream::GetPosition()? 

 

Could such an "drift to both directions simultaneously effect" be related to
the hardware or the OS? (So far we've seen this drifting effect only on a HP
Dual Xeon Workstation running Windows Server 2012)

 

Von: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > Im Auftrag von Matthew van Eerde
(Redacted sender "Matthew.van.Eerde" for DMARC)
Gesendet: Mittwoch, 22. August 2018 20:05
An: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Betreff: [wdmaudiodev] Re: AW: Re: AW: Re: AW: Re: external audio driver
clocking

 

Yes, that's correct.

 



From: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > on behalf of Johannes Freyberger
<jfreyberger@xxxxxxxxxxxxxxxxxxxx <mailto:jfreyberger@xxxxxxxxxxxxxxxxxxxx>

Sent: Wednesday, August 22, 2018 11:04:08 AM
To: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] AW: Re: AW: Re: AW: Re: external audio driver
clocking 

 

Does that mean, the micro-SRC in Windows audio engine will never do anything
except an application explicitly calls IAudioClockAdjustment? It will never
become active by itself? If it's like this then I misinterpreted your
previous answers - sorry. And I also didn't want to bark at anything - I
thought it was a normal question.

 

Von: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > Im Auftrag von Matthew van Eerde
(Redacted sender "Matthew.van.Eerde" for DMARC)
Gesendet: Mittwoch, 22. August 2018 19:47
An: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Betreff: [wdmaudiodev] Re: AW: Re: AW: Re: external audio driver clocking

 

The micro-SRC almost always does nothing at all.

 

If an application wants to connect two different realtime clocks (e.g., an
ADC and a DAC running on hardware clocks) it can either:

*       Live with the drift
*       Insert its own micro-SRC
*       Use Windows' micro-SRC by calling the IAudioClockAdjustment API

 

The application would, in the second and third cases, monitor the long-term
real clock rate (slightly different than the nominal clock rate) relative to
some application clock (perhaps QueryPerformanceConter), and then adjust
some or all of the streams to correct the drift.

 



From: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > on behalf of Johannes Freyberger
<jfreyberger@xxxxxxxxxxxxxxxxxxxx <mailto:jfreyberger@xxxxxxxxxxxxxxxxxxxx>

Sent: Wednesday, August 22, 2018 10:39:50 AM
To: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] AW: Re: AW: Re: external audio driver clocking 

 

Yes, it's a drift and it has been worse as long as I was using
KeQueryPerformanceCounter() only without the PTP correction factor. 

 

What makes me think it could be the SRC in Windows audio engine:

- it's not an identical drift for different instances while my code and the
PTP correction factor is exactly the same for all instances

- so far I've seen this effect only on a machine which uses WASAPI non
exclusive and also has recording active while playing

 

How is the SRC factor computed in Windows audio engine and is it dynamically
adjusted?

 

Von: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > Im Auftrag von Matthew van Eerde
(Redacted sender "Matthew.van.Eerde" for DMARC)
Gesendet: Mittwoch, 22. August 2018 19:17
An: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Betreff: [wdmaudiodev] Re: AW: Re: external audio driver clocking

 

*       Could this very slow increase/decrease of the jitter buffer be
related to the SRC in Windows audio engine?

 

No, you're barking up the wrong tree.

 

*       very slow increase/decrease of the jitter buffer

 

This is "drift". Your driver is using the wrong clock. You're using
KeQueryPerformanceCounter, when you should be using whatever is driving the
reads from the jitter buffer.

 

What's on the other end of the network stream? Does the network stream feed
a single client or multiple clients?

 



From: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > on behalf of Johannes Freyberger
<jfreyberger@xxxxxxxxxxxxxxxxxxxx <mailto:jfreyberger@xxxxxxxxxxxxxxxxxxxx>

Sent: Wednesday, August 22, 2018 10:09:03 AM
To: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] AW: Re: external audio driver clocking 

 

It writes the audio data to the jitter buffer and from there it's read and
sent to the stream. No SRC etc. is in there, it's just a buffer with a write
and read pointer. 

 

Could this very slow increase/decrease of the jitter buffer be related to
the SRC in Windows audio engine?

 

Von: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > Im Auftrag von Matthew van Eerde
(Redacted sender "Matthew.van.Eerde" for DMARC)
Gesendet: Mittwoch, 22. August 2018 19:03
An: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Betreff: [wdmaudiodev] Re: external audio driver clocking

 

You said your driver hands data to the application. What does the
application do with it?

 



From: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > on behalf of Johannes Freyberger
<jfreyberger@xxxxxxxxxxxxxxxxxxxx <mailto:jfreyberger@xxxxxxxxxxxxxxxxxxxx>

Sent: Wednesday, August 22, 2018 9:53:44 AM
To: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] external audio driver clocking 

 

OK, let's forget about the bit transparency - I already changed the topic.
My driver is implementing IMiniportWaveCyclicStream and inside GetPosition()
I'm using KeQueryPerformanceCounter() and my "PTP clock factor" to compute
the number of desired samples. All driver instances use the same factor
which is updated every 10 seconds to adjust to drifts due to temperature
etc.. The audio data is then transferred to my application from where I send
the stream. Here I also have my adjustable jitter buffer. In this situation
it's 8000 samples which is about 160 millisecs at 48 kHz. I think this
should be fairly enough and on my PC the jitter buffer always is about the
same for many many hours. On a customers PC I can see the jitter buffer
growing and shrinking very slowly at the same time for different instances
of my driver. This results in buffer underruns and overruns after several
hours and every instance (up to 8) seems to behave a little different. Some
are rather stable. He's using WASAPI in non exclusive mode so my guess is
this could be due to the SRC in Windows audio engine as the customer also
runs a recording from this device simultaneously. Could this be true? As his
application also offers WASAPI in exclusive mode I asked him to do some
tests in this mode. Hopefully I will receive some logfiles the next days.

 

Von: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > Im Auftrag von Matthew van Eerde
(Redacted sender "Matthew.van.Eerde" for DMARC)
Gesendet: Mittwoch, 22. August 2018 18:24
An: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Betreff: [wdmaudiodev] Re: bit transparency from app to WDM audio driver
depending from API?

 

Windows audio uses the audio driver's clock. Usually this is the DAC or ADC,
but your DAC is on the other end of a network. That's fine, you'll still
need to use that as the master, and you'll need to figure out how to rough
that clock into the DDIs Windows uses to talk to you. If you screw it up,
though, there's nothing the application (or Windows) can do to avoid
glitching. You'll also have to decide how much of a jitter buffer to keep
around to avoid variable network latency from screwing things up, while at
the same time avoiding introducing too much latency.

 

This is a totally independent concern from bit transparency, though. I would
suggest starting separate threads for each of your concerns.

 

From: Johannes Freyberger <mailto:jfreyberger@xxxxxxxxxxxxxxxxxxxx
Sent: Wednesday, August 22, 2018 6:20 AM
To: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] Re: bit transparency from app to WDM audio driver
depending from API?

 

My driver doesn't run at the internal clock, but at an external PTP master
as I'm going to send the audio data to a RTP network stream. Although PTP is
quite close it's not the same but something like a factor of 1.00002
compared to the internal clock (taken from performance counter). Now on some
systems this runs correct for hours and days without over- or underruns, but
on others I can see both over- and underruns. Both can occur even at the
same time on the same PC as my driver runs in multiple instances and one
seems to be a little slow while another is slightly too fast (on a HP Dual
Xeon Workstation). I had no explanation and so I started digging into the
APIs the applications are using and whether this could be the reason for
this behavior. I also wrote a little application myself that can handle all
the APIs to check the clocking and do some bit transparency tests. What I've
learned from you so far makes me think it's not the API itself, but
exclusive mode or not. And non exclusive mode seems to introduce a lot of
trouble with its format conversion, its limiter and its SRC if you expect
bit transparency and audio without any glitches for hours and days. And both
is expected as we're in the field of 24/7 pro audio broadcasting. So
probably I have to recommend our customers to prefer exclusive mode for this
kind of pro audio applications?

 

Von: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > Im Auftrag von Matthew van Eerde
(Redacted sender "Matthew.van.Eerde" for DMARC)
Gesendet: Mittwoch, 22. August 2018 14:42
An: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Betreff: [wdmaudiodev] Re: AW: Re: AW: Re: bit transparency from app to WDM
audio driver depending from API?

 

I could better answer your questions if I understood where you were going
with this. Why do you ask? What is your scenario? These don't really sound
like "how do I write a driver" questions.

 

In Windows, the burden falls on the application to either invoke their own
micro-sample-rate-converter, or adjust Windows' built-in
micro-sample-rate-converter (e.g. via the IAudioClockAdjustment API.)

 



From: wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>  <wdmaudiodev-bounce@xxxxxxxxxxxxx
<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> > on behalf of Johannes Freyberger
<jfreyberger@xxxxxxxxxxxxxxxxxxxx <mailto:jfreyberger@xxxxxxxxxxxxxxxxxxxx>

Sent: Wednesday, August 22, 2018 2:03:14 AM
To: wdmaudiodev@xxxxxxxxxxxxx <mailto:wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] AW: Re: AW: Re: bit transparency from app to WDM
audio driver depending from API? 

 

Thank you very much for this info and the one concerning the exclusive mode
for bit transparency. Is this micro SRC insertion only done in non exclusive
mode or would this also be inserted in exclusive mode, if such a
microphone/speaker situation is detected? Is the SRC factor only computed
once or dynamically adjusted? I'm thinking about a situation where you have
a playout system running multiple hours or even days and if the SRC wouldn't
be adjusted or extremely precise it probably would result in buffer under-
or overruns on any end after a while.

 

Does this information concerning exclusive mode, SRC etc. apply to all
Windows OS versions (saying all I think about Windows 7, 8, 8.1, 10 64 bit
and Windows Server 2102 and 2016)?

____________________________________________________

 

"Usually a micro SRC is only inserted if the application in question has to
connect two clocks.

If it's just music playback, then the whole clock is driven by the DAC. If
the effective sample rate is a little slow, then the music just takes a
little longer to play.

But if the microphone and the speaker are both involved, and the ADC and
DACs are at different effective sample rates, then yes, a micro SRC is
(hopefully!) inserted."

 

 

PNG image

Other related posts: