Audio Setup and Development#
This topic concerns the ASoC driver, audio hub hardware, USB audio, and other matters connected with audio on NVIDIA® IGX devices.
ASoC Driver for the IGX#
Advanced Linux Sound Architecture (ALSA) provides audio functionality to the Linux operating system. The NVIDIA ALSA System-on-Chip (ASoC) drivers enable ALSA to work seamlessly with different NVIDIA SoCs. Platform-independent and generic components are maintained by the upstream Linux community.
For more details on ALSA, follow ALSA Project.
The IGX device exposes multiple interfaces that can be used for audio functionalities. For information about the supported interfaces, see I/O and External Interfaces.
ALSA#
The ALSA framework is a part of the Linux kernel that is supported and maintained by the Linux community. This makes it feasible to adapt the framework to the IGX device by designing a driver that utilizes NVIDIA audio routing support. ALSA includes a collection of sound card drivers, including actual codec drivers, and can support adding new codec drivers.
ALSA includes libraries and utilities that enable more refined audio control in Linux user space. These libraries control audio applications without having to interact with kernel space drivers directly. These libraries include:
amixeraplayarecord
The following image illustrates the ALSA software hierarchy:
The functions of the platform and codec drivers are:
tegra210-admaif: A kernel driver that represents the interface between audio DMA (ADMA) and audio hub (AHUB).tegra210-<xxxx>: Kernel drivers that represent various hardware accelerators in AHUB.tegra210-ahub: A kernel driver that helps to configure audio routing between various hardware accelerators.
For more information about these modules, see the section Audio Hub Hardware Architecture.
User space ALSA applications interact with the ALSA core (kernel space) through APIs provided by user space libraries that initialize the actual hardware codecs at the backend of the audio pipeline.
DAPM#
ALSA is designed to support various functionalities including, but not limited to, dynamic audio routing to available PCM devices. The component of ALSA core that provides this support is called Dynamic Audio Power Management (DAPM).
DAPM minimizes power consumption by controlling the power flow into and out of various codec blocks in the audio subsystem.
DAPM provides switches or kernel controls in the form of widgets (components that affect audio power) to turn a module’s power on and off and to manipulate register bits from user space applications such as aplay, arecord, and amixer.
For more details on DAPM, refer ASoC DAPM.
In terms of software hierarchy, DAPM is part of the ALSA core, which manages the codec module’s power consumption. See the ALSA software hierarchy diagram under ALSA for details.
For more information, see Clocking and Power Management.
Device Tree#
The device tree is a data structure that describes devices on the platform. It is passed to the operating system at boot time to avoid hard coding component details in the operating system. This makes it easier to change hardware configurations without rebuilding the kernel. The device tree is composed of nodes and properties. Each node can have properties or child nodes. Each property consists of a name and one or more values. Device tree structures must be written in the correct format so that the data structure can be parsed by the operating system.
A simple device tree example is available at Codec Driver Instantiation Using Device Tree.
ASoC Driver#
The ASoC driver provides better ALSA support for embedded system-on-chip processors (e.g. DSP, AHUB) and portable audio codecs. It consists of these components:
- Platform driver:
Responsible for PCM registration and interfacing with the PCM driver. ADMAIF is the platform driver.
- Codec drivers:
Typically a generic, hardware-independent component that configures the codecs. IGX ASoC extends this to some of the internal modules which are described in subsequent sections.
A codec driver must have at least one input or one output.
The driver architecture provides a way to define users own DAPM widgets for power management and kcontrols for register settings from user space.
- Machine driver:
Registers a sound card by binding the platform and codec components.
ASoC uses a common structure, snd_soc_component_driver, which represents both a platform and a codec component. It finally depends on which interfaces the drivers implement. For example, a platform component implements PCM interface as well, whereas a codec component can ignore it. Hence at top level, both platform and codec are referred as ASoC components. The same terminology is used in this document whenever a generic reference is needed.
For details on writing a machine driver and identifying a sound card, see ASoC Machine Driver.
Audio Hub Hardware Architecture#
The Audio Processing Engine (APE) is a standalone hardware block that takes care of all the audio needs of IGX processors with minimal supervision from the CPU. Its audio hub (AHUB) contains many hardware accelerators and a DMA engine.
This section provides an overview of:
The audio hub hardware architecture inside the SoC.
The software architecture of the ASoC driver.
The following diagram summarizes the hardware architecture of the ASoC:
Chip-Specific Information#
The audio hub contains several other modules as shown in the following table and it captures AHUB capabilities of a processor. Each module is described in detail in subsequent sections. The table below lists the AHUB modules and their capabilities:
Module |
Component |
Instances |
|---|---|---|
Mixer |
Mixer |
1x |
AMX |
Audio multiplexer |
4x |
ADX |
Audio demultiplexer |
4x |
SFC |
Sample frequency converter |
4x |
MVC |
Master volume control |
2x |
ADMA |
Audio Direct Memory Access |
1x (32 channels) |
ADMAIF |
AHUB Direct Memory Access Interface |
1x (20 TX and RX channels) |
XBAR |
Crossbar; routes audio samples through other modules |
1x |
The modules in the audio hub support various kinds of audio devices that are expected to interface with the application processor, such as:
Cellular baseband devices
Different types of audio CODECs
Bluetooth® modules
Digital microphones
Digital speakers
The audio hub supports the different interfaces and signal quality requirements of these devices in the following ways:
Each of the AHUB modules has at least one RX port or one TX port or both.
RX ports receive data from XBAR, and TX ports send data to XBAR. Thus XBAR is a switch where an audio input can be fed to multiple outputs, depending on the use case.
Each ADMAIF has TX and RX FIFOs that support simultaneous playback and capture. ADMA transfers the data to the ADMAIF FIFO for all audio routing scenarios.
For dynamic audio routing examples, see Usage and Examples.
ASoC Driver Software Architecture#
The software architecture of the ASoC driver for IGX leverages the features supported by the hardware and conforms to the ALSA framework.
As mentioned earlier, the ASoC driver comprises the platform, codec and machine drivers. The roles of these drivers are described briefly below and in more detail in subsequent sections.
The ASoC driver provides NVIDIA Audio Hub (AHUB) hardware acceleration to the platform and codec drivers. AHUB Direct Memory Access Interface (ADMAIF) is implemented as a platform driver with PCM interfaces for playback and capture. The rest of the AHUB modules, such as the crossbar (XBAR), multiplexer (AMX), demultiplexer (ADX), and inter-IC sound (I2S), are implemented as codec drivers. Each of the drivers is connected to XBAR through a digital audio interface (DAI), inside a machine driver, forming an audio hub.
The machine driver probe instantiates the sound card device and registers all of the PCM interfaces as exposed by ADMAIF. After booting, but before using these interfaces for audio playback or capture, user must set up the audio paths inside XBAR.
By default, XBAR has no routing connections at boot, and no complete DAPM paths to power on the corresponding widgets. The XBAR driver introduces MUX widgets for all of the audio components and enables custom routing through kcontrols from user space using the ALSA amixer utility.
If the audio path is not complete, the DAPM path is not closed, the hardware settings are not applied, and audio output cannot be heard.
For more details on how to set up the route and how to play back or capture on the PCM interfaces, see Usage and Examples.
Platform Driver#
The platform driver initializes and instantiates the ports for playback and capture inside the AHUB. Users must connect some or all of these ports to form a full audio routing path. For examples of full audio paths, see the examples in Usage and Examples.
Note
There are other elements in a full audio path setup, which are discussed in subsequent sections. The playback/capture ports set up by the platform driver are only a subset.
ADMAIF#
ADMAIF is the platform driver in the IGX ASoC design. It implements required PCM interfaces exposed via the snd_soc_component_driver structure.
These interfaces help perform DMA operations by interacting with the SoC DMA engine’s upstream APIs. The ADMAIF platform driver defines DAIs and registers them with ASoC core.
The ADMAIF channels are mapped to the following PCM interfaces:
/dev/snd/pcmC1D<CHANNEL_NUMBER>pfor playback/dev/snd/pcmC1D<CHANNEL_NUMBER>cfor capture
Where <CHANNEL_NUMBER> is the channel number minus 1. For example, ADMAIF1 is mapped to pcmC1D0p for playback, and pcmC1D0c for capture. ADMAIF2 is mapped to pcmC1D1p for playback, and pcmC1D1c for capture.
Codec Driver#
An overview of codec drivers is presented in ASoC Driver. In the ASoC driver implementation, the rest of the AHUB modules, except for ADMAIF, are implemented as codec drivers.
Their responsibilities include:
Interfacing to other modules by defining DAIs.
Defining DAPM widgets and establishing DAPM routes for dynamic power switching.
Exposing additional kcontrols as needed for user space utilities to dynamically control module behavior.
Codec Driver Instantiation Using Device Tree#
Based on architecture, the Makefile in the following directory conditionally compiles the required device tree structure files into DTB files:
$KERNEL_TOP/arch/arm64/boot/dts/
When the kernel is flashed, the flash script chooses the appropriate board-specific DTB file for parsing during boot, and the ASoC codecs listed in device tree are instantiated.
To add new devices to the device tree, edit the DTS file, and flash the target again. The DTS file name can be identified from the corresponding DTB file name, and the DTB file is in the /boot/dtb target directory.
For example:
If ``/boot/dtb/kernel_tegra234-p3740-0002+p3701-0008-nv.dtb`` is the platform DTB, the corresponding DTS file is ``hardware/nvidia/t23x/nv-public/nv-platform/tegra234-p3740-0002+p3701-0008-nv.dts``.
To add a new device, add the device name with the base address and status as "okay":
ahub@2900800 {
status = "okay";
i2s@2901000 {
status = "okay";
};
};
Custom ALSA Mixer Control Configuration at Boot#
To configure ALSA mixer controls that are automatically applied when the system boots:
Navigate to the ALSA initialization directory at
/usr/share/alsa/init/postinit/in the platform.Edit or create a configuration file under this directory. Refer to the
00-tegra.conffile in the platform.Add mixer control settings under the appropriate Jetson sound card name.
XBAR#
The XBAR codec driver defines RX, TX and MUX widgets for all of the following modules that interface with XBAR:
ADMAIF
AMX
ADX
I2S
Mixer
SFC
MVC
MUX widgets are permanently routed to the corresponding TX widgets inside the structure snd_soc_dapm_route.
XBAR interconnections are made by connecting any RX widget block to any MUX widget block as needed using the ALSA amixer utility. The get and put handlers for these widgets are implemented so that audio connections are stored by setting the appropriate bit in the hardware MUX register.
Mixer Controls#
If the sound card is available after boot, that indicates that the machine driver was successful in binding all codec drivers and the platform driver. The remaining step before obtaining the audio output on the physical codecs involves the use of MUX widgets to establish the DAPM path in order to route data from a specific input module to a specific output module. Input and output modules are dependent on the applicable use case. This provides flexibility for complex use cases.
This command realizes the internal AHUB path “ADMAIF1 RX to XBAR to I2S1 TX”:
amixer -c APE cset name='I2S1 Mux' 'ADMAIF1'
For usage and examples of various AHUB modules, see Usage and Examples.
AMX#
The Audio Multiplexer (AMX) module can multiplex up to four streams ofup to 16 channels, with a maximum of 32-bits per channel, into a time division multiplexed (TDM) stream of up to 16 channels with up to 32-bits per channel. The AMX has four RX ports for receiving data from XBAR and one TX port for transmitting the multiplexed output to XBAR. Each port is exposed as a DAI, as indicated in the following diagram by solid lines. Routes are established using DAPM widgets, as indicated by dotted lines.
The AMX code driver supports the following features:
Can multiplex up to four input streams of up to 16 channels each, and generate one output stream of up to 16 channels.
Can assemble assemble an output frame from any combination of bytes from the four input frames (“byte ram”).
Provides two modes for data synchronization of the first output frame: * Wait for All mode: Wait for all enabled input streams to have data before forming the first output frame. * Wait for Any mode: Start forming the first output frame as soon as data is available in any enabled input stream.
Byte Map Configuration#
Each byte in the output stream is uniquely mapped from a byte in one of the four input streams. Mapping of bytes from input streams to the output stream is software-configurable through a byte map in the AMX module.
Each byte in the byte map is encoded with the following fields:
Field |
Bits |
Description |
|---|---|---|
Input stream |
7:6 |
Identifies the input stream (0 to 3) that the byte is mapped from, where 0 is RxCIF0, etc.
|
Input stream channel |
5:2 |
Identifies the input stream channel (0 to 15) that the byte is mapped from, where 0 is channel 0, etc.
|
Input stream byte |
1:0 |
Identifies the byte in the input stream channel that the byte is mapped from (0 to 3), where 0 is byte 0, etc.
|
Because the largest supported output frame size is 16 samples (from 16 channels) with 32-bits per sample, the byte map is organized as 16 words of 4 bytes (32-bits) each. Each word represents one input channel, and each byte in the word represents one output channel that the input channel may be mapped to. If the output frame gets samples from only two input channels, then only the bytes in word 0 and word 1 need be programmed. If the output frame gets samples from all 16 channels, then the bytes in all 16 words must be programmed.
The output frame sample size determines which bytes must be programmed in each word. If the sample size of each channel in the output frame is 16-bits, then only byte 0 and byte 1 of each word in the byte map need be programmed. If the sample size of each channel in the output frame is 32-bits, then all four bytes of each word in the byte map must be programmed.
Bear these points in mind:
Input bytes must be mapped to output bytes in order. For example, if input frame bytes 0 and 1 are both mapped to the output frame, byte 1 must be mapped to a position in the output frame after byte 0.
Not all bytes from an input frame need be mapped to the output frame.
Each byte in the output frame has a software-configurable enable flag. If a particular byte’s enable flag is cleared, the corresponding mapping in the byte map is ignored, and that byte is populated with zeros.
Mixer Controls#
Mixer controls are registered for each instance of AMX by the respective codec driver, and are used to configure the path, characteristics, and processing method of audio data. The table below lists instance-specific mixer controls:
Mixer Control |
Description |
Possible Values |
|---|---|---|
AMX<INST_ID> RX<PORT_ID> Mux |
Selects the AHUB client device from which the AMX input receives data. |
Run the following command to get possible values: amixer -c APE cget name="AMX<INST_ID> RX<PORT_ID> Mux"
|
AMX<INST_ID> Input<PORT_ID> Audio Channels |
Specifies the channel count of the input streams. |
0-16 |
AMX<INST_ID> Output Audio Channels |
Specifies the channel count of the output stream. |
0-16 |
AMX<INST_ID> Byte Map <BYTE_NUM> |
Specifies the byte map (see Byte Map Configuration). |
0-255 |
Note
In the table above, <INST_ID> refers to the instance ID of the AMX client, <PORT_ID> refers to the input port ID, and <BYTE_NUM> refers to the byte number in the byte map.
Usage and examples of the AMX module can be found in Examples: AMX.
ADX#
The Audio Demultiplexer (ADX) module can demultiplex a single TDM stream of up to 16 channels and a maximum of 32-bits per channel into four streams of up to 16 channels and 32-bits per channel. The RX port of ADX receives input data from XBAR, and four TX ports transmit demultiplexed output to XBAR. Each port is exposed as a DAI, indicated by a solid line and routes are established using DAPM widgets as indicated by the dotted lines in the following diagram.
ADX has one input, RxCIF, which supplies the input stream. The core logic selects bytes from this input stream based on a byte map and forms output streams which are directed to a TxCIF FIFO to be transmitted to a downstream module in AHUB.
The ADX demultiplexer supports these features:
Demultiplexing one input stream of up to
MAXchannels to four output streams of up to 16 channels eachAssembling output frames that contain any combination of bytes from the input frame (“byte RAM”). The byte RAM design is the same as in AMX, except that the direction of data flow is reversed.
Byte Map Configuration#
Each byte in each output stream is mapped from a byte in the input stream. The mapping of the bytes from input stream to output streams is software-configurable through a byte map in the ADX module.
Field |
Bits |
Description |
|---|---|---|
Output stream |
7:6 |
Specifies the output stream that the byte is mapped to, where 0 represents TxCIF0, etc. |
Output stream channel |
5:2 |
Specifies the output stream channel that the byte is mapped to, where 0 represents channel 0, etc. |
Output stream byte |
1:0 |
Specifies the byte in the output stream channel that the byte is mapped to, where0 represents byte 0, etc. |
The byte map is organized as MAX words of 32 bits (4 bytes) each.
Each word represents
one channel in the input frame. Therefore, if the input frame only
has two channels then only the bytes in word 0 and word 1 need be
programmed. If the input frame has the maximum allowed channels, bytes in all MAX words must be programmed.
The input frame sample size determines the bytes that must be programmed in each word. If the sample size of each channel in the input frame is 16-bits, then only byte 0 and byte 1 of each word need be programmed. If the sample size of each channel in the input frame is 32-bits, then all four bytes of each word must be programmed.
Bear these points in mind:
Input bytes must be mapped to output bytes in order. For example, if input frame bytes 0 and 1 are both mapped to the output frame, byte 1 must be mapped to a position in the output frame after byte 0.
Not all bytes in an input frame need be mapped to the output frame.
Each byte in the output frame has a software-configurable enable flag. If a particular byte’s enable flag is cleared, the corresponding mapping in the byte map is ignored, and that byte is populated with zeros.
Mixer Controls#
Mixer controls are registered for each instance of ADX by the respective codec driver, and are used to configure the path, characteristics, and processing method audio data. The table below lists the instance-specific mixer controls for each instance of the ADX module.
Mixer Control |
Description |
Possible Values |
|---|---|---|
ADX<i> Mux |
Selects the AHUB client device from which the ADX input receives data. |
To get the possible values, run this command:
|
ADX<i> Byte Map <byte_num> |
Configures the byte map (see Byte Map Configuration) |
0–255 |
ADX<i> Input Sample Channels |
Configures the channel count of the input stream. |
0–<MAX> |
ADX<i> Output<j> Sample Channels |
Configures the channel count of the output streams. |
0–16 |
Notation:
<i>is an ADX instance from1toN. For the value ofN.<j>is an output stream number from1to4associated with the specified ADX.<MAX>is the maximum number of input channels supported by the ADX. For the value of<MAX>.<byte_num>is 4 bytes (32-bit format) multiplied by<MAX>.
For items 1 and 3, see Chip-Specific Information.
Usage and examples of the AMX module can be found in Examples: AMX.
I2S#
An I2S codec driver supports bidirectional data flow, and so defines CIF and DAP RX/TX DAPM widgets with the CIF side of I2S interfacing with XBAR, and the DAP side interfacing with the physical codec on the IGX device.
The DAPM routes established with these DAPM widgets are shown in the following diagram as dotted lines. I2S modules also expose kernel control to enable internal I2S loopback.
The I2S controller implements full-duplex and half-duplex point-to-point serial interfaces. It can interface with I2S-compatible products, such as digital audio tape devices, digital sound processors, modems, and Bluetooth chips.
The I2S codec driver supports these features:
Can operate both as master and slave
Supports the following modes of data transfer:
LRCK modes: I2S mode, Left Justified Mode (LJM), or Right Justified Mode (RJM)
FSYNC modes: DSP A or B mode
Can transmit and receive data:
Sample size: 8 bits (S8), 16 (S16_LE), or 24/32 bits (S32_LE)
Sample rate: 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88400, 96000, 176400, or 192000 Hz
Channels: LRCK modes support stereo data; DSP A and B modes support 1 to
MAXchannels
Device Tree Entry#
This node enables one instance of I2S on IGX Orin series:
aconnect@2900000 {
status = "okay";
...
tegra_ahub: ahub@2900800 {
status = "okay";
...
tegra_i2s1: i2s@2901000 {
status = "okay";
...
};
};
};
The snippet above is from the device tree structure for IGX.
The address and a few other properties are
IGX device-specific and might be referenced by the corresponding IGX device’s tree files. In the case of I2S, the device entry above specifies the
names of clocks needed by the device, the source of each clock, and the register base address and address range belonging to the device.
Other properties such as fsync-width may be adjusted to fit the use case’s
requirements.
Mixer Controls#
Mixer controls are registered for each instance of I2S by the respective codec driver, and are used to configure the path, characteristics, and processing method of audio data. The table below lists instance-specific mixer controls.
Mixer Control |
Description |
Possible Values |
|---|---|---|
I2S<i> Mux |
Selects the AHUB client device from which the I2S input receives data. |
To get the possible values, run this command:
|
I2S<i> Loopback |
Enables internal I2S loopback. |
|
I2S<i> FSYNC Width |
Configures frame sync signal’s width in terms of bit clocks. |
0–255 |
I2S<i> Capture Stereo To Mono |
Configures stereo-to-mono conversion method to be applied to capture stream. |
|
I2S<i> Capture Mono To Stereo |
Configures mono-to-stereo conversion method to be applied to capture stream. |
|
I2S<i> Playback Stereo To Mono |
Configures stereo-to-mono conversion method to be applied to playback stream. |
|
I2S<i> Playback Mono To Stereo |
Configures mono-to-stereo conversion method to be applied to playback stream. |
|
I2S<i> Playback FIFO Threshold |
Configures CIF’s FIFO threshold for playback to start. |
0–63 |
I2S<i> BCLK Ratio |
I2S BCLK (bit clock) multiplier |
1, 2, … |
I2S<i> codec frame mode |
Configures I2S/TDM frame mode. For I2S mode, use |
|
I2S<i> codec master mode |
Configures I2S codec’s mode of operation (bit-master, bit-slave, frame-slave, or frame-master). |
|
I2S<i> Sample Bits |
Configures length of sample bits. |
16 or 32 |
I2S<i> Sample Rate |
Configures sample rate of audio stream. |
8000, 11025, 16000, 22500, 24000, 32000, 44100, 48000, 88400, 96000, 176400, or 192000 Hz |
I2S<i> Sample Channels |
Configures channel count of audio stream. |
0–<MAX> |
Notation:
<i>is an I2S instance from1toN. For the value ofN.<MAX>is the maximum number of input channels supported by the I2S. For the value of<MAX>.
For items 1 and 2, see Chip-Specific Information.
For usage and an example for the I2S module, see Examples: I2S.
Mixer#
The Mixer mixes audio streams from any of the 10 input ports that receive data from XBAR to any of the 5 output ports that transmit data onto XBAR. The DAPM widgets and routes for Mixer are shown in the figure below. The Mixer driver also exposes RX Gain and Mixer Enable as additional kcontrols to set the volume of each input stream and to globally enable or disable the Mixer respectively.
Features Supported#
Supports mixing up to 10 input streams
Supports five outputs, each of which can be a mix of any combination of 10 input streams
Can transmit and receive:
Sample size: 8, 16, 24, or 32
Sample rate: 8000, 11025, 16000, 22500, 24000, 32000, 44100, 48000, 88400, 96000, or 192000 Hz
Channels: 1-8
Fixed gain for each stream is also available
Mixer Controls#
Mixer controls are registered for each instance of Mixer by the corresponding codec driver. They are used to the configure path, characteristics, and processing method of audio data. The table below lists instance-specific mixer controls.
Mixer Control |
Description |
Possible Values |
|---|---|---|
MIXER1 RX<i> Mux |
Selects the AHUB client device from which the MIXER1 input receives data. |
To get the possible values, run this command:
|
MIXER1 Adder<j> RX<i> |
Enables the input stream |
|
MIXER1 Fade |
Set Fade settings for multiple Mixer input streams. |
Fade settings for an input stream consisting of three values and thus a total of 30 values:
- Input stream ID: 1 to 10
- Gain: see the RX<i> Gain control
- Duration:
64-0x7fffffff |
MIXER1 Fade Status |
Read-only control. Queries Fade status of all the input streams. |
-
-1: Fade is not programmed-
0: Fade is not completed-
1: Fade is completed |
MIXER1 RX<i> Gain Volume |
Configures the gain for an input stream before you add in the adder. |
0–131072 |
MIXER1 RX<i> Instant Gain Volume |
Configures the gain for an input stream before you add in the adder. |
0–131072 |
MIXER1 RX<i> Sample Channels |
Configures the channel count of the input stream. |
0–8 |
MIXER1 TX<j> Sample Channels |
Configures the channel count of the output stream. |
0–8 |
Notation:
<i>is a Mixer input stream number from1to10.<j>is a Mixer output stream number from1to5.
For usage and examples for the Mixer module, see Examples: Mixer.
SFC#
The Sampling Frequency Converter (SFC) converts the input sampling frequency to the required sampling rate. SFC has one input port and one output port, which are connected to XBAR.
Features Supported#
Sampling frequency conversion of streams of up to two channels (stereo)
Very low latency (maximum latency less than 125 microseconds)
Supported frequency conversions appear in the following table. When the frequency in and out are the same, frequency conversion is bypassed.
Fs in → |
|||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
8 |
11.025 |
16 |
22.05 |
24 |
32 |
44.1 |
48 |
88.2 |
96 |
176.4 |
192 |
||
Fs out ↓ |
8 |
n/a |
yes |
yes |
yes |
yes |
|||||||
11.025 |
n/a |
yes |
yes |
||||||||||
16 |
yes |
n/a |
yes |
yes |
yes |
||||||||
22.05 |
n/a |
yes |
yes |
||||||||||
24 |
n/a |
yes |
yes |
||||||||||
32 |
n/a |
yes |
yes |
||||||||||
44.1 |
yes |
yes |
n/a |
yes |
|||||||||
48 |
yes |
yes |
yes |
yes |
n/a |
yes |
yes |
||||||
88.2 |
yes |
yes |
n/a |
||||||||||
96 |
yes |
yes |
n/a |
||||||||||
176.4 |
yes |
yes |
n/a |
||||||||||
192 |
yes |
yes |
n/a |
Mixer Controls for SFC#
Mixer controls are registered for each instance of SFC by the corresponding codec driver. They are used to configure the path, characteristics, and processing method of audio data. The table below lists instance-specific mixer controls.
Mixer Control |
Description |
Possible Values |
|---|---|---|
SFC<i> Mux |
Selects the AHUB client device from which the SFC input receives data. |
To get the possible values, run this command:
|
SFC<i> Input Sample Rate |
Configures sampling rate of the input stream. |
8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, or 192000 Hz |
SFC<i> Output Sample Rate |
Configures sampling rate of the output stream. |
8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, or 192000 Hz |
SFC<i> Input Sample Channels |
Configures channel count of the input stream. |
1, 2 |
SFC<i> Output Sample Channels |
Configures channel count of the input stream. |
1, 2 |
SFC<i> Input Sample Bits |
Configures sample size of the input stream. |
16 or 32 |
SFC<i> Output Sample Bits |
Configures sample size of output stream. |
16 or 32 |
SFC<i> Input Stereo To Mono |
Configures stereo-to-mono conversion of input stream. |
|
SFC<i> Input Mono To Stereo |
Configures mono-to-stereo conversion of input stream. |
|
SFC<i> Output Stereo To Mono |
Configures stereo-to-mono conversion of output stream. |
|
SFC<i> Output Mono To Stereo |
Configures mono-to-stereo conversion of output stream. |
|
Notation:
<i>is an SFC instance from1toN. For the value ofN.
For item 1, see Chip-Specific Information.
For usage and examples for the SFC module, see Examples: SFC.
Arbitrary Sample Rate Converter (ASRC)#
The Arbitrary Sample Rate Converter (ASRC) converts audio samples from one sample rate to another. The conversion ratio between input and output sample rates can be any arbitrary number and the input and output clocks could be derived from asynchronous clocks.
Features Supported#
Input sample rates in the range 8 KHz to 192 KHz.
Output sample rates in the range 8 KHz to 192 KHz.
Any sampling ratio from 1:24 to 24:1.
Input formats up to 16, 24, and 32 bits.
Up to 6 streams and up to 16 total channels, with a maximum of 8 channels per stream.
Mixer Controls for ASRC#
Mixer controls are registered for ASRC by the corresponding codec driver. They are used to configure the path, characteristics, and processing method of audio data. The following table lists ASRC mixer controls.
Mixer Control |
Description |
Possible Values |
|---|---|---|
ASRC1 RX<i> Mux |
Selects the AHUB client device from which the ASRC input receives data. |
To get the possible values, run this command:
|
ASRC1 Ratio<i> Source |
Configure ASRC ratio source. |
|
ASRC1 Ratio<i> |
Conversion ratio (input_frequency/output_frequency). |
Ratio = <integer part>,<frac part>
Integer part: 0 to 24
Fraction part: Q32 format
|
ASRC1 Stream<i> HW Component Disable |
Enable or disable ASRC hardware compensation. |
|
ASRC1 Stream<i> Input Threshold |
Configure ASRC input threshold. |
0–3 |
ASRC1 Stream<i> Output Threshold |
Configure ASRC output threshold. |
0–3 |
Notation:
<i> refers to the stream number: 1 to 6.
For usage and examples for the ASRC module, see Examples: ASRC.
MVC#
MVC (volume control) applies gain or attenuation to a digital signal path. The MVC block is a generic block. It can be used to apply volume control:
To the input or output digital signal path
Per-stream and to all streams (primary volume control)
The following diagram shows MVC’s DAPM widgets and routes.
Features Supported#
Programmable volume gain for data formats:
Sample size: 8, 16, 24, or 32 bits
Sample rate: 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88400, 96000, 176400, or 192000 Hz
Channels: 1-8
Programmable curve ramp for volume control
Separate mute and unmute controls
Mixer Controls#
Mixer controls are registered for each instance of MVC by the corresponding codec driver. They are used to configure the path, characteristics, and processing method of audio data. The table below lists instance-specific mixer controls.
Mixer Control |
Description |
Possible Values |
|---|---|---|
MVC<i> Mux |
Selects the AHUB client device from which the MVC input receives data. |
To get the possible values, run this command:
|
MVC<i> Volume |
Configures master volume. |
0 to 16000 (represents -120 to +40 dB with 100x scale factor) |
MVC<i> Channel<j> Volume |
Configures channel-specific volume. |
0 to 16000 (represents -120 to +40 dB with 100x scale factor) |
MVC<i> Mute |
Enables/disables Master mute. |
|
MVC<i> Per Channel Mute Mask |
Controls channel-specific mute and unmute. |
0 to 255 |
MVC<i> Curve Type |
Configures volume ramp curve type. |
|
MVC<i> Sample Channels |
Configures channels of audio data passing through MVC. |
0–8 |
MVC<i> Sample Bits |
Configures sample size of input audio data through MVC. |
16 or 32 |
MVC<i> Bits |
Configures sample size of output audio data through MVC. |
16 or 32 |
Notation:
<i>is an MVC instance from1toN. For the value ofN.
For item 1, see Chip-Specific Information.
For usage and examples of the MVC module, see Examples: MVC.
AHUB Client TX Port Names#
This is a list of names of AHUB clients’ TX ports.
AHUB Client |
TX Port Names * |
|---|---|
ADMAIF |
|
I2S |
|
AMX |
|
ADX |
|
SFC |
|
MVC |
|
MIXER |
|
* |
|
ASoC Machine Driver#
The ASoC machine driver connects the codec drivers to a PCM driver by linking the DAIs exposed by each module, and instantiates the sound card.
The structure snd_soc_dai_link, in ASoC core, defines a link
that connects two DAIs from different modules. Such a link is called a
DAI link. A given machine driver can have one or more DAI links,
which are connected at runtime to form an audio path.
Dynamic PCM (DPCM) links are used to support runtime routing between multiple DAIs. Tegra audio systems utilize DPCM-based DAI links to enable flexible audio routing between the Audio Hub (AHUB) modules and external codecs.
For more information about DPCM, see the Kernel DPCM documentation.
In brief, the ASoC machine driver’s functions are to:
Parse all DAI links from DT. These include both SoC internal DAI links (those between XBAR and various AHUB modules) and IGX device-specific DAI links between SoC I/O modules and external audio codecs.
The following is a list of the ASoC machine driver’s key functions:
Set up audio routing between devices based on device tree configuration.
- Configure audio routing using DAPM widgets and routes.
Machine widgets (like headphone jacks, speakers, and microphones) are mapped to codec endpoints.
Routes define valid audio paths between widgets.
Set up clocking for the Audio Processing Engine (APE) and codecs.
Handle runtime configuration of PCM parameters (such as sample rate, format, and channels).
The IGX ASoC machine driver is available in the kernel sources archive in this location:
$KERNEL_TOP/sound/soc/tegra/tegra_audio_graph_card.c
The Tegra machine driver implementation is based on graph-based data from the device tree, following the standard Device Tree Graph Schema, which defines the generic framework for audio connections.
For example, the IGX Orin platform base device tree contains the core port configurations and routing endpoints needed for audio functionality:
I/O interfaces like I2S have two ports: the Internal port (port@0) that connects to the XBAR through the
i2s1_cifendpoint and the External port (port@1)i2s1_portwith thei2s1_dapendpoint for codec connection.
For example, I2S1 DAI is connected to the dummy codec, and looks like below:
i2s1_to_codec: nvidia-audio-card,dai-link@76 {
status = "okay";
format = "i2s";
link-type = <C2C_LINK>;
i2s1_cpu: cpu {
sound-dai = <&tegra_i2s1 I2S_DAP>;
};
codec {
sound-dai = <&tegra_i2s1 I2S_DUMMY>;
};
}
Definition of a DAI Node#
Each I2S interface requires both an endpoint configuration and a DAI link definition in the device tree. The endpoint defines the physical connection points; the DAI link establishes the logical audio path. The overall format of a DAI node is described in ASoC Machine Driver. For each I2S interface DAI link, users can configure the properties as per use case. For details, see the Audio Graph Port Device Tree Bindings
Other DAI link properties are common for all the DAI links. For details, see the DAI Parameters Device Tree Bindings.
Clocking and Power Management#
The following debugfs node listing, obtained from
/sys/kernel/debug/clk/clk_summary, shows the clock tree of the ASoC
driver for IGX in the idle state, when no audio
playback or capture operations are in progress.
clock |
enable_cnt |
prepare_cnt |
rate |
req_rate |
accuracy |
phase |
|---|---|---|---|---|---|---|
i2s6_sync_input |
0 |
0 |
0 |
0 |
0 |
0 |
i2s5_sync_input |
0 |
0 |
0 |
0 |
0 |
0 |
i2s4_sync_input |
0 |
0 |
0 |
0 |
0 |
0 |
i2s3_sync_input |
0 |
0 |
0 |
0 |
0 |
0 |
i2s2_sync_input |
0 |
0 |
0 |
0 |
0 |
0 |
i2s1_sync_input |
0 |
0 |
0 |
0 |
0 |
0 |
dmic4_sync_clk |
0 |
0 |
0 |
0 |
0 |
0 |
dmic3_sync_clk |
0 |
0 |
0 |
0 |
0 |
0 |
dmic2_sync_clk |
0 |
0 |
0 |
0 |
0 |
0 |
dmic1_sync_clk |
0 |
0 |
0 |
0 |
0 |
0 |
i2s6_sync_clk |
0 |
0 |
0 |
0 |
0 |
0 |
i2s5_sync_clk |
0 |
0 |
0 |
0 |
0 |
0 |
i2s4_sync_clk |
0 |
0 |
0 |
0 |
0 |
0 |
i2s3_sync_clk |
0 |
0 |
0 |
0 |
0 |
0 |
i2s2_sync_clk |
0 |
0 |
0 |
0 |
0 |
0 |
i2s1_sync_clk |
0 |
0 |
0 |
0 |
0 |
0 |
pll_a1 |
0 |
0 |
600000000 |
600000000 |
0 |
0 |
ape |
0 |
0 |
150000000 |
150000000 |
0 |
0 |
apb2ape |
0 |
0 |
150000000 |
150000000 |
0 |
0 |
pll_a |
0 |
0 |
258000000 |
258000000 |
0 |
0 |
dmic4 |
0 |
0 |
12285714 |
12285714 |
0 |
0 |
dmic3 |
0 |
0 |
12285714 |
12285714 |
0 |
0 |
dmic2 |
0 |
0 |
12285714 |
12285714 |
0 |
0 |
dmic1 |
0 |
0 |
12285714 |
12285714 |
0 |
0 |
i2s6 |
0 |
0 |
23454545 |
23454545 |
0 |
0 |
i2s5 |
0 |
0 |
23454545 |
23454545 |
0 |
0 |
i2s4 |
0 |
0 |
23454545 |
23454545 |
0 |
0 |
i2s3 |
0 |
0 |
23454545 |
23454545 |
0 |
0 |
i2s2 |
0 |
0 |
23454545 |
23454545 |
0 |
0 |
i2s1 |
0 |
0 |
23454545 |
23454545 |
0 |
0 |
ahub |
0 |
0 |
86000000 |
86000000 |
0 |
0 |
The clocks of the individual modules, AMX, ADX, AFC, SFC, MIXER, and others, are internally driven by the APE clock.
The clock for all codec drivers (I2S, XBAR, etc.) are switched off in the idle state. They are turned on when audio playback or capture begins.
Dynamic PLL_A Rate Update#
PLL_A is a clock source provided by IGX processors for audio needs. Its primary
function is to source the clocking requirements of I2S modules. The AUD_MCLK clock is also derived from PLL_A.
IGX devices support two families of sample rates:
Multiples of 8 Kbps (8x): 8000, 16000, 24000, 32000, 48000, 96000, and 192000 Hz
Multiples of 11.025 Kbps (11.025x): 11025, 22050, 44100, 88200, and 176400 Hz
A single PLL_A base rate cannot support both families of rates.
Therefore, separate base rates are used for 8x and 11.025x. The machine
driver sets the rate of PLL_A at run time, depending on the incoming
stream’s sample rate. Thus users can play and capture at a rate from
either list above.
High Definition Audio#
IGX devices support one or more High Definition Audio (HDA) interfaces through on-board HDMI and DP ports. These interfaces can be used to perform high-quality audio rendering on devices like TVs and A/V receivers. These HDA interfaces are available on IGX:
IGX Orin: One DP output (can support single or multiple streams), One HDMI input for HDMI-IN.
IGX Thor: One DP output (can support single or multiple streams).
HDMI and DP interfaces can be connected using the respective connectors.
Features Supported#
IGX High Definition Audio supports the following features:
Compliant with High Definition Audio Specification Revision 1.0
Supports HDMI 1.3a and DP
Audio Format Support
Channels: 2 to 8
Sample size: 16 bits (S16_LE) or 24 bits (S32_LE)
Sample rate:
32000, 44100, 48000, 88200, 96000, 176400, or 192000 Hz (HDMI)
32000, 44100, 48000, 88200, or 96000 Hz (DP)
If you experience issues when playing high resolution audio formats (using multichannel output or a high sampling rate), even with an audio format that your monitor supports, this is because the available audio bandwidth depends on the HDMI configuration, increasing with higher display resolutions.
If you encounter issues when playing a high resolution audio format, NVIDIA recommends that you set your display resolution to at least the level that corresponds to your audio format in the following table. This table is taken from the HDMI 1.3a specification document.
Note
Two-channel PCM can never exceed 192 kHz. Higher values indicate higher frame rates that can be used for compressed streams.
Display Resolution |
Format Timing |
Pixel Repetition |
Maximum fs 8 Channels (Hz) |
Maximum Frame Rate 2 Channels Compressed |
SuperAudio CD Channel Count |
|---|---|---|---|---|---|
VGA |
640 x 480p |
none |
48000 |
192 |
2 |
240p |
1440 x 240p |
2 |
88200 |
192 |
2 |
240p |
2880 x 240p |
4 |
192000 |
768 |
8 |
480i |
1440 x 480i |
2 |
88200 |
192 |
2 |
480i |
2880 x 480i |
4 |
192000 |
768 |
8 |
480p |
720 x 480p |
none |
48000 |
192 |
2 |
480p |
1440 x 480p |
2 |
176400 |
384 |
8 |
480p |
2880 x 480p |
4 |
192000 |
768 |
8 |
720p |
1280 x 720p |
none |
192000 |
768 |
8 |
1080i |
1920 x 1080i |
none |
192000 |
768 |
8 |
1080p |
1920 x 1080p |
none |
192000 |
768 |
8 |
Software Driver Details#
HDA interfaces are accessible through standard ALSA interfaces.
Use the aplay utility for rendering audio:
aplay -Dhw:HDA,<DEVICE-ID> <WAV-IN>
Where:
<DEVICE-ID>is the sound interface’s device ID.<WAV-IN>is the name of the sound file to be played. It should be a .wav file.
Here are some further details about driver usage:
All HDA interfaces are available under one card.
Read card details from
/proc/asound/cards.To see available PCM devices (i.e. HDA interfaces) under
/proc/asound/card<n>/.AHUB supports 16-bit audio in S16_LE format, and 20 or 24-bit audio in S32_LE format.
USB Audio#
All IGX devices provide a USB host interface for connecting various USB devices, including USB audio devices such as speakers, microphones and headsets.
Features Supported#
IGX High Definition Audio supports the following features:
Channels: 8 maximum
Sample size: 16 bits (S16_LE) or 24 bits (S24_3LE)
Sample rate: 32000, 44100, 48000, 88200, 96000, 176400, or 192000 Hz
Supported audio formats are determined by the USB audio equipment connected.
Software Driver Details#
USB audio is accessible through standard ALSA interfaces. Use the aplay and arecord utilities to render and capture audio, respectively:
aplay -Dhw:<CARD-ID>,<DEV-ID> <FILE-WAV>
arecord -Dhw:<CARD-ID>,<DEV-ID> -r <RATE> -c <CHANNELS> -f <FORMAT> <FILE-WAV>
Where:
<CARD-ID>is the card ID, a string that identifies the type of sound card:APEorHDA.<DEV-ID>is the device ID.<FILE-WAV>is the name of the input file (foraplay) or output file (forarecord). It must be a .wav file.<RATE>is the sampling rate.<CHANNELS>is the number of audio channels.<FORMAT>is the sample format
Here are some further details about driver usage:
The USB audio card is enumerated upon connecting a USB device (e.g. a USB headphone).
You can read card details from
/proc/asound/cards.You can see available PCM devices under
/proc/asound/card<n>/.
In-Built Audio Codec#
The Playback and Capture jack ports are connected internally to the RT5640 codec on IGX.
Audio Formats Supported#
The IGX ASoC driver supports these formats:
Sample size: 8 bits (S8), 16 bits (S16_LE), or 24/32 bits (S32_LE)
Sample rate: 8000, 11025, 16000, 22050. 24000, 32000, 44100, 48000, 88400, 96000, 176400, or 192000 Hz
Channels: 1 or 2
Usage Guide#
To establish the audio route for playback or recording through the header, it’s necessary to configure several ALSA mixer controls for both the IGX device and the onboard codec. By default, audio route is set for LINE OUT and MIC path.
Playback and Capture Commands#
The following commands can be used to perform playback and capture using the in-built audio codec.
Playback:
aplay -D hw:APE,0 <IN-WAV>
Capture:
arecord -Dhw:APE,0 -c <CHANNELS> -r <RATE> -f <FORMAT> -d <DURATION> <OUT-WAV>
HDMI IN Capture#
Considering HDMI IN signal are present to start Audio capture:
# AHUB Mixer Controls (apply on IGX)
amixer -c APE cset name="ADMAIF2 Mux" "I2S6"
amixer -c APE cset name="I2S6 codec master mode" "cbm-cfm"
# Start capture
arecord -Dhw:APE,1 -c 2 -r 48000 -f S16_LE -d 15 <OUT-WAV>
Usage and Examples#
This section gives an example of how a device’s I/O interfaces and AHUB modules can be used in audio applications.
This shows a dump of sound card descriptions from an IGX device.
Note
The example uses a specific ADMAIF, but you may choose any ADMAIF you want.
$ cat /proc/asound/cards
0 [HDA ]: tegra-hda - NVIDIA IGX HDA
NVIDIA Jetson IGX HDA at 0x3518000 irq 122
1 [APE ]: tegra-ape - NVIDIA IGX APE
Unknown-Jetson{ORIN | THOR}DeveloperKit-NotSpecified
For each sound card, the dump shows:
The initial number is the index of the sound card, a sequential number counting from 0.
The word in square brackets is the card ID (“card identifier”), a string that identifies a sound card. Trailing spaces are not part of the card ID.
tegra-hdaortegra-apeis the ALSA card driver name, that is, the machine driver name associated with the sound card. On IGX devices, HDA sound cards usetegra-hdaand APE sound cards usetegra-ape.“NVIDIA IGX HDA” and “…APE”: Short name of the sound card, and it is considered to be the name of the card.
“NVIDIA IGX HDA at 0x3518000 irq 118” and “…APE”: Long name of the sound card.
Note
The example shows the two types of sounds cards that are built into the IGX AHUB architecture, and use drivers provided by NVIDIA. An IGX device might have other types. If you attached a USB headset to the device, for example, the dump will also show a USB sound card.
USB sound card names depend on the vendor and model of the sound card. A dump like the one above can help you determine a USB sound card’s long name.
The following table lists the short names that are used on different IGX devices for APE and HDA cards.
Board name |
APE card name |
HDA card name |
USB card name |
|---|---|---|---|
IGX Orin |
NVIDIA IGX APE |
NVIDIA IGX HDA |
For the name after plugging in the device, run the following command: cat /proc/asound/cards
|
In addition to a name, each sound card has a device ID, as shown in the table later in this section.
For an APE card, the device ID refers to the ADMAIF channel index being used. IGX devices have 20 ADMAIF channels, and each channel is associated with a playback device and a capture device. Each device has a device ID ranging from 0 to 19.
To determine how many sound cards are available, enter:
cat /proc/asound/cards
This command displays the index of the last sound card, which is one less than the number of sound cards. For example, if /proc/asound/cards contains ‘2’, the IGX device has three sound cards, with card indexes 0, 1, and 2.
To list all of the available PCM sound cards’ device IDs, enter:
ls /dev/snd/pcmC?D*
This a convenient way to get the available device IDs for a given card. If you know the card’s index, you may use it in place of the ‘?’.
Note
Sound card indexes are assigned in the order that the kernel registers the sound cards at boot time. Therefore, a given card ID may not represent the same card from boot to boot.
To display a description of a specific PCM sound card, enter:
cat /dev/snd/pcmC<N>D<DEV-ID><F>
Where:
<N>is the card’s index, 0 or 1.<DEV-ID>is the card’s device ID<F>is the function of this device,cfor “capture” orpfor “playback.”
This table lists port to <DEV-ID> mappings for HDA devices, for which different HDA ports are mapped to specific <DEV-ID> values.
Port to device ID map
Device
Port Name
PCM Device ID
IGX Orin
DP
3 (DP single stream)
3 and 7 (DP multi-stream)
HDMI
HDMI IN
IGX Thor
DP
3, 7, 8, and 9
Following are examples of device name usage for several different types of interfaces. In these examples:
<I>and<I-1>are respectively the number of the ADMAIF channel to be used, and that number minus 1.<IN-WAV>and<OUT-WAV>are respectively the pathnames of the input and output sound files. Both must be .wav files.<RATE>is the sampling rate to be used.<BITS>is the number of bits per sample.<CHANNELS>is the number of channels to be used.
Examples: I2S#
These examples illustrate various I/O playback and capture using I2S2 with ADMAIF<i>.
Playback#
Playback using I2S2 with ADMAIF<I>:
amixer -c APE cset name="I2S2 Mux" ADMAIF<I>
aplay -D hw:APE,<I-1> <IN-WAV>
Capture#
Capture using I2S2 with ADMAIF<I>:
amixer -c APE cset name="ADMAIF<I> Mux" I2S2
arecord -D hw:APE,<I-1> -r <RATE> -c <CHANNELS> -f <SAMPLE-FORMAT> <OUT-WAV>
Internal Loopback#
Internal Loopback using I2S2 with ADMAIF<I>:
amixer -c APE cset name="I2S2 Mux" "ADMAIF<I>"
amixer -c APE cset name="ADMAIF<I> Mux" "I2S2"
amixer -c APE cset name="I2S2 Loopback" "on"
aplay -D hw:APE,<I-1> <IN-WAV> &
arecord -D hw:APE,<I-1> -r <RATE> -c <CHANNELS> -f <SAMPLE-FORMAT> <OUT-WAV>
Multi-Channel (TDM) Capture#
To perform TDM capture on I2S4 via ADMAIF, enter these commands:
amixer -c APE cset name="ADMAIF<I> Mux" "I2S4"
amixer -c APE cset name="I2S4 codec master mode" "cbs-cfs"
amixer -c APE cset name="I2S4 codec frame mode" "dsp-a"
amixer -c APE cset name="I2S4 FSYNC width" 0
arecord -D hw:APE,<I-1> -r <RATE> -c <CHANNELS> -f <SAMPLE-FORMAT> <OUT-WAV>
Where:
<i>and<i-1>respectively represent an ADMAIF instance number, and the number minus 1.The last digit of I2S4 may be changed to use a different channel.
Note that I2S4 frame mode and “I2S4 FSYNC Width” must be set to the data offset with regard to fsync and fsync width available from the I2S timing diagram in the codec data sheet. I2S4 clock mode must be set as per the mode of operation (master/slave). For more details on mixer controls, see Mixer Controls.
Examples: MVC#
The following examples show how to apply gain and to mute and unmute the stream. The MVC supports up to eight channels, with control of per-channel gain and mute/unmute.
Apply Gain to a Playback Stream#
This command model shows how to use the MVC module to control volume during playback on I2S:
amixer -c APE cset name="MVC1 Mux" ADMAIF<I>
amixer -c APE cset name="I2S1 Mux" MVC1
amixer -c APE cset name="MVC1 Volume" <Q8.24_VALUE>
aplay -D hw:APE,<I-1> <IN-WAV>
The MVC module supports per-channel volume control. That is, it can apply a different gain factor to each channel. To set per-channel volume, use this mixer control:
amixer -c APE cset name="MVC1 Channel<X> Volume" <Q8.24_VALUE>
Where <X> is the MVC channel number (1, 2 … 8).
Mute and Unmute Channels#
This example shows how to mute and unmute channels during I2S playback:
amixer -c APE cset name="MVC1 Mux" ADMAIF<I>
amixer -c APE cset name="I2S1 Mux" MVC1
amixer -c APE cset name="MVC1 Per Chan Mute Mask" <MASK>
aplay -D hw:APE,<I-1> <IN-WAV>
Where <MASK> is the mute/unmute mask value. The mask supports per-channel mute control. The mask’s value may be 0 to 255 (0x0 to 0xFF); to mute channel n of the stream, set bit n to 1.
Similarly to unmute channel n of the stream, set bit n to 0.
Examples: AMX#
These sections provide usage examples for multiplexing two and three streams and for demultiplexing one stereo stream into two mono streams.
Multiplexing Two Streams#
This example shows how to use the AMX module to multiplex two stereo streams, ADMAIF1 and ADAMIF2:
amixer -c APE cset name="AMX2 RX1 Mux" "ADMAIF1"
amixer -c APE cset name="AMX2 RX2 Mux" "ADMAIF2"
amixer -c APE cset name="AMX2 Output Audio Channels" 4
amixer -c APE cset name="ADMAIF<I> Mux" AMX2
amixer -c APE cset name="ADMAIF<I> Playback Audio Channels" 4
amixer -c APE cset name="ADMAIF<I> Capture Audio Channels" 4
amixer -c APE cset name="ADMAIF<I> Playback Client Channels" 4
amixer -c APE cset name="ADMAIF<I> Capture Client Channels" 4
amixer -c APE cset name="AMX2 RX1 Mux" "ADMAIF1"
amixer -c APE cset name="AMX2 Byte Map 0" 0
amixer -c APE cset name="AMX2 Byte Map 1" 1
amixer -c APE cset name="AMX2 Byte Map 2" 2
amixer -c APE cset name="AMX2 Byte Map 3" 3
amixer -c APE cset name="AMX2 Byte Map 4" 4
amixer -c APE cset name="AMX2 Byte Map 5" 5
amixer -c APE cset name="AMX2 Byte Map 6" 6
amixer -c APE cset name="AMX2 Byte Map 7" 7
amixer -c APE cset name="AMX2 Byte Map 8" 64
amixer -c APE cset name="AMX2 Byte Map 9" 65
amixer -c APE cset name="AMX2 Byte Map 10" 66
amixer -c APE cset name="AMX2 Byte Map 11" 67
amixer -c APE cset name="AMX2 Byte Map 12" 68
amixer -c APE cset name="AMX2 Byte Map 13" 69
amixer -c APE cset name="AMX2 Byte Map 14" 70
amixer -c APE cset name="AMX2 Byte Map 15" 71
aplay -D hw:APE,0 <IN1-WAV>
aplay -D hw:APE,1 <IN2-WAV>
arecord -D hw:APE,<I-1> -r 48000 -c 4 -f S16_LE <OUT-WAV>
Examples: ADX#
This example shows how to use the ADX module to demultiplex 16-bit stereo streams onto ADMAIF1 and ADMAIF2:
amixer -c APE cset name="ADX1 Mux" ADMAIF<i>
amixer -c APE cset name="ADX1 Input Audio Channels" 2
amixer -c APE cset name="ADMAIF1 Mux" "ADX1 TX1"
amixer -c APE cset name="ADMAIF2 Mux" "ADX1 TX2"
amixer -c APE cset name="ADX1 Output1 Audio Channels” 1
amixer -c APE cset name="ADX1 Output2 Audio Channels” 1
amixer -c APE cset name="ADX1 Byte Map 0" 0
amixer -c APE cset name="ADX1 Byte Map 1" 1
amixer -c APE cset name="ADX1 Byte Map 2" 2
amixer -c APE cset name="ADX1 Byte Map 3" 3
amixer -c APE cset name="ADX1 Byte Map 4" 64
amixer -c APE cset name="ADX1 Byte Map 5" 65
amixer -c APE cset name="ADX1 Byte Map 6" 66
amixer -c APE cset name="ADX1 Byte Map 7" 67
aplay -D hw:APE,<i-1> <INPUT-WAV>
arecord -D hw:APE,0 -r 48000 -c 1 -f S16_LE <OUT1-WAV>
arecord -D hw:APE,1 -r 48000 -c 1 -f S16_LE <OUT2-WAV>
Note
Update the ADX1 input port channels to 2 and 2 output port channels to 1 by updating the ADX1 DAI node in DT as mentioned in the section Definition of a DAI Node.
Examples: SFC#
This example shows how to perform sample rate conversion from 48000 to 44100 Hz and capture using ADMAIF2, where ADMAIF3 feeds the SFC1 and generates sample frequency-converted output:
amixer -c APE cset name="SFC1 Mux" ADMAIF3
amixer -c APE cset name="ADMAIF2 Mux" SFC1
amixer -c APE cset name="SFC1 Input Sample Rate" 48000
amixer -c APE cset name="SFC1 Output Sample Rate" 44100
aplay -D hw:APE,2 <INPUT-WAV>
arecord -D hw:APE,1 -r 44100 -c <CHANNELS> -f <SAMPLE-FORMAT> <OUT-WAV>
Note
Update the SFC1 input rate to 48000 and output rate to 44100 by updating the SFC1 DAI node in DT as mentioned in the section Definition of a DAI Node.
Examples: ASRC#
This example shows how to perform sample rate conversion from 8000 to 48000 Hz and capture using ADMAIF2, where ADMAIF3 feeds the ASRC1 and generates sample frequency-converted output:
$ amixer -c APE cset name="ASRC1 RX1 Mux" ADMAIF3
$ amixer -c APE cset name="ASRC1 Ratio1 Source" SW
$ amixer -c APE cset name="ASRC1 Ratio1" "0,715827882"
$ amixer -c APE cset name="ADMAIF2 Mux" "ASRC1 TX1"
$ aplay -D hw:APE,2 <in_wav>
$ arecord -D hw:APE,1 -r 48000 -c <channels> -f <sample_format> <out_wav>
Examples: Mixer#
This example shows how to mix two input streams to generate a single output stream using Adder1 of the Mixer module:
amixer -c APE cset name="MIXER1 RX1 Mux" ADMAIF1
amixer -c APE cset name="MIXER1 RX2 Mux" ADMAIF2
amixer -c APE cset name="MIXER1 Adder1 RX1" 1
amixer -c APE cset name="MIXER1 Adder1 RX2" 1
amixer -c APE cset name="MIXER1 Mixer Enable" 1
amixer -c APE cset name="ADMAIF3 Mux" MIXER1 TX1
aplay -D hw:APE,0 <INPUT-FILE1.WAV>
aplay -D hw:APE,1 <INPUT-FILE2.WAV>
arecord -D hw:APE,2 -r <RATE> -c <CHANNELS> -f <SAMPLE-FORMAT> <OUT-WAV>
Examples: HDMI/DP Playback#
This example shows how to perform playback on an HDMI/DP device (e.g. a monitor with speakers):
aplay -Dhw:HDA,<DEVICE-ID> <INPUT-WAV>
Examples: USB#
The following sections provide usage examples of playback and capture on USB.
Playback#
This example shows how to perform playback on a USB device:
aplay -Dhw:<CARD-ID>,<DEV-ID> <INPUT-WAV>
Capture#
This example shows how to perform capture on a USB device:
arecord -Dhw:<CARD-ID>,<DEV-ID> -r <RATE> -c <CHANNELS> -f <SAMPLE-FORMAT> <OUT-WAV>
Troubleshooting#
This section describes some issues that are liable to occur when you are working with ASoC drivers, and their probable causes and solutions.
No Sound Cards Found#
This has several possible causes. Some typical ones are described below. In most cases the dmesg output can provide clues.
Source/Sink Widget Not Found#
The dmesg output shows that “no source widget” or “no sink widget” was found, as shown in this example log:
dmesg | grep "ASoC"
tegra-asoc: sound: ASoC: no source widget found for x OUT
tegra-asoc: sound: ASoC: Failed to add route x OUT -> direct -> Headphone Jack
tegra-asoc: sound: ASoC: no sink widget found for x IN
tegra-asoc: sound: ASoC: Failed to add route Mic Jack -> direct -> x IN
In the above log, x OUT and x IN widgets are not found. ASoC may not have instantiated corresponding codecs. Confirm this by checking below:
cat /sys/kernel/debug/asoc/components
If the codec is not instantiated, it could be due to one of these reasons:
The codec is not enabled in the Linux kernel configuration. Enter these commands to determine whether the codec is enabled:
zcat /proc/config.gz | grep <CODEC_CONFIG>
Where
<CODEC_CONFIG>is the name of the config that represents the codec in config.gz. Users must define it if it is not already available, and you must ensure that it is enabled in the Linux kernel configuration.Enter below command to scan the desired I2C bus and confirm that the codec is being probed:
i2cdetect -y -r <I2C-BUS-NUMBER>
If the scan does not indicate that the codec is present, it could be due to a loose connection, or the codec could be connected to another I2C bus. To check for the latter cause, scan the rest of the available I2C buses, identify the bus that is connected to the codec, and place the codec device tree node in the that I2C bus’s DT node.
The widget’s prefix (
xin this case) is neither the same as the one specified in theprefixentry of the codec subnode of DAI link, nor the same as the one specified under thesound-name-prefixentry of the corresponding codec device node. In this case, edit or override the prefixes appropriately.
CPU DAI Not Registered#
The dmesg output shows that no “CPU DAI” was found:
dmesg | grep "ASoC"
tegra-asoc: sound: ASoC: CPU DAI DAP not registered
In this case, “DAP” is the CPU DAI for the I2S-to-codec DAI link.
The ASoC may not have instantiated the I2S codec. To determine whether the codec is instantiated, enter the command:
cat /sys/kernel/debug/asoc/components
If the I2S codec is instantiated, it has a name like <addr>.i2s, where
<addr> is the corresponding unit-address (i2s@<addr>) used in DT for the device.
Identifying the DAI link at the point of failure can give a clue to the I2S instance number that failed to instantiate. Accordingly, you can instantiate the I2S codec driver by providing a suitable entry point in the device tree structure (DTS) file as described in Codec Driver Instantiation Using Device Tree.
Sound Not Audible or Not Recorded#
Follow this procedure to diagnose the issue:
Determine whether the DAPM path is completed. User may need to set some codec-specific mixer controls to enable playback or capture. Get these settings from the codec vendor or from the codec data sheet. For tracing the DAPM path, DAPM tracing events must be enabled before user run the playback or capture use case using the command:
for i in `find /sys/kernel/debug/tracing/events -name "enable" | grep snd_soc_`; do echo 1 > $i; done
If the DAPM path is not complete, the use case cannot proceed. The DAPM path is populated in the file below as and when it is set up:
cat /sys/kernel/debug/tracing/trace_pipe | grep \*
Below is a complete sample DAPM path for recording through the microphone jack on IGX through an RT5640 audio codec, ADMAIF1, and I2S1. Another audio path will produce a similar dump, depending on the widgets defined in the path. Here is a filtered log for the sake of illustration:
snd_soc_dapm_path: *CVB-RT AIF1 Capture <- (direct) <- CVB-RT AIF1TX snd_soc_dapm_path: *CVB-RT AIF1 Capture -> (direct) -> rt5640-playback-capture snd_soc_dapm_path: *CVB-RT AIF1TX -> (direct) -> CVB-RT AIF1 Capture [ ... ] snd_soc_dapm_path: *CVB-RT IN1N -> (direct) -> CVB-RT BST1 snd_soc_dapm_path: *CVB-RT IN1P -> (direct) -> CVB-RT BST1 snd_soc_dapm_path: *CVB-RT IN2N -> (direct) -> CVB-RT BST2 snd_soc_dapm_path: *CVB-RT IN2N -> (direct) -> CVB-RT INR VOL snd_soc_dapm_path: *CVB-RT IN2P -> (direct) -> CVB-RT BST2 snd_soc_dapm_path: *CVB-RT IN2P -> (direct) -> CVB-RT INL VOL snd_soc_dapm_path: *CVB-RT Mic Jack -> (direct) -> CVB-RT IN1P snd_soc_dapm_path: *CVB-RT Mic Jack -> (direct) -> CVB-RT IN2P [ ... ] snd_soc_dapm_path: *I2S4 CIF-Capture <- (direct) <- I2S4 TX snd_soc_dapm_path: *I2S4 CIF-Capture -> (direct) -> tegra-dlink-64-capture snd_soc_dapm_path: *I2S4 DAP-Playback -> (direct) -> I2S4 TX snd_soc_dapm_path: *I2S4 DAP-Playback <- (direct) <- rt5640-playback-capture snd_soc_dapm_path: *I2S4 XBAR-Playback -> (direct) -> I2S4 XBAR-RX snd_soc_dapm_path: *I2S4 XBAR-Playback <- (direct) <- tegra-dlink-64-capture
Users must ensure that there is a valid DAPM path from source widgets to sink widgets. This dump gives a platform DAPM path involving all the components that get activated during a use case.
Confirm that the audio interface’s
statusproperty is set to"okay"in the appropriate device tree source file.For example, for IGX, the device tree file is at:
hardware/nvidia/t23x/nv-public/tegra234-p3701.dtsi
An alternative method is to use the following command to inspect the device tree entries from the target and find the
.dtsfile that has been flashed:dtc -I fs -O dts /proc/device-tree >/tmp/dt.log
Probe the audio signals with an oscilloscope.
For example, if using I2S, probe the frame sync (
FS) and bit clock (BCLK) to verify that the timings are correct. If the I2S is transmitting, probeFSandBCLKto verify that they are generated as desired.
I2S Software Reset Failed#
A common problem is that the I2S software reset fails when starting playback or capture via an I2S interface. Error messages like this one appear in the dmesg log:
tegra210-i2s 2901000.i2s: timeout: failed to reset I2S for playback
tegra210-i2s 2901000.i2s: ASoC: PRE_PMU: I2S1 RX event failed: -22
This problem occurs when the clock for the I2S interface is not active, and hence the software reset fails. It typically occurs when the I2S interface is the bit clock slave and hence the bit clock is provided by an external device such as a codec. If this problem occurs, check whether the bit clock is being enabled when the playback or capture is initiated.
XRUN Observed During Playback or Capture#
An XRUN is either an underrun (on playback) or overrun (on capture) of the audio circular buffer.
In the case of playback, the CPU writes to the audio circular buffer. The DMA reads it and sends the data to the appropriate audio interface (I2S, etc.) through the AHUB.
In the case of capture, the DMA writes data received from the AHUB to the audio circular buffer, and the CPU reads it.
An XRUN event typically indicates that the CPU is unable to keep up with the DMA. In the case of playback, the DMA reads stale data. In the case of capture, data is lost. Hence, an XRUN event can signify a system performance or latency issue, which can have many different causes.
If an XRUN occurs, try these measures to determine whether there is a performance issue:
Enable maximum performance by running jetson_clocks.sh. This script is in the user home directory on the IGX device’s root file system.
Use a RAM file system for reading and writing the audio data. The default root file system format for IGX devices is EXT4 with journaling enabled. Latencies have been observed with journaling file systems such as EXT4, and can lead to XRUN events. Enter these commands to create a simple 100MB RAM file system:
sudo mkdir /mnt/ramfs sudo mount -t tmpfs -o size=100m tmpfs /mnt/ramfs
User can increase the size of the audio circular buffer to reduce the impact of system latencies. The default size of the buffer is 32KB. The buffer size is specified by the
buffer_bytes_maxmember of the structuretegra_alt_pcm_hardwarein the Linux kernel source file:cat kernel/3rdparty/canonical/linux-jammy/kernel-source/sound/soc/tegra/tegra_pcm.c
Audio Pops and Clicks#
Pops and clicks may occur at the start or end of playback or capture because I2S starts transmitting or receiving data before the codec is completely powered up or down.
The following command delays transmission or reception of data by a specified number of milliseconds:
echo 10 | sudo tee /sys/kernel/debug/asoc/APE/dapm_pop_time
Get More Help on NVIDIA Developer Forum#
If none of the preceding steps help, post a query to the appropriate section of the NVIDIA Developer Forum, providing the following information:
Conditions in which the problem manifests, such as sampling rate and sample width, along with the audio files used and generated.
Mixer control settings. Enter this command to display the settings:
amixer - c <cardID> contents > ~/settings.txt
Kernel log. Enter this command to display it:
dmesg > ~/kernel_log
Device tree log. Enter this command to display it:
dtc -I fs -O dts /proc/device-tree >/tmp/dt.log
Oscilloscope snapshots at an appropriate resolution, with and without the codec.
Register dump of I2S being used while running the use case, for example:
cat /sys/kernel/debug/regmap/<ADDR>.i2s/registers > ~/reg_dump
where <ADDR> is the unit-address of I2S device (i2s@<ADDR>) in DT. Use the same for lookup of corresponding regmap path.