FramesPeriods

From AlsaProject
Jump to: navigation, search

A frame is equivalent of one sample being played, irrespective of the number of channels or the number of bits. e.g.

  • 1 frame of a Stereo 48khz 16bit PCM stream is 4 bytes.
  • 1 frame of a 5.1 48khz 16bit PCM stream is 12 bytes.

A period is the number of frames in between each hardware interrupt. The poll() will return once a period.

The buffer is a ring buffer. The buffer size always has to be greater than one period size. Commonly this is 2*period size, but some hardware can do 8 periods per buffer. It is also possible for the buffer size to not be an integer multiple of the period size.

Now, if the hardware has been set to 48000Hz , 2 periods, of 1024 frames each, making a buffer size of 2048 frames. The hardware will interrupt 2 times per buffer. ALSA will endeavor to keep the buffer as full as possible. Once the first period of samples has been played, the third period of samples is transfered into the space the first one occupied while the second period of samples is being played. (normal ring buffer behaviour).

 

Additional example

Here is an alternative example for the above discussion.

Say we want to work with a stereo, 16-bit, 44.1 KHz stream, one-way (meaning, either in playback or in capture direction). Then we have:

  • 'stereo' = number of channels: 2
  • 1 analog sample is represented with 16 bits = 2 bytes
  • 1 frame represents 1 analog sample from all channels; here we have 2 channels, and so:
    • 1 frame = (num_channels) * (1 sample in bytes) = (2 channels) * (2 bytes (16 bits) per sample) = 4 bytes (32 bits)
  • To sustain 2x 44.1 KHz analog rate - the system must be capable of data transfer rate, in Bytes/sec:
    • Bps_rate = (num_channels) * (1 sample in bytes) * (analog_rate) = (1 frame) * (analog_rate) = ( 2 channels ) * (2 bytes/sample) * (44100 samples/sec) = 2*2*44100 = 176400 Bytes/sec (link to formula img)


Alsa Bps formula


Now, if ALSA would interrupt each second, asking for bytes - we'd need to have 176400 bytes ready for it (at end of each second), in order to sustain analog 16-bit stereo @ 44.1Khz.

  • If it would interrupt each half a second, correspondingly for the same stream we'd need 176400/2 = 88200 bytes ready, at each interrupt;
  • if the interrupt hits each 100 ms, we'd need to have 176400*(0.1/1) = 17640 bytes ready, at each interrupt.


We can control when this PCM interrupt is generated, by setting a period size, which is set in frames.

  • Thus, if we set 16-bit stereo @ 44.1Khz, and the period_size to 4410 frames => (for 16-bit stereo @ 44.1Khz, 1 frame equals 4 bytes - so 4410 frames equal 4410*4 = 17640 bytes) => an interrupt will be generated each 17640 bytes - that is, each 100 ms.
  • Correspondingly, buffer_size should be at least 2*period_size = 2*4410 = 8820 frames (or 8820*4 = 35280 bytes).


It seems (writing-an-alsa-driver.pdf), however, that it is the ALSA runtime that decides on the actual buffer_size and period_size, depending on: the requested number of channels, and their respective properties (rate and sampling resolution) - as well as the parameters set in the snd_pcm_hardware structure (in the driver).

Also, the following quote may be relevant, from "(alsa-devel) Questions about writing a new ALSA driver for a very limitted device":

> > The "frame" represents the unit, 1 frame = # channels x sample_bytes.
> > In your case, 1 frame corresponds to 2 channels x 16 bits = 4 bytes.
> > 
> > The periods is the number of periods in a ring-buffer.  In OSS, called
> > as "fragments".
> > 
> > So,
> >  - buffer_size = period_size * periods
> >  - period_bytes = period_size * bytes_per_frame
> >  - bytes_per_frame = channels * bytes_per_sample 
> >
> 
> I still don't understand what 'period_size' and a 'period' is?

The "period" defines the frequency to update the status, usually via
the invokation of interrupts.  The "period_size" defines the frame
sizes corresponding to the "period time".  This term corresponds to
the "fragment size" on OSS.  On major sound hardwares, a ring-buffer
is divided to several parts and an irq is issued on each boundary.
The period_size defines the size of this chunk.

On some hardwares, the irq is controlled on the basis of a timer.  In
this case, the period is defined as the timer frequency to invoke an
irq.

original created 2006-09-24 by User:JamesCourtierDutton

Custom Search
Personal tools
Namespaces

Variants
Actions
Navigation
wiki
Toolbox