You are not logged in.

#1 2019-04-16 22:06:14

mkbodanu4
Member
Registered: 2016-10-31
Posts: 5

PulseAudio with external DAC over S/PDIF - can't set sample format

Recently got new external DAC - FX-Audio DAC-x6 and connected it to my PC (Z270 motherboard with Realtek ALC1220 Audio Codec) using Toslink optical fibre. Due specifications DAC supports up to 24-bits/192kHz over S/PDIF, and in Windows 10 it works perfectly.

But something strange I see in Arch Linux - while in configuration default-sample-format is s24le:

resample-method = speex-float-10
default-sample-format = s24le
default-sample-rate = 192000
alternate-sample-rate = 48000

PulseAudio showing sample format S32_LE (32-bits):

$ pacmd list-sinks

2 sink(s) available.
...
* index: 1
	name: <alsa_output.pci-0000_00_1f.3.iec958-stereo>
	driver: <module-alsa-card.c>
	flags: HARDWARE HW_MUTE_CTRL DECIBEL_VOLUME LATENCY DYNAMIC_LATENCY
	state: SUSPENDED
	suspend cause: IDLE
	priority: 9038
	volume: front-left: 21982 /  34% / -28,46 dB,   front-right: 21982 /  34% / -28,46 dB
	        balance 0,00
	base volume: 65536 / 100% / 0,00 dB
	volume steps: 65537
	muted: no
	current latency: 0,00 ms
	max request: 0 KiB
	max rewind: 0 KiB
	monitor source: 1
	sample spec: s32le 2кан. 192000Гц
	channel map: front-left,front-right
	             Стерео
	used by: 0
	linked by: 0
	configured latency: 0,00 ms; range is 0,50 .. 2000,00 ms
	card: 1 <alsa_card.pci-0000_00_1f.3>
	module: 7
	properties:
		alsa.resolution_bits = "32"
		device.api = "alsa"
		device.class = "sound"
		alsa.class = "generic"
		alsa.subclass = "generic-mix"
		alsa.name = "ALC1220 Digital"
		alsa.id = "ALC1220 Digital"
		alsa.subdevice = "0"
		alsa.subdevice_name = "subdevice #0"
		alsa.device = "1"
		alsa.card = "0"
		alsa.card_name = "HDA Intel PCH"
		alsa.long_card_name = "HDA Intel PCH at 0x2ffff20000 irq 130"
		alsa.driver_name = "snd_hda_intel"
		device.bus_path = "pci-0000:00:1f.3"
		sysfs.path = "/devices/pci0000:00/0000:00:1f.3/sound/card0"
		device.bus = "pci"
		device.vendor.id = "8086"
		device.vendor.name = "Intel Corporation"
		device.product.id = "a2f0"
		device.product.name = "200 Series PCH HD Audio"
		device.form_factor = "internal"
		device.string = "iec958:0"
		device.buffering.buffer_size = "3072000"
		device.buffering.fragment_size = "1536000"
		device.access_mode = "mmap+timer"
		device.profile.name = "iec958-stereo"
		device.profile.description = "Цифрове стерео (IEC958)"
		device.description = "Вбудоване аудіо Цифрове стерео (IEC958)"
		alsa.mixer_name = "Realtek ALC1220"
		alsa.components = "HDA:10ec1220,18491220,00100003"
		module-udev-detect.discovered = "1"
		device.icon_name = "audio-card-pci"
	ports:
		iec958-stereo-output: Цифровий вихід (S/PDIF) (priority 0, latency offset 0 usec, available: unknown)
			properties:
				
	active port: <iec958-stereo-output>

If play FLAC (24/96) - sound output params will be next:

$ cat /proc/asound/card0/pcm1p/sub0/hw_params 
access: MMAP_INTERLEAVED
format: S32_LE
subformat: STD
channels: 2
rate: 192000 (192000/1)
period_size: 192000
buffer_size: 384000

codec details:

$ cat /proc/asound/card0/codec#0
Codec: Realtek ALC1220
Address: 0
AFG Function Id: 0x1 (unsol 1)
Vendor Id: 0x10ec1220
Subsystem Id: 0x18491220
Revision Id: 0x100003
No Modem Function Group found
Default PCM:
    rates [0x5f0]: 32000 44100 48000 88200 96000 192000
    bits [0xe]: 16 20 24
    formats [0x1]: PCM
Default Amp-In caps: N/A
Default Amp-Out caps: N/A
State of AFG node 0x01:
  Power states:  D0 D1 D2 D3 D3cold CLKSTOP EPSS
  Power: setting=D0, actual=D0
GPIO: io=8, o=0, i=0, unsolicited=1, wake=0
  IO[0]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[1]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[2]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[3]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[4]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[5]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[6]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[7]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
...
Node 0x06 [Audio Output] wcaps 0x611: Stereo Digital
  Control: name="IEC958 Playback Con Mask", index=0, device=0
  Control: name="IEC958 Playback Pro Mask", index=0, device=0
  Control: name="IEC958 Playback Default", index=0, device=0
  Control: name="IEC958 Playback Switch", index=0, device=0
  Control: name="IEC958 Default PCM Playback Switch", index=0, device=0
  Device: name="ALC1220 Digital", type="SPDIF", device=1
  Converter: stream=1, channel=0
  Digital: Enabled GenLevel
  Digital category: 0x2
  IEC Coding Type: 0x0
  PCM:
    rates [0x5f0]: 32000 44100 48000 88200 96000 192000
    bits [0xe]: 16 20 24
    formats [0x1]: PCM
  Power states:  D0 D1 D2 D3 EPSS
  Power: setting=D0, actual=D0

If run pulseaudio server in debug mode - in log shown that server tried to set 24-bit format but device doesn't support it:

$ pulseaudio -vvvv
...
D: [pulseaudio] alsa-util.c: Trying iec958:0 with SND_PCM_NO_AUTO_FORMAT ...
D: [pulseaudio] alsa-util.c: Managed to open iec958:0
D: [pulseaudio] alsa-util.c: snd_pcm_hw_params_set_format(Signed 24 bit Little Endian in 3bytes) failed: Некоректний аргумент
D: [pulseaudio] alsa-util.c: snd_pcm_hw_params_set_format(Signed 24 bit Big Endian in 3bytes) failed: Некоректний аргумент
D: [pulseaudio] alsa-util.c: snd_pcm_hw_params_set_format(Float 32 bit Little Endian) failed: Некоректний аргумент
D: [pulseaudio] alsa-util.c: snd_pcm_hw_params_set_format(Float 32 bit Big Endian) failed: Некоректний аргумент
D: [pulseaudio] alsa-util.c: Maximum hw buffer size is 2730 ms
D: [pulseaudio] alsa-util.c: Set buffer size first (to 19200 samples), period size second (to 4800 samples).
I: [pulseaudio] alsa-util.c: Device iec958:0 doesn't support sample format s24le, changed to s32le.
D: [pulseaudio] alsa-mixer.c: Profile output:iec958-stereo supported.
D: [pulseaudio] conf-parser.c: Parsing configuration file '/usr/share/pulseaudio/alsa-mixer/paths/iec958-stereo-output.conf'
I: [pulseaudio] (alsa-lib)control.c: Invalid CTL iec958:0
I: [pulseaudio] alsa-util.c: Unable to attach to mixer iec958:0: Немає такого файла або каталогу
I: [pulseaudio] alsa-util.c: Successfully attached to mixer 'hw:0'
D: [pulseaudio] alsa-mixer.c: Probing path 'iec958-stereo-output'
D: [pulseaudio] alsa-mixer.c: Probe of element 'IEC958' succeeded (volume=0, switch=1, enumeration=0).
D: [pulseaudio] alsa-mixer.c: Available mixer paths (after tidying):
D: [pulseaudio] alsa-mixer.c: Path Set 0x56475920ba20, direction=1
D: [pulseaudio] alsa-mixer.c: Path iec958-stereo-output (Цифровий вихід (S/PDIF)), direction=1, priority=0, probed=yes, supported=yes, has_mute=yes, has_volume=no, has_dB=no, min_volume=0, max_volume=0, min_dB=inf, max_dB=-inf
D: [pulseaudio] alsa-mixer.c: Element IEC958, direction=1, switch=1, volume=0, volume_limit=-1, enumeration=0, required=0, required_any=0, required_absent=0, mask=0x0, n_channels=0, override_map=no
D: [pulseaudio] alsa-mixer.c: Skipping profile output:iec958-stereo+input:analog-mono - will not be able to open input:analog-mono
D: [pulseaudio] alsa-mixer.c: Looking at profile output:iec958-stereo+input:analog-stereo
D: [pulseaudio] alsa-mixer.c: Checking for recording on Аналогове стерео (analog-stereo)
...

while playing FLAC (24/192) logs next:

...
I: [pulseaudio] client.c: Created 8 "Native client (UNIX socket client)"
D: [pulseaudio] protocol-dbus.c: Interface org.PulseAudio.Core1.Client added for object /org/pulseaudio/core1/client8
D: [pulseaudio] protocol-native.c: Protocol version: remote 32, local 32
I: [pulseaudio] protocol-native.c: Got credentials: uid=1000 gid=1000 success=1
D: [pulseaudio] protocol-native.c: SHM possible: yes
D: [pulseaudio] protocol-native.c: Negotiated SHM: yes
D: [pulseaudio] protocol-native.c: Memfd possible: yes
D: [pulseaudio] protocol-native.c: Negotiated SHM type: shared memfd
D: [pulseaudio] log.c: Invalid UTF-8 string following below:
D: [pulseaudio] memblock.c: Using shared memfd memory pool with 1024 slots of size 64,0 Кі each, total size is 64,0 Мі, maximum usable slot size is 65472
D: [pulseaudio] srbchannel.c: SHM block is 65472 bytes, ringbuffer capacity is 2 * 32712 bytes
D: [pulseaudio] protocol-native.c: Enabling srbchannel...
D: [pulseaudio] module-augment-properties.c: Looking for .desktop file for deadbeef
D: [pulseaudio] protocol-native.c: Client enabled srbchannel.
I: [pulseaudio] module-stream-restore.c: Restoring device for stream sink-input-by-media-role:music.
D: [pulseaudio] module-intended-roles.c: Not setting device for stream Music, because already set.
D: [pulseaudio] sink-input.c: Negotiated format: pcm, format.sample_format = "\"s24le\""  format.rate = "192000"  format.channels = "2"  format.channel_map = "\"front-left,front-right\""
I: [pulseaudio] sink-input.c: Trying to change sample rate
I: [pulseaudio] module-stream-restore.c: Restoring volume for sink input sink-input-by-media-role:music.
I: [pulseaudio] module-stream-restore.c: Restoring mute state for sink input sink-input-by-media-role:music.
D: [pulseaudio] module-suspend-on-idle.c: Sink alsa_output.pci-0000_00_1f.3.iec958-stereo becomes busy, resuming.
D: [pulseaudio] reserve-wrap.c: Successfully acquired reservation lock on device 'Audio0'
I: [alsa-sink-ALC1220 Digital] alsa-sink.c: Trying resume...
I: [alsa-sink-ALC1220 Digital] alsa-util.c: Trying to disable ALSA period wakeups, using timers only
D: [alsa-sink-ALC1220 Digital] alsa-util.c: Maximum hw buffer size is 2730 ms
D: [alsa-sink-ALC1220 Digital] alsa-util.c: Set buffer size first (to 384000 samples), period size second (to 192000 samples).
I: [alsa-sink-ALC1220 Digital] alsa-util.c: ALSA period wakeups disabled
D: [alsa-sink-ALC1220 Digital] alsa-sink.c: hwbuf_unused=0
D: [alsa-sink-ALC1220 Digital] alsa-sink.c: setting avail_min=381121
I: [alsa-sink-ALC1220 Digital] alsa-sink.c: Time scheduling watermark is 15,00ms
I: [alsa-sink-ALC1220 Digital] alsa-sink.c: Resumed successfully...
D: [pulseaudio] sink.c: alsa_output.pci-0000_00_1f.3.iec958-stereo: suspend_cause: IDLE -> (none)
D: [pulseaudio] sink.c: alsa_output.pci-0000_00_1f.3.iec958-stereo: state: SUSPENDED -> IDLE
D: [pulseaudio] module-suspend-on-idle.c: Sink alsa_output.pci-0000_00_1f.3.iec958-stereo becomes idle, timeout in 5 seconds.
I: [alsa-sink-ALC1220 Digital] alsa-sink.c: Starting playback.
D: [alsa-sink-ALC1220 Digital] alsa-sink.c: Cutting sleep time for the initial iterations by half.
D: [alsa-sink-ALC1220 Digital] alsa-sink.c: Cutting sleep time for the initial iterations by half.
D: [pulseaudio] source.c: alsa_output.pci-0000_00_1f.3.iec958-stereo.monitor: suspend_cause: IDLE -> (none)
D: [pulseaudio] source.c: alsa_output.pci-0000_00_1f.3.iec958-stereo.monitor: state: SUSPENDED -> IDLE
D: [pulseaudio] module-suspend-on-idle.c: Sink alsa_output.pci-0000_00_1f.3.iec958-stereo becomes idle, timeout in 5 seconds.
I: [pulseaudio] resampler.c: Forcing resampler 'copy', because of fixed, identical sample rates.
D: [pulseaudio] resampler.c: Resampler:
D: [pulseaudio] resampler.c:   rate 192000 -> 192000 (method copy)
D: [pulseaudio] resampler.c:   format s24le -> s32le (intermediate float32le)
D: [pulseaudio] resampler.c:   channels 2 -> 2 (resampling 2)
D: [pulseaudio] memblockq.c: memblockq requested: maxlength=33554432, tlength=0, base=8, prebuf=0, minreq=1 maxrewind=0
D: [pulseaudio] memblockq.c: memblockq sanitized: maxlength=33554432, tlength=33554432, base=8, prebuf=0, minreq=8 maxrewind=0
I: [pulseaudio] sink-input.c: Created input 5 "Music" on alsa_output.pci-0000_00_1f.3.iec958-stereo with sample spec s24le 2кан. 192000Гц and channel map front-left,front-right
I: [pulseaudio] sink-input.c:     media.name = "Music"
I: [pulseaudio] sink-input.c:     application.name = "Deadbeef"
I: [pulseaudio] sink-input.c:     native-protocol.peer = "UNIX socket client"
I: [pulseaudio] sink-input.c:     native-protocol.version = "32"
I: [pulseaudio] sink-input.c:     application.process.id = "29689"
I: [pulseaudio] sink-input.c:     application.process.user = "mkbodanu4"
I: [pulseaudio] sink-input.c:     application.process.host = "mkwork3"
I: [pulseaudio] sink-input.c:     application.process.binary = "deadbeef"
I: [pulseaudio] sink-input.c:     application.language = "uk_UA.UTF-8"
I: [pulseaudio] sink-input.c:     window.x11.display = ":0"
I: [pulseaudio] sink-input.c:     application.process.machine_id = "c4e4b2c9d41b472cb6eb2daea03f4968"
I: [pulseaudio] sink-input.c:     application.process.session_id = "1"
I: [pulseaudio] sink-input.c:     media.role = "music"
I: [pulseaudio] sink-input.c:     application.icon_name = "deadbeef"
I: [pulseaudio] sink-input.c:     module-stream-restore.id = "sink-input-by-media-role:music"
I: [pulseaudio] protocol-native.c: Requested tlength=250,00 ms, minreq=20,00 ms
D: [pulseaudio] protocol-native.c: Adjust latency mode enabled, configuring sink latency to half of overall latency.
D: [alsa-sink-ALC1220 Digital] alsa-sink.c: Cutting sleep time for the initial iterations by half.
D: [alsa-sink-ALC1220 Digital] alsa-sink.c: Cutting sleep time for the initial iterations by half.
D: [pulseaudio] protocol-native.c: Requested latency=105,00 ms, Received latency=105,00 ms
D: [pulseaudio] memblockq.c: memblockq requested: maxlength=4194304, tlength=167040, base=6, prebuf=144006, minreq=23040 maxrewind=0
D: [pulseaudio] memblockq.c: memblockq sanitized: maxlength=4194306, tlength=167040, base=6, prebuf=144006, minreq=23040 maxrewind=0
I: [pulseaudio] protocol-native.c: Final latency 250,00 ms = 105,00 ms + 2*20,00 ms + 105,00 ms
D: [alsa-sink-ALC1220 Digital] alsa-sink.c: Cutting sleep time for the initial iterations by half.
...

Last thing I tried - play 24-bit audio directly using ALSA:

$ aplay -D iec958:CARD=PCH,DEV=0 --dump-hw-params warbles-192.wav 
Playing WAVE 'warbles-192.wav' : Signed 24 bit Little Endian in 3bytes, Rate 192000 Hz, Mono
HW Params of device "iec958:CARD=PCH,DEV=0":
--------------------
ACCESS:  MMAP_INTERLEAVED RW_INTERLEAVED
FORMAT:  S16_LE S32_LE
SUBFORMAT:  STD
SAMPLE_BITS: [16 32]
FRAME_BITS: [32 64]
CHANNELS: 2
RATE: [32000 192000]
PERIOD_TIME: (83 16384000]
PERIOD_SIZE: [16 524288]
PERIOD_BYTES: [128 4194304]
PERIODS: [2 32]
BUFFER_TIME: (166 32768000]
BUFFER_SIZE: [32 1048576]
BUFFER_BYTES: [128 4194304]
TICK_TIME: ALL
--------------------
aplay: set_params:1339: Sample format non available
Available formats:
- S16_LE
- S32_LE

That all confusing me - Windows allows to set 24 bits but not Linux. Codec support 24-bit, driver not. PC sending 32-bits stream - 24-bit DAC working without any effects.

Maybe anyone here know how to set 24-bit format under this conditions?
Or just ignore current situation as soon it working well?

Thanks!

Offline

#2 2019-04-24 01:23:40

pigiron
Member
From: USA
Registered: 2009-07-14
Posts: 149

Re: PulseAudio with external DAC over S/PDIF - can't set sample format

I looked into this and found that my ALC887 codec chip is basically doing the same thing. Even though the datasheet says that it handles 16, 20, and 24 bit S/PDIF data. So both of our codec chips claim they handle 24 bits, but ALSA says they only handle 16 or 32 bits... why???

The answer was a long journey.

Spending days in the ALSA kernel source didn't help much. It wasn't until I wandered into the Intel HDA Specification that I think I found the answer. For example, here's where it describes the audio data streams to be sent to/from the HDA chip:

4.5.1 Stream Data In Memory
  Samples represent one channel of data to be played at one instant
  in time. In a 24 bit, three-channel, 96-kHz stream, one sample is
  24 bits long. Samples are packed in containers which are 8 bits,
  16 bits, or 32 bits wide; the smallest container size which will
  fit the sample size is used.

  In the case of a 24-bit sample, a 32-bit container would be used.
  Samples are padded with 0's at the LSB to left justify the sample
  within the container.

In other sections, the specification describes how the software (ALSA) informs the HDA chip about the amount of audio data within the container.

So while that "warbles-192.wav" audio file is indeed in 24 bit format (called "S24_3LE" in the ALSA world), it must be converted to 32 bits ("S32_LE") to be accepted by the Intel (or other brand) of HDA chip. Windows is probably doing the same thing, but might not be informing the user.

Offline

#3 2019-04-24 06:31:35

d_fajardo
Member
Registered: 2017-07-28
Posts: 480

Re: PulseAudio with external DAC over S/PDIF - can't set sample format

You have to configure your DAC to play bit-perfect. I have a Cambridge Audio DAC that reads my media stream bit-perfect so I can play play my DSD files. For this I use MPD and use Cantata as my front end. There are other ways if you search in the net to play bit-perfect audio in Linux. For me it's just best if the streams are read and played as they come. Pulse remains my default system sound but MPD plays my music.

EDIT:
There's a similar thread to this: https://bbs.archlinux.org/viewtopic.php?id=245907

Last edited by d_fajardo (2019-04-24 12:57:01)

Offline

#4 2019-04-24 14:34:33

pigiron
Member
From: USA
Registered: 2009-07-14
Posts: 149

Re: PulseAudio with external DAC over S/PDIF - can't set sample format

You have to configure your DAC to play bit-perfect. I have a Cambridge Audio DAC that reads my media stream bit-perfect so I can play play my DSD files.

If "bit-perfect" means that the audio data is completely unaltered on playback, then that may be true when certain audio file formats are matched with a particular audio hardware device.

In this case, we were discussing the S16_LE/S32_LE limitation for some Realtek codecs attached to the PCI bus through a HDA chip. But most (if not nearly all) audio hardware devices have a format limitation of some sort that they can play/capture.

One easy way to determine those limitations is to install the "alsacap" utility in the AUR:

  https://aur.archlinux.org/packages/alsacap/

Offline

#5 2019-04-24 21:17:17

d_fajardo
Member
Registered: 2017-07-28
Posts: 480

Re: PulseAudio with external DAC over S/PDIF - can't set sample format

But as I understand it, mkbudanu4's DAC should be able to be read by the OS as another separate audio card which means that his DAC should not have the need to go to through the built in motherboard Realtec HDA codec. I have the same situation. I also have a Realtec HDA card that comes with my motherboard but I don't use it and I configured ALSA to feed my DAC directly with unaltered streams through mpd. The output comes out directly from the DAC which my speakers are connected to. My Realtec HDA card in the motherboard in the end just becomes an unused card as nothing is attached to it.

When I first setup my system, I did use the Realtec HDA audio directly but I have these ultra-sensitive monitor speakers that picked up unnecessary internal noises from the system hardware and so after some research, I decided to purchase a DAC and get the stream input through a cleaner USB interface which I must say works very well.

Offline

Board footer

Powered by FluxBB