alsa_pcm (alsa v0.3.0)

View Source

Capture and playback of audio through an ALSA PCM device.

Open a device with open/2, configure it with set_params/2 (or with set_hwparams/2 and set_swparams/2 for finer control), then play audio with writei/3 or capture it with readi/2, and close the device with close/1. The PCM handle is closed automatically if the process that opened it terminates.

The functions return {error, Error} with a posix error Error, see error/0. recover/2 recovers a stream from the errors that can be recovered from, such as an underrun or an overrun.

Example

Playing audio:

{ok, PCM} = alsa_pcm:open("default", playback),
ok = alsa_pcm:set_params(PCM, #{
    format => s16_le,
    access => rw_interleaved,
    channels => 2,
    rate => 48000,
    rate_resample => true,
    latency => 100000
}),
ok = alsa_pcm:writei(PCM, Data, infinity),
ok = alsa_pcm:close(PCM).

See the examples directory for more.

Summary

Types

A posix error. The most common ones are atoms, the others are error numbers.

The access mode of the PCM: rw_interleaved when the channels data is multiplexed into the same buffer, or rw_noninterleaved when each channel has a separate buffer.

The sample format. The names are those of the ALSA sample formats, such as s16_le for signed 16 bit little endian samples and float_be for 32 bit float big endian samples. The names without an endianness (s16, u16, s24, u24, s32, u32, float, float64, iec958_subframe, s20 and u20) are aliases for the endianness of the machine.

The hardware parameters of a PCM, see set_hwparams/2.

The parameters for set_params/2, which are all required.

A handle to a PCM.

The current software parameters, see get_swparams/1.

The software parameters to set, see set_swparams/2.

Functions

Closes a previously opened PCM handle.

Stops the PCM, dropping the pending frames. The PCM is stopped immediately and the pending samples on the buffer are ignored.

Gets the size in bytes of a frame, that is of one sample for each channel, with the current hardware parameters.

Gets the current software parameters.

Opens a PCM. The returned PCM handle will be closed automatically if the opening process terminates.

Pauses the PCM. Note that this function works only on the hardware which supports the pause feature.

Prepares the PCM for use.

Reads interleaved audio frames from the PCM. At most 4096 frames are read at a time.

Recovers the stream state from an error or a suspend. This function handles the eintr (interrupted system call), epipe (overrun or underrun) and estrpipe (stream is suspended) errors, trying to prepare the given stream for the next I/O.

Gets the size in bytes of a sample with the current hardware parameters.

Sets the hardware parameters. The parameters that are not given are left for the device to choose.

Sets the hardware and software parameters in a simple way. The following parameters are all required

Sets the software parameters.

Starts the PCM. Normally you do not need to call this function for playback if using set_params/2, as the auto-start mechanism will kick in. However, you need to call this function in capture mode.

Unpauses a previously paused PCM.

Writes interleaved audio frames to the PCM.

Types

error()

-type error() :: eagain | ebadfd | ebusy | eintr | enoent | enosys | epipe | estrpipe | pos_integer().

A posix error. The most common ones are atoms, the others are error numbers.

hwparam_access()

-type hwparam_access() :: rw_interleaved | rw_noninterleaved.

The access mode of the PCM: rw_interleaved when the channels data is multiplexed into the same buffer, or rw_noninterleaved when each channel has a separate buffer.

hwparam_format()

-type hwparam_format() ::
          s8 | u8 | s16_le | s16_be | u16_le | u16_be | s24_le | s24_be | u24_le | u24_be | s32_le |
          s32_be | u32_le | u32_be | float_le | float_be | float64_le | float64_be |
          iec958_subframe_le | iec958_subframe_be | mu_law | a_law | ima_adpcm | mpeg | gsm | s20_le |
          s20_be | u20_le | u20_be | special | s24_3le | s24_3be | u24_3le | u24_3be | s20_3le |
          s20_3be | u20_3le | u20_3be | s18_3le | s18_3be | u18_3le | u18_3be | g723_24 | g723_24_1b |
          g723_40 | g723_40_1b | dsd_u8 | dsd_u16_le | dsd_u16_be | dsd_u32_le | dsd_u32_be | s16 |
          u16 | s24 | u24 | s32 | u32 | float | float64 | iec958_subframe | s20 | u20.

The sample format. The names are those of the ALSA sample formats, such as s16_le for signed 16 bit little endian samples and float_be for 32 bit float big endian samples. The names without an endianness (s16, u16, s24, u24, s32, u32, float, float64, iec958_subframe, s20 and u20) are aliases for the endianness of the machine.

hwparams()

-type hwparams() ::
          #{access => hwparam_access(),
            format => hwparam_format(),
            channels => pos_integer(),
            rate => pos_integer(),
            rate_resample => boolean()}.

The hardware parameters of a PCM, see set_hwparams/2.

  • access - the access mode
  • format - the sample format
  • channels - the number of channels
  • rate - the sample rate, such as 44100 or 48000
  • rate_resample - whether to allow software resampling in case the provided sample rate is not supported by the device

params()

-type params() ::
          #{access := hwparam_access(),
            format := hwparam_format(),
            channels := pos_integer(),
            rate := pos_integer(),
            rate_resample := boolean(),
            latency := pos_integer()}.

The parameters for set_params/2, which are all required.

pcm()

-opaque pcm()

A handle to a PCM.

swparams()

-type swparams() ::
          #{avail_min := pos_integer(),
            boundary := pos_integer(),
            start_threshold := non_neg_integer(),
            stop_threshold := non_neg_integer(),
            silence_threshold := non_neg_integer(),
            silence_size := non_neg_integer()}.

The current software parameters, see get_swparams/1.

swparams_options()

-type swparams_options() ::
          #{avail_min => pos_integer(),
            start_threshold => non_neg_integer(),
            stop_threshold => non_neg_integer(),
            silence_threshold => non_neg_integer(),
            silence_size => non_neg_integer()}.

The software parameters to set, see set_swparams/2.

Functions

close(PCM)

-spec close(pcm()) -> ok | {error, error()}.

Closes a previously opened PCM handle.

  • PCM - the PCM handle to close

Returns ok on success otherwise a posix error.

drop(PCM)

-spec drop(pcm()) -> ok | {error, error()}.

Stops the PCM, dropping the pending frames. The PCM is stopped immediately and the pending samples on the buffer are ignored.

  • PCM - the PCM handle

Returns ok on success otherwise a posix error.

frame_size(PCM)

-spec frame_size(pcm()) -> pos_integer().

Gets the size in bytes of a frame, that is of one sample for each channel, with the current hardware parameters.

  • PCM - the PCM handle

get_swparams(PCM)

-spec get_swparams(pcm()) -> {ok, swparams()} | {error, error()}.

Gets the current software parameters.

  • PCM - the PCM handle

Returns the parameters, see swparams/0, on success otherwise a posix error. The boundary is the position at which the PCM position wraps around.

open(Device, Direction)

-spec open(string() | binary(), playback | capture) -> {ok, pcm()} | {error, error()}.

Opens a PCM. The returned PCM handle will be closed automatically if the opening process terminates.

  • Device - ASCII identifier of the PCM handle
  • Direction - wanted stream direction, that is either capture for reading audio data from the audio device, or playback for writing audio data to the audio device

Returns a handle to the PCM device on success otherwise a posix error.

pause(PCM)

-spec pause(pcm()) -> ok | {error, error()}.

Pauses the PCM. Note that this function works only on the hardware which supports the pause feature.

  • PCM - the PCM handle

Returns ok on success otherwise a posix error. See unpause/1.

prepare(PCM)

-spec prepare(pcm()) -> ok | {error, error()}.

Prepares the PCM for use.

  • PCM - the PCM handle to prepare

Returns ok on success otherwise a posix error.

readi(PCM, Timeout)

-spec readi(pcm(), timeout() | nowait) ->
               {ok, binary()} | {wait, {ready_readi, reference()}} | {error, timeout} | {error, error()}.

Reads interleaved audio frames from the PCM. At most 4096 frames are read at a time.

  • PCM - the PCM handle
  • Timeout - how long to wait, in milliseconds, for the device to have data, infinity to wait without a limit, or nowait to not wait

Returns:

  • {ok, Data} - the audio data that was read, as interleaved frames
  • {wait, {ready_readi, Reference}} - only with nowait, when the device has no data yet. Wait for the {ready_readi, Reference} message to be delivered to the calling process, then call this function again
  • {error, timeout} - the device did not have data in time
  • {error, Error} - a posix error. Use recover/2 to recover from it

In capture mode the PCM has to be started with start/1 first.

recover(PCM, Error)

-spec recover(pcm(), error()) -> ok | {error, error()}.

Recovers the stream state from an error or a suspend. This function handles the eintr (interrupted system call), epipe (overrun or underrun) and estrpipe (stream is suspended) errors, trying to prepare the given stream for the next I/O.

Note that this function returns the original error when it is not handled inside this function.

  • PCM - the PCM handle
  • Error - the previously returned error from which we are trying to recover

Returns ok on success otherwise a posix error.

sample_size(PCM)

-spec sample_size(pcm()) -> pos_integer().

Gets the size in bytes of a sample with the current hardware parameters.

  • PCM - the PCM handle

set_hwparams(PCM, Params)

-spec set_hwparams(pcm(), hwparams()) -> ok | {error, error()}.

Sets the hardware parameters. The parameters that are not given are left for the device to choose.

  • PCM - the PCM handle
  • Params - a map of the parameters to set, see hwparams/0

Returns ok on success otherwise a posix error. See set_params/2 to set the hardware and software parameters in a simple way.

set_params(PCM, Params)

-spec set_params(pcm(), params()) -> ok | {error, error()}.

Sets the hardware and software parameters in a simple way. The following parameters are all required:

  • access - the access mode, see hwparam_access/0. Interleaved access means that the channels data is multiplexed into the same buffer, and that readi/2 and writei/3 are to be used. Non interleaved access means that the channels data is read or written to separate buffers, this library does not provide functions for it.
  • format - the sample format, see hwparam_format/0. The format specifies how the data in each sample is encoded.
  • channels - the number of channels, which must be a strictly positive integer.
  • rate - the sample rate, such as 44100 or 48000.
  • rate_resample - whether to allow software resampling in case the provided sample rate is not supported by the target device.
  • latency - the required overall latency in microseconds.

Arguments:

  • PCM - the PCM handle
  • Params - a map of the parameters to set, see params/0

Returns ok on success otherwise a posix error.

set_swparams(PCM, Params)

-spec set_swparams(pcm(), swparams_options()) -> ok | {error, error()}.

Sets the software parameters.

  • avail_min - the minimum number of frames that must be available before the PCM wakes up. The valid values are determined by the specific hardware. Most PC sound cards can only accept power of 2 frame counts (i.e. 512, 1024, 2048).
  • start_threshold - the PCM is automatically started when the playback frames available to the PCM are greater than or equal to start_threshold, or when the requested capture frames are greater than or equal to start_threshold.
  • stop_threshold - the PCM is automatically stopped in an underrun or overrun state when the available frames are greater than or equal to stop_threshold. If the stop threshold is equal to the boundary then the automatic stop is disabled (thus the device will do the endless loop in the ring buffer).
  • silence_threshold - a portion of the playback buffer is overwritten with silence when the playback underrun is nearer than the silence threshold.
  • silence_size - a portion of the playback buffer is overwritten with silence when the playback underrun is nearer than the silence threshold (see snd_pcm_sw_params_set_silence_threshold). The special case is when the silence size is equal to or greater than the boundary. The unused portion of the ring buffer (initial written samples are untouched) is filled with silence at start. Later, only the just processed sample area is filled with silence. Note: silence_threshold must be set to zero.

Arguments:

Returns ok on success otherwise a posix error.

start(PCM)

-spec start(pcm()) -> ok | {error, error()}.

Starts the PCM. Normally you do not need to call this function for playback if using set_params/2, as the auto-start mechanism will kick in. However, you need to call this function in capture mode.

  • PCM - the PCM handle

Returns ok on success otherwise a posix error.

unpause(PCM)

-spec unpause(pcm()) -> ok | {error, error()}.

Unpauses a previously paused PCM.

  • PCM - the PCM handle

Returns ok on success otherwise a posix error. See pause/1.

writei(PCM, Buffer, Timeout)

-spec writei(pcm(), binary(), timeout() | nowait) ->
                ok |
                {wait, {ready_writei, reference()}, Remaining :: binary()} |
                {error, incomplete_frame, Remaining :: binary()} |
                {error, timeout, Remaining :: binary()} |
                {error, error(), Remaining :: binary()}.

Writes interleaved audio frames to the PCM.

  • PCM - the PCM handle
  • Buffer - the audio data, which should hold a whole number of frames, see frame_size/1
  • Timeout - how long to wait, in milliseconds, for the device to accept the data, infinity to wait without a limit, or nowait to not wait

Returns:

  • ok - all the frames were written
  • {wait, {ready_writei, Reference}, Remaining} - only with nowait, when the device cannot accept more data yet. Wait for the {ready_writei, Reference} message to be delivered to the calling process, then call this function again with Remaining
  • {error, incomplete_frame, Remaining} - the whole frames of Buffer were written, and Remaining holds the trailing bytes that do not make a frame
  • {error, timeout, Remaining} - the device did not accept the data in time
  • {error, Error, Remaining} - a posix error. Use recover/2 to recover from it. Remaining is the data that was not written

When Buffer ends with bytes that do not make a frame, those bytes are part of Remaining in the wait, timeout and posix error results.