Original http://www.volkerschatz.com/noise/alsa.html
Intro
If anyone often uses a Linux machine to process music, he will deal with ALSA sooner or later. ALSA, short for advanced Linux sound architecture, is more powerful than the outdated Open Sound System (OSS. In fact, you may have unknowingly used ALSA, such as the OSS simulation function of ALSA. When searching for answers to ALSA on the web, I found that they are both questions and self-contradictory statements, with few definite answers. I think there are two reasons: First, some sound problems are not as simple as they seem, and the Alsa documentation is a mess. This article will try to solve these sound problems and correct the messy ALSA documentation.
Before we officially start, you 'd better browse other resources first. Some of them include some example programs that can be used to execute and call ALSA for playing or recording. They may also include the answers you are looking.
First, I would like to recommend a comprehensive page http://www.sabi.co.uk/Notes/linuxSoundALSA.html, which has a wider coverage than this article focuses on in-depth research.
Other resources include:
A Linux journal article about basic ALSA programming contains some sample code
Tutorials on the Alsa project web site contains some sample code
One of the developers 'home page is old
Some documents are embedded in the source code of the Alsa library. You can use the source code document generation tool doxygen to generate and use the command make Doc. You can also read the API documentation online. Unfortunately, it is incomplete and difficult to browse. In my opinion, the developer initially imagined not only to provide API documentation, but the results were the same. If you really want to understand how ALSA works, you 'd better look at these documents with the source code.
ALSA concepts
Sound Card and hardware devices
ALSA uses the layered structure of cards, device, and subdevices to represent audio hardware devices and their components. This layered structure is the perspective from which ALSA looks at the structure and capabilities of hardware devices. If the layered structure of the sound card is different from the sound card documentation, it may be because the driver does not support all functions.
ALSA cards and sound card hardware correspond one by one. ALSA cards stores the list of devices on each card. A card can be represented by an ID (string) or a number starting from 0.
Most ALSA hardware accesses occur at the device level. You can enumerate the devices of each card from 0. Different devices can be opened and used independently. Typically, sound cards and devices are sufficient to determine where the sound signal is read and sent.
Subdevices is a more fine-grained object that ALSA can distinguish. The most common scenario is that each channel of a device corresponds to a subdevice or there is only one subdevice in total. In theory, the subdevice of a device can be used independently. However, when the multi-channel signal is played on a subdevice, other subdevices are also used. Like device, the subdevices index identifier starts from 0.
PCM parameters and configuration space
Digital sounds have a fixed number of parameters: Sampling Rate, number of channels, and sample value storage format. If you have already used OSS programming, you may be used to setting these parameters before playing a music file. Similar to the configuration space mentioned in the Alsa document.
The answer to the reality is not that simple: for example, some sound cards cannot combine all supported sampling formats, sampling rates, and the number of channels. Therefore, these parameters are not independent. Considering this situation, ALSA uses a parameter set in an n-dimensional space. Each dimension corresponds to the sampling rate, sampling format, number of channels, and so on. If the parameters of a given sound card are independent, all valid configurations are in an n-dimensional box. In this case, we need to describe the value range of each dimension. If the parameters are not independent, the allowed configuration set is more complex.
When a hardware device is accessed through ALSA, the parameters are not always independent. Further, due to certain parameter restrictions, a device's valid configuration space is reduced accordingly. This allows us to use a small space instead of a definite value. In addition, the order of parameter settings is also caused. That is to say, ALSA plugin can automatically select the most suitable hardware parameters and perform format conversion. We will discuss this plug-in and Other plug-ins in the following section.
ALSA devices and plugins
To avoid confusion, let's briefly introduce ALSA device. The ALSA device mentioned here is totally different from the hardware devices mentioned above. The ALSA device is represented by a string. They are defined in a configuration file of ALSA. More complicated, some standard ALSA devices are: Card, devicce, and subdevice. However, hardware card and Device specifications cannot be used as ALSA devices. In fact, some ALSA devices parameters are not related to hardware.
It is no exaggeration to say that ALSA is mostly composed of plugins. No matter when a player or program uses the Alsa device, plugins perform dirty work. The complete list of plugins is in pcm_plugins.html of the Alsa library doxygen file. Note that the Plugins list is not equivalent to the Alsa devices list. Some standard devices have the same name as their plugins, but some devices do not. Sometimes different ALSA devices use the same plugin. Therefore, in this section, we will give the name of each plugin. If possible, we will also give the names allowed by specific hardware devices to use this plugin.
The most important plug-in is HW plug-in. It does not process itself, but only accesses the hardware driver. If the application selects the PCM parameter (sampling rate, channel count or sample format) that is not supported by hardware, HW plugin returns an error message. Therefore, the next important plug-in is 'plug' in. Plug plugin performs channel replication, sample rate conversion, and necessary re-sampling. Unlike HW plugin, which is used by device HW:, the device name of plug plugin is different: plughw. However, both device names contain the hardware cards, device, and subdevice to be accessed. (In fact, plug
The device also exists, and plug plugin is also used, and Its Parameter slave specifies where data is to be sent, so this plugin must be linked with other plugins)
Another useful plug-in is file plugin, which writes the sample data to a file. It has two ALSA devices: file and tee. The former has two parameters: File Name and format. The latter transmits data to another device to write data to a file. The first parameter is the device. If the second device has any parameters (such as "plughw:"), enclose the name in quotation marks to prevent it from being interpreted by the command line. Assume that you want to use the first device on the first sound card to play the audio. You can use the following method to obtain the copy of the output sound.
aplay -Dtee:\'plughw:0,0\', /tmp/alsatee.out, rawxy.wav
It seems meaningless (because you can simply copy xy.wav or convert it to SOX). However, using this method, ALSA-based movie player can extract sound content. Tee's output is raw sample data without any file header. File plugin can also be used to read data from files, but is not used by predefined devices.
Many existing plugins are used for mixer and rerouting channels. Because these plugins require a large number of parameters, they are not scheduled to be used by ALSA devices. Route plugin is a mixing matrix. Channels can not only be exchanged or assigned any value, but can also be mixed. Multiple plug-ins only allow reroute channels, but can have several slave devices. Therefore, they can be played on channels of different sound cards. Dmix and dshare plugins allow one device to be multiple clients (player
Application. Dshare plugin allocates available channels to the required clients, while dmix mixes the content played by multiple clients to one channels.
This section briefly introduces the most important plugins and predefined ALSA devices. To use more complex plugins, you need to write your own configuration file. The configuration file will be described in detail in the next section. For device-specific examples, refer to the Alsa project documentation of its configuration file and list
Of plugins
Grouping ALSA
Configuration Files
The configuration file defines ALSA devices. Without these configuration files, you will not be able to use any functions of ALSA. Although you do not need to write any configuration file for simple playback and recording, this is because the built-in configuration file ALSA. conf contains some devices definitions. However, if you have special requirements or encounter problems, you may need to add your own definitions.
ALSA supports three types of configuration files. The first one is ALSA. conf, which is located in the Alsa data directory, usually/usr/share/ALS. This directory and Its subdirectories contain more configuration files. For sound cards or specific plugins, they are all included in ALSA. conf. The configuration file in this directory is usually considered as built-in, so the system administrator and common users should not modify it.
The other two configuration files are also included by ALSA. conf. The configuration files within the system are stored in/etc/asoundrc. Users can store their own configuration files to. asoundrc in the home directory. Every time you open ALSA devices, all the configuration files will be re-analyzed. Therefore, the configuration file changes take effect immediately without restarting anything.
Basic configuration file format
The ALSA configuration file stores the parameter-value pairs of the layered structure. The top layer of the layered structure corresponds to the interfaces provided by ALSA. An Interface contains a set of alsa api functions: Enable a device, perform operations on the interface, and then disable the device. Different interfaces have different functions. For example, aplay and other players use the PCM Interface, and the program alsactl uses the CTL interface. Amixer uses the mixer interface and amidi uses the rawmidi interface. (In fact, most of them will eventually use the CTL interface, at least part of the function ). To enable these programs to use devices, they must be defined on the corresponding interfaces.
Most of the examples I provided are related to the PCM Interface, mainly because PCM is almost the most important and I spend most of my time on PCM. (PCM stands for the pulse code modulation, which digitizes the sound into a sample Value Stream ). In addition, the command aplay-l allows you to list all definitions on the PCM Interface.
The second level of the hierarchy stores the name of ALSA devices. You can use this device to operate the interface of the device.
Let's take an example. Suppose you want to create an alsa pcm device to access your first sound card and perform necessary format conversion. Plugin is an automatic Format Conversion Implemented by plug plugin. Add the following lines to asoundrc to create the PCM device.
pcm.plug0 { type plug slave { pcm "hw:0,0" }}
Explain the meaning of these lines: a new device plug0 can be accessed through the PCM Interface. The data output of this device will be processed by plug plugin. The slave of This plugin is PCM device HW: 0, 0. This device definition is the most commonly used definition method. Of course, ALSA allows a certain degree of freedom in syntax. For example, you can place an equal sign between the parameter name and value, or add a semicolon and a comma between the value assignment statements. So we can rewrite the above definition as follows:
pcm.plug0 = { type = plug; slave = { pcm = "hw:0,0" ; },};
As you can see, the parameter name is in front of the curly brackets, and the parameter value is in the curly brackets. The last parameter value in the parameter body can be assigned with a comma or semicolon. Now we know what slave PCM should use a semicolon. Otherwise, the comma in slave PCM will cause a syntax error.
In fact, the syntax has a greater degree of freedom. The sub-parameter name can be defined by '.' or in parentheses. The first symbol plug0 is the name of the new device and is also a parameter of PCM. The second parameter defines the obtained sub-parameters. In addition, you can use spaces to split the configuration file and line-oriented data. Therefore, the above definition can be written in the following two forms:
pcm { plug0 { type plug slave { pcm "hw:0,0" } }}
Or
pcm.plug0.type = plug; pcm.plug0.slave.pcm = "hw:0,0"
Now let's summarize the organization of the Alsa configuration file. The parameter name is composed of letters, numbers, and underscores (this conclusion is the result of debugging, and there is no documentation in fact ). The parameter value contains letters, numbers, and underscores and is enclosed in quotation marks. Both parameter names and parameter values are case sensitive. The remarks in the configuration file start with # until the end of the line.
To make the definition of slave clearer, we should define slave separately. In this way, the definition of plug0 above should be as follows.
pcm_slave.slave0 { pcm "hw:0,0"}pcm.plug0 { type plug slave slave0}
The configuration file also supports aliases. You can assign a parameter to an existing device name, which is an alias.
pcm.alias_plug0 = plug0
Both alias_plug0 and plug0 are part of the PCM Interface. Note that they cannot be defined as (PCM. alias_plug0 = PCM. plug0) Because ALSA devices aliases cannot contain parameters.
Now we have a rough understanding. You can continue to read the doxygen documentation at http://alsa.opensrc.org/.asoundrcand ALSA library. They provide more examples.
Advanced Configuration File features
Overriding parameters and Parameter Data Types
If you have read other asoundrc files, you may have learned to redefine the ALSA's default device as follows:
pcm.!default { type hw card 0 }
The exclamation point overwrites the original PCM. default definition. This symbol can be used in any configuration file assignment. Now let's take a look at how it works. The normal assignment is to add a leaf node to the tree structure. If a leaf node already exists, its value will be overwritten. So if you put the following two lines in asoundrc, the default sound card is the second, not the first one.
pcm.!default { type hw card 1 }pcm.default.card 1
If you remove the definition of the first line of default, you will receive an error message, default is not a compund. Obviously, a parameter has several data types, and the type cannot be modified only by using the value assignment statement. By overwriting a parameter with an exclamation point, you can change its type. The exclamation point removes all parameters and their subparameters. So do not use the exclamation mark as follows! PCM..., this will delete all definitions of the PCM Interface.
A little bit of experience, we will find that the alias is actually a string that contains the name of the PCM device to which they point. PCM. Default is an alias defined in ALSA. conf.
Similar to the exclamation mark, other prefix characters can be used to modify the parameter value assignment. Question mark? The existing parameter values are ignored.
pcm.?default { type hw card 1}
Define the second sound card of the first device as the default device. However, if default has been defined before, this statement is invalid.
The other two prefixes are + and -.
Parameterised device Definitions
In the Plugins section, we encounter many ALSA devices parameters that need to be given, which are separated by "," after the device name. As I mentioned above, these devices are completely different from the plug-ins behind them. devices can be seen as the encapsulation of plugins. In the basic configuration section, we use plug plugin to define a device. The predefined devices we encounter in the plugin section are different from the simple ones. The plughw device can be used by any sound card or hardware device, because card and device number can be used as parameters. Although all parameterized devices are defined in ALSA. conf, and their syntax is not described in the Alsa documentation, you can still define your own devices
Let's take a look at the definition of plughw in ALSA. conf. Here plughw is scaled down
plughw { @args [ CARD DEV SUBDEV ] @args.CARD { type string } @args.DEV { type integer } @args.SUBDEV { type integer } type plug slave.pcm { type hw card $CARD device $DEV subdevice $SUBDEV }}
The first line of the plughw structure defines the parameter list. This is a new data type: array. The elements can be assigned values together.
plughw { @args.0 CARD @args.1 DEV @args.2 SUBDEV}
Like Structure assignment, an element or group assignment can be inserted with equal signs. The following lines define the data type of each parameter. In the original plughw definition, the struct definition parameter also includes the default definition. If you are interested in this definition, you can check ALSA. conf.
Troubleshooting
Useful Tools
The easiest way to view sound card devices is to call
Aplay-l or arecord-l
These two commands list sound cards, hardware devices, and sub-devices that can be playback and recording.
If you have any questions about ALSA parsing asoundrc, you can use the aplay-l command to print out all the configurations of the PCM Interface. Note that the prefix "PCM." does not appear in the parameter name because it is always hidden.
Another option of aplay is-V, which prints the hardware parameters of each subdevice during playback. Unlike the other two mentioned options, this option can only work during playback. When you use plug plugin to play the sound, you can use this option to check whether plug has performed resampling.
But what if you use another audio or movie player? You can use/proc/file system. When the subdevice is in use, you can obtain the hardware parameters from/proc/asound/card #/PCM # P/sub #/hw_params. By comparing the output results of aplay test.wav-V and/proc/asound/card #/PCM # P/sub #/hw_params, we can know which parameters are simulated. If the subdevice is not used, the parameter file hw_params only outputs "closed ". If "closed" is displayed during music playback, it indicates that the sound is not transmitted to this subdevice. Exception: if an ALSA
If the device is used by a multi-channel playback, the first subdevice records the total number of channels, and the others report the number as closed. If ALSA's OSS simulation is used, the hw_params file also contains the OSS parameter settings.
The amidi program uses the rawmidi interface. Option-l lists all available MIDI devices, and the-L option prints out the configuration of the rawmidi interface.
Speaker-test: When you cannot hear any sound and want to determine whether the player is faulty, you can use speaker-test as the benchmark test program. This test program can send a bell or noise to each speaker in sequence.
Alsacap
Alsacap is a small program written by the author to capture some hardware configurations that the author pays special attention. I think this tool is very helpful for finding problems. Source Code address http://www.volkerschatz.com/noise/alsacap.c, the source code at the top of the notes are compiled instructions. The Tool Name is ALSA capability, used to show your sound card and the capabilities of the Alsa driver.