Stumped with multi-channel USB sound output

Andrew Reilly areilly at bigpond.net.au
Wed Dec 26 04:44:21 UTC 2018


Hi there,

I've recently acquired one of these:
https://www.minidsp.com/products/usb-audio-interface/u-dac8 to do some multi-amp speaker crossover hi-fi tweaking.  Since my FreeBSD-12.STABLE file server is quite close to my amplifier, I thought that I'd start by using it to drive the DAC.

It is a USB Audio Class 2.0 device, and as such is recognised seemingly well by the snd_uaudio driver (loaded by /boot/loader.conf, as it doesn't seem to be compiled-in):

(from dmesg.boot:)
uaudio0 on uhub1
uaudio0: <U-DAC8> on usbus1
uaudio0: Play: 192000 Hz, 8 ch, 32-bit S-LE PCM format, 2x8ms buffer.
uaudio0: Play: 176400 Hz, 8 ch, 32-bit S-LE PCM format, 2x8ms buffer.
uaudio0: Play: 96000 Hz, 8 ch, 32-bit S-LE PCM format, 2x8ms buffer.
uaudio0: Play: 88200 Hz, 8 ch, 32-bit S-LE PCM format, 2x8ms buffer.
uaudio0: Play: 48000 Hz, 8 ch, 32-bit S-LE PCM format, 2x8ms buffer.
uaudio0: Play: 44100 Hz, 8 ch, 32-bit S-LE PCM format, 2x8ms buffer.
uaudio0: No recording.
uaudio0: No MIDI sequencer.
pcm0: <USB audio> on uaudio0
uaudio0: No HID volume keys found.

(The motherboard has a an hdac sound device of course, and on the off-chance that the sound driver was getting confused about unsynchronised sample rate domains, I've disabled that in /boot/device.hints: 
hint.hdacc.0.disabled="1"

That still leaves this output in dmesg:
hdac0: <ATI (0xaab0) HDA Controller> mem 0xfe860000-0xfe863fff irq 55 at device 0.1 on pci10
hdac0: hdac_get_capabilities: Invalid corb size (0)
device_attach: hdac0 attach returned 6
hdac0: <AMD (0x1457) HDA Controller> mem 0xfe700000-0xfe707fff irq 43 at device 0.3 on pci12

but the only pcm to show up in /dev/sndstat now is pcm0 belonging to the uaudio device.

I tried using device.hints to disable hdac0, at first, but all that did was re-number it to hdac1, and all of the motherboard pcm devices were still found.)


Anyway, I can't make it produce sensible output under FreeBSD.  It sounds to me as though somewhere a buffer is incorrectly formatted, or the wrong size.  Sound plays at seemingly about the right rate, but there is distortion that sounds like blocks of null values at a rate of about 20-30Hz.  It doesn't seem to matter whether I write one, two or eight channels: sounds the same pitch and distortion rate, although with mono output my test signal plays out both channel 0 and 1.  I expect that is the automatic vchan mixer at work?

The DAC works without problems on macOS.

The sysctl values for hw.snd are:

hw.snd.maxautovchans: 16
hw.snd.default_unit: 0
hw.snd.version: 2009061500/amd64
hw.snd.default_auto: 1
hw.snd.verbose: 2
hw.snd.vpc_mixer_bypass: 1
hw.snd.feeder_rate_quality: 1
hw.snd.feeder_rate_round: 25
hw.snd.feeder_rate_max: 2016000
hw.snd.feeder_rate_min: 1
hw.snd.feeder_rate_polyphase_max: 183040
hw.snd.feeder_rate_presets: 100:8:0.85 100:36:0.92 100:164:0.97
hw.snd.feeder_eq_exact_rate: 0
hw.snd.feeder_eq_presets: PEQ:16000,0.2500,62,0.2500:-9,9,1.0:44100,48000,88200,96000,176400,192000
hw.snd.basename_clone: 1
hw.snd.compat_linux_mmap: 0
hw.snd.syncdelay: -1
hw.snd.usefrags: 0
hw.snd.vpc_reset: 0
hw.snd.vpc_0db: 45
hw.snd.vpc_autoreset: 1
hw.snd.timeout: 5
hw.snd.latency_profile: 1
hw.snd.latency: 5
hw.snd.report_soft_matrix: 1
hw.snd.report_soft_formats: 1

and for dev.pcm:

dev.pcm.0.feedback_rate: 47999
dev.pcm.0.mixer.mute_1.desc: 
dev.pcm.0.mixer.mute_1.max: 1
dev.pcm.0.mixer.mute_1.min: 0
dev.pcm.0.mixer.mute_1.val: 0
dev.pcm.0.mixer.vol_0.desc: 
dev.pcm.0.mixer.vol_0.max: 0
dev.pcm.0.mixer.vol_0.min: -32512
dev.pcm.0.mixer.vol_0.val: -11475
dev.pcm.0.bitperfect: 0
dev.pcm.0.buffersize: 0
dev.pcm.0.play.vchanformat: s16le:2.0
dev.pcm.0.play.vchanrate: 48000
dev.pcm.0.play.vchanmode: fixed
dev.pcm.0.play.vchans: 1
dev.pcm.0.hwvol_mixer: vol
dev.pcm.0.hwvol_step: 5
dev.pcm.0.%parent: uaudio0
dev.pcm.0.%pnpinfo: 
dev.pcm.0.%location: 
dev.pcm.0.%driver: pcm
dev.pcm.0.%desc: USB audio
dev.pcm.%parent: 

When running squeezelite, compiled to use portaudio (from ports), /dev/sndstat says:
FreeBSD Audio Driver (64bit 2009061500/amd64)
Installed devices:
pcm0: <USB audio> at ? kld snd_uaudio (1p:1v/0r:0v) default
	snddev flags=0x200002e3<SIMPLEX,AUTOVCHAN,BUSY,MPSAFE,REGISTERED,VPC,PRIO_WR>
	[pcm0:play:dsp0.p0]: spd 48000, fmt 0x00200010/0x08801000, flags 0x00002108, 0x00000046
	interrupts 543, underruns 0, feed 1084, ready 0 [b:24576/12288/2|bs:4096/2048/2]
	channel flags=0x2108<TRIGGERED,BUSY,HAS_VCHAN>
	{userland} -> feeder_mixer(0x00200010) -> feeder_format(0x00200010 -> 0x00201000) -> feeder_matrix(2.0 -> 7.1) -> {hardware}
	pcm0:play:dsp0.p0[pcm0:virtual:dsp0.vp0]: spd 44100/48000, fmt 0x00200010, flags 0x1000114c, 0x00000029, pid 9675 (squeezelite)
	interrupts 0, underruns 0, feed 1072, ready 7232 [b:0/0/0|bs:8192/2048/4]
	channel flags=0x1000114c<RUNNING,TRIGGERED,NBIO,BUSY,HAS_SIZE,VIRTUAL>
	{userland} -> feeder_root(0x00200010) -> feeder_volume(0x00200010) -> feeder_rate(0x00200010 q:1 44100 -> 48000) -> {hardware}
No devices installed from userspace.

I think that is saying (working from the bottom up) that userland is sending data which is being sample-rate converted using the default (q:1) sample rate converter to 48kHz, and then feeder_matrix(2.0 -> 7.1) is probably trying to do the right thing to drive eight output channels?

If I run my little test program (attached) to drive all eight channels directly, it does something much weirder:
FreeBSD Audio Driver (64bit 2009061500/amd64)
Installed devices:
pcm0: <USB audio> at ? kld snd_uaudio (1p:1v/0r:0v) default
	snddev flags=0x200002e3<SIMPLEX,AUTOVCHAN,BUSY,MPSAFE,REGISTERED,VPC,PRIO_WR>
	[pcm0:play:dsp0.p0]: spd 48000, fmt 0x00200010/0x08801000, flags 0x00002108, 0x00000046
	interrupts 409, underruns 0, feed 816, ready 0 [b:24576/12288/2|bs:4096/2048/2]
	channel flags=0x2108<TRIGGERED,BUSY,HAS_VCHAN>
	{userland} -> feeder_mixer(0x00200010) -> feeder_format(0x00200010 -> 0x00201000) -> feeder_matrix(2.0 -> 7.1) -> {hardware}
	pcm0:play:dsp0.p0[pcm0:virtual:dsp0.vp0]: spd 48000, fmt 0x08801000/0x00200010, flags 0x1000012c, 0x00000063, pid 9752 (singen)
	interrupts 0, underruns 0, feed 34680, ready 131072 [b:0/0/0|bs:131072/4096/32]
	channel flags=0x1000012c<RUNNING,TRIGGERED,SLEEPING,BUSY,VIRTUAL>
	{userland} -> feeder_root(0x08801000) -> feeder_format(0x08801000 -> 0x08800010) -> feeder_matrix(7.1 -> 2.0) -> feeder_volume(0x00200010) -> {hardware}
No devices installed from userspace.

That looks as though my eight channels is being mixed down to two (on the last line) and then up-mixed to eight (7.1)?  I don't want it to do that.  How do I stop it?

Also, this hardware is perfectly capable of running at 44100Hz, as shown in the dmesg output.  Is there a way to tell the pcm driver to set the hardware sample rate, rather than do sample rate conversion in software?

Is there any documentation about any of this?  The pcm(4) man page says that there is matrixing support to handle channel routing and up/down mixing, but it isn't particularly clear about the possibilities.

If I sysctl dev.pcm.0.play.vchanformat=s32le:7.1 then sndstat seems more promising:
FreeBSD Audio Driver (64bit 2009061500/amd64)
Installed devices:
pcm0: <USB audio> at ? kld snd_uaudio (1p:1v/0r:0v) default
	snddev flags=0x200002e3<SIMPLEX,AUTOVCHAN,BUSY,MPSAFE,REGISTERED,VPC,PRIO_WR>
	[pcm0:play:dsp0.p0]: spd 48000, fmt 0x08801000, flags 0x00002108, 0x00000004
	interrupts 6612, underruns 0, feed 6611, ready 0 [b:24576/12288/2|bs:32768/16384/2]
	channel flags=0x2108<TRIGGERED,BUSY,HAS_VCHAN>
	{userland} -> feeder_mixer(0x08801000) -> {hardware}
	pcm0:play:dsp0.p0[pcm0:virtual:dsp0.vp0]: spd 48000, fmt 0x08801000, flags 0x1000012c, 0x00000021, pid 9819 (singen)
	interrupts 0, underruns 0, feed 6611, ready 131072 [b:0/0/0|bs:131072/4096/32]
	channel flags=0x1000012c<RUNNING,TRIGGERED,SLEEPING,BUSY,VIRTUAL>
	{userland} -> feeder_root(0x08801000) -> feeder_volume(0x08801000) -> {hardware}
No devices installed from userspace.

but the audio output distortion is the same.  Despite the distorted output, sndstat is indicating that there are no underruns, and there are no kernel messages showing up in the dmesg buffer about pcm misbehaviour.

Setting dev.pcm.0.bitperfect=1 doesn't seem to make any difference, except the feeder_volume() node goes away in the sndstat output:
FreeBSD Audio Driver (64bit 2009061500/amd64)
Installed devices:
pcm0: <USB audio> at ? kld snd_uaudio (1p:1v/0r:0v) default
	snddev flags=0x200003e3<SIMPLEX,AUTOVCHAN,BUSY,MPSAFE,REGISTERED,BITPERFECT,VPC,PRIO_WR>
	[pcm0:play:dsp0.p0]: spd 48000, fmt 0x08801000, flags 0x00002108, 0x00000004
	interrupts 359, underruns 0, feed 358, ready 0 [b:24576/12288/2|bs:32768/16384/2]
	channel flags=0x2108<TRIGGERED,BUSY,HAS_VCHAN>
	{userland} -> feeder_mixer(0x08801000) -> {hardware}
	pcm0:play:dsp0.p0[pcm0:virtual:dsp0.vp0]: spd 48000, fmt 0x08801000, flags 0x3000012c, 0x00000001, pid 9993 (singen)
	interrupts 0, underruns 0, feed 358, ready 131072 [b:0/0/0|bs:131072/4096/32]
	channel flags=0x3000012c<RUNNING,TRIGGERED,SLEEPING,BUSY,VIRTUAL,BITPERFECT>
	{userland} -> feeder_root(0x08801000) -> {hardware}
No devices installed from userspace.

Am I going to win, with additional tweaking, do you think?  Or will I be better off setting up a Raspberry Pi or the like, running linux, to drive it?

Where can I find documentation about the mixer/feeder architecture, to interpret those sndstat outputs?

Cheers,

Andrew Reilly
M: 0409-824-272
areilly at bigpond.net.au


-------------- next part --------------
A non-text attachment was scrubbed...
Name: Makefile
Type: application/octet-stream
Size: 90 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-multimedia/attachments/20181226/0bdb2dfa/attachment.obj>


More information about the freebsd-multimedia mailing list