Re: USB Audio streaming start
Re: USB Audio streaming start
- Subject: Re: USB Audio streaming start
- From: Daniel Mack <email@hidden>
- Date: Wed, 19 Oct 2011 20:30:28 +0200
On 10.10.11 16:06, Vyacheslav Matyushin wrote:
> I'm developing an USB Audio driver and I'm stuck with streaming
> start.
>
> For streaming to work without gaps I must have a number of USB
> transactions queued ahead, so when a callback for completed
> transactions is called there will still be queued transactions to be
> sent over a bus. Right now I have 4 buffers each containing 32
> transactions (or 4 ms of data) for output stream.
>
> When a transaction for a buffer is completed a callback is called
> which queues samples for output again. As it takes 4 ms to process 32
> transactions (or 32 micro frames) a callback is constantly called
> every 4 ms.
>
> CoreAudio assumes that audio engine advances through it's buffers
> (increasing and wrapping an offset) at a constant rate. So at the
> beginning of the streaming I can't send all 4 buffers with real
> samples because I will have to take 16 ms of data from output stream
> buffers and advance audio engine's offset by 16 ms. Next callbacks
> will advance the offset by only 4 ms each.
>
> This way I will stream our first (sample_rate/10) output samples
> faster than tenth of a second. This will produce a HAL error because
> I will wrap around audio engine buffers earlier than HAL expected.
Make your IOAudioEngine buffer bigger so it wraps around once or twice a
second only. Getting the USB queuing right can be really tricky, but
here are some things to consider.
Note that your driver will be called from different contexts. One is the
IO workloop context which notifies you about handled USB packets (ie,
when they have been sent or read requests have been fulfilled). This
context is unusable for anything that is real-time audio related, as
callbacks can be held back by the magnitude of some 10ms under high
workload. So don't do anything from the callbacks but requeue the USB
requests. Because the IO workloop is so jitter-affected, Apple
recommends to actually queue the USB packets without any actual payload
provided at submission time (just zero-out the buffer). You have to set
up the buffer sizes, though. And you can many of them, as the number of
queued buffers won't add to your latency.
The other context is the high-priority real-time thread OS X calls your
::clipOutputSamples() method with. You can still access the previously
submitted buffers later and modify their contents from this real-time
thread. So do your audio material queuing from there, and also use it to
scan your submitted USB packet lists and see where the hardware engine's
head currently operates (IOUSBLowLatencyIsocFrame.frStatus). Once you
notice that the head wrapped over a position that translates to your
internal IOAudioEngine buffer's zero position, call takeTimeStamp().
Hope this helps,
Daniel
_______________________________________________
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