How to "loopback" an audio stream and arecord it.

I have a setup

amixer sset "MIXER1-1 Mux" "ADMAIF9"
amixer sset "AMX1-1 Mux" "MIXER1-1"
amixer sset "I2S1 Mux" "AMX1"
amixer sset "Adder1 RX1" on
amixer sset "Adder1 RX2" on
amixer sset "Mixer Enable" on

When I play a wav file

aplay -D hw:0,8 -c 1 -f S32_LE /root/n51441.wav

I am able to see signal coming out of the I2S1 bus (dout and f-sync, etc.).

I would like to “loopback” the stream and record it with arecord. Here is what I tried:

amixer sset "ADMAIF1 Mux" "I2S1"  // I2S1 --> ADMAIF1
arecord -D hw:0,1 -f dat -d 10  /tmp/test-mic.wav

It did not seems to work. Please advise on how to do that. Thanks in advance.

Jin

correction. I actually tried

amixer sset "ADMAIF1 Mux" "I2S1"  // I2S1 --> ADMAIF1
arecord -D hw:0,0 -f dat -d 20  /tmp/test-mic.wav   // record from ADMAIF1

I got a wav file but it does not have much in it.

Note that for simple playback you only need …

amixer sset "I2S1 Mux" "ADMAIF9"

Unless you need to use the AMX and MIXER components.

Can you try setting …

amixer sset "I2S1 Loopback" "on"

Regards,
Jon

Jon,

Thanks. The loopback works with I2S1 loopback on. I noticed that the file I played has 5.1 surround sound in it, but the recorded wav file only contain 2 channels. Any idea?

Thanks again.

Jin

Hi Jin,

So 5.1 channels, implies that there are 6 channels. When using aplay and arecord, make sure you set the number of channels to 6. In other words, ‘-c 6’.

Regards,
Jon

Jon,

Thanks. Instead of internal “loopback” which works, I would like to do an external loopback with my system configured as

I2S1 ---- dout ----> external loopback — din —> I2S1

In words, I want to aplay a wav file out of I2S1 (dout) and capture it on I2S1 (din). I used the same amixer commands as above, rewritten here:

amixer sset "MIXER1-1 Mux" "ADMAIF9"
amixer sset "AMX1-1 Mux" "MIXER1-1"
amixer sset "I2S1 Mux" "AMX1"
amixer sset "Adder1 RX1" on
amixer sset "Adder1 RX2" on
amixer sset "Mixer Enable" on
amixer sset "ADMAIF1 Mux" "I2S1"

and aplay and arecord like this

arecord -D hw:0,1 -f dat -d 70  /tmp/capture.wav
aplay -D hw:0,8 -c 6 -f S32_LE /root/n51441.wav

I did not set

amixer sset "I2S1 Loopback" "on"

Because I think that is for internal loop.

I can see signals on both din and dout, but the capture.wav was empty. Was my setup not correct?

Hi Jin,

Given that you are recording from ‘ADMAIF1 Mux’, you should be using ‘hw:0,0’ for recording …

arecord -D hw:0,0 -f dat -d 70  /tmp/capture.wav

Regards,
Jon

Jon,

I am able to capture with loop back. But somehow, when I play the attached wav file that includes 5.1 surround sound as

aplay -D hw:0,8 -c 6 -f S32_LE /root/n51441.wav

I only capture 2 channels. I verified that with a scope on the I2S1’s dout; I can see that within one f-sync period, I only have one or two channels. Can you see if my control is properly configured. And see if you can play this short wav file and be able to see 6 channels.

n51441.wav.tar.gz (7.28 MB)

Attachment

The amixer controls for the vaw file playing is listed above.

attached is my amixer setting obtained with

amixer -c 0 scontents > alsa-settings.txt

Maybe I need to “enable” a “surround sound” mode somewhere?

Thanks again.

Jin

alsa-settings.txt.tar.gz (5.32 KB)

alsa-settings.txt

Hi Jin,

To play multi-channel audio via the I2S interface, you need to configure the I2S for TDM mode (ie. dsp-a or dsp-b mode). This can be configured by either device-tree for the I2S interface or if you have the latest L4T release you should be able to set via …

amixer -c 0 cset name='I2S1 codec frame mode' 'dsp-a'
amixer -c 0 cset name='I2S1 fsync width' 0

Make sure that you set the number of channels to capture as 6.

How many channels does aplay state that it is playing?

Regards,
Jon

Jon,

Thanks. I checked the dts file where the TDM mode (format) appears to be fine:

nvidia,dai-link-3 {
                        link-name = "dummy-playback";
                        cpu-dai = <0x97>;
                        codec-dai = <0x98>;
                        cpu-dai-name = "I2S1";
                        codec-dai-name = "dit-hifi";
                        tx-mask = <0xff>;
                        rx-mask = <0xff>;
                        format = "dsp_a";
                        bitclock-slave;
                        frame-slave;
                        bitclock-noninversion;
                        frame-noninversion;
                        bit-format = "s32_le";
                        bclk_ratio = <0x1>;
                        srate = <0xbb80>;
                        num-channel = <0x8>;
                        name-prefix = [64 00];
                };

I am not able to run

root@nvidia:/# amixer -c 0 cset name='I2S1 fsync width' 0
amixer: Cannot find the given element from control hw:0

Also, aplay sated 6 channels:

root@nvidia:~#  aplay -D hw:0,8 -c 6 -f S32_LE /root/n51441.wav
Warning: format is changed to S16_LE
Playing WAVE '/root/n51441.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Channels 6

My scope displayed clearly two “chunks” (channels) instead of 6 channels in a TDM frame on I2S1 dout line. My capture command is

arecord -D hw:0,0 -c 6 -f dat -d 70  /tmp/test-mic.wav

Anything else I can do to check it.

Thanks again.

Jin

Hi Jin,

Can you attach your complete DT source showing all the nvidia,dai-link properties? Any chance you have more than one link with I2S1 as the cpu-dai?

While the audio is playing can you dump the I2S registers using the following command and attach as well?

sudo cat /sys/kernel/debug/regmap/tegra186-i2s.0/registers

I checked the latest L4T rel28 for TX2 and it does not have the mixer control for ‘I2S1 fsync width’ and so yes that will not work indeed. Don’t worry about this for now.

Regards,
Jon

Jon,

Thanks so much. Attached is the entire device tree showing all the nvidia,dai-link properties:

So while playing the wav file

root@nvidia:~# aplay -D hw:0,8 -c 6 -f S32_LE /root/n51441.wav
Warning: format is changed to S16_LE
Playing WAVE '/root/n51441.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Channels 6

I got

root@nvidia:~# cat /sys/kernel/debug/regmap/tegra210-i2s.0/registers
00: 00000001
04: 00000000
0c: 00000001
10: 0000000c
14: 00000003
18: 00000000
1c: 00000000
20: 03777700
24: 00000100
28: 000000ff
2c: 00000000
34: 00000000
40: 00000000
44: 00000000
4c: 00000002
50: 00000000
54: 00000003
58: 00000000
5c: 00000000
60: 00007700
64: 00000100
68: 000000ff
6c: 00000000
74: 00000000
80: 00000001
84: 00000000
88: 00000001
8c: 00000000
90: 00000c00
a0: 1f001407
a4: 000000ff
a8: 00000007
ac: 00000000
b0: 00000000

Attached is also the screen shot of the I2S1, and you can see only 2 channels are on the dout. The wav file was attached earlier in this thread. Let me know if you can find anything. Thanks again.
attachment.tar.gz (4.64 MB)

Hi Jin,

Looking at the I2S configuration, it appears to be configured for 8 channels and not 6. What does the following command show …

file /root/n51441.wav

The I2S configuration shows that there are 32-bits for the frame-sync. Do you see 32-bits of data on dout? I am wondering if you are only seeing 1 channel on dout and not two.

Regards,
Jon

Jon,

I have

root@nvidia:~#     file /root/n51441.wav
/root/n51441.wav: RIFF (little-endian) data, WAVE audio, 6 channels 44100 Hz

I see 32 bits for the f-sync and I see two channels, each 16 bits. See the attached zoom-in scope shot. I confirmed that by playing a single channel wav, which only occupy half of the f-sync.

Hi Jin,

I think that the problem is mostly likely because you are using the ‘nvidia,tegra-audio-t186ref-p2382’ driver. For L4T we do all the validation with the ‘nvidia,tegra-audio-t186ref-mobile-rt565x’ machine driver. I believe that because you are using driver and you have 8 channels specified in the device-tree file it is using 8 channels (which is what I see in the I2S registers). So I recommend that you use the ‘nvidia,tegra-audio-t186ref-mobile-rt565x’ driver.

What version of L4T are you using? The frame-sync appears to be inverted which indicates that you may not have the latest L4T release for TX2 which is rel28.2. I recommend that you use this version as well.

Regards,
Jon