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 } }
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) [mmap_emulation BOOL] # Enable mmap emulation for ro/wo devices }
pcm.name { type shm # Shared memory PCM server STR # Server name pcm STR # PCM name }
Note: This implementation uses devices /dev/null (playback, must be writable) and /dev/full (capture, must be readable).
pcm.name { type null # Null PCM }
pcm.name { type copy # Copy PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition } }
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 } }
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 } }
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 } }
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 } }
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 } }
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 } }
pcm.name { type rate # Rate PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name # or pcm { } # Slave PCM definition } }
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) } } }
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 # Filename or file INT # File descriptor number [format STR] # File format (only "raw" at the moment) }
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:
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.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 }
pcm.quad2 { type route slave.pcm "quad" ttable.0.0 1 ttable.1.1 1 ttable.2.2 1 ttable.3.3 1 }
The difference from dshare plugin is that share plugin requires the server program "aserver", while dshare plugin doesn't need the explicit server but access to the shared buffer.
pcm.name { type share # Share PCM slave STR # Slave name # or slave { # Slave definition pcm STR # Slave PCM name } bindings { N INT # Slave channel INT for client channel N } }
# 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:
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, thehooks.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 ] } ] }
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.
pcm.name { type dmix # Direct mix ipc_key INT # unique IPC key ipc_key_add_uid BOOL # add current uid to unique IPC key 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 } }
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:
You can hear 48000 Hz samples still using this dmix pcm via plug plugin like: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 } }
% 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 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.pcm.dmixoss { ... bindings { 0 0 # map from 0 to 0 1 1 # map from 1 to 1 } }
pcm.name { type dshare # Direct sharing ipc_key INT # unique IPC key ipc_key_add_uid BOOL # add current uid to unique IPC key 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 } }
pcm.name { type dsnoop # Direct snoop ipc_key INT # unique IPC key ipc_key_add_uid BOOL # add current uid to unique IPC key 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 } }
The policy duplicate means that there must be only one binding definition for channel zero. This definition is automatically duplicated for all channels.
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 } [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 { 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 } } } } }
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.