Skip to content

Commit

Permalink
ASoC: rockchip: Add support for Digital Loopback
Browse files Browse the repository at this point in the history
This patch add support for DMA-based digital loopback.

BACKGROUND
Audio Products with AEC require loopback for echo cancellation.
the hardware LP is not always available on some products, maybe
the HW limitation(such as internal acodec) or HW Cost-down.

This patch add support software DLP for such products.

Enable:

  CONFIG_SND_SOC_ROCKCHIP_DLP

  &i2s {
      rockchip,digital-loopback;
  };

Mode List:

  amixer contents
  numid=2,iface=MIXER,name='Software Digital Loopback Mode'
    ; type=ENUMERATED,access=rw------,values=1,items=7
    ; Item #0 'Disabled'
    ; Item #1 '2CH: 1 Loopback + 1 Mic'
    ; Item #2 '2CH: 1 Mic + 1 Loopback'
    ; Item #3 '2CH: 1 Mic + 1 Loopback-mixed'
    ; Item #4 '2CH: 2 Loopbacks'
    ; Item #5 '4CH: 2 Mics + 2 Loopbacks'
    ; Item #6 '4CH: 2 Mics + 1 Loopback-mixed'
    : values=0

Testenv:

wired SDO0 --> SDI0 directly to get external digital loopback
as reference.

Testcase: dlp.sh

  /#!/bin/sh

  item=0
  id=`amixer contents | grep "Software Digital Loopback" | \
      awk -F ',' '{print $1}'`

  items=`amixer contents | grep -A 1 "Software Digital Loopback" | \
         grep items | awk -F 'items=' '{print $2}'`

  echo "Software Digital Loopback: $id, items: $items"

  mode_chs() {
          case $1 in
          [0-4])
                  echo "2"
                  ;;
          [5-6])
                  echo "4"
                  ;;
          *)
                  echo "2"
                  ;;
          esac
  }

  while true
  do
          ch=`mode_chs $item`
          amixer -c 0 cset $id $item
          arecord -D hw:0,0 --period-size=1024 --buffer-size=4096 -r 48000 -c $ch -f s16_le \
                  -d 15 sine/dlp_$item.wav &
          sleep 2
          for i in $(seq 1 10)
          do
                  aplay -D hw:0,0 --period-size=1024 --buffer-size=8192 $((ch))ch.wav -d 1
          done
          pid=$(ps | egrep "aplay|arecord" | grep -v grep | awk '{print $1}' | sort -r)
          for p in $pid
          do
                  wait $p 2>/dev/null
          done
          item=$((item+1))
          if [ $item -ge $items ]; then
                  sleep 1
                  break
          fi
  done
  echo "Done"

Result:

do shell test and verify dlp_x.wav:

* Alignment: ~1 samples shift (loopback <-> mics).
* Integrity: no giltch, no data lost.
* AEC: align loopback and mics sample and do simple AEC, get clean
  waveform.

Logs:
...
numid=2,iface=MIXER,name='Software Digital Loopback Mode'
  ; type=ENUMERATED,access=rw------,values=1,items=7
  ; Item #0 'Disabled'
  ; Item #1 '2CH: 1 Loopback + 1 Mic'
  ; Item #2 '2CH: 1 Mic + 1 Loopback'
  ; Item #3 '2CH: 1 Mic + 1 Loopback-mixed'
  ; Item #4 '2CH: 2 Loopbacks'
  ; Item #5 '4CH: 2 Mics + 2 Loopbacks'
  ; Item #6 '4CH: 2 Mics + 1 Loopback-mixed'
  : values=2
Recording WAVE 'sine/dlp_2.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Playing WAVE '2ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Playing WAVE '2ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Playing WAVE '2ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Playing WAVE '2ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Playing WAVE '2ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Playing WAVE '2ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Playing WAVE '2ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Playing WAVE '2ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Playing WAVE '2ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
Playing WAVE '2ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
...
numid=2,iface=MIXER,name='Software Digital Loopback Mode'
  ; type=ENUMERATED,access=rw------,values=1,items=7
  ; Item #0 'Disabled'
  ; Item #1 '2CH: 1 Loopback + 1 Mic'
  ; Item #2 '2CH: 1 Mic + 1 Loopback'
  ; Item #3 '2CH: 1 Mic + 1 Loopback-mixed'
  ; Item #4 '2CH: 2 Loopbacks'
  ; Item #5 '4CH: 2 Mics + 2 Loopbacks'
  ; Item #6 '4CH: 2 Mics + 1 Loopback-mixed'
  : values=6
Recording WAVE 'sine/dlp_6.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 4
Playing WAVE '4ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 4
Playing WAVE '4ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 4
Playing WAVE '4ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 4
Playing WAVE '4ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 4
Playing WAVE '4ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 4
Playing WAVE '4ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 4
Playing WAVE '4ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 4
Playing WAVE '4ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 4
Playing WAVE '4ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 4
Playing WAVE '4ch.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Channels 4
Done

Signed-off-by: Sugar Zhang <[email protected]>
Change-Id: I5772f0694f7a14a0f0bd1f0777b6c4cdbd781a64
  • Loading branch information
Sugar Zhang authored and rkhuangtao committed Jul 20, 2022
1 parent ba8a6e6 commit 9975bc5
Show file tree
Hide file tree
Showing 4 changed files with 1,116 additions and 0 deletions.
7 changes: 7 additions & 0 deletions sound/soc/rockchip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ config SND_SOC_ROCKCHIP
the Rockchip SoCs' Audio interfaces. You will also need to
select the audio interfaces to support below.

config SND_SOC_ROCKCHIP_DLP
tristate "Rockchip Digital Loopback Driver"
depends on SND_SOC_ROCKCHIP
help
Say Y or M if you want to add support for DLP driver for
Rockchip DMA-Based Digital Loopback.

config SND_SOC_ROCKCHIP_I2S
tristate "Rockchip I2S Device Driver"
depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
Expand Down
2 changes: 2 additions & 0 deletions sound/soc/rockchip/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
# ROCKCHIP Platform Support
snd-soc-rockchip-dlp-objs := rockchip_dlp.o
snd-soc-rockchip-i2s-objs := rockchip_i2s.o
snd-soc-rockchip-i2s-tdm-objs := rockchip_i2s_tdm.o
snd-soc-rockchip-multi-dais-objs := rockchip_multi_dais.o rockchip_multi_dais_pcm.o
Expand All @@ -14,6 +15,7 @@ snd-soc-rockchip-vad-$(CONFIG_ARM64) += vad_preprocess_arm64.o
snd-soc-rockchip-vad-$(CONFIG_ARM) += vad_preprocess_arm.o
endif

obj-$(CONFIG_SND_SOC_ROCKCHIP_DLP) += snd-soc-rockchip-dlp.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-rockchip-i2s.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S_TDM) += snd-soc-rockchip-i2s-tdm.o
obj-$(CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS) += snd-soc-rockchip-multi-dais.o
Expand Down
Loading

0 comments on commit 9975bc5

Please sign in to comment.