Re: Synchronization problem in 10.2
Re: Synchronization problem in 10.2
- Subject: Re: Synchronization problem in 10.2
- From: Mark Cookson <email@hidden>
- Date: Fri, 4 Oct 2002 10:42:34 -0700
On Thursday, October 3, 2002, at 03:53 PM, Michel wrote:
The buffer size is limited due to IOMallocContiguous. I don't have a
choice.
the bigger I allocate, the more chance there is for it to return
addresses I
can't use.
What is "special" about what is happening in my driver is that I
publish 8
channels to the IOAudioStream, but I have a different DMA setup. and I
do the
black magic in clipOutputSample/convertInputSamples by completely
ignoring
the buffer I had passed to the stream, and using instead the DMA one
for
source/destination.
Thats the only way I found for masquerate the DMA layout. It works
pretty
well, save from the mixing issues.
If it doesn't work with two clients, then I don't think that we can
really consider it working at all, unless this is going to be for a
dedicated system where you know the user will only ever be running your
application.
The interesting thing about having two or more clients is that the mix
routine will be working on parts of your buffer. Maybe a picture will
help...
|.........client 1.........|.........client 1.........|.........client
1.........|
|.........client 2.........|.........client
2.........|.........client 2.........|
|.........client 3.........|.........client
3.........|.........client 3.........|
What this picture is trying to show is how the mix routine is trying to
mix and clip the source buffers into your destination buffer. The
first time the HAL calls it for client 1, the HAL passes in 512
samples. At some point later client 2 starts playing audio. At that
point the IOAudioFamily issues a resetClipPosition() call to your
driver to back up to the point where client 2 is coming in. It then
mixes in the bit of client 2 that overlaps with client 1, but not all
of client 2 because the timing of calls down into your driver is being
driven by client 1. Let's say that only 400 samples are mixed in with
the 512 passed by client 1. Then at some time later, client 3 decides
it wants to play audio. Once again, a resetClipPosition() call is made
to your driver and a little bit of client 3's buffer is mixed in with
what client 1 and 2 have already passed in. Let's say that 150 samples
are mixed in from client 3. You driver's clipOutputSamples() function
is now called with a buffer of 512 samples, 512 from client 1, 400 from
client 2, and 150 from client 3. The next time client 1 gives the HAL
data, IOAudioFamily mixes that with the remaining 112 samples from
client 2 and 362 samples client 3, and the cycle repeats.
Perhaps your interesting DMA is getting into problems with this offset
mixing, or with the fact that you are ignoring the buffer you
registered with the stream. The IOAudioFamily only knows about the
buffer you registered with setSampleBuffer(). You can use other
buffers, but all of your source input will be in that buffer, and all
of your recorded samples need to be placed into that buffer.
Are you sure that your DMA can't do scatter-gather transactions? I've
not seen any DMA hardware for quite some time that can't be programmed
to jump around in physical memory. Physically contiguous memory is
great, but you really can't design hardware expecting that you'll
always be able to get it, so every DMA engine I've ever seen has the
ability to X bytes from location x, Y bytes from location y, Z from z,
and so on. It makes programming the DMA engine a bit trickier, but
it's almost always possible.
Using an IOMemoryDescriptor allows you to allocate a buffer using
IOMalloc, and then walk through it using getPhysicalSegment() to
program your hardware's DMA. Each segment will be physically
contiguous, so you can program the DMA engine with each segment, using
as many segments as necessary to describe the entire buffer. The
entire buffer doesn't have to be physically contiguous if your DMA
engine allows you program multiple transfer descriptors at once, and
even if you can only program one segment at a time, if you get a
half-done interrupt, you should have enough time to prepare the next
segment before the first finishes. Using and IOMemoryDescriptor, you
can even make the end of the ring buffer look like it's attached to the
front of the ring buffer. This allows you to seamlessly wrap around
the buffer without the code that's preparing the DMA transfer
descriptors even noticing, a very cool feature that I take advantage of
in the AppleUSBAudio driver.
Mac OS X really frowns on devices that need physically contiguous
memory which is why the API is so limited and often fails. Having a
large pool of physically contiguous memory in the kernel really hampers
the kernels ability to do efficient memory allocation, which is why it
is not encouraged. Whenever this requirement is presented to a kernel
engineer, they always reply that these devices will never be fully
accepted by Mac OS X, that they just aren't going to do the work to
make physically contiguous memory easy to come by.
--
Mark Cookson
Engineering Droid
Apple Computer, Inc.
Core Audio CPU Software
6 Infinite Loop MS 306-2CW
Cupertino, CA 95014
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.