[alsa-devel] [PATCH 4/4] ALSA: x86: Refactor PCM process engine
Takashi Iwai
tiwai at suse.de
Sat Feb 4 08:51:54 CET 2017
On Sat, 04 Feb 2017 00:22:00 +0100,
Pierre-Louis Bossart wrote:
>
>
>
> On 02/03/2017 02:11 PM, Takashi Iwai wrote:
> > On Fri, 03 Feb 2017 20:47:55 +0100,
> > Pierre-Louis Bossart wrote:
> >> On 2/3/17 10:44 AM, Takashi Iwai wrote:
> >>> This is again a big rewrite of the driver; now it touches the code to
> >>> process PCM stream transfers.
> >>>
> >>> The most fundamental change is that now the driver supports more than
> >>> four periods. Instead of keeping the same index between the ring
> >>> buffers (from A to D) and the PCM buffer periods, now we keep
> >>> difference indices for both. Also, for the cases with less periods
> >>> than four, we track the head index, too. That is, we now have four
> >>> indices: ringbuf_head, pcm_head, ringbuf_filled, and pcm_filled.
> >> Well that's not completely right. The DMA can only generate an
> >> interrupt once the buffer you submit was played, and with 4
> >> descriptors you can't have more than 4 points where interrupts are
> >> generated. If you program different values in different descriptors
> >> then the notion of periodic hardware interrupts will be lost.
> > There is a standard trick such as used for ICH or other drivers.
> > With this kind of hardware, the address to be written to each buffer
> > descriptor can be changed dynamically while streaming. (BTW, on some
> > hardware like HD-audio, it's not allowed, but HD-audio has a larger
> > table, so it doesn't matter.)
> >
> > That is, each BD maps to each period on the PCM buffer, and it moves
> > there. A picture like below would illustrate:
> >
> > At time=0
> >
> > PCM | 0 | 1 | 2 | 3 | 4 | 5 | .... |n-1|
> > BD | A | B | C | D |
> >
> > At time=1 (period elapsed)
> >
> > PCM | 0 | 1 | 2 | 3 | 4 | 5 | .... |n-1|
> > BD | B | C | D | A |
> >
> > At time=2
> >
> > PCM | 0 | 1 | 2 | 3 | 4 | 5 | .... |n-1|
> > BD | C | D | A | B |
> Yes I thought this was a case of a moving window being used but what
> sort of application needs this? I never understood the benefits of
> expanding the number of periods, it just forces additional wake-ups
> for no good reason. It's really silly from a power perspective.
The usage like dmix requires more periods for more finer wakeups.
With the old driver with the fixed 4 periods, dmix doesn't work
properly. The dmix needs the synced timing control over multiple
streams, and the period wakeup is used. It could be rewritten with
POSIX timer, but it'd make things a bit complicated.
> > and so on.
> >
> > For the case periods < 4, it works other way round:
> >
> > t=0
> > PCM | 0 | 1 |
> > BD | A | B | - | - |
> >
> > t=1
> > PCM | 1 | 0 |
> > BD | - | B | C | - |
> >
> > t=2
> > PCM | 0 | 1 |
> > BD | - | - | C | D |
> it can be done this way but I don't believe this is required. I think
> you can mark 2 descriptors as invalid and use only two, i.e. to follow
> your example you'd loop on A-B. The hardware will loop on the 4
> descriptors, ignore the invalid ones and stop if it can't find a valid
> one.
Ah, that's good to know. So I just keep to set the rest invalid.
(The code change would be likely only one or two line reduction,
though :)
thanks,
Takashi
More information about the Alsa-devel
mailing list