I want to keep the latency of I2S audio capture/playback constant

In the following environment, when outputting audio data to I2S and inputting loopback data, Latency may fluctuate by 1 sample.

  • Target: Jetson AGX Orin
  • OS: R35 (release), REVISION: 3.1
  • Audio device: I2S2, 40-pin GPIO expander header, Connect DIN and DOUT for Loopback

ALSA configuration is below:

amixer -c APE cset name=“I2S2 codec frame mode” dsp-b
amixer -c APE cset name=“I2S2 Capture Audio Bit Format” 32
amixer -c APE cset name=“I2S2 Playback Audio Bit Format” 32
amixer -c APE cset name=“I2S2 Client Bit Format” 16
amixer -c APE cset name=“I2S2 Capture Audio Channels” 16
amixer -c APE cset name=“I2S2 Playback Audio Channels” 16
amixer -c APE cset name=“I2S2 Client Channels” 16
amixer -c APE cset name=“I2S2 FSYNC Width” 15
amixer -c APE cset name=“I2S2 Sample Rate” 48000
amixer -c APE cset name=“I2S2 Mux” ADMAIF2
amixer -c APE cset name=“ADMAIF2 Mux” I2S2
amixer -c APE cset name=“I2S2 Loopback” off

The I2S capture and playback devices are synchronized by calling the alsa_snd_pcm_link() ALSA API.
I want the input/output latency to remain constant.
However, the latency changes when the stream is opened.
When inputting/outputting 8 samples at a time, the latency may be 17 samples or 18 samples.

Is there a solution for this latency variation?
Or I want to know the cause.

Hi kenichi.shibata,

Welcome to the Jetson Developer Forum!

In HW, snd_pcm_link API won’t ensure that playback and capture paths DMAs are synchronized.

Before I answer your query further, I have few questions:
Q. How are you measuring the latency?
Q. Are you playing a silence file for measurement? if so, avoid that and ensuring first capture sample as valid (non zero) to measure real loopback latency. Also, start capture path first (before playback).

Thank you for answering

Writes all 1.0 data to the playback device.
The captured data may fluctuate by 1 sample as shown below.

Looking at the documentation below, it seems that I2S has a FIFO inside the SoC.

data flow:
Application <=> ALSA <=> ADMAIF(DMA) <=> I2S(FIFO)

It seems that the input/output to the I2S FIFO also needs to be synchronized.

Is it possible to match the start timing of capture and playback in units of 1 sample in terms of hardware?
Also, is there a way to set it?

I made a sample code to measure Latency.

  1. I2S Pinmux configuration

    sudo /opt/nvidia/jetson-io/jetson-io.py
    

    Assign i2s2 to Pin 12,35,38,40

  2. Connect pins 40 and 38 with a jumper wire for loopback

  3. pyaudio install

    pip3 install pyaudio
    
  4. ALSA setup

    unzip setup_i2s_loopback_16ch_16bit.sh.zip
    bash setup_i2s_loopback_16ch_16bit.sh
    
  5. Latency measure
    unzip measure_latency.py.zip python3 measure_latency.py

Latency will be 513 or 514 sample in this sample code.
I would like to know how to synchronize the input and output to keep the Latency constant.
setup_i2s_loopback_16ch_16bit.sh.zip (677 Bytes)
measure_latency.py.zip (741 Bytes)

Connect pins 40 and 38 with a jumper wire for loopback

What you are trying is external loopback (using Wire). I2S has internal flow control for capture and playback paths. It is not possible to do something in HW at FIFO level for playback and capture synchronization since both these paths are independent.

I am not sure what is the end usecase here. Could you explain a bit more on the usecase may be we could help you with and alternate approach.

Used for ANC (Active Noise Control).
Therefore, it is necessary to always output the sound of the secondary sound source with constant latency to the input sound from the reference microphone.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.