PCM (digital audio) plugins
PCM plugins extends functionality and features of PCM devices. The plugins take care about various sample conversions, sample copying among channels and so on.
Slave definition
The slave plugin can be specified directly with a string or the definition can be entered inside a compound configuration node. Some restrictions can be also specified (like static rate or count of channels).
pcm_slave.NAME { pcm STR # PCM name # or pcm { } # PCM definition format STR # Format or "unchanged" channels INT # Count of channels or "unchanged" string rate INT # Rate in Hz or "unchanged" string period_time INT # Period time in us or "unchanged" string buffer_time INT # Buffer time in us or "unchanged" string }
Example:
pcm_slave.slave_rate44100Hz { pcm "hw:0,0" rate 44100 } pcm.rate44100Hz { type plug slave slave_rate44100Hz }
The equivalent configuration (in one compound):
pcm.rate44100Hz { type plug slave { pcm "hw:0,0" rate 44100 } }
Plugin: hw
This plugin communicates directly with the ALSA kernel driver. It is a raw communication without any conversions. The emulation of mmap access can be optionally enabled, but expect worse latency in the case.
The nonblock option specifies whether the device is opened in a non-blocking manner. Note that the blocking behavior for read/write access won’t be changed by this option. This influences only on the blocking behavior at opening the device. If you would like to keep the compatibility with the older ALSA stuff, turn this option off.
pcm.name { type hw # Kernel PCM card INT/STR # Card name (string) or number (integer) [device INT] # Device number (default 0) [subdevice INT] # Subdevice number (default -1: first available) [sync_ptr_ioctl BOOL] # Use SYNC_PTR ioctl rather than the direct mmap access for control structures [nonblock BOOL] # Force non-blocking open mode [format STR] # Restrict only to the given format [channels INT] # Restrict only to the given channels [rate INT] # Restrict only to the given rate [chmap MAP] # Override channel maps; MAP is a string array }
Function reference
Plugin: mmap_emul
pcm.name { type mmap_emul slave PCM }
Function reference
Plugin: shm
This plugin communicates with aserver via shared memory. It is a raw communication without any conversions, but it can be expected worse performance.
pcm.name { type shm # Shared memory PCM server STR # Server name pcm STR # PCM name }
Function reference
Plugin: Null
This plugin discards contents of a PCM stream or creates a stream with zero samples.
Note: This implementation uses devices /dev/null (playback, must be writable) and /dev/full (capture, must be readable).
pcm.name { type null # Null PCM [chmap MAP] # Provide channel maps; MAP is a string array }
Function reference
Plugin: copy
This plugin copies samples from master copy PCM to given slave PCM. The channel count, format and rate must match for both of them.
pcm.name { type copy # Copy PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition } }
Function reference
Plugin: linear
This plugin converts linear samples from master linear conversion PCM to given slave PCM. The channel count, format and rate must match for both of them.
pcm.name { type linear # Linear conversion PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition format STR # Slave format } }
Function reference
Plugin: linear<->float
This plugin converts linear to float samples and float to linear samples from master linear<->float conversion PCM to given slave PCM. The channel count, format and rate must match for both of them.
pcm.name { type lfloat # Linear<->Float conversion PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition format STR # Slave format } }
Function reference
Plugin: Mu-Law
This plugin converts Mu-Law samples to linear or linear to Mu-Law samples from master Mu-Law conversion PCM to given slave PCM. The channel count, format and rate must match for both of them.
pcm.name { type mulaw # Mu-Law conversion PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition format STR # Slave format } }
Function reference
Plugin: A-Law
This plugin converts A-Law samples to linear or linear to A-Law samples from master A-Law conversion PCM to given slave PCM. The channel count, format and rate must match for both of them.
pcm.name { type alaw # A-Law conversion PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition format STR # Slave format } }
Function reference
Plugin: Ima-ADPCM
This plugin converts Ima-ADPCM samples to linear or linear to Ima-ADPCM samples from master Ima-ADPCM conversion PCM to given slave PCM. The channel count, format and rate must match for both of them.
pcm.name { type adpcm # Ima-ADPCM conversion PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition format STR # Slave format } }
Function reference
Plugin: Route & Volume
This plugin converts channels and applies volume during the conversion. The format and rate must match for both of them.
SCHANNEL can be a channel name instead of a number (e g FL, LFE). If so, a matching channel map will be selected for the slave.
pcm.name { type route # Route & Volume conversion PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition [format STR] # Slave format [channels INT] # Slave channels } ttable { # Transfer table (bi-dimensional compound of cchannels * schannels numbers) CCHANNEL { SCHANNEL REAL # route value (0.0 - 1.0) } } }
Function reference
Plugin: Rate
This plugin converts a stream rate. The input and output formats must be linear.
pcm.name { type rate # Rate PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition rate INT # Slave rate [format STR] # Slave format } converter STR # optional # or converter [ STR1 STR2 ... ] # optional # Converter type, default is taken from # defaults.pcm.rate_converter }
Function reference
Automatic conversion plugin
This plugin converts channels, rate and format on request.
pcm.name { type plug # Automatic conversion PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition [format STR] # Slave format (default nearest) or "unchanged" [channels INT] # Slave channels (default nearest) or "unchanged" [rate INT] # Slave rate (default nearest) or "unchanged" } route_policy STR # route policy for automatic ttable generation # STR can be 'default', 'average', 'copy', 'duplicate' # average: result is average of input channels # copy: only first channels are copied to destination # duplicate: duplicate first set of channels # default: copy policy, except for mono capture - sum ttable { # Transfer table (bi-dimensional compound of cchannels * schannels numbers) CCHANNEL { SCHANNEL REAL # route value (0.0 - 1.0) } } rate_converter STR # type of rate converter # or rate_converter [ STR1 STR2 ... ] # type of rate converter # default value is taken from defaults.pcm.rate_converter }
Function reference
snd_pcm_plug_open()
_snd_pcm_plug_open()
Plugin: File
This plugin stores contents of a PCM stream to file or pipes the stream to a command, and optionally uses an existing file as an input data source (i.e., “virtual mic”)
pcm.name { type file # File PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition } file STR # Output filename (or shell command the stream # will be piped to if STR starts with the pipe # char). # STR can contain format keys, replaced by # real values corresponding to the stream: # %r rate (replaced with: 48000) # %c channels (replaced with: 2) # %b bits per sample (replaced with: 16) # %f sample format string # (replaced with: S16_LE) # %% replaced with % or file INT # Output file descriptor number infile STR # Input filename - only raw format or infile INT # Input file descriptor number [format STR] # File format ("raw" or "wav") [perm INT] # Output file permission (octal, def. 0600) }
Function reference
Plugin: Multiple streams to One
This plugin converts multiple streams to one.
pcm.name { type multi # Multiple streams conversion PCM slaves { # Slaves definition ID STR # Slave PCM name # or ID { pcm STR # Slave PCM name # or pcm { } # Slave PCM definition channels INT # Slave channels } } bindings { # Bindings table N { slave STR # Slave key channel INT # Slave channel } } [master INT] # Define the master slave }
For example, to bind two PCM streams with two-channel stereo (hw:0,0 and hw:0,1) as one 4-channel stereo PCM stream, define like this:
pcm.quad { type multi slaves.a.pcm "hw:0,0" slaves.a.channels 2 slaves.b.pcm "hw:0,1" slaves.b.channels 2 bindings.0.slave a bindings.0.channel 0 bindings.1.slave a bindings.1.channel 1 bindings.2.slave b bindings.2.channel 0 bindings.3.slave b bindings.3.channel 1 }
Note that the resultant pcm “quad” is not in the interleaved format but in the “complex” format. Hence, it’s not accessible by applications which can handle only the interleaved (or the non-interleaved) format. In such a case, wrap this PCM with route or plug plugin.
pcm.quad2 { type route slave.pcm "quad" ttable.0.0 1 ttable.1.1 1 ttable.2.2 1 ttable.3.3 1 }
Function reference
Plugin: hooks
This plugin is used to call some ‘hook’ function when this plugin is opened, modified or closed. Typically, it is used to change control values for a certain state specially for the PCM (see the example below).
# Hook arguments definition hook_args.NAME { ... # Arbitrary arguments } # PCM hook type pcm_hook_type.NAME { [lib STR] # Library file (default libasound.so) [install STR] # Install function (default _snd_pcm_hook_NAME_install) } # PCM hook definition pcm_hook.NAME { type STR # PCM Hook type (see pcm_hook_type) [args STR] # Arguments for install function (see hook_args) # or [args { }] # Arguments for install function } # PCM hook plugin pcm.NAME { type hooks # PCM with hooks slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition } hooks { ID STR # Hook name (see pcm_hook) # or ID { } # Hook definition (see pcm_hook) } }
Example:
hooks.0 { type ctl_elems hook_args [ { name "Wave Surround Playback Volume" preserve true lock true optional true value [ 0 0 ] } { name "EMU10K1 PCM Send Volume" index { @func private_pcm_subdevice } lock true value [ 0 0 0 0 0 0 255 0 0 0 0 255 ] } ] }
Here, the controls “Wave Surround Playback Volume” and “EMU10K1 PCM Send Volume” are set to the given values when this pcm is accessed. Since these controls take multi-dimensional values, the value
field is written as an array. When preserve
is true, the old values are saved and restored when the pcm is closed. The lock
means that the control is locked during this pcm is opened, and cannot be changed by others. When optional
is set, no error is returned but ignored even if the specified control doesn’t exist.
Function reference
The function ctl_elems - _snd_pcm_hook_ctl_elems_install() - installs CTL settings described by given configuration.
Plugin: dmix
This plugin provides direct mixing of multiple streams. The resolution for 32-bit mixing is only 24-bit. The low significant byte is filled with zeros. The extra 8 bits are used for the saturation.
pcm.name { type dmix # Direct mix ipc_key INT # unique IPC key ipc_key_add_uid BOOL # add current uid to unique IPC key ipc_perm INT # IPC permissions (octal, default 0600) slave STR # or slave { # Slave definition pcm STR # slave PCM name # or pcm { } # slave PCM definition format STR # format definition rate INT # rate definition channels INT period_time INT # in usec # or period_size INT # in bytes buffer_time INT # in usec # or buffer_size INT # in bytes periods INT # when buffer_size or buffer_time is not specified } bindings { # note: this is client independent!!! N INT # maps slave channel to client channel N } slowptr BOOL # slow but more precise pointer updates }
ipc_key
specfies the unique IPC key in integer. This number must be unique for each different dmix definition, since the shared memory is created with this key number. When ipc_key_add_uid
is set true, the uid value is added to the value set in ipc_key
. This will avoid the confliction of the same IPC key with different users concurrently.
Note that the dmix plugin itself supports only a single configuration. That is, it supports only the fixed rate (default 48000), format (S16
), channels (2), and period_time (125000). For using other configuration, you have to set the value explicitly in the slave PCM definition. The rate, format and channels can be covered by an additional plug plugin, but there is only one base configuration, anyway.
An example configuration for setting 44100 Hz, S32_LE
format as the slave PCM of “hw:0” is like below:
pcm.dmix_44 { type dmix ipc_key 321456 # any unique value ipc_key_add_uid true slave { pcm "hw:0" format S32_LE rate 44100 } }
You can hear 48000 Hz samples still using this dmix pcm via plug plugin like:
% aplay -Dplug:dmix_44 foo_48k.wav
For using the dmix plugin for OSS emulation device, you have to set the period and the buffer sizes in power of two. For example,
pcm.dmixoss { type dmix ipc_key 321456 # any unique value ipc_key_add_uid true slave { pcm "hw:0" period_time 0 period_size 1024 # must be power of 2 buffer_size 8192 # ditto } }
period_time 0
must be set, too, for resetting the default value. In the case of soundcards with multi-channel IO, adding the bindings would help
pcm.dmixoss { ... bindings { 0 0 # map from 0 to 0 1 1 # map from 1 to 1 } }
so that only the first two channels are used by dmix. Also, note that ICE1712 have the limited buffer size, 5513 frames (corresponding to 640 kB). In this case, reduce the buffer_size to 4096.
Function reference
Plugin: dsnoop
This plugin splits one capture stream to more. It works the reverse way of dmix plugin, reading the shared capture buffer from many clients concurrently. The meaning of parameters below are almost identical with dmix plugin.
pcm.name { type dsnoop # Direct snoop ipc_key INT # unique IPC key ipc_key_add_uid BOOL # add current uid to unique IPC key ipc_perm INT # IPC permissions (octal, default 0600) slave STR # or slave { # Slave definition pcm STR # slave PCM name # or pcm { } # slave PCM definition format STR # format definition rate INT # rate definition channels INT period_time INT # in usec # or period_size INT # in bytes buffer_time INT # in usec # or buffer_size INT # in bytes periods INT # when buffer_size or buffer_time is not specified } bindings { # note: this is client independent!!! N INT # maps slave channel to client channel N } slowptr BOOL # slow but more precise pointer updates }
Function reference
Plugin: LADSPA <-> ALSA
This plugin allows to apply a set of LADPSA plugins. The input and output format is always SND_PCM_FORMAT_FLOAT (note: this type can be either little or big-endian depending on architecture).
The policy duplicate means that there must be only one binding definition for channel zero. This definition is automatically duplicated for all channels. If the LADSPA plugin has multiple audio inputs or outputs the policy duplicate is automatically switched to policy none.
The plugin serialization works as expected. You can eventually use more channels (inputs / outputs) inside the LADPSA plugin chain than processed in the ALSA plugin chain. If ALSA channel does not exist for given LADSPA input audio port, zero samples are given to this LADSPA port. On the output side (ALSA next plugin input), the valid channels are checked, too. If specific ALSA channel does not exist, the LADSPA output port is connected to a dummy sample area.
Instances of LADSPA plugins are created dynamically.
pcm.name { type ladspa # ALSA<->LADSPA PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition } [channels INT] # count input channels (input to LADSPA plugin chain) [path STR] # Path (directory) with LADSPA plugins plugins | # Definition for both directions playback_plugins | # Definition for playback direction capture_plugins { # Definition for capture direction N { # Configuration for LADPSA plugin N [id INT] # LADSPA plugin ID (for example 1043) [label STR] # LADSPA plugin label (for example 'delay_5s') [filename STR] # Full filename of .so library with LADSPA plugin code [policy STR] # Policy can be 'none' or 'duplicate' input | output { bindings { C INT or STR # C - channel, INT - audio port index, STR - audio port name } controls { # valid only in the input block I INT or REAL # I - control port index, INT or REAL - control value # or STR INT or REAL # STR - control port name, INT or REAL - control value } } } } }
Function reference
Plugin: asym
This plugin is a combination of playback and capture PCM streams. Slave PCMs can be defined asymmetrically for both directions.
pcm.name { type asym # Asym PCM playback STR # Playback slave name # or playback { # Playback slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition } capture STR # Capture slave name # or capture { # Capture slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition } }
For example, you can combine a dmix plugin and a dsnoop plugin as as a single PCM for playback and capture directions, respectively.
pcm.duplex { type asym playback.pcm "dmix" capture.pcm "dsnoop" }
By defining only a single direction, the resultant PCM becomes half-duplex.
Function reference
Plugin: IEC958
This plugin converts 32bit IEC958 subframe samples to linear, or linear to 32bit IEC958 subframe samples.
pcm.name { type iec958 # IEC958 subframe conversion PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition } [status status-bytes] # IEC958 status bits (given in byte array) # IEC958 preamble bits definitions # B/M/W or Z/X/Y, B = block start, M = even subframe, W = odd subframe # As default, Z = 0x08, Y = 0x04, X = 0x02 [preamble.z or preamble.b val] [preamble.x or preamble.m val] [preamble.y or preamble.w val] }
Function reference
Plugin: Soft Volume
This plugin applies the software volume attenuation. The format, rate and channels must match for both of source and destination.
When the control is stereo (count=2), the channels are assumed to be either mono, 2.0, 2.1, 4.0, 4.1, 5.1 or 7.1.
If the control already exists and it’s a system control (i.e. no user-defined control), the plugin simply passes its slave without any changes.
pcm.name { type softvol # Soft Volume conversion PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition [format STR] # Slave format } control { name STR # control element id string [card STR] # control card index [iface STR] # interface of the element [index INT] # index of the element [device INT] # device number of the element [subdevice INT] # subdevice number of the element [count INT] # control channels 1 or 2 (default: 2) } [min_dB REAL] # minimal dB value (default: -51.0) [max_dB REAL] # maximal dB value (default: 0.0) [resolution INT] # resolution (default: 256) # resolution = 2 means a mute switch }
Function reference
Plugin: Null
This plugin discards contents of a PCM stream or creates a stream with zero samples.
Note: This implementation uses devices /dev/null (playback, must be writable) and /dev/full (capture, must be readable).
pcm.name { type null # Null PCM }