* [BUG] snd-usb-audio: Audient iD14 (2708:0008) 20 dB channel imbalance
@ 2026-08-10 19:25 Neil Andrews
2026-08-11 6:09 ` Takashi Iwai
0 siblings, 1 reply; 3+ messages in thread
From: Neil Andrews @ 2026-08-10 19:25 UTC (permalink / raw)
To: linux-sound; +Cc: tiwai, perex
[-- Attachment #1: Type: text/plain, Size: 5587 bytes --]
Hi,
On an Audient iD14 (USB 2708:0008), snd-usb-audio exposes a mixer control
"Speaker Playback Volume" that covers only 4 of the device's 6 playback
channels, and does not cover PCM channel 0. Userspace (PipeWire, PulseAudio)
adopts it as the card's hardware playback volume, so any setting below 100%
attenuates some channels but not others. At a typical 80% setting the
inter-channel imbalance is 20 dB. The device is balanced under Windows, where
the vendor driver does not drive this control.
Not a regression: I diagnosed it on kernel 6.19.14 and re-measured on
7.1.6 with identical results.
System:
Kernel: 7.1.6-1-cachyos (CachyOS)
alsa-lib: 1.2.16.1, alsa-utils 1.2.16
PipeWire: 1.6.8, WirePlumber 0.5.15
Device: Audient iD14, USB 2708:0008, bcdDevice 1.11
The control, against a playback stream that is 6 channels
(Channels: 6, Channel map: FL FR FC LFE RL RR):
numid=11,iface=MIXER,name='Speaker Playback Volume'
; type=INTEGER,access=rw---R--,values=4,min=0,max=127,step=0
: values=107,107,107,107
| dBminmax-min=-127.00dB,max=0.00dB
The driver records the partial coverage itself (from alsa-info):
Unit: 12
Control: name="Speaker Playback Volume", index=0
Info: id=12, control=2, cmask=0xf, channels=4, type="S16"
Descriptor origin. FEATURE_UNIT bUnitID=12 advertises Volume on only 4 of its
6 logical channels:
bmaControls(0) 0x00000000
bmaControls(1..4) 0x0000000c Volume Control (read/write)
bmaControls(5) 0x00000000
bmaControls(6) 0x00000000
FU 12 is also not in the direct playback path. USB streaming input to Speaker
output runs:
INPUT_TERMINAL 2 (USB Streaming, 6ch)
-> EXTENSION_UNIT 51 (6ch)
-> FEATURE_UNIT 10 (6ch, bmaControls(0..6) all 0x00000000, no controls)
-> OUTPUT_TERMINAL 20 (0x0301 Speaker)
whereas FU 12 sits on the monitor-mixer branch:
EXTENSION_UNIT 50 (16ch) -> MIXER_UNIT 60 (6ch) -> FEATURE_UNIT 12
-> EXTENSION_UNIT 54 (6ch) / EXTENSION_UNIT 55 (3ch)
-> back into EXTENSION_UNIT 51 and 52
So FU 12 is traced through to the Speaker output terminal and named
"Speaker Playback Volume", but it is a partial-coverage control on a mixer
branch rather than a master volume for the stream. Consistent with that, the
measured coverage does not match a naive reading of cmask=0xf (logical
channels 1-4): it is PCM channel 0 that escapes attenuation and PCM channel 1
that receives it.
Measurements. The iD14 loops output channels 0 and 1 back onto capture
channels 10 and 11. I played 6-channel S32_LE WAVs carrying a -12 dBFS sine in
exactly one channel, straight to hw: with the card profile set to off so
PipeWire was out of the path, and recorded all 12 capture channels. The two
files are bit-identical in amplitude and differ only in which channel carries
the tone.
Speaker Playback Volume = 107/127 (-20.00 dB):
output ch0 -> loopback ch10 RMS -15.89 dBFS
output ch1 -> loopback ch11 RMS -35.89 dBFS
delta: 20.00 dB
Speaker Playback Volume = 127/127 (0.00 dB):
output ch0 -> loopback ch10 RMS -15.89 dBFS
output ch1 -> loopback ch11 RMS -15.89 dBFS
delta: 0.00 dB
The delta tracks the control's own dB value exactly. PCM channel 0 is
unaffected at either setting; PCM channel 1 is attenuated by precisely the
amount the control reports. Output channels 2-5 are not carried on the
loopback, so I could not measure them. Those four figures came out the same on
6.19.14 and 7.1.6.
Workaround. Setting api.alsa.soft-mixer = true for the device in WirePlumber,
so PipeWire does volume in software and leaves the control at 0 dB, fixes it
completely. That also requires the ALSA state saved at 0 dB, or alsa-restore
reinstates the attenuation at the next boot and soft-mixer leaves it there.
Suggested fix. Ignoring the unit via sound/usb/mixer_maps.c looks like the
minimal change, so no hardware volume control is exported and userspace falls
back to software volume:
/* Audient iD14: FU 12 advertises Volume on only 4 of 6 logical channels and
* sits on the monitor-mixer branch, but is traced to the Speaker output
* terminal and adopted by userspace as the stream's hardware volume,
* producing a large inter-channel imbalance. Ignore it.
*/
static const struct usbmix_name_map audient_id14_map[] = {
{ 12, NULL },
{ 0 }
};
and in usbmix_ctl_maps[]:
{
.id = USB_ID(0x2708, 0x0008),
.map = audient_id14_map,
},
Untested, and you may prefer a different approach - such as declining to
export any feature unit whose channel coverage is narrower than the stream it
is attached to, which would presumably help other interfaces with the same
descriptor shape. Happy to test patches; I have the device and a measurement
rig that gives an objective pass/fail in about thirty seconds.
Two incidental notes, neither of which I think bears on the imbalance. The
driver logs "usb 1-13: 11:0: cannot get min/max values for control 11 (id 11)"
twice at probe, for unit 11 rather than FU 12. And the device reports
bNumConfigurations 2 while returning a byte-identical configuration descriptor
for both indices, so lsusb legitimately prints config 1 twice.
alsa-info and the lsusb descriptor dump attached, both gzipped. I also have
before/after loopback recordings as WAVs (~7 MB each) available on request.
For transparency: Claude Code (Opus 5) helped diagnose this issue
and generate this report.
Thanks,
Neil
[-- Attachment #2: alsa-info-id14.txt.gz --]
[-- Type: application/gzip, Size: 14744 bytes --]
[-- Attachment #3: id14-lsusb.txt.gz --]
[-- Type: application/gzip, Size: 2652 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [BUG] snd-usb-audio: Audient iD14 (2708:0008) 20 dB channel imbalance
2026-08-10 19:25 [BUG] snd-usb-audio: Audient iD14 (2708:0008) 20 dB channel imbalance Neil Andrews
@ 2026-08-11 6:09 ` Takashi Iwai
2026-08-11 18:13 ` Neil Andrews
0 siblings, 1 reply; 3+ messages in thread
From: Takashi Iwai @ 2026-08-11 6:09 UTC (permalink / raw)
To: Neil Andrews; +Cc: linux-sound, tiwai, perex
On Mon, 10 Aug 2026 21:25:20 +0200,
Neil Andrews wrote:
>
> Hi,
>
> On an Audient iD14 (USB 2708:0008), snd-usb-audio exposes a mixer control
> "Speaker Playback Volume" that covers only 4 of the device's 6 playback
> channels, and does not cover PCM channel 0. Userspace (PipeWire, PulseAudio)
> adopts it as the card's hardware playback volume, so any setting below 100%
> attenuates some channels but not others. At a typical 80% setting the
> inter-channel imbalance is 20 dB. The device is balanced under Windows, where
> the vendor driver does not drive this control.
>
> Not a regression: I diagnosed it on kernel 6.19.14 and re-measured on
> 7.1.6 with identical results.
>
> System:
> Kernel: 7.1.6-1-cachyos (CachyOS)
> alsa-lib: 1.2.16.1, alsa-utils 1.2.16
> PipeWire: 1.6.8, WirePlumber 0.5.15
> Device: Audient iD14, USB 2708:0008, bcdDevice 1.11
>
> The control, against a playback stream that is 6 channels
> (Channels: 6, Channel map: FL FR FC LFE RL RR):
>
> numid=11,iface=MIXER,name='Speaker Playback Volume'
> ; type=INTEGER,access=rw---R--,values=4,min=0,max=127,step=0
> : values=107,107,107,107
> | dBminmax-min=-127.00dB,max=0.00dB
>
> The driver records the partial coverage itself (from alsa-info):
>
> Unit: 12
> Control: name="Speaker Playback Volume", index=0
> Info: id=12, control=2, cmask=0xf, channels=4, type="S16"
>
> Descriptor origin. FEATURE_UNIT bUnitID=12 advertises Volume on only 4 of its
> 6 logical channels:
>
> bmaControls(0) 0x00000000
> bmaControls(1..4) 0x0000000c Volume Control (read/write)
> bmaControls(5) 0x00000000
> bmaControls(6) 0x00000000
>
> FU 12 is also not in the direct playback path. USB streaming input to Speaker
> output runs:
>
> INPUT_TERMINAL 2 (USB Streaming, 6ch)
> -> EXTENSION_UNIT 51 (6ch)
> -> FEATURE_UNIT 10 (6ch, bmaControls(0..6) all 0x00000000, no controls)
> -> OUTPUT_TERMINAL 20 (0x0301 Speaker)
>
> whereas FU 12 sits on the monitor-mixer branch:
>
> EXTENSION_UNIT 50 (16ch) -> MIXER_UNIT 60 (6ch) -> FEATURE_UNIT 12
> -> EXTENSION_UNIT 54 (6ch) / EXTENSION_UNIT 55 (3ch)
> -> back into EXTENSION_UNIT 51 and 52
>
> So FU 12 is traced through to the Speaker output terminal and named
> "Speaker Playback Volume", but it is a partial-coverage control on a mixer
> branch rather than a master volume for the stream. Consistent with that, the
> measured coverage does not match a naive reading of cmask=0xf (logical
> channels 1-4): it is PCM channel 0 that escapes attenuation and PCM channel 1
> that receives it.
>
> Measurements. The iD14 loops output channels 0 and 1 back onto capture
> channels 10 and 11. I played 6-channel S32_LE WAVs carrying a -12 dBFS sine in
> exactly one channel, straight to hw: with the card profile set to off so
> PipeWire was out of the path, and recorded all 12 capture channels. The two
> files are bit-identical in amplitude and differ only in which channel carries
> the tone.
>
> Speaker Playback Volume = 107/127 (-20.00 dB):
> output ch0 -> loopback ch10 RMS -15.89 dBFS
> output ch1 -> loopback ch11 RMS -35.89 dBFS
> delta: 20.00 dB
>
> Speaker Playback Volume = 127/127 (0.00 dB):
> output ch0 -> loopback ch10 RMS -15.89 dBFS
> output ch1 -> loopback ch11 RMS -15.89 dBFS
> delta: 0.00 dB
>
> The delta tracks the control's own dB value exactly. PCM channel 0 is
> unaffected at either setting; PCM channel 1 is attenuated by precisely the
> amount the control reports. Output channels 2-5 are not carried on the
> loopback, so I could not measure them. Those four figures came out the same on
> 6.19.14 and 7.1.6.
>
> Workaround. Setting api.alsa.soft-mixer = true for the device in WirePlumber,
> so PipeWire does volume in software and leaves the control at 0 dB, fixes it
> completely. That also requires the ALSA state saved at 0 dB, or alsa-restore
> reinstates the attenuation at the next boot and soft-mixer leaves it there.
>
> Suggested fix. Ignoring the unit via sound/usb/mixer_maps.c looks like the
> minimal change, so no hardware volume control is exported and userspace falls
> back to software volume:
>
> /* Audient iD14: FU 12 advertises Volume on only 4 of 6 logical channels and
> * sits on the monitor-mixer branch, but is traced to the Speaker output
> * terminal and adopted by userspace as the stream's hardware volume,
> * producing a large inter-channel imbalance. Ignore it.
> */
> static const struct usbmix_name_map audient_id14_map[] = {
> { 12, NULL },
> { 0 }
> };
>
> and in usbmix_ctl_maps[]:
>
> {
> .id = USB_ID(0x2708, 0x0008),
> .map = audient_id14_map,
> },
>
> Untested, and you may prefer a different approach - such as declining to
> export any feature unit whose channel coverage is narrower than the stream it
> is attached to, which would presumably help other interfaces with the same
> descriptor shape. Happy to test patches; I have the device and a measurement
> rig that gives an objective pass/fail in about thirty seconds.
It's fine to skip the volume if it actually improves -- so please test
it ;)
Judging from your description, an alternative with keeping the volume
control would be to just rename it; the problem is that it's tied with
"Speaker". You can name it a different, some non-standard one,
instead, too.
thanks,
Takashi
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [BUG] snd-usb-audio: Audient iD14 (2708:0008) 20 dB channel imbalance
2026-08-11 6:09 ` Takashi Iwai
@ 2026-08-11 18:13 ` Neil Andrews
0 siblings, 0 replies; 3+ messages in thread
From: Neil Andrews @ 2026-08-11 18:13 UTC (permalink / raw)
To: Takashi Iwai; +Cc: linux-sound, tiwai, perex
On Tue, 11 Aug 2026, Takashi Iwai wrote:
> It's fine to skip the volume if it actually improves -- so please test
> it ;)
>
> Judging from your description, an alternative with keeping the volume
> control would be to just rename it; the problem is that it's tied with
> "Speaker". You can name it a different, some non-standard one,
> instead, too.
Hi Takashi,
I tested both on 7.1.6 with sound/usb rebuilt out of tree, measured with
the loopback rig from the original report. Both fix it. I would suggest
the rename.
Baseline, unpatched, PipeWire at 50% (control driven to 109/127):
18.00 dB imbalance.
1. { 12, NULL }
Control gone, userspace falls back to software volume, 0.00 dB. So it
does improve.
One wrinkle: FU 12 keeps its value across a module reload, so if the
quirk arrives while the hardware is already attenuated, the imbalance
stays and there is no longer a control with which to undo it (measured:
18.00 dB, control absent). Only a power cycle clears it, which matters
for anyone whose saved ALSA state holds a value below 0 dB.
2. { 12, "Monitor Mix Playback" }
--- a/sound/usb/mixer_maps.c
+++ b/sound/usb/mixer_maps.c
@@ -495,6 +495,19 @@
{}
};
+/* Audient iD14: FU 12 advertises Volume on only 4 of its 6 logical channels
+ * and sits on the monitor-mixer branch, but it is traced through to the
+ * Speaker output terminal and gets named "Speaker Playback Volume". Userspace
+ * then adopts it as the stream's hardware volume, and any setting below 0 dB
+ * attenuates some channels but not others (20 dB imbalance at 80%). Give it a
+ * non-standard name so that it is no longer taken for the stream's master
+ * volume, while remaining reachable for anyone who wants the monitor gain.
+ */
+static const struct usbmix_name_map audient_id14_map[] = {
+ { 12, "Monitor Mix Playback" }, /* FU, partial coverage */
+ {}
+};
+
/*
* Control map entries
*/
@@ -579,6 +592,11 @@
.map = maya44_map,
},
{
+ /* Audient iD14 */
+ .id = USB_ID(0x2708, 0x0008),
+ .map = audient_id14_map,
+ },
+ {
/* KEF X300A */
.id = USB_ID(0x27ac, 0x1000),
.map = scms_usb3318_map,
Gives numid=11,name='Monitor Mix Playback Volume'. PipeWire no longer
picks it up (control stays at 127, 0.00 dB), and it still works when set
deliberately, so an attenuated device can be recovered: 107 by hand
gives 20.00 dB, back to 127 gives 0.00 dB. The name ends in "Playback"
because a mapped name suppresses the automatic " Playback" but still
gets " Volume" appended.
3. A qualification to my report
I said userspace adopts the control as the card's hardware playback
volume, without qualifying it. That is too broad.
alsa-ucm-conf 1.2.16.1 ships
USB-Audio/Audient/Audient-iD14-HiFi-0008.conf, which splits the device
into 2-channel sinks and declares no playback mixer element. With it in
use PipeWire never touches FU 12: the control stays at 127 at every
volume setting, on both split sinks and on the underlying node.
Reproducing needs the ACP path instead, which I got by setting
api.alsa.use-ucm = false for the device in WirePlumber (then 100% ->
127, 80% -> 122, 50% -> 109). All measurements above were taken that
way.
So the affected set is narrower than I implied: the ACP path rather than
that UCM profile, plus anyone whose saved ALSA state carries a value
below 0 dB, since that is restored at boot either way. The descriptor
problem itself is unchanged.
Happy to send either version as a proper patch with a Signed-off-by, and
to test anything else on the hardware.
thanks,
Neil
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-11 18:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-10 19:25 [BUG] snd-usb-audio: Audient iD14 (2708:0008) 20 dB channel imbalance Neil Andrews
2026-08-11 6:09 ` Takashi Iwai
2026-08-11 18:13 ` Neil Andrews
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox