Re: Speeding HAL plugin loop rate
Re: Speeding HAL plugin loop rate
- Subject: Re: Speeding HAL plugin loop rate
- From: Jeff Moore <email@hidden>
- Date: Tue, 20 Jan 2009 11:11:35 -0800
So the purpose of your user-land driver is to have the IO thread track
the hardware not some ideal. That's the reality I was referring to.
The measured sample rate of real hardware is pretty much never the
same as it's nominal rate. The HAL has a lot of semantics surrounding
that observation. Among these are the time stamps that your driver
doles out as well as the rate at which IOProcs get called.
The sample code uses a 1.0 rate scalar because it was convenient and
didn't require a ton of math to manage. My presumption is that you
were already doing something more sophisticated to link the timing of
your driver with the true timing of your hardware (and thus would know
the true rate scalar of your hardware by empirical means). It sounds
like that presumption is incorrect. This is why you think you need to
speed up or slow down the IO thread. If your driver was providing
proper timing services, the IO thread would just naturally track what
your hardware is doing.
So, what you need to do is to figure a way to provide the sort of
timing services that a driver is required to. This means that you need
to figure out a way to measure the true rate at which your hardware is
running and to feed that into your driver.
As for your sample rate problem with the sample code, that seems to me
to be due to a short-cut that the sample code takes. The short cut is
that by only allowing one sample rate, the sample code avoids having
to have code that updates all the streams of the device when the
sample rate changes on one of them. That's not a bug, per se, but it
is something that could be improved to make the sample code better.
That said, there also appears to be an actual bug in the sample code
relating to changing the format where the sample code fails to send
any notifications when the format actually does change. The fix for
that would be to add code to
SHP_Stream::TellHardwareToSetPhysicalFormat() to send the appropriate
notifications (using HP_FormatList::DetermineNotifications()). Note
that if you undertake addressing the issue with multiple sample rates,
you'd also need to send notifications for all the other streams too.
Feel free to file a feature request on the former problem and a bug
about the latter problem.
On Jan 20, 2009, at 12:07 AM, Mike Kluev wrote:
On Mon, 19 Jan 2009 11:14:21 Jeff Moore <email@hidden> wrote:
On Jan 19, 2009, at 5:54 AM, Mike Kluev wrote:
On Tue, 06 Jan 2009 12:31:00 Jeff Moore <email@hidden> wrote:
FWIW, the timing code the the SampleHardwarePlugin does all it's
math assuming a rate scalar of 1.0. You can see this in how
SHP_Device::TranslateTime is implemented.
I found that if I make small adjustments to the outNextWakeUpTime
within HP_Thread::CalculateNextWakeUpTime I can speed or slow down
the rate of I/O proc:
....
theSampleTime.mSampleTime -= myDeltaSamples;
mDevice->TranslateTime(theSampleTime, outNextWakeUpTime);
theSampleTime.mSampleTime += myDeltaSamples;
....
This works, but again, I haven't done thorough testing.
Is this a no-no for some reason?
I don't know where to begin with what's wrong with what you are
proposing to do with the time stamps in the IO thread. Suffice to
say, doing what you describe (in essence, divorcing the IO thread
from reality) is basically breaking most of the promises an audio
device makes about how it deals with time.
Why don't we back up a bit and start off with what you are doing.
You've been asking questions on a few fronts and I'm not getting a
good sense of what you are trying to accomplish that would lead to
questions like this. Perhaps if I had a better idea, I could
provide better advice.
I implement user land audio driver based on Sample Hardware Plugin
sample. This
driver gets its input data from external source that runs at a
certain frequency,
lets say 44100 Hz. It turns out that the actual rate of my driver
(measured by
taking times between I/O calls and averaging over a period of
several seconds)
is slightly lower than 44100 (e.g. 43945 on average). I do not know
why. I need the
two rates to match perfectly on average: it is ok if the driver rate
will be slightly
faster or slower, just on average they should be equal. I do not
want to introduce
resampler (AudioConverter/AUConverter or Varispeed) between external
source and
driver to make the two rates equal, because I need the signal's wave
front to be as
close to original as possible. I found that if I speed up the rate
of I/O procedure
firing (dynamically adjusting the exact delta on how much to speed
up) I get what
I need. Just wanted to know if there is more appropriate way to do
this instead of
the code above (that, granted, looks like a hack). Should I somehow
change the rate
scalar you've mentioned above? Or maybe publish a range of rates my
driver supports
(say 43000--45000) and dynamically adjust the rate within this
range? Currently the
range of rates I publish in SHP_Stream.cpp has it's
mSampleRateRange.mMaximum ==
mSampleRateRange.mMinimum.
Separate to this, my driver needs to support more than one rate
(e.g. 22050).
I found that if I just add support for this rate to
SHP_Stream::AddAvailablePhysicalFormats and do nothing else, HALLab
and AMS
can't choose this rate (while showing this new rate in rate's
popup). I do not
know where the problem is (Sample Hardware Plugin sample code or
CoreAudio
itself or the way AMS/HALLab is written), however I want to fix it.
Looks like I
found the workaround and I'd appreciate if you comment on this as
well:
http://lists.apple.com/archives/coreaudio-api//2009/Jan/msg00195.html
Mike
--
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