ALSA project - the C library reference
Functions
Direct Access (MMAP) Functions
Collaboration diagram for Direct Access (MMAP) Functions:

Functions

int snd_pcm_mmap_begin (snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)
 Application request to access a portion of direct (mmap) area. More...
 
snd_pcm_sframes_t snd_pcm_mmap_commit (snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t frames)
 Application has completed the access to area requested with snd_pcm_mmap_begin. More...
 
snd_pcm_sframes_t snd_pcm_mmap_writei (snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
 Write interleaved frames to a PCM using direct buffer (mmap) More...
 
snd_pcm_sframes_t snd_pcm_mmap_readi (snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
 Read interleaved frames from a PCM using direct buffer (mmap) More...
 
snd_pcm_sframes_t snd_pcm_mmap_writen (snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 Write non interleaved frames to a PCM using direct buffer (mmap) More...
 
snd_pcm_sframes_t snd_pcm_mmap_readn (snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 Read non interleaved frames to a PCM using direct buffer (mmap) More...
 

Detailed Description

See the PCM (digital audio) interface page for more details.

Function Documentation

◆ snd_pcm_mmap_begin()

int snd_pcm_mmap_begin ( snd_pcm_t pcm,
const snd_pcm_channel_area_t **  areas,
snd_pcm_uframes_t offset,
snd_pcm_uframes_t frames 
)

Application request to access a portion of direct (mmap) area.

Parameters
pcmPCM handle
areasReturned mmap channel areas
offsetReturned mmap area offset in area steps (== frames)
framesmmap area portion size in frames (wanted on entry, contiguous available on exit)
Returns
0 on success otherwise a negative error code

It is necessary to call the snd_pcm_avail_update() function directly before this call. Otherwise, this function can return a wrong count of available frames.

The function should be called before a sample-direct area can be accessed. The resulting size parameter is always less or equal to the input count of frames and can be zero, if no frames can be processed (the ring buffer is full).

See the snd_pcm_mmap_commit() function to finish the frame processing in the direct areas.

The function is thread-safe when built with the proper option.

Examples
/test/pcm.c.

◆ snd_pcm_mmap_commit()

snd_pcm_sframes_t snd_pcm_mmap_commit ( snd_pcm_t pcm,
snd_pcm_uframes_t  offset,
snd_pcm_uframes_t  frames 
)

Application has completed the access to area requested with snd_pcm_mmap_begin.

Parameters
pcmPCM handle
offsetarea offset in area steps (== frames)
framesarea portion size in frames
Returns
count of transferred frames otherwise a negative error code

You should pass this function the offset value that snd_pcm_mmap_begin() returned. The frames parameter should hold the number of frames you have written or read to/from the audio buffer. The frames parameter must never exceed the contiguous frames count that snd_pcm_mmap_begin() returned. Each call to snd_pcm_mmap_begin() must be followed by a call to snd_pcm_mmap_commit().

Example:

double phase = 0;
const snd_pcm_area_t *areas;
snd_pcm_sframes_t avail, size, commitres;
snd_pcm_uframes_t offset, frames;
int err;
avail = snd_pcm_avail_update(pcm);
if (avail < 0)
error(avail);
// at this point, we can transfer at least 'avail' frames
// we want to process frames in chunks (period_size)
if (avail < period_size)
goto _skip;
size = period_size;
// it is possible that contiguous areas are smaller, thus we use a loop
while (size > 0) {
frames = size;
err = snd_pcm_mmap_begin(pcm_handle, &areas, &offset, &frames);
if (err < 0)
error(err);
// this function fills the areas from offset with count of frames
generate_sine(areas, offset, frames, &phase);
commitres = snd_pcm_mmap_commit(pcm_handle, offset, frames);
if (commitres < 0 || commitres != frames)
error(commitres >= 0 ? -EPIPE : commitres);
size -= frames;
}
_skip:
int snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames)
Application request to access a portion of direct (mmap) area.
Definition: pcm.c:7221
snd_pcm_sframes_t snd_pcm_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset, snd_pcm_uframes_t frames)
Application has completed the access to area requested with snd_pcm_mmap_begin.
Definition: pcm.c:7334
long snd_pcm_sframes_t
Definition: pcm.h:390
snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm)
Return number of frames ready to be read (capture) / written (playback)
Definition: pcm.c:2956
unsigned long snd_pcm_uframes_t
Definition: pcm.h:388

Look to the Sine-wave generator example for more details about the generate_sine function.

The function is thread-safe when built with the proper option.

Examples
/test/pcm.c.

◆ snd_pcm_mmap_readi()

snd_pcm_sframes_t snd_pcm_mmap_readi ( snd_pcm_t pcm,
void *  buffer,
snd_pcm_uframes_t  size 
)

Read interleaved frames from a PCM using direct buffer (mmap)

Parameters
pcmPCM handle
bufferframes containing buffer
sizeframes to be read
Returns
a positive number of frames actually read otherwise a negative error code
Return values
-EBADFDPCM is not in the right state (SND_PCM_STATE_PREPARED or SND_PCM_STATE_RUNNING)
-EPIPEan overrun occurred
-ESTRPIPEa suspend event occurred (stream is suspended and waiting for an application recovery)

If the blocking behaviour was selected, then routine waits until all requested bytes are filled. The count of bytes can be less only if a signal or underrun occurred.

If the non-blocking behaviour is selected, then routine doesn't wait at all.

◆ snd_pcm_mmap_readn()

snd_pcm_sframes_t snd_pcm_mmap_readn ( snd_pcm_t pcm,
void **  bufs,
snd_pcm_uframes_t  size 
)

Read non interleaved frames to a PCM using direct buffer (mmap)

Parameters
pcmPCM handle
bufsframes containing buffers (one for each channel)
sizeframes to be written
Returns
a positive number of frames actually read otherwise a negative error code
Return values
-EBADFDPCM is not in the right state (SND_PCM_STATE_PREPARED or SND_PCM_STATE_RUNNING)
-EPIPEan overrun occurred
-ESTRPIPEa suspend event occurred (stream is suspended and waiting for an application recovery)

If the blocking behaviour was selected, then routine waits until all requested bytes are filled. The count of bytes can be less only if a signal or underrun occurred.

If the non-blocking behaviour is selected, then routine doesn't wait at all.

◆ snd_pcm_mmap_writei()

snd_pcm_sframes_t snd_pcm_mmap_writei ( snd_pcm_t pcm,
const void *  buffer,
snd_pcm_uframes_t  size 
)

Write interleaved frames to a PCM using direct buffer (mmap)

Parameters
pcmPCM handle
bufferframes containing buffer
sizeframes to be written
Returns
a positive number of frames actually written otherwise a negative error code
Return values
-EBADFDPCM is not in the right state (SND_PCM_STATE_PREPARED or SND_PCM_STATE_RUNNING)
-EPIPEan underrun occurred
-ESTRPIPEa suspend event occurred (stream is suspended and waiting for an application recovery)

If the blocking behaviour is selected, then routine waits until all requested bytes are played or put to the playback ring buffer. The count of bytes can be less only if a signal or underrun occurred.

If the non-blocking behaviour is selected, then routine doesn't wait at all.

Examples
/test/pcm.c.

◆ snd_pcm_mmap_writen()

snd_pcm_sframes_t snd_pcm_mmap_writen ( snd_pcm_t pcm,
void **  bufs,
snd_pcm_uframes_t  size 
)

Write non interleaved frames to a PCM using direct buffer (mmap)

Parameters
pcmPCM handle
bufsframes containing buffers (one for each channel)
sizeframes to be written
Returns
a positive number of frames actually written otherwise a negative error code
Return values
-EBADFDPCM is not in the right state (SND_PCM_STATE_PREPARED or SND_PCM_STATE_RUNNING)
-EPIPEan underrun occurred
-ESTRPIPEa suspend event occurred (stream is suspended and waiting for an application recovery)

If the blocking behaviour is selected, then routine waits until all requested bytes are played or put to the playback ring buffer. The count of bytes can be less only if a signal or underrun occurred.

If the non-blocking behaviour is selected, then routine doesn't wait at all.