On jUN 22 2015 21:10, Alexander E. Patrakov wrote:
22.06.2015 16:54, Raymond Yau wrote:
Are all soc audio driver use cyclic dma ?
I'm not sure I understand the question. All audio drivers use some kind of cyclic DMA.
The ALSA API requires the driver to provide a cyclic sample buffer (or something that behaves like one).
However, not all hardware works this way. USB and FireWire require the driver to continually queue new packets, whose size and timing are determined by the bus clock and are not directly related to the ALSA ring buffer. These drivers use double buffering; the actual DMA happens from those packets, not from the ring buffer.
If those queued packets/urb cannot be rewind, snd_pcm_rewindable should return zero for those driver
No need at all for ALSA firewire drivers, because PCM frames which is not transferred are still rewindable.
Current ALSA firewire stack implementation, 16 packets are queued in one callback from software interrupt context. In IEEE 1394 bus, 8,000 packets are transmitted per second. Therefore, one callback processes PCM frames around 2 msec. (Actually, in IEC 61883-6, two ways to transfer PCM frames in these packets, thus one callback cannot processes PCM frames 'just' 2 msec.)
Let's consider about actual time, for example, in my system: * Software interrupt interval takes 1.986-2.015msec * The processing of one callback takes 0.024-0.026msec
(Intel DH77DF, Core i3-2120T, 4GB RAM, VT6315 as 1394 OHCI controller)
During processing one callback, pcm frames are copied to packet buffer. The 'hw_ptr' is updated every time the number of copied pcm frames is across period boundary. Therefore, the 'hw_ptr' suddenly jumps by one period. This is a reason to use 'SNDRV_PCM_INFO_BLOCK_TRANSFER'.
While, snd-firewire-lib has internal representation to count the number of transferred PCM frames. The 'struct snd_pcm_ops.pointer()' returns the counter in the representation. This counter is updated during the callback processing, while it's not updated between the callback. Therefore, the counter changes during 0.024-0.026msec and calm during 1.986-2.015msec. In short, the counter doesn't move continuously. Roughly, this may be observed as the returned value of 'struct snd_pcm_ops.pointer()' changes every 1.986-2.015msec. This is a reason to use 'SNDRV_PCM_INFO_BATCH'.
(I think we use these two flags as the same way as Lars explained: http://mailman.alsa-project.org/pipermail/alsa-devel/2015-June/093750.html)
(In my understanding, 'SNDRV_PCM_INFO_BATCH' means that 'struct snd_pcm_ops.pointer()' returns correct value in PCM period/buffer but the value doesn't change constantly against actual time frame. Therefore, several periods must be included in the buffer.)
Well, here, I describe two aspects; one is for period size and across-boundary, another is for rewindability.
* period size and across-boundary: All of ALSA firewire drivers has a restriction that the minimum size of period is equivalent to 5 msec. Our intension is that at least one callback from software interrupt context occurs during processing PCM frames equivalent to the size of period. ('5' msec is for safe. '3' msec may be OK, I think.)
* rewindability During the 0.024-0.026msec, snd_pcm_rewindable() returns the value based on currect pointer position in the internal representation in snd-firewire-lib, while the value is immediately changed and the retrieved value becomes old. During the 1.986-2.015msec, snd_pcm_rewindable returns the fastened value because no PCM frames are processed for transmission.
By the way, abour the packetization and PCM frame processing, I've written a report: https://github.com/takaswie/alsa-firewire-report
If you want to post your questions about ALSA firewire stack, please read this report and consider about your issues before posting it, Raymond. Of cource, I'm welcome to receive any questions or indications about the content of my report.
Regards
Takashi Sakamoto