3.2.2.2. Audio

3.2.2.2.1. Introduction

The audio subsystem present on various TI SoCs consists of two major components:

  1. Multi-channel Audio Serial Port (McASP) - Provides a full-duplex serial interface between the host processor and external audio peripherals like codecs over industry-standard protocols like Inter-IC sound (I2S).

  2. System DMA engine - Provides McASP with direct access to system memory to read audio samples from (for playback) or store audio samples to (for capture).

Along with the above, most TI EVMs and SKs have line input/output jack(s) wired to an on-board codec that can convert between the analog signals and the digital protocol supported by McASP.

3.2.2.2.2. Software Architecture

All the hardware components are exposed to userspace applications using the Linux ALSA (Advance Linux Sound Architecture) framework, which allows control and configuration of the hardware through common APIs. For more details check the links below.

Within the kernel there are separate drivers for each component. For each board a sound-card instance is created, usually using the sound {} device tree node, that links together various components like different McASP instances to a codec or an HDMI bridge.

../../../../_images/audio-asoc-arch.png

3.2.2.2.3. Generic commands and instructions

Most of the boards have simple audio setup which means we have one sound card with one playback and one capture PCM. To list the available sound cards and PCMs for playback:

aplay -l

To list the available sound cards and PCMs for capture:

arecord -l

In most cases -Dplughw:0,0 is the device we want to use for audio but in case we have several audio devices (onboard + USB for example) one need to specify which device to use for audio:

-Dplughw:j721ecpbanalog,0 will use the onboard audio on J721E-EVM board.

To play audio on card0’s PCM0 and let ALSA to decide if resampling is needed:

aplay -Dplughw:0,0 <path to wav file>

To record audio to a file:

arecord -Dplughw:0,0 -t wav <path to wav file>

To test full duplex audio (play back the recorded audio w/o intermediate file):

arecord -Dplughw:0,0 | aplay -Dplughw:0,0

To request specific audio format to be used for playback/capture take a look at the help of aplay/arecord. For example, one can specify the format with -f, the sampling rate with -r, or the number of channels with -c. In this case, one should open the hw device (not the plughw) via -Dhw:0,0. For example, record 48KHz, stereo 16bit audio:

arecord -Dhw:0,0 -fdat -t wav record_48K_stereo_16bit.wav

Or to record record 96KHz, stereo 24bit audio:

arecord -Dhw:0,0 -fS24_LE -c2 -r96000 -t wav record_96K_stereo_24bit.wav

It is a good practice to save the mixer settings found to be good and reload them after every boot (if your distribution is not doing this already)

Set the mixers for the board with amixer, alsamixer
alsactl -f board.aconf store

After booting up the board it can be restored with a single command:

alsactl -f board.aconf restore

3.2.2.2.4. Board-specific instructions

J721e Common Processor Board

The board uses pcm3168a codec connected through McASP10 [AXR0-3 for playback, AXR4-6 for capture]. The codec receives its SCKI clock from the AUDIO_EXT_REFCLK2 pin output of the j721e.
PLL4 is configured to 1179648000 Hz for the 48KHz sampling rate family.
PLL15 is configured to 1083801600 Hz for the 44.1KHz sampling rate family.
The board has seven stereo jacks, including four jacks for playback and three jacks for capture.

The audio channel mapping to jacks depends on the number of channels (slots) in the audio stream:

       |o|c1  |o|p1  |o|p3
 _     | |    | |    | |
|o|c3  |o|c2  |o|p4  |o|p2
--------------------------

c1/2/3 - capture jacks (3rd is line input)
p1/2/3/4 - playback jacks (4th is line output)

2 channel audio (stereo):
-------------------------
0 (left):  p1/c1 left
1 (right): p1/c1 right

4 channel audio:
----------------
0: p1/c1 left
1: p2/c2 left
2: p1/c1 right
3: p2/c2 right

6 channel audio:
----------------
0: p1/c1 left
1: p2/c2 left
2: p3/c3 left
3: p1/c1 right
4: p2/c2 right
5: p3/c3 right

8 channel audio:
----------------
0: p1/c1 left
1: p2/c2 left
2: p3/c3 left
3: p4 left
4: p1/c1 right
5: p2/c2 right
6: p3/c3 right
7: p4 right

For example, if the playback is opened in 8-channel mode and stereo audio is desired on the line output (p4), then the left channel of the 8-channel stream should be placed to time slot 3, and the right channel of the 8-channel stream should be placed in time slot 7.

Kernel config

Device Drivers  --->
  Sound card support  --->
    Advanced Linux Sound Architecture  --->
      ALSA for SoC audio support  --->
        Audio support for Texas Instruments SoCs  --->
          <*> SoC Audio support for j721e EVM

User space

NOTE: Playback volume is HIGH after boot. Do not use headset without lowering it!!!

amixer -c j721ecpbanalog sset 'codec1 DAC1' 141  # Playback volume for p1 jack
amixer -c j721ecpbanalog sset 'codec1 DAC2' 141  # Playback volume for p2 jack
amixer -c j721ecpbanalog sset 'codec1 DAC3' 141  # Playback volume for p3 jack
amixer -c j721ecpbanalog sset 'codec1 DAC4' 141  # Playback volume for p4 jack

Master volume control is disabled by default. It can be enabled by:

amixer -c j721ecpbanalog sset 'codec1 DAC Volume Control Type' 'Master + Individual'

Then, a master gain control can be applied to all outputs:

amixer -c j721ecpbanalog sset 'codec1 Master' 141  # Master Playback volume for p1/2/3/4 jack

3.2.2.2.5. Potential issues

In case of XRUN (under or overrun)

The underrun can happen when an application does not feed new samples in time to alsa-lib (due CPU usage). The overrun can happen when an application does not take new captured samples in time from alsa-lib.
There could be several reasons for XRUN to happen, but it usually points to system latency issues connected to CPU utilization or latency caused by the storage device.
Things to try:
  • Increase the buffer size (ALSA buffer and period size)

  • Try to cache the file to be played in memory

  • Try to use application which uses threads for interacting with ALSA and with the filesystem

In case of CPU stalls (when recording)

No longer relevant as DMA driver does a force teardown of the channel.
On some platforms, recording audio on high sample rates may work fine the first time, but due to issues with channel cleanup it may cause CPU stalls when recording the second time, requiring a reboot to fix.
In such scenarios, use smaller period sizes (64 to 256) while recording. For example:
arecord -Dplughw:0,0 -r 48000 -t wav --period-size=64 <path to wav file>

ALSA period size must be aligned with the FIFO depth (tx/rx numevt)

No longer relevant as the kernel side takes care of the AFIFO depth vs period size issue.
To decrease audio-caused stress on the system, the AFIFO is enabled and the depth is set to 32 for McASP.
If the ALSA period size is not aligned with this FIFO setting, a constant ‘trrrrr’ can be heard on the output. This is caused by the eDMA not being able to handle a fragment size that is not aligned with burst size (AFIFO depth).
Application needs to make sure that period_size / FIFO depth is even number.