Skip to content

Audio in Linux

ALSA

Advanced Linux Sound Architecture (ALSA) is a software framework and part of the Linux kernel that provides an application programming interface (API) for sound card device drivers.

The project to develop ALSA was led by Jaroslav Kysela, and it started in 1998 and was developed separately from the Linux kernel until it was introduced in the 2.5 development series in 2002. In the 2.6 version, ALSA replaced the previous system, Open Sound System (OSS), by default (although a backwards-compatibility layer does exist).

asla-lnx-blockdiagram

Figure. A block diagram for ALSA in Linux

ALSA concept

*TBD

ASoC

The ASoC (ALSA System on Chip) layer aims to provide better support for ALSA on embedded systems that use a system-on-chip (SoC) design.

The codec class driver is platform independent and contains audio controls, audio interface capabilities, codec DAPM definition and codec IO functions.

The platform class driver includes the audio DMA engine driver, digital audio interface (DAI) drivers (e.g. I2S, AC97, PCM) and any audio DSP drivers for that platform.

The machine driver class acts as the glue that describes and binds the other component drivers together to form an ALSA "sound card device". It handles any machine specific controls and machine level audio events (e.g. turning on an amp at start of playback).

ALSA SoC Layer in Kernel Document.

For example with iMX8MQ and wm8960 Codec.

wm8960.c is ASoC Codec Class driver:

  • register a soc dai driver by calling: snd_soc_register_codec. This DAI driver provides two streams: playback & capture. It also provides DAI operation such as mute, free...

  • define mixers and audio paths by calling SOC_* macro.

imx-wm8960.c is ASoC Platform Driver.

ALSA Application

arecord & aplay

arecord -t raw -f S16_LE -c 1 output.raw

output.raw can be played by using aplay

aplay -f S16_LE output.raw

or extracted by a simple C program.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
    int16_t buf;
    int fd = open("./input", O_RDWR);
    if (fd < 0) {
        printf("open file fail\n");
        return 1;
    }
    while (read(fd, &buf, 2) > 0)
        printf("%d\n", buf);
    close(fd);
    return 0;
}

Raw data

raw-data

DAPM - Dynamic Audio Power Management

Modern sound cards consist of many independent discrete components and each component has functional units that can be powered independently.

view-of-sound-card

Figure. Anatomy of a modern sound card (Lars-Peter Clausen – Analog Devices)

What is DAPM?

DAPM is model data flow and power dependencies in a directed graph. Each node in graph represents a functional unit (called widget). Route or Path represent connections between functional units.

dapm-simple-path

Eache widget (node) has a type and this type defines how the widget behaves in the graph. E.g. Speaker, Microphone, Amplifier, DAC, ADC, internal supply, external supply, headphone output, line-in input, line-out output, audio interface, audio interface link, mixer, mux, input pin, output pin ...

How DAPM works?

DAPM operation has two phases:

  • Phase 1: Determine target power state
  • Phase 2: Power sequencing

In phase 1, finding out the power state DAPM differentiates between three different categories of widgets: Enpoint widgets, Pass-through widgets, Supply widgets.

enpoint-widgets

Power state of eache widget in graph is determined.

power-state

After Phase 1, target power state is determined. Widgets in graph is powered.

  • Power-down all newly disabled widgets
  • Perform routing changes (if any)
  • Power-up all newly enabled widgets

Case Study - WM8960

Macro for defining widgets can be found at /include/sound/soc-dapm.h.

DAPM widgets in wm8960.c fall into a number of types:

  • Stream Domain Widgets: ADCs (analog to digital converters), DACs (digital to analog converters).

    SND_SOC_DAPM_ADC("Left ADC", "Capture", WM8960_POWER1, 3, 0), SND_SOC_DAPM_ADC("Right ADC", "Capture", WM8960_POWER1, 2, 0), SND_SOC_DAPM_DAC("Left DAC", "Playback", WM8960_POWER2, 8, 0), SND_SOC_DAPM_DAC("Right DAC", "Playback", WM8960_POWER2, 7, 0),

  • Path Domain Widgets: Path domain widgets have a ability to control or affect the audio signal or audio paths within the audio subsystem

    SOC_DAPM_SINGLE("Left Switch", WM8960_MONOMIX1, 7, 1, 0), SOC_DAPM_SINGLE("Right Switch", WM8960_MONOMIX2, 7, 1, 0),

Machine Widgets appears in imx-wm8960.c. A machine widget is assigned to each machine audio component (non codec or DSP) that can be independently powered. e.g Microphone Bias, Jack Connectors. In iMX8-MQ, machine widget and codec widget interconnections are defined in device tree:

        audio-routing =
            "Headphone Jack", "HP_L",
            "Headphone Jack", "HP_R",
            "Ext Spk", "SPK_LP",
            "Ext Spk", "SPK_LN",
            "LINPUT1", "Main MIC",
            "LINPUT2", "Main MIC",
            "RINPUT1", "Mic Jack",
            "Mic Jack", "MICB",
            "Main MIC", "MICB",
            "Playback", "CPU-Playback",
            "CPU-Capture", "Capture";

Headphone Jack, Ext Spk, Main MIC, Mic Jack are machine widgets.

Physical interface definitions

I2S - Inter IC Sound

What is I2S? and What is I2S used for?

I2S - Inter IC Sound is an electrical serial bus interface standard used for connecting digital audio devices together. This standard was introduced in 1986 by Philips Semiconductor (now NXP Semiconductors) and was last revised on June 5, 1996.

i2s-bus-in-system

What is I2S made from?

i2s-bus-spec

Figure. I2S Bus Timing from I2S standard by Philips Seminconductors

The bus consists of at least three lines:

  • Bit clock line: Officially "continuous serial clock (SCK)".[1] Typically written "bit clock (BCLK)".[2]
  • Word clock line: Officially "word select (WS)".[1] Typically called "left-right clock (LRCLK)"[2] or "frame sync (FS)".
    • 0 = Left channel
    • 1 = Right channel
  • At least one multiplexed data line
    Officially "serial data (SD)",[1] but can be called SDATA, SDIN, SDOUT, DACDAT, ADCDAT, etc.[2]

What kind of data is transfered in I2S?

Digital Audio Data e.g. PCM

SAI - Synchronous Audio Interface

Synchronous Audio Interface or Serial Audio Interface? It is quite hard to find definition for SAI in Internet. So, it will be defined by using an example from NPX IMX SoC.

In IMX8M, NXP integrates an audio module called SAI/I2S. This module which is platform device (has its own address in CPU memory map) will receive audio data from external CODEC and transfer these data to CPU. It supports I2S bus standard.

imx-sai

DAI - Digital Audio Interfaces

ASoC currently supports the three main Digital Audio Interfaces (DAI) found on SoC controllers and portable audio CODECs today, namely AC97, I2S and PCM (PCM means a kind of bus, not a type of digital audio data).

References

[1] DAPM - Analog Device - Lars-Petter Clausen.

Back to top