Re: [alsa-devel] USB Audio questions
Pierre-Louis Bossart wrote:
- Is there any good reason why the max number of packets per urb defaults to
8?
Not really. It is an attempt to compromise between interrupt frequency and the latency resulting from packet queueing.
- Increasing the number of packets/urbs solves my power issue but not the
synchronization issue. If I reduce the number of urbs to reduce the interrupt rate, then the accuracy of the hw_pointer is decreased big time and it becomes difficult to synchronize with video. The .pointer routine only keeps track of retired urbs, it seems there's no way to know how many samples were played at a given time?
Only the URB completion callback tells us about finished packets.
For playback, we know how many bytes we had submitted, so we could derive the current position from the USB frame counter, but for capture, we don't know the precise byte count until the HCD has looked at the descriptors.
Isn't there a direct way to query the usb core to know how many bytes have been transmitted and make the hw_ptr/delay information independent of the urb buffer size?
No, this information isn't returned earlier than the completion callback.
It would be nice to be able to tell the HCD to collect information about all currently completed USB frames, regardless of whether the entire URB has finished or whether its interrupt flag is set, but this would require changes in all host controller drivers. (I'm contemplating something like this for FireWire, but there we have only one controller driver.)
- Is there any reason why the driver relies on vmalloc and memcpy? It seems
like using physically-contiguous memory would be more efficient, as done in the CAIQ driver?
Why more efficient? You cannot avoid double-buffering when a USB packet wraps around the end of the ALSA ring buffer.
- The period information is not updated when the urbs are allocated. In my
case the period specified was 25ms, but with all the approximations the actual period (number of urbs*buffer_size_per_urb) was 24ms.
Please note that URBs are usually not completely filled. For playback, the driver makes URBs shorter so that they end as nearly as possible on or after a period boundary; for capture, we cannot predict sample counts, so the driver just uses one URB per ms.
Regards, Clemens
On Tue, Aug 16, 2011 at 8:37 AM, Clemens Ladisch clemens@ladisch.de wrote:
Pierre-Louis Bossart wrote:
- Is there any good reason why the max number of packets per urb defaults to
8?
Not really. It is an attempt to compromise between interrupt frequency and the latency resulting from packet queueing.
Ah, I thought there is a limit of frames per urb that is the same than subframes per packet on USB. That's not the case then?
- Increasing the number of packets/urbs solves my power issue but not the
synchronization issue. If I reduce the number of urbs to reduce the interrupt rate, then the accuracy of the hw_pointer is decreased big time and it becomes difficult to synchronize with video. The .pointer routine only keeps track of retired urbs, it seems there's no way to know how many samples were played at a given time?
Only the URB completion callback tells us about finished packets.
For playback, we know how many bytes we had submitted, so we could derive the current position from the USB frame counter, but for capture, we don't know the precise byte count until the HCD has looked at the descriptors.
Wouldn't it be possible to not count what we submitted but look at the playback packets that return from the HCD and move the hwptr there? That information is presumably closer to the actual hardware position than the time when we queue.
Daniel
Daniel Mack wrote:
On Tue, Aug 16, 2011 at 8:37 AM, Clemens Ladisch clemens@ladisch.de wrote:
Pierre-Louis Bossart wrote:
- Is there any good reason why the max number of packets per urb defaults to
8?
Not really. It is an attempt to compromise between interrupt frequency and the latency resulting from packet queueing.
Ah, I thought there is a limit of frames per urb that is the same than subframes per packet on USB. That's not the case then?
URBs are a Linux-defined data structure; they can be arbitrarily long (as long as you don't reach the undocumented limit of how far in the future the HCD can schedule packets).
Wouldn't it be possible to not count what we submitted but look at the playback packets that return from the HCD and move the hwptr there? That information is presumably closer to the actual hardware position than the time when we queue.
In this case, the "hardware position" is the read pointer in ALSA's ring buffer, which must be incremented whenever data is moved from there into the URBs' buffers.
Regards, Clemens
Hi Clemens,
For playback, we know how many bytes we had submitted, so we could derive the current position from the USB frame counter, but for capture, we don't know the precise byte count until the HCD has looked at the descriptors.
Isn't there a direct way to query the usb core to know how many bytes have been transmitted and make the hw_ptr/delay information
independent
of the urb buffer size?
No, this information isn't returned earlier than the completion callback.
I am lost here, bear with my ignorance of USB... What is this USB frame counter and what would to enable its use, at least for playback where there is scope for lots of power optimizations.
Why more efficient? You cannot avoid double-buffering when a USB packet wraps around the end of the ALSA ring buffer.
What I had in mind is a case where the ring buffer is divided in separate periods, which would each correspond to an integer number of URBs/packets. This way there is _never_ a case of wrap-around and no need for memcpys. It's probably less generic than the current driver but a whole lot simpler/efficient.
- The period information is not updated when the urbs are allocated.
In my
case the period specified was 25ms, but with all the approximations
the
actual period (number of urbs*buffer_size_per_urb) was 24ms.
Please note that URBs are usually not completely filled. For playback, the driver makes URBs shorter so that they end as nearly as possible on or after a period boundary; for capture, we cannot predict sample counts, so the driver just uses one URB per ms.
Well I am precisely preaching for filling the URBs as much as possible to make things simpler for cases where latency doesn't matter. Of course for capture/speech cases latency does matter and I understand the need to do things differently there. -Pierre
participants (3)
-
Clemens Ladisch
-
Daniel Mack
-
Pierre-Louis Bossart