Re: ALSA: usb-audio: guessed channel positions on a device that names its channels

From: Takashi Iwai

Date: Fri Aug 28 2026 - 09:50:28 EST


On Mon, 24 Aug 2026 00:55:21 +0200,
Mikhail Gavrilov wrote:
>
> Hello,
> I ran into this setting up a Topping M62 on Linux. It is a USB
> interface with ten playback channels and sixteen capture channels --
> five stereo pairs out, a set of inputs and loopback returns in. Nothing
> about it is a home cinema. But alsamixer labels its playback controls
> M62 Front, Rear, Center, Woofer and Side, its capture controls Mic
> Front, Rear, Center, Woofer and Side, and a player that lists ALSA
> devices directly offers "5.1 Surround output to Front, Center, Rear and
> Subwoofer speakers" for it. Choosing one of those gives silence or the
> wrong pair, and nothing explains why.
>
> The layout is not in the descriptors. Every AudioStreaming interface on
> this device declares bmChannelConfig 0x00000000. It comes from
> convert_chmap() in sound/usb/stream.c:
>
> } else {
> /* If we're missing wChannelConfig, then guess something
> to make sure the channel map is not skipped entirely */
> if (channels == 1)
> chmap->map[c++] = SNDRV_CHMAP_MONO;
> else
> for (; c < channels && *maps; maps++)
> chmap->map[c++] = *maps;
> }
>
> for (; c < channels; c++)
> chmap->map[c] = SNDRV_CHMAP_UNKNOWN;
>
> The standard position list is walked positionally, so channel 3 becomes
> FC, channel 4 LFE and so on, while the honest answer the next lines
> already use for the tail -- SNDRV_CHMAP_UNKNOWN -- never reaches the
> head.
>
> What makes this more than an unlucky guess is that the device does say
> what its channels are, in the field beside the one we read:
>
> bNrChannels 10
> bmChannelConfig 0x00000000
> iChannelNames 11 Playback 1
>
> bNrChannels 16
> bmChannelConfig 0x00000000
> iChannelNames 21 Analogue 1
>
> iChannelNames indexes the name of the first channel and the rest follow
> in order. Reading those string descriptors from the same Linux machine
> gives:
>
> 11 Playback 1 21 Analogue 1 29 Loopback 1
> 12 Playback 2 22 Analogue 2 30 Loopback 2
> 13 Playback 3 23 AUX 1 31 Loopback 3
> 14 Playback 4 24 AUX 2 32 Loopback 4
> 15 Playback 5 25 BT 1 33 Loopback 5
> 16 Playback 6 26 BT 2 34 Loopback 6
> 17 Playback 7 27 Mobile 1 35 Loopback 7
> 18 Playback 8 28 Mobile 2 36 Loopback 8
> 19 Playback 9
> 20 Playback 10
>
> That is the hardware, exactly: two microphone inputs, a stereo AUX, a
> Bluetooth return, a phone return and eight loopback returns. In
> sound/usb the field appears only in validate.c, counted towards a
> descriptor's expected length and never read.
>
> Two questions, then, and I would rather ask than send a patch that
> guesses at the answer.
>
> Should the positional guess stop where the position list stops meaning
> anything? For two channels it is almost always right and clearly
> useful. For ten or sixteen it is not uncertain but wrong, and UNKNOWN
> is both honest and already available.
>
> And is there interest in surfacing iChannelNames at all? The chmap API
> is positional and has no room for free text, so this is not a matter of
> filling in a map -- it would need somewhere new to live, and I do not
> want to invent that unilaterally. But devices do provide these names,
> and on an interface with ten identical-looking channels they are the
> only thing that tells a user which is which.
>
> Happy to write either patch if a direction is agreeable.

I'd say yes for both. It's beyond the standard definition, so we'd
just need to do the best.


thanks,

Takashi