Project:Sound/Alsa

From Gentoo Wiki
Jump to:navigation Jump to:search
The information in this article is probably outdated. You can help the Gentoo community by verifying and updating this article.

Advanced Linux Sound Architecture

Introduction

Note
This guide was last updated for ALSA release 1.0.14_rc2.

ALSA is the "next generation" sound drivers suite for Linux, that supersedes the old OSS (Open Sound System) drivers. The ALSA drivers are provided by kernels 2.6 inside the kernel's sources and are available as external package for those who are still running 2.4 series kernels. The external package can be used with 2.6 kernels, too, and allows to run a different version of ALSA drivers than the one shipped with the current kernel.

This guide is being wrote to help developers interested in maintenance of ALSA related packages, as they might be tricky, and it's always useful to know a few things that are not in the official documentation. It also shows the reasons why the external ALSA drivers package can't be dropped for 2.6 kernels.

Expansion of this guide is really welcome as it might be a bit tricky sometimes as details are often forgotten until you really need to remember them.

Resources

It's important to know the resources that might be needed to get ALSA right, as there can be lot of problems that might require one to dig through many different sites and mailing lists.

The first important resource is, obviously, the main ALSA Project homepage. You can find there a list of latest news with changelog for different version and a simple box with latest releases for stable and development packages. As you'll see later, sometimes development releases are needed to go in ~arch or even on stable trees, depending on the kernel version used in those trees.

As many other projects, ALSA project has a bugtracker, but that might be a bit difficult to get a hold of, as it's a Mantis tracker instead of the more common Bugzilla. It's important to note the selector on top right of the screen: if you select something there you mask all the other projects' bug and looking for or reporting bugs becomes an hell.

Other important resources are the mailing list. ALSA project have different mailing lists, but the main ones you need to subscribe if you're interested in maintaining ALSA related packages are alsa-announce and alsa-devel. You might also want to take a look to lkml, as ALSA drivers are also developed as part of 2.6 series kernel.

When fixing software that uses alsa-lib or when looking at alsa-lib itself, it might be useful to have at hand the library reference that contains the tech level documentation of the functions inside the library.

Mercurial repository

ALSA sources are managed through mercurial SCM, and as it's stated in ALSA's download page, the checkout command is the following:

CODE Checking out ALSA's repositories
$ hg clone http://hg-mirror.alsa-project.org/alsa-driver alsa-driver
$ hg clone http://hg-mirror.alsa-project.org/alsa-lib alsa-lib

And so on for the different needed repositories
Note
For people not used to mercurial, the command to update the repository checkout is hg pull -u.

Snapshots of ALSA packages are discouraged unless very special circumstances applies, as they are strictly tied to the kernel development, too. It might be unsurprising that if no new release candidate are released by upstream, a snapshot is required after a new kernel release.

The packages

Overview

ALSA support in Linux is provided by a list of different packages; upstream splits the different pieces of the framework as they might not be used in every system: some might just need alsa-lib, other might want to use utilities and tools, too. For this reason there are also different ebuilds for all of them, distributed between media-sound, media-libs and media-plugins categories.

It's important to note that, while you can use just some of the packages provided by ALSA, when you use more than one of them, they should always be of the same version; while some of them are told to be compatible, we had in the past some problems (between moving from 1.0.8 to 1.0.9) with unaligned drivers and library, that caused a lot of problems to users.

Usually it's anyway possible to use different patchlevels of the same version without big problems, so different rc versions can work together without being a problem to users, in most cases.

alsa-driver

The most important piece of ALSA framework is for sure alsa-driver package. This package is the only way to provide ALSA drivers to 2.4 kernels and an alternative way to provide ALSA drivers to 2.6 kernels. The ebuild in portage installs only the plain modules for the drivers, while the original version would have also installed the headers for them (this is taken care of in the following package).

The alsa-driver package should always remain supported and available for 2.6 kernels, as it provides more reliable drivers for many cases, as it doesn't get changed by kernel's patches and similar. While the ALSA guide suggests to use the in-kernel drivers for 2.6 kernels because it's simpler for the users, we had a few cases in the past where people complained about problems with ALSA due to in-kernel drivers.

When receiving bugs about alsa at alsa-bugs@gentoo.org alias, it's always the case, if the reporter didn't specify it, to ask if he's using the in-kernel drivers or alsa-driver package. In the former case it's useful to know the version of the drivers (can be found at /proc/asound/version) and to try to reproduce the bug with alsa-driver. If the problem is limited to the in-kernel drivers, re-route the bug to kernel@gentoo.org devs.

alsa-driver uses a mix of autotools-fu and Kconfig to work fine on many different setups with kernels that might be using incompatible APIs. To the base drivers' sources found in the package (that are the ones found in the development kernel at the moment of the release), they apply a series of patches to become compatible with older kernels, when needed. For this reason, newer versions of the drivers are usually compatible with older kernels, but the other way around is not always true.

Note
Some API changes specific to given patchsets, such as the ones in suspend2-sources 2.6.12, are not considered by upstream worth of detection. As changing the kernel API does anyway break the compatibility with lots of modules, there's no actual reason for alsa-driver to support them.

Kernels does not look at the status of ALSA drivers sources when releasing, at least they don't look if they are release candidates or even beta versions; this created lot of problems in the past. For this reason, while it's usually the case to mask pre-release versions of ALSA framework, you might be required to remove them from package masking if a new kernel is released and latest unmasked version of the drivers does not build against, or the kernel is shipped with a pre-release version of the drivers (see the notes about alsa-lib package).

When a new kernel is going to be marked stable, ALSA drivers that builds against it must be marked stable, too. This is required to have a working tree. Usually this also means that the other packages needs to be stabled at the same point. This lead more than once in the past to have marked stable release candidate versions, because of stable marking of a newer kernel too. Many arch teams had their own stable tree unreliable for many weeks after a new kernel was marked stable.

Warning
alsa-driver package does not only contain the drivers that are available on the Linux kernel tree, but also some drivers that are not present there. Those might be more of a problem as they are often outdated and happened in the past (and still now) to fail building when the kernel deprecates and remove some APIs or defines.

Starting from the unofficial snapshot 1.0.14_pre20061130, and excluded the live 9999 ebuild, the ebuild provides access to the ALSA_CARDS variable using the USE_EXPAND method, so that the user can see which cards are supported. The list of available cards for a given release can be found in the acinclude.m4 files inside the alsa-driver tarball, looking for the string "Possible cards are:" (TODO: create a simple wrapper script that converts that list to a suitable IUSE_ALSA_CARDS variable in the ebuild itself).

As the USE_EXPANDED variables need a description for the entries, the file gentoo-x86/profiles/desc/alsa_cards.desc contains the descriptions of the drivers that can be enabled; the (almost complete) description of the drivers available can be generated through the following command ran into the source directory for alsa-driver:

CODE generating descriptions of ALSA_CARDS values
alsa-driver-${PV} $ find . -name Kconfig | xargs alsa_cards_desc_converter.awk | sort -u > /tmp/alsa_cards_desc.update

The alsa_cards_desc_converter.awk script will convert the descriptions in the Kconfig files in the kernel in a suitable format for the alsa_cards.desc file. This file won't contain the values for the drivers that miss a description in the files.

alsa-headers

The alsa-headers package is split out from alsa-driver upstream package. This package is used to install the headers needed by both the drivers and the library. It's used to allow people to install alsa-driver for many different kernel versions without having problems with collision-protect feature.

The ebuild is quite simple, as it does install only a series of header files. The only catchup is that it needs a single patch to define __user if it's not defined already.

alsa-lib

As ALSA uses a way more complex interaction between software and driver, the use of simple access to the devices as done by OSS is no more a viable option. Due to the number of possible options, and the access to hardware options, the alsa-lib package is the preferred way to access the sound devices.

In the past alsa-lib had a series of "generations" of API compatibility, so many packages configure in different ways depending if they find a version of alsa pre-0.5, 0.5 or 0.9. At the moment, portage provides only >=1.0 versions, so all the packages should configure with ALSA generation 0.9.

Beside the different generations stated above, alsa-lib should be API and ABI stable inside the same generation. Unfortunately there are cases for particular drivers that does not apply cleanly, for example the emu10k1 breakage between versions 1.0.5 and 1.0.6.

An important problem is with testing. alsa-lib comes with a couple of simple testcases to make sure that it works fine. Unfortunately upstream does not seems to pay enough attention to them before release, so they are often broken even in the final release. While disabling them is probably simpler, when possible it's suggested to try fixing the tests and submitting the patches to ALSA's bugzilla.

It's particularly important that alsa-lib and the drivers used (either from kernel or alsa-driver) are the same version in a working system. This to avoid problems in communication between the lib (and so forth all the applications that uses it) and the drivers inside the kernel. Being the single communication node between kernel and userspace, the library is the strategic point for the rest of the framework. While it's possible to use an older or newer init script for alsasound it's usually highly deprecated the use of alsa-lib with a different version than the current running drivers.

alsa-utils

Almost as important as alsa-lib, the alsa-utils package provides the basic utilities to work in an ALSA enabled system. Not only it contains basic utilities like alsactl and alsamixer, it contains the alsasound init script that is used to initialize ALSA framework on a system and to load modules. The init script is better explained later in this document.

The init script loads the modules for ALSA support: before the ALSA interfaces, then the actual soundcards' drives, looking for snd-card-* aliases as specified in /etc/modules.d/alsa. When the aliases are not present because the user hasn't configured them, the init script starts looking for all the modules installed that corresponds to PCI ids.

This is a problem for arches where the sound cards are not on PCI bus, such as the powermac driver used for Apple PPC systems. For this reason the init script requires on non-PCI platforms the explicit setting of snd-card-* aliases so that it knows what to load. It also needs to know the aliases when there are more than one sound card on the box, so that they can be loaded in the right order.

alsa-plugins

alsa-lib can also output, instead than to an actual ALSA device, to some plugins that pipes the output elsewhere. The first of these plugins was the jack plugin that was present inside alsa-lib 1.0.9, and then split out in the alsa-jack ebuild, up to version 1.0.11. Since 1.0.11 there is a new ebuild, alsa-plugins that replaces alsa-jack entirely and that also provides the extra plugins as released by upstream.

In particular this ebuild provides the OSS output plugin and an AC3 conversion plugin, that uses ffmpeg for the encoding, other than the jack plugin as before.

Note
With this version the PDEPEND on alsa-jack is gone from alsa-lib ebuild, too.

As of January 2007, alsa-jack is totally phased out and removed from the tree, and the only way to have Jack output from ALSA is to use the alsa-plugins package with the jack useflag enabled.

Since version 1.0.12, alsa-plugins also provides a pulseaudio use flag to enable the PulseAudio plugin. Assertions for the plugin are disabled, because it makes some sanity check assumptions that are broken by some clients like alsaplayer (they are errors in the players, not in the plugin), and this makes it more usable to public. If debug is required they can easily re-enabled.

Arch-specific notes

PowerPC

For some reasons, ALSA support on PowerPC platform is not the state of the art. The first main problem, already noted in alsa-utils section above, is that the init script does not autorecognize the snd-powermac module that is used by almost all Apple machines, such as iBooks and PowerBooks. This means that it has to be aliased to snd-card-0 to be loaded correctly, as it hasn't a PCI alias (not being on PCI bus).

Also the driver itself seems to be cause of problems: the snd-powermac module segfaults modprobe on insertion on ALSA 1.0.10, while works mostly fine on rc3 (after being patched as rc3 released was not building at all on PPC).

SPARC

ALSA support on SPARC systems is, at the time of writing, supported by experimental development profiles based on 2.6 series kernel (in particular, the ALSA shipped with kernel 2.6.15).

alsa-driver is not supported and not keyworded because it misses some of the patches needed to make ALSA work on SPARC and because it's not aware of the mixed userland/kernel compilers.

For this reason, SPARC has no reason to forcefully mark stable a new ALSA release if the main problem lies in alsa-driver not compiling with current kernel (as there's no alsa-driver keyworded), and can continue using the most recent non-RC release of ALSA userland that works with their kernel.

Quirks, useflags and interactions

The midi useflag

As of 1.0.14_rc2 sub-releases, a new useflag was introduced in some ALSA packages, the midi useflag. This useflag is used to enable or disable code, drivers or utilities that are used to control the sequencer support in ALSA (MIDI support), both hardware, software and virtual.

Probably the majority of users nowadays won't care about MIDI support at all, so it makes sense for them to disable MIDI support altogether to save space, time and code that can cause bugs. Unfortunately some software checks the presence of snd_seq_* functions when checking for the presence of ALSA itself, leading to unexpected failures or missing ALSA support where requested.

It was then necesssary not to release to public consumption in ~arch the new versions of alsa-lib that contain the experimental midi useflag for a transition phase. The packages testing for snd_seq_* functions has to be fixed by either make them check for ALSA through pkg-config (if they don't really require sequencer support, like K3B), or to check that alsa-lib is built with midi useflag enabled.

CODE Checking for the midi useflag on alsa-lib.
pkg_setup() {
    if ! built_with_use --missing true media-libs/alsa-lib midi; then
        eerror ""
        eerror "To be able to build this package with midi support you need"
        eerror "to have built media-libs/alsa-lib with midi USE flag enabled."
        die "Missing midi USE flag on media-libs/alsa-lib"
    fi
}

Please note that the built_with_use check is ran with the --missing true parameter, to tell the check to report success if the version of alsa-lib currently installed does not support the midi useflag at all. This is needed because older version of alsa-lib always built the sequencer part of the library, without caring for that useflag.

The midi useflag on media-sound/alsa-driver disables the sequencer drivers, this means that if it's not enabled, even having it enabled on alsa-lib won't allow you to use sequencers, even virtual ones created by TiMidity++.