How I debugged my Audioengine HD3 speakers in Linux
I purchased a pair of desktop speakers recently, the Audioengine HD3 (based on this review). On my desktop, I'm running Ubuntu; 20.10 Groovy Gorilla until recently, but 21.04 Hirsute Hippo now. The speakers worked just fine when I first got them, but somewhere along the way (I don't know exactly when, but quite possibly when I updated), I couldn't get any sound out of them, despite the system having no trouble detecting them.
With the help of my local Linux User Group, this is how we debugged the issue, and what I learned along the way. This post is structured like a bug report with all the information I thought might be relevant, in order of what was tried, but it is sprinkled with exposition and just happens to end with a solution.
When connecting my speakers, I see this in
usb 1-1: 1:1: cannot set freq 48000 to ep 0x3
I've been told that audio in Ubuntu (and most Linux distributions) consists of two primary layers:
- Advanced Linux Sound Architecture (ALSA), the lower layer.
- PulseAudio, the higher layer.
To restore audio, I should first make sure I can play audio through ALSA with its tools. Once that is solved, then any remaining problems can be attributed to the Pulse layer. To play audio through ALSA, I must first disable Pulse to make it release its handles to my audio devices:
systemctl --global stop pulseaudio.service pulseaudio.socket
aplay is an ALSA tool for playing audio.
aplay -L lists all the "devices" (in ALSA parlance) that can play audio.
Each device is actually a combination of a plugin and the hardware.
It listed 14 devices for my speakers.
(There are even more for my onboard audio, video card, and webcam).
speaker-test is an ALSA tool for playing test audio when one doesn't have an audio file on hand.
speaker-test -D $device -c 2 makes sound with 6 of my speaker's ALSA devices, the ones with these plugins:
To name the device, they are all suffixed with
aplay requires an audio file.
I generated a test audio file using
ffmpeg -f lavfi -i "sine=frequency=1000:sample_rate=48000:duration=5" \
-c:a pcm_s16le -ac 2 sine.wav
aplay -D $device -c 2 sine.wav works when the WAV file is encoded in stereo at 48k Hz to 16 bit signed little endian (SLE), and only with those parameters.
Trying a 44.1k WAV file plays a burst of audio for a fraction of a second at the beginning of the very first attempt, and then nothing at all following or on subsequent attempts.
At this point it appears that sound is working, at 48k at least. So I enable Pulse audio:
systemctl --global start pulseaudio.service pulseaudio.socket
I see this in
retire_capture_urb: 39 callbacks suppressed
When I have Pulse enabled, I'm testing sound via Settings -> Sound -> Volume Levels -> Output -> Test.
pacmd list-sinks lists Pulse "sinks" (their name for devices, which may be virtual).
sample spec: s16le 2ch 44100Hz for my speakers.
Trying this command changes the
properties list but does not affect the
pacmd update-sink-proplist alsa_output.$alsa_output \
/etc/pulse/daemon.conf to set
alternate-sample-rate both to
48000 and restarting Pulse (
pulseaudio -k) corrects the
sample spec, but still no sound is made.
I disable Pulse again, and find my previously working ALSA commands have stopped making sound.
alsamixer, select my speakers, and see volume at
Holding the Up key, I can bring the volume to
100<>100, and sound works again.
So it seems something in Pulse is setting my volume to 0%, and there's nothing I can do in Pulse to change it.
In fact, everything I saw in Pulse showed my volume at 100%.
But unlike the other ALSA tools, I can run
alsamixer while Pulse is enabled.
So I enable Pulse, open
alsamixer, restore volume to 100%, and the speakers start making sound.