Monday 13 July 2020

Topping E30: another DAC for linux/RPi

The Topping brand has put out various well received budget Chi-fi units over the last few years, and of interest to me, with various USB enabled DACs such as the D90, D50s and so forth. The most recent addition as of Q2 2020, the Topping E30 is a hi-res DAC with an all metal case, requiring 5v ~1A via by a 2.1mm barrel jack. The E30 has traditional inputs and outputs: toslink/coax and USB digital input and RCA out and crucially for me, without the bloat of a headphone amp or bluetooth receiver- a pure DAC.



How does it work with Linux and a RPi music server running forked-daapd.

A few more words on the specification of the E30:
  • USB - supports up to 32bit/44.1-768Khz PCM, DSD (native/DoP) 64-512 / 64-256
  • optical/coaxial - supports 16-24bit/44.1-192Khz PCM
via an XU208 USB receiveer and an AK4493 DAC chip.

Connectivity to my Linux boxes will be via USB and its important to note the supported USB details: up to 32bit.

On Linux

On attaching to my Linux hosts, 4.9.x and 5.1.x kernels, the E30 is recognised.
$ dmesg
...
[188876.320561] usb 1-2: new high-speed USB device number 46 using ehci-pci
[188876.336658] usb 1-2: New USB device found, idVendor=152a, idProduct=8750, bcdDevice= 1.08
[188876.336673] usb 1-2: New USB device strings: Mfr=1, Product=3, SerialNumber=0
[188876.336682] usb 1-2: Product: E30
[188876.336691] usb 1-2: Manufacturer: Topping
[188877.507922] usb 1-2: 1:3 : unsupported format bits 0x100000000
[188877.527899] usbcore: registered new interface driver snd-usb-audio

$ lsusb
...
Bus 001 Device 048: ID 152a:8750 Thesycon Systemsoftware & Consulting GmbH E30
The serial number is not encoded but the box notes that this is 2006xxx unit which fixes, both in hardware and firemware, a reverse polarity issue that was in the early batches (serial# below 2004xxxx).

Basic ALSA validation, we see aplay -l and aplay -L give us the card number, in this case card#1, and the device alias as hw:CARD=E30. We do notice that the mixer name is a little annoying, with a trailing whitespace.

# device shows as second alsa soundcard, 'hw:1' or 'hw:CARD=E30'
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
...
card 1: E30 [E30], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0

$ aplay -L
...
default:CARD=E30
E30, USB Audio
Default Audio Device
...
hw:CARD=E30,DEV=0
E30, USB Audio
Direct hardware device without any conversions
plughw:CARD=E30,DEV=0
E30, USB Audio
Hardware device with all software conversions

# notice the mixer name and trailing whitespace
$ amixer -c 1
Simple mixer control 'E30 ',0
Capabilities: pvolume pvolume-joined pswitch pswitch-joined
Playback channels: Mono
Limits: Playback 0 - 127
Mono: Playback 127 [100%] [0.00dB] [on]
Whilst this is the only additional soundcard to be added to the Linux box it's nevertheless safer to use the ALSA device alias when referring to the card to avoid different hw:??? assignments.

When looking at the supported bit rates and formats, we notice that the device only supports 32bit, 44.1-768Khz - note the unit spec above; up to 32bit. Now its not clear whether this is a Linux driver issue or whether this is how the device works and/or whether this makes a difference. Certainly my AlloBoss dac natively supports SE16,24 and 32.
$ cat /proc/asound/E30/stream0
Topping E30 at usb-0000:01:00.0-1.4, high speed : USB Audio

Playback:
Status: Stop
Interface 1
Altset 1
Format: S32_LE
Channels: 2
Endpoint: 1 OUT (ASYNC)
Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000
Data packet interval: 125 us
Interface 1
Altset 2
Format: S32_LE
Channels: 2
Endpoint: 1 OUT (ASYNC)
Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000
Data packet interval: 125 us
Interface 1
Altset 3
Format: SPECIAL DSD_U32_BE
Channels: 2
Endpoint: 1 OUT (ASYNC)
Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000
Data packet interval: 125 us

For comparison, this is a cheap USB DAC on another RPi that also natively supports 16 and 24bit.
C-Media Electronics Inc. USB Advanced Audio Device at usb-20980000.usb-1.3, ful : USB Audio

Playback:
Status: Stop
Interface 1
Altset 1
Format: S16_LE
Channels: 2
Endpoint: 1 OUT (SYNC)
Rates: 44100, 48000
Interface 1
Altset 2
Format: S24_3LE
Channels: 2
Endpoint: 1 OUT (SYNC)
Rates: 44100, 48000
Interface 1
Altset 3
Format: S16_LE
Channels: 2
Endpoint: 1 OUT (SYNC)
Rates: 88200, 96000
Interface 1
Altset 4
Format: S24_3LE
Channels: 2
Endpoint: 1 OUT (SYNC)
Rates: 88200, 96000
...
What this means in practise is that we cannot use the ASLA hw:E30 (direct h/w access) but rather plughw:E30 that implements sample format and potential sample rate conversion.

Furthmore, the E30 does not support concurrent playback which is potentially an issue for forked-daapd.


# only support S32_LE with direct h/w access
$ sox -n -c 2 -r 44100 -b 32 -C 128 /tmp/sine441.wav synth 10 sin 500-100 fade h 1 0 1

$ aplay -v -Dhw:CARD=E30 /tmp/sine441.wav &
Playing WAVE '/tmp/sine441.wav' : Signed 32 bit Little Endian, Rate 44100 Hz, Stereo
Hardware PCM card 1 'E30' device 0 subdevice 0
Its setup is:
stream : PLAYBACK
access : RW_INTERLEAVED
format : S32_LE
subformat : STD
channels : 2
rate : 44100
exact rate : 44100 (44100/1)
msbits : 32
buffer_size : 22050
period_size : 5513
period_time : 125011
tstamp_mode : NONE
tstamp_type : MONOTONIC
period_step : 1
avail_min : 5513
period_event : 0
start_threshold : 22050
stop_threshold : 22050
silence_threshold: 0
silence_size : 0
boundary : 6206523236469964800
appl_ptr : 0
hw_ptr : 0

# try concurrently
$ aplay -v -Dhw:CARD=E30 /tmp/sine441.wav
aplay: main:828: audio open error: Device or resource busy

Power Saving

When optical or coaxial is plugged into the E30, the unit can auto-wakeup and shutdown once no signal is detected, showing Err for a short while before going into power save. A minor tweak is reqired with the udev rules to acheive this with USB connected to Linux.
$ sudo vi /etc/udev/rules.d/topping-e30.rules
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="152a", ATTR{idProduct}=="8750", TEST=="power/control", ATTR{power/control}="auto"

$ sudo udevadm control --reload-rules

forked-daapd

Making the E30 available to forked-daapd is relatively simple, adding the following to the config file and restarting:
alsa "plughw:E30" {
nickname = "Topping E30"
mixer = "E30 "
mixer_device = "hw:E30"
}
Once forked-daapd is restarted we can select the E30 as an additional output source.

Concurrent Playback

The E30 does not support concurrent playback - with forked-daapd this currently gives us a little problem in that audio at the end of the track can be truncated/dropped. To resolve this, we can create an ALSA software muxing device for the server but this does have the limitation of a fixed sample rate. However, we can add this as an additional output to allow us to dynamically choose between the E30 outputs.
# /etc/asound.conf
pcm.E30 {
type plug
slave.pcm "E30dmix"
hint.description "Topping E30 DAC s/w dmix enabled device"
}

pcm.E30dmix {
type dmix
ipc_key 1025
ipc_key_add_uid false
ipc_perm 0666
slave {
pcm "hw:E30"
period_time 0
period_size 4096
buffer_size 22052
rate 44100
}
hint.description "Topping E30 DAC s/w dmix device"
}

ctl.E30mix {
type hw
card "E30"
}

# /etc/forked-daapd.conf
alsa "E30" {
nickname = "Topping E30 concurrent"
mixer = "E30 "
mixer_device = "hw:E30"
}

No comments:

Post a Comment