# S/PDIF capture/playback with an ESI U24XL



## leres (Sep 12, 2016)

ESI makes a nice usb box with analog and digital (both S/PDIF and TOSLINK) inputs and outputs.  I'd like to use it to do "bit perfect" recording and playback of S/PDIF PCM.

If I `sysctl hw.snd.verbose=1` and plug it into a 10.3-RELEASE box I see:


```
ugen0.5: <ESI> at usbus0
uhid0: <ESI U24XL, class 0/0, rev 1.10/0.01, addr 5> on usbus0
uaudio0: <U24XL with SPDIF IO> on usbus0
uaudio0: Play: 48000 Hz, 2 ch, 24-bit S-LE PCM format, 2x8ms buffer.
uaudio0: Play: 44100 Hz, 2 ch, 24-bit S-LE PCM format, 2x8ms buffer.
uaudio0: Record: 48000 Hz, 2 ch, 24-bit S-LE PCM format, 2x8ms buffer.
uaudio0: Record: 44100 Hz, 2 ch, 24-bit S-LE PCM format, 2x8ms buffer.
uaudio0: No MIDI sequencer.
pcm2: <USB audio> on uaudio0
uaudio0: No HID volume keys found.
```
The way I've done recording with other systems (e.g. a foxconn netbox with S/PDIF input and outputs) is to first sysctl(8):


```
dev.pcm.2.bitperfect=1
dev.pcm.2.rec.vchans=0
dev.pcm.2.play.vchans=0
```
then open /dev/dsp2.0 and do a AIOSFMT ioctl(2) to set:


```
rec_rate = 44100
rec_format = AFMT_S16_LE
```
However with U24XL, I can't change the rec_format; it stays set to AFMT_S24_LE. I believe this is because the device is configured to use the ADC inputs. Anyway if I record I just get silence (and I need to get some 1/4" adapters to test the theory that the ADC inputs are being used).

I've attached debug.txt that shows the sound card being plugged with hw.usb.uaudio.debug=1 in effect. It sort of looks like the driver is rejecting formats the card supports including the one I want: stereo, 44.1 kHz 16-bit LE:


```
uaudio_chan_fill_info_sub: Sample rate = 44100Hz, channels = 2, bits = 16, format = 16-bit S-LE PCM
uaudio_chan_fill_info_sub: Multiple formats is not supported
uaudio_chan_fill_info_sub: Wrong number of channels
uaudio_chan_dump_ep_desc: endpoint=0xfffff8000bae4125 bLength=9 bDescriptorType=5
bEndpointAddress=3 bmAttributes=0x9
wMaxPacketSize=196 bInterval=1
bRefresh=0 bSynchAddress=0
uaudio_chan_fill_info_sub: Sample rate = 44100Hz, channels = 2, bits = 16, format = 16-bit S-LE PCM
uaudio_chan_fill_info_sub: Multiple formats is not supported
uaudio_chan_fill_info_sub: Wrong number of channels
uaudio_chan_dump_ep_desc: endpoint=0xfffff8000bae40b7 bLength=9 bDescriptorType=5
bEndpointAddress=130 bmAttributes=0x9
wMaxPacketSize=240 bInterval=1
bRefresh=0 bSynchAddress=0
```
Looking at dev/sound/usb/uaudio.c in uaudio_chan_fill_info_sub() the place where it logs "Multiple formats is not supported" seems to be using 24 bit because that's what is checked first. (This still doesn't solve the problem of being able to select the digital inputs.)

To verify the U24XL is capable of recording S/PDIF I built an Ubuntu 16.04 system to do some testing with a "real" alsa driver.  I found that I could use alsamixer to change the capture from "Line" to "IEC958" and was then able to capture a good wav file using:


```
arecord -vv -f CD -D hw:2,0 -d 5 test.wav
```
while feeding the S/PDIF or TOSLINK inputs with digital audio.

So I know the hardware can definitely record digital audio. But how can I do this under FreeBSD? Am I looking at deficiencies in the FreeBSD dev/sound/usb driver?  Have I overlooked a magic ioctl in sys/soundcard.h?


----------

