mikebrady / shairport-sync

AirPlay and AirPlay 2 audio player
Other
7.29k stars 574 forks source link

Apple DAC fails w/ *fatal error: The output DAC can not be set to 44100 frames per second #1504

Closed quantonian closed 2 years ago

quantonian commented 2 years ago

Scratching my head on this one... I'm using the Apple usb-c DAC that is fully capable of 44100 Hz but shairport fails with the following error: *fatal error: The output DAC can not be set to 44100 frames per second (fps). The nearest speed available is 48000 fps.

Device: Apple usb-c dongle
Review tested at 41000Hz https://www.audiosciencereview.com/forum/index.php?threads/review-apple-vs-google-usb-c-headphone-adapters.5541/

Uses Cirrus Logic 46L06-CWZR DAC Chip per teardown https://www.cabledo.com/apple-usb-c-digital-to-3-5-mm-headphone-adapter-teardown/

Config:

shairport-sync version 4.1-dev-420-g23d0502f
nqptp version: 1.1-dev-161-g353093a

lsusb
Bus 001 Device 007: ID 05ac:110a Apple, Inc. USB-C to 3.5mm Headphone Jack Adapter
Bus 002 Device 001: ID 1d6b:0003 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 004 Device 001: ID 1d6b:0003 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 001 Device 002: ID 1a40:0801  USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 003 Device 001: ID 1d6b:0002 Linux 5.10.127 xhci-hcd xHCI Host Controller

aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: A [USB-C to 3.5mm Headphone Jack A], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

/etc/shairport-sync.conf
// Sample Configuration File for Shairport Sync on a Raspberry Pi using the built-in audio DAC
general =
{
  volume_range_db = 60;
  name = "sono_g1";
};

alsa =
{
  output_device = "hw:A";
};

Debug:

root@sono-g1:/etc# shairport-sync -v
         0.001911750 "shairport.c:1497" default pid filename is "/var/run/shairport-sync".
         0.000503396 "shairport.c:2016" startup in Airplay 2 mode with features 0x405c4a00,0x1c340 on device "38:8b:59:d6:7f:5c".
         0.000192812 "shairport.c:2059" software version: "4.1-dev-AirPlay2-libdaemon-OpenSSL-Avahi-ALSA-soxr-sysconfdir:/etc"
         0.000129729 "shairport.c:2065" log verbosity is 1.
         0.000133167 "audio_alsa.c:1002" alsa: alsa_maximum_stall_time of 0.200000 sec.
         0.000165833 "audio_alsa.c:1156" alsa output rate is 44100 frames per second
         0.000085021 "audio_alsa.c:1291" alsa: disable_standby_mode is "never".
         0.000045563 "audio_alsa.c:1295" alsa: disable_standby_mode_silence_threshold is 0.040000 seconds.
         0.000057625 "audio_alsa.c:1297" alsa: disable_standby_mode_silence_scan_interval is 0.004000 seconds.
         0.000054625 "audio_alsa.c:1337" alsa: output device name is "hw:A".
         0.000354604 "shairport.c:2094" libsodium initialised.
         0.000515416 "shairport.c:2144" disable resend requests is off.
         0.000066938 "shairport.c:2145" diagnostic_drop_packet_fraction is 0.000000. A value of 0.0 means no packets will be dropped deliberately.
         0.000060375 "shairport.c:2149" statistics_requester status is 0.
         0.000042500 "shairport.c:2151" daemon status is 0.
         0.000046562 "shairport.c:2152" daemon pid file path is "/var/run/shairport-sync/shairport-sync.pid".
         0.000049855 "shairport.c:2154" rtsp listening port is 7000.
         0.000039041 "shairport.c:2155" udp base port is 6001.
         0.000040667 "shairport.c:2156" udp port range is 10.
         0.000040375 "shairport.c:2157" player name is "sono_g1".
         0.000040271 "shairport.c:2158" backend is "alsa".
         0.000040666 "shairport.c:2159" run_this_before_play_begins action is "(null)".
         0.000045646 "shairport.c:2160" run_this_after_play_ends action is "(null)".
         0.000045625 "shairport.c:2161" wait-cmd status is 0.
         0.000037917 "shairport.c:2162" run_this_before_play_begins may return output is 0.
         0.000047750 "shairport.c:2163" run_this_if_an_unfixable_error_is_detected action is "(null)".
         0.000051542 "shairport.c:2165" run_this_before_entering_active_state action is  "(null)".
         0.000051770 "shairport.c:2167" run_this_after_exiting_active_state action is  "(null)".
         0.000051688 "shairport.c:2169" active_state_timeout is  10.000000 seconds.
         0.000051687 "shairport.c:2170" mdns backend "(null)".
         0.000043896 "shairport.c:2172" interpolation setting is "auto".
         0.000041459 "shairport.c:2175" interpolation soxr_delay_threshold is 30000000.
         0.000052770 "shairport.c:2176" resync time is 0.050000 seconds.
         0.000042250 "shairport.c:2177" allow a session to be interrupted: 0.
         0.000039771 "shairport.c:2178" busy timeout time is 0.
         0.000037584 "shairport.c:2179" drift tolerance is 0.001995 seconds.
         0.000044083 "shairport.c:2180" password is "(null)".
         0.000038083 "shairport.c:2181" ignore_volume_control is 0.
         0.000180813 "shairport.c:2185" volume_max_db is not set
         0.000300375 "shairport.c:2186" volume range in dB (zero means use the range specified by the mixer): 60.
         0.000526771 "shairport.c:2188" volume_range_combined_hardware_priority (1 means hardware mixer attenuation is used first) is 0.
         0.000097083 "shairport.c:2192" playback_mode is 0 (0-stereo, 1-mono, 1-reverse_stereo, 2-both_left, 3-both_right).
         0.000055833 "shairport.c:2194" disable_synchronization is 0.
         0.000040834 "shairport.c:2195" use_mmap_if_available is 1.
         0.000041645 "shairport.c:2196" output_format automatic selection is enabled.
         0.000089313 "shairport.c:2200" output_rate automatic selection is disabled.
         0.000038833 "shairport.c:2204" audio backend desired buffer length is 0.200000 seconds.
         0.000051125 "shairport.c:2206" audio_backend_buffer_interpolation_threshold_in_seconds is 0.120000 seconds.
         0.000055354 "shairport.c:2208" audio backend latency offset is 0.000000 seconds.
         0.000054375 "shairport.c:2210" audio backend silence lead-in time is "auto".
         0.000054563 "shairport.c:2214" zeroconf regtype is "_raop._tcp".
         0.000043020 "shairport.c:2215" decoders_supported field is 1.
         0.000039209 "shairport.c:2216" use_apple_decoder is 0.
         0.000038708 "shairport.c:2217" alsa_use_hardware_mute is 0.
         0.000039146 "shairport.c:2221" no special mdns service interface was requested.
         0.000090104 "shairport.c:2224" configuration file name "/etc/shairport-sync.conf" resolves to "/etc/shairport-sync.conf".
         0.000061333 "shairport.c:2254" loudness is 0.
         0.000040188 "shairport.c:2255" loudness reference level is -20.000000
         0.005974125 "shairport.c:2337" NQPTP is online.
         1.513879769 "shairport.c:250" "soxr" interpolation has been chosen.
        41.055082045 "rtp.c:1571" Connection 1: AP2 Event Receiver started
         2.355661581 "rtsp.c:3112" Connection 1. AP2 Buffered Audio Stream.
         0.038869625 "audio_alsa.c:630" *fatal error: The output DAC can not be set to 44100 frames per second (fps). The nearest speed available is 48000 fps.

I've successfully tested the DAC on windows at 44100 Hz

image

I have a couple other usb-c DACs using shairport-sync that play without issue. I'm hoping it's just a simple config issue that I'm overlooking. Any help is greatly appreciated!

mikebrady commented 2 years ago

Thanks. This is a quite a puzzle. Could you try using sps-alsa-explore to investigate it, please? It might shed some light on it.

[Update] I had forgotten that these things existed, so I've ordered one.

quantonian commented 2 years ago

Thanks Mike, I think I may have discovered the culprit:

I noticed that my usb connection keeps dropping:

the dmesg tail shows a consistent usb disconnect and reconnect:

[  172.688071] usb 1-1.1: USB disconnect, device number 7
[  173.022475] usb 1-1.1: new full-speed USB device number 8 using xhci-hcd
[  223.632163] usb 1-1.1: USB disconnect, device number 8
[  223.963116] usb 1-1.1: new full-speed USB device number 9 using xhci-hcd
[  225.936103] usb 1-1.1: USB disconnect, device number 9
[  226.273954] usb 1-1.1: new full-speed USB device number 10 using xhci-hcd
[  227.471775] usb 1-1.1: USB disconnect, device number 10
[  227.802532] usb 1-1.1: new full-speed USB device number 11 using xhci-hcd
[  245.392058] usb 1-1.1: USB disconnect, device number 11
[  245.872458] usb 1-1.1: new full-speed USB device number 12 using xhci-hcd
[  252.561427] usb 1-1.1: USB disconnect, device number 12
[  252.992919] usb 1-1.1: new full-speed USB device number 13 using xhci-hcd
[  255.632070] usb 1-1.1: USB disconnect, device number 13
[  255.967611] usb 1-1.1: new full-speed USB device number 14 using xhci-hcd
[  265.872049] usb 1-1.1: USB disconnect, device number 14
[  266.423084] usb 1-1.1: new full-speed USB device number 15 using xhci-hcd
[  283.535738] usb 1-1.1: USB disconnect, device number 15
[  283.922455] usb 1-1.1: new full-speed USB device number 16 using xhci-hcd
[  311.440054] usb 1-1.1: USB disconnect, device number 16
[  311.923552] usb 1-1.1: new full-speed USB device number 17 using xhci-hcd
[  326.545707] usb 1-1.1: USB disconnect, device number 17
[  328.123384] usb 1-1.1: new full-speed USB device number 18 using xhci-hcd

This coincides with the Apple usb dongle per lsusb. Notice the Device number keeps incrementing:

root@sono-g1:~# lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 004 Device 001: ID 1d6b:0003 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 001 Device 019: ID 05ac:110a Apple, Inc. USB-C to 3.5mm Headphone Jack Adapter
Bus 001 Device 002: ID 1a40:0801  USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 003 Device 001: ID 1d6b:0002 Linux 5.10.127 xhci-hcd xHCI Host Controller
root@sono-g1:~# lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 004 Device 001: ID 1d6b:0003 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 001 Device 020: ID 05ac:110a Apple, Inc. USB-C to 3.5mm Headphone Jack Adapter
Bus 001 Device 002: ID 1a40:0801  USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 003 Device 001: ID 1d6b:0002 Linux 5.10.127 xhci-hcd xHCI Host Controller
root@sono-g1:~# lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 004 Device 001: ID 1d6b:0003 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 001 Device 021: ID 05ac:110a Apple, Inc. USB-C to 3.5mm Headphone Jack Adapter
Bus 001 Device 002: ID 1a40:0801  USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 003 Device 001: ID 1d6b:0002 Linux 5.10.127 xhci-hcd xHCI Host Controller

I also noticed a possible bad cable error in dmesg on one occasion but didn't capture it. I'm thinking the dongle is defective. I'm going to exchange it and see if that clears the usb messages and resolves the issue. If the fatal error persists in shairport-sync, I'll run sps-alsa-explore but I'll need to cross compile that on another machine that will take some time. -thanks

mikebrady commented 2 years ago

Super. I should have mine by Wednesday or Thursday so I’ll be able to check here too.

quantonian commented 2 years ago

A quick update: I purchased another apple usb-c dongle but now aplay -l does not recognize the hardware. This is really strange...

lsusb shows the device:

lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 004 Device 001: ID 1d6b:0003 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 001 Device 003: ID 05ac:110a Apple, Inc. USB-C to 3.5mm Headphone Jack Adapter
Bus 001 Device 002: ID 1a40:0801  USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux 5.10.127 xhci-hcd xHCI Host Controller
Bus 003 Device 001: ID 1d6b:0002 Linux 5.10.127 xhci-hcd xHCI Host Controller

But aplay -l does not:

aplay -l
aplay: device_list:274: no soundcards found...

I tried the original apple dongle and same results. There have been no changes to the config.

At this point I'm thinking it might be the usb-c to usb-a adaptor. I ordered some more of those which should be here Monday. Stay tuned...

quantonian commented 2 years ago

Update: Received the new usb-c female to usb-a male adaptors and no luck. Same results as above. I'm perplexed as to why aplay -l no longer recognizes the device. Mike, I'll continue troubleshooting this but am greatly anticipating your results when you get your apple dongle.

mikebrady commented 2 years ago

Thanks. It's still a couple of days away -- Wednesday probably.

quantonian commented 2 years ago

Another Update: I figured out why aplay -l was not detecting the device... The 3.5mm input jack needs to be plugged in with a powered audio source. This was not so obvious to me because the other two dongles I'm using do not require a powered audio source to be detected.

Regarding the *fatal error for 44100Hz playback, I discovered that the Apple DAC is hardcoded to 48000Hz per the following:

/proc/asound/card0/stream0

Apple, Inc. USB-C to 3.5mm Headphone Jack A at usb-0000:01:00.0-1.3, full speed : USB Audio

Playback:
  Status: Stop
  Interface 1
    Altset 1
    Format: S24_3LE
    Channels: 2
    Endpoint: 2 OUT (SYNC)
    Rates: 48000 - 48000 (continuous)  <-- Here
    Bits: 0
    Channel map: FL FR
  Interface 1
    Altset 2
    Format: S16_LE
    Channels: 2
    Endpoint: 2 OUT (SYNC)
    Rates: 48000 - 48000 (continuous)  <-- and Here
    Bits: 0
    Channel map: FL FR

This is discussed in the original thread for the Apple DAC Review on page 32. Evidently this was broken in kernel 5 https://www.audiosciencereview.com/forum/index.php?threads/review-apple-vs-google-usb-c-headphone-adapters.5541/page-32

Currently I'm looking for a fix or workaround to this issue.

mikebrady commented 2 years ago

Well, I got the device and can confirm that it does not accept a rate of 44,100 frames per second or a multiple of it. Of course, ALSA does provide transcoding, but it would not be particularly satisfactory from a fidelity perspective and requires a pretty hefty CPU.

quantonian commented 2 years ago

Mike, thanks for confirming. I'm going to test on an older version of picoreplayer that is using the 4.19 kernel to see if there is in fact a difference between kernels. But even if this is the case, I'm not sure what can be done to resolve it and if it would be worth the effort? I'm guessing a bug would need to be opened with the usb-audio kernel package with the linux community?

Unless you have any other ideas we can probably close this thread. I'll update my findings later.

mikebrady commented 2 years ago

Yeah, on the face of it it would look like something that should be of interest to those guys. It’s a real pity, because it looks like a great device. It would be interesting to hear how you do with the older kernel, and maybe then it would be appropriate to close the issue for the present.

quantonian commented 2 years ago

Sure enough the 4.19 kernel shows 44100Hz capabilities:

uname -a
Linux piCorePlayer 4.19.105-pcpCore_v8

/proc/asound/card1/stream0

Apple, Inc. USB-C to 3.5mm Headphone Jack A at usb-0000:01:00.0-1.1, full speed : USB Audio

Playback:
  Status: Stop
  Interface 1
    Altset 1
    Format: S24_3LE
    Channels: 2
    Endpoint: 2 OUT (SYNC)
    Rates: 44100, 48000
  Interface 1
    Altset 2
    Format: S16_LE
    Channels: 2
    Endpoint: 2 OUT (SYNC)
    Rates: 44100, 48000

Mike, I have no idea who to contact about this for a potential fix, do you have any connections in your circles? I'm really surprised this has not been addressed because of the value to performance of this dongle.

mikebrady commented 2 years ago

[Update]

Actually I just ran it up on an Ubuntu 16.04 VM:

$ uname -a
Linux ubuntu 4.4.0-210-generic #242-Ubuntu SMP Fri Apr 16 09:57:56 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

It runs at 44,100 and it sounds just great. So it really looks like some kind of oversight.

I ran sps-alsa-explore on it too (which only checks for rates of 44100 or multiples):

mike@ubuntu:~/sps-alsa-explore$ ./sps-alsa-explore -e
...
> Device Full Name:    "hw:A"
  Short Name:          "hw:1"
    Card Name:         "USB-C to 3.5mm Headphone Jack A"
    Device ID:         "USB Audio"
    Device Name:       "USB Audio"
    Subdevice Name:    "subdevice #0"
  This device seems suitable for use with Shairport Sync.
  Possible mixers:     "PCM",0                 Range:  60.00 dB, max:   0.00 dB, min: -60.00 dB
    Suitable rates and formats (suggested setting first):
     Rate              Formats
     44100             S24_3LE,S16_LE
mikebrady commented 2 years ago

Mike, I have no idea who to contact about this for a potential fix, do you have any connections in your circles? I'm really surprised this has not been addressed because of the value to performance of this dongle.

Offhand, I don't have any particular connections, I'm afraid...

quantonian commented 2 years ago

Ok, I'll keep poking around. In the meanwhile I suppose this thread can be closed. I appreciate your time in helping troubleshoot this issue. If I find anything of significance for a workaround or fix I will post an update. -thanks

mikebrady commented 2 years ago

Okay, thanks.

mikebrady commented 2 years ago

Just for completeness, as I mentioned earlier, there is an obvious workaround, which is to use an ALSA transcoder, as follows:

If the output_device is set to, say hw:1, then by changing it to plughw:1, you'll be sending audio to an ALSA virtual device which will transcode the audio and deliver it to hw:1. I just tried it and it works.

It does defeat the purpose a bit, I suppose, because it introduces another layer of audio processing. OTOH, it's arguably better than nothing.

quantonian commented 2 years ago

Mike, thanks for the update.

An update on my end... I've made some progress on trying to overcome this by modifying and recompiling the kernel sound/usb code but have not been able to completely resolve it yet.

Here's what I've done:

The kernel /sound/usb/quirks-table.h header file appears to have override values for certain usb audio devices. I added the following code for the Apple usb-c dongle (this was a copy/paste and modification of existing code):

/* Apple usb-c Dongle */
{
    USB_DEVICE(0x05ac, 0x110a),
    .bInterfaceClass = USB_CLASS_PER_INTERFACE,
    .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
        .ifnum = QUIRK_ANY_INTERFACE,
        .type = QUIRK_COMPOSITE,
        .data = &(const struct snd_usb_audio_quirk[]) {
            {
                .ifnum = 1,
                .type = QUIRK_AUDIO_FIXED_ENDPOINT,
                .data = &(const struct audioformat) {
                    .formats = SNDRV_PCM_FMTBIT_S24_3LE,
                    .channels = 2,
                    .iface = 1,
                    .altsetting = 1,
                    .altset_idx = 1,
                    .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
                    .endpoint = 0x02,
                    .ep_attr = USB_ENDPOINT_SYNC_SYNC,
                    .rates = SNDRV_PCM_RATE_44100 |
                         SNDRV_PCM_RATE_48000,
                    .rate_min = 44100,
                    .rate_max = 48000,
                    .nr_rates = 2,
                    .rate_table = (unsigned int[]) {
                        44100, 48000
                    }
                }
            },
            {
                .ifnum = 1,
                .type = QUIRK_AUDIO_FIXED_ENDPOINT,
                .data = &(const struct audioformat) {
                    .formats = SNDRV_PCM_FMTBIT_S16_LE,
                    .channels = 2,
                    .iface = 1,
                    .altsetting = 1,
                    .altset_idx = 2,
                    .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
                    .endpoint = 0x02,
                    .ep_attr = USB_ENDPOINT_SYNC_SYNC,
                    .rates = SNDRV_PCM_RATE_44100 |
                         SNDRV_PCM_RATE_48000,
                    .rate_min = 44100,
                    .rate_max = 48000,
                    .nr_rates = 2,
                    .rate_table = (unsigned int[]) {
                        44100, 48000
                    }
                }
            },
            {
                .ifnum = -1
            }
        }
    }
},

After compiling and installing, I get the proper specs for the dongle:

proc/asound/card0/stream0
Apple, Inc. USB-C to 3.5mm Headphone Jack A at usb-xhci-hcd.0.auto-1.2, full sp : USB Audio

Playback:
  Status: Stop
  Interface 1
    Altset 1
    Format: S24_3LE
    Channels: 2
    Endpoint: 2 OUT (SYNC)
    Rates: 44100, 48000
    Bits: 0
  Interface 1
    Altset 2
    Format: S16_LE
    Channels: 2
    Endpoint: 2 OUT (SYNC)
    Rates: 44100, 48000
    Bits: 0

This mostly matches with the stream0 output from th 4.x kernel, with the exception of the Bits: 0.

However, shairport-syc fails with the following:

         7.881090513 "rtp.c:1571" Connection 1: AP2 Event Receiver started
        14.364486966 "rtsp.c:3112" Connection 1. AP2 Buffered Audio Stream.
         0.024138208 "audio_alsa.c:602" *fatal error: audio_alsa: Unable to set hw parameters for device "hw:A": Invalid argument.

shairport-sync.conf is configured correctly:

// Sample Configuration File for Shairport Sync 
{
  volume_range_db = 60;
  name = "sono_g1";
};

alsa =
{
  output_device = "hw:A";
// mixer_control_name = "PCM";
};

aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: A [USB-C to 3.5mm Headphone Jack A], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

So there must be more to it that just overriding the device parameters in the header file. I may just be making a cosmetic change?? I'm still troubleshooting but wanted to update the progress. -thanks

mikebrady commented 2 years ago

Great work there. I’ll see if I can make any sense of it when I get back to a machine.

quantonian commented 2 years ago

Thanks Mike!

sps-alsa-explore output is not recognizing the 44100Hz rate so it looks like there is more work to do.

sps-alsa-explore -e
> Device Full Name:    "hw:A"
  Short Name:          "hw:0"
    Card Name:         "USB-C to 3.5mm Headphone Jack A"
    Device ID:         "USB Audio"
    Device Name:       "USB Audio"
    Subdevice Name:    "subdevice #0"
  Shairport Sync can not use this device.

sps-alsa-explore -vvv
         0.000006833 "sps-alsa-explore.c:702" startup.
         0.009198833 "sps-alsa-explore.c:417" card number 0, device number: 0.
         0.000111417 "sps-alsa-explore.c:425" 1 subdevices,
         0.000080021 "sps-alsa-explore.c:451" device name: "hw:A"
         0.000054271 "sps-alsa-explore.c:453" card: 0, device: 0
         0.001746875 "sps-alsa-explore.c:292" could not set output format 10 for device "hw:0": Invalid argument
         0.000154854 "sps-alsa-explore.c:356" check 44100, S32_LE, result: -2.
         0.001598896 "sps-alsa-explore.c:292" could not set output format 11 for device "hw:0": Invalid argument
         0.000151250 "sps-alsa-explore.c:356" check 44100, S32_BE, result: -2.
         0.001588062 "sps-alsa-explore.c:292" could not set output format 6 for device "hw:0": Invalid argument
         0.000155084 "sps-alsa-explore.c:356" check 44100, S24_LE, result: -2.
         0.001561020 "sps-alsa-explore.c:292" could not set output format 7 for device "hw:0": Invalid argument
         0.000159605 "sps-alsa-explore.c:356" check 44100, S24_BE, result: -2.
         0.009853854 "sps-alsa-explore.c:283" unable to set hardware parameters for device "hw:0": Invalid argument.
         0.033455041 "sps-alsa-explore.c:356" check 44100, S24_3LE, result: -1.
         0.004346355 "sps-alsa-explore.c:292" could not set output format 10 for device "hw:0": Invalid argument
         0.000537083 "sps-alsa-explore.c:356" check 44100, S32_LE, result: -2.
         0.003869500 "sps-alsa-explore.c:292" could not set output format 11 for device "hw:0": Invalid argument
         0.000529333 "sps-alsa-explore.c:356" check 44100, S32_BE, result: -2.
         0.003537667 "sps-alsa-explore.c:292" could not set output format 6 for device "hw:0": Invalid argument
         0.000517792 "sps-alsa-explore.c:356" check 44100, S24_LE, result: -2.
         0.003560854 "sps-alsa-explore.c:292" could not set output format 7 for device "hw:0": Invalid argument
         0.000524937 "sps-alsa-explore.c:356" check 44100, S24_BE, result: -2.
         0.013138688 "sps-alsa-explore.c:283" unable to set hardware parameters for device "hw:0": Invalid argument.
         0.032664187 "sps-alsa-explore.c:356" check 44100, S24_3LE, result: -1.
         0.003682146 "sps-alsa-explore.c:292" could not set output format 10 for device "hw:0": Invalid argument
         0.000531000 "sps-alsa-explore.c:356" check 44100, S32_LE, result: -2.
         0.003715208 "sps-alsa-explore.c:292" could not set output format 11 for device "hw:0": Invalid argument
         0.000526688 "sps-alsa-explore.c:356" check 44100, S32_BE, result: -2.
         0.003566812 "sps-alsa-explore.c:292" could not set output format 6 for device "hw:0": Invalid argument
         0.000518063 "sps-alsa-explore.c:356" check 44100, S24_LE, result: -2.
         0.003827791 "sps-alsa-explore.c:292" could not set output format 7 for device "hw:0": Invalid argument
         0.000521146 "sps-alsa-explore.c:356" check 44100, S24_BE, result: -2.
         0.014425104 "sps-alsa-explore.c:283" unable to set hardware parameters for device "hw:0": Invalid argument.
         0.032759063 "sps-alsa-explore.c:356" check 44100, S24_3LE, result: -1.
         0.020433062 "sps-alsa-explore.c:583" Devices found in the sound devices directory "/dev/snd": 3, devices accessible: 3.
mikebrady commented 2 years ago

Very interesting alright -- I do think you are correct about the change you made being cosmetic in nature, but I also think it offers an important clue as to where to look for / insert the fix. FWIW I might try to make sps-alsa-explore list the actual error codes as well as the -1, -2, etc.

quantonian commented 2 years ago

[Update]

Hey Mike, I've still been working at this without success but I've made a few interesting discoveries

In the original stream0 output I noticed that the Bits: value is 0, whereas on my other usb-c dacs there is a value for 16, 24bits, etc.

proc/asound/card0/stream0
Apple, Inc. USB-C to 3.5mm Headphone Jack A at usb-xhci-hcd.0.auto-1.2, full sp : USB Audio

Playback:
  Status: Stop
  Interface 1
    Altset 1
    Format: S24_3LE
    Channels: 2
    Endpoint: 2 OUT (SYNC)
    Rates: 44100, 48000
    Bits: 0
  Interface 1
    Altset 2
    Format: S16_LE
    Channels: 2
    Endpoint: 2 OUT (SYNC)
    Rates: 44100, 48000
    Bits: 0

I was able to populate these values by adding .fmt_bits = 24, and .fmt_bits = 16, in the quirks-table.h file above which successfully populates the Bits: value but unfortunately had no effect on the dac.

On top of that, when playing a .wav file natively through aplay, it shows the following output:

aplay StarWars60.wav
Playing WAVE 'StarWars60.wav' : Signed 16 bit Little Endian, Rate 22050 Hz, Mono

It's interesting this output shows 22050 Hz which is half of the spec'd 44100 Hz. And it's odd that it shows Mono out?? I'm not able to designate any other output rates using the -r option, it always defaults to 22050 Hz.

This is definitely a clock issue, but I'm not convinced that the problem lies in the /sound/usb kernel code and that it may actually be in the /drivers/usb code, or possibly somewhere else?? At this point this is way beyond my skillset and has been a good time-suck, but I'm thinking it may be time to move on. Plus the fact this is only a $9 dac.

If you have any other ideas or want me to try anything else, I'll keep my eye on this thread. If I make any other constructive progress I'll continue to make updates. As always, thanks for your time!

mikebrady commented 2 years ago

Thanks for the update. I too have spent some time looking at this and am none the wiser yet. I am not at all familiar with the architecture of usb audio, but maybe over the weeks ahead — and I think it will at least be weeks — something will turn up.

Is it possible that the file is where the 22,050 number is coming from, I wonder?

mikebrady commented 2 years ago

See also this issue, where a file is definitely being played by aplay at the wrong rate.

tw-hx commented 1 year ago

The kernel /sound/usb/quirks-table.h header file appears to have override values for certain usb audio devices. I added the following code for the Apple usb-c dongle (this was a copy/paste and modification of existing code): ...

@quantonian Thanks for posting this. I can confirm the same problem with a locked 48000Hz sample rate persists with the Apple USB-C dongle (A2049) on Linux 6.2.12. Would you consider submitting your patch upstream to the ALSA/kernel developers? Looking in the current kernel source code there's nothing yet for this dongle in the quirks-table.h file.

jonathansapp commented 1 year ago

After reading https://bugzilla.kernel.org/show_bug.cgi?id=217501 I looked to see how I might change the active device configuration.

usb_modeswitch -v 05ac -p 110a -u 3 appears to change the configuration from #2 to #3, such that the device now supports 44khz playback.

Since my device shows up as audio card 2:

root@pi2:/mnt/smb-sark-docker/shairport-sync# cat /proc/asound/card2/stream0
Apple, Inc. USB-C to 3.5mm Headphone Jack A at usb-3f980000.usb-1.3, full speed : USB Audio

Playback:
  Status: Running
    Interface = 1
    Altset = 1
    Packet Size = 288
    Momentary freq = 44100 Hz (0x2c.199a)
  Interface 1
    Altset 1
    Format: S24_3LE
    Channels: 2
    Endpoint: 0x02 (2 OUT) (SYNC)
    Rates: 44100, 48000
    Bits: 24
    Channel map: FL FR
  Interface 1
    Altset 2
    Format: S16_LE
    Channels: 2
    Endpoint: 0x02 (2 OUT) (SYNC)
    Rates: 44100, 48000
    Bits: 16
    Channel map: FL FR

I was able to use it in shairport-sync with "hw:2" instead of "plughw:2". As an added bonus, cpu usage has dropped from 75%+ to ~15%

I might code a udev rule to automatically perform this configuration switch on boot/plug events.

mikebrady commented 1 year ago

That is fantastic work, thanks! It's a lovely DAC.

[Update]

I can confirm that I got it to work, but as the root user. Also, it might be worth explaining the parameters:

-v 05ac means the product vendor is Apple, -p 110a identifies the specific product, in this case the USB-C to Headphone DAC -u 3 means select configuration 3.

Running sps-alsa-explore (it's DAC 4 on my system) after this gives:

...
> Device Full Name:    "hw:A"
  Short Name:          "hw:4"
  This device seems suitable for use with Shairport Sync.
  Possible mixers:     "PCM",0                 Range:  60.00 dB
  The following rate and format would be chosen by Shairport Sync in "auto" mode:
     Rate              Format
     44100             S24_3LE
...

Also, remember that the device will not appear as a DAC unless something is plugged into the audio jack!

jonathansapp commented 1 year ago

As root:

I droppd a udev rule on my system at /etc/udev/rules.d/85-apple-dac-config.rules with the following contents:

ATTRS{idVendor}=="05ac", ATTRS{idProduct}=="110a", RUN+="/usr/sbin/usb_modeswitch -v 05ac -p 110a -u 3"

Then, running udevadm control --reload-rules, I was able to remove and re-insert the device and get the automatic configuration treatment. I don't know if the udev rule is following idiomatic norms for this usage nor if the sequence number on the udev rule file is correct (I picked something arbitrary).

Of interesting note is /lib/udev/rules.d/40-usb_modeswitch.rules.

I'd like to explore the hot plug issue as, after a power outage, my pi 2 comes up before my amp's relay and I get no sound at first.

wongcoder commented 1 year ago

I'd like to thank everyone else for solving this issue for me. The only thing I had to change from the setup directions is that, instead of using hw:2, I ended up using hw:A, which I received after running shairport's $ shairport-sync -h. That way, even though the hardware location might change, the hardware wouldn't change on restart.

mc510 commented 1 year ago

Wonder if someone here would be willing to provide step-by-step instructions for the complete dummy? I'd like to use one of these Apple usb-c DACs but I'm not sure that I understand the fix.

wongcoder commented 1 year ago

Sure.

  1. Have Shairport-Sync installed and configured. This is a major prerequisite, as it installs the prerequisites for ALSA, which are the commands you personally will be touching.
  2. Create a new file /etc/udev/rules.d/85-apple-dac-config.rules using your text editor of choice (nano if you're a beginner).
  3. Enter ATTRS{idVendor}=="05ac", ATTRS{idProduct}=="110a", RUN+="/usr/sbin/usb_modeswitch -v 05ac -p 110a -u 3". Save the file.
  4. Run udevadm control --reload-rules.
  5. Unplug the Apple dongle.
  6. Modify Shairport Sync's /etc/shairport-sync.conf. Again, open this in the text editor of your choice and jump to the ALSA section, which likely will look like this:
    alsa =
    {
    output_device = "hw:Headphones"; // the name of the alsa output device. Use "shairport-sync -h" to discover the names of ALSA hardware devices. Use "alsamixer" or "aplay" to find out the names of devices, mixers, etc.
    mixer_control_name = "default"; // the name of the mixer to use to adjust output volume. If not specified, volume in adjusted in software.
    ...
    }
  7. Replace the current input in output_device with "hw: A". It should look like the following:
    alsa =
    {
    output_device = "hw:A"; // the name of the alsa output device. Use "shairport-sync -h" to discover the names of ALSA hardware devices. Use "alsamixer" or "aplay" to find out the names of devices, mixers, etc.
    mixer_control_name = "default"; // the name of the mixer to use to adjust output volume. If not specified, volume in adjusted in software.
    ...
    }

    image

  8. Save the configuration, restart the service (or your Pi) and you should be off to the races.

Debugging: In case it doesn't work, likely one of two things happened:

  1. It's not called hw:A. Run shairport-sync -h.. Try me first.
  2. Apple in the ever knowing genius recently changed the hardware attributes. I doubt this would happen, but if it does, you can validate this by following this page (https://www.alsa-project.org/wiki/Changing_card_IDs_with_udev), which in case this page is broken, it's just running: udevadm monitor --kernel --subsystem-match=sound, unplugging your card, and then plugging it in again. You'll likely see some event that says: /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:3.0/sound/card3/controlC3. You can omit the final part. The device path almost certainly ends in /cardN, where N represents a valid integer. From there, you can check using udevadm info -q all -a /sys<the path that you found above here>. For example, mine would be: udevadm info -q all -a /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:3.0/sound/card3.

From there, look at the idVendor and idProduct. If they don't match, we have our issue.