// we are

Nura Headphones on Linux

Tl;dr: Quirk for the USB mode is on the way for fixing the problem upstream, force a sampling rate of 48kHz to get sound out in the mean time

I received a couple of days ago my nuraphones which I backed on Kickstarter some time ago. So far, I really like the sound quality and they sound a bit better than my monitoring loud speakers. I really like in-ear monitors, so this headset is no issue for me, on the contrary!

Since I am exclusively a Linux user, I wanted to get things working on my work’s PC and my Sailfish OS X. I had no issue with bluetooth on my phone and Desktop PC (instructions), but the tethered mode was not on either platforms… The sound card would be recognized but no sounds coming out…

Debugging the issue

After verifying that the headset indeed works out of the box on Windows (no driver needed), I knew the headset was likely misconfigured. Back on Linux, I tried using alsa directly to reduce the problem as much as possible, and the sound just came out without any hickups!

After fiddling with some pulseaudio parameters to mimic as closely as possible the settings used by aplay, I managed to get the sound out simply by setting the following parameter in /etc/pulse/daemon.conf:

default-sample-rate = 48000

Now that we have some sound out, let’s try to understand why pulseaudio was defaulting to 44.1kHz. It would seem like Windows, or ALSA (protocol used by aplay to play sound) are using the default sampling rate of the headphones. However, pulseaudio uses 44.1kHz and 16 bit samples by default because it is already sufficient to cover the entire spectrum that can be heard by the human ear and increasing it for playback is just a waste of computing power. So, to avoid resampling from 44.1kHz to 48kHz, which reduces the quality of the sound and uses more CPU, pulseaudio prefers selecting a matching sampling rate if the USB interface supports it.

Let’s check what are the supported sampling rates:

$ cat /proc/asound/nuraphone/stream0
nura nuraphone at usb-0000:00:14.0-4, full speed : USB Audio

Status: Stop
Interface 2
    Altset 1
    Format: S16_LE
    Channels: 2
    Endpoint: 3 OUT (NONE)
    Rates: 48000, 44100, 32000, 22050, 16000, 8000

Status: Stop
Interface 1
    Altset 1
    Format: S16_LE
    Channels: 1
    Endpoint: 3 IN (NONE)
    Rates: 48000

Bingo, 44.1kHz is indeed a valid option, if are to believe what the headphones report! After trying to operate pulseaudio at all the listed sampling rates, it appears that only the 48kHz mode actually works… Also, I never managed to make use of the microphone, on Windows or Linux. So, to avoid any problem, we need to instruct Linux to deactivate the features the headset is falsely claiming to support.

Patching the Linux kernel (patch)

I have been a kernel developer for almost 8 years, and have been compiling Linux kernels for a bit more than a decade, but I never had to deal with the sound sub-system, so that was an interesting feeling.

Identifying the driver I needed to fix was quite easy, and I quickly found the file sound/usb/quirks-table.h which contains most of the quirks for the USB sound cards.

After that, it was just a matter of following the countless examples found in the file, figuring out some parameters by using printk, testing the result, iterating until it worked as expected, and then crafting a patch that I sent to the alsa-devel mailing list.

I am now waiting for reviews, which will end either with me having to implement a better solution or with the patch getting accepted directly. I’ll keep you up to date.

EDIT 2017-01-15: My patch got accepted as-is (link), and it will land in Linux 4.16 or 4.17.

EDIT 2017-01-21: My patch is part of the 4.16 sound pull request, which means it will almost certainly be part of Linux 4.16.

Workaround until Linux is fixed

For some distributions, it may take years until the fixed code lands. In the mean time, you may change pulseaudio’s configuration by adding the following line:

default-sample-rate = 48000

This will slightly increase your CPU consumption, but you will likely not be able to measure it, so don’t sweat about it!

What’s next?

Here is a list of features I would like to see on the Linux desktop:

  • Battery status: Not sure this is even possible with the current hardware, I will need to investigate
  • Selecting profile: Right now, profiles can only be changed using a smartphone. I would like to change that.

I am not commiting to implementing any of this, but that would be nice to see.

That’s all, folks!