[alsa-devel] problems writing pcm driver

Takashi Iwai tiwai at suse.de
Tue Aug 21 11:43:19 CEST 2007


At Mon, 20 Aug 2007 13:47:48 -0700 (PDT),
Trent Piepho wrote:
> 
> I'm trying to write an ALSA driver, but there are some thing I'm not clear on
> and it's not working as well as I'd like.
> 
> Atomicity:
> trigger, pointer, and ack are atomic with respect to themselves.  e.g., two
> copies of the trigger callback can't be running at the same time.  That much
> is clear.  But are they atomic with respect to each other?  Can the trigger
> callback run at the same time as the pointer callback?  How about the atomic
> callbacks with respect to the non-atomic ones?  Can trigger run at the same
> time as prepare?

No, these callbacks are exclusive.  In principle, they are called with
substream->lock spinlock already held by the PCM core, so they cannot
be called at the same time as long as belonging to the same PCM
substream instance.

> The pointer callback:
> What exactly is the current hardware position?  My hardware has a counter that
> tells me how many periods have been DMAed into the buffer.
> 
> Suppose my period size is 256 frames and I'm doing audio capture.  If pointer
> is called before any DMA transfers have completed, do I return 0?  Now suppose
> it's called after one period of audio has been DMAed into the buffer.  Do I
> return 255 or 256?  After two periods have been received, should I return 511
> or 0?

The pointer callback returns the position offset of the "ring
buffer".  It's not the period size.  Usually, a ring buffer consists
of multiple periods, and buffer_size = num_periods * period_size.
In such a case, the pointer callback returns the range from 0 to
buffer_size - 1.  If you have period_size=256 and periods=16, the
range would be between 0 and 4095.  Overlaps go to zero again.
Note that this unit is in "frames", not bytes.
1 frame = bytes_per_sample * nchannels.

> Why is pointer called so many times?

This callback is called not only at the IRQ handler (via
snd_pcm_period_elapsed()) but also when the PCM status query is
called, e.g. snd_pcm_status() invokation, and to check the status
before the read/write operations.

(snip)
> exited, it's called again.  What is the purpose of this?  Is it ok that
> I return the same value as the previous time it was called?

The pointer callback isn't necessarily to be so accurate, but it's
supposed to be fast.  Hence, yes, it's fine that you return the same
value as before unless updated via IRQ if the operation takes long
time.


Takashi


More information about the Alsa-devel mailing list