[pulseaudio-discuss] [alsa-devel] ALSA -> pulseaudio channel mapping, what is it (and why?)

Tanu Kaskinen tanuk at iki.fi
Mon May 6 11:04:37 UTC 2019

On Fri, 2019-05-03 at 11:05 -0700, frederik at ofb.net wrote:
> Dear ALSA developers,
> I ran into a problem which seems to be caused by some lines in
> "alsa-plugins-1.1.8/pulse/pcm_pulse.c".
> The problem is that if I create a 6-channel PulseAudio device, and
> then I configure an ALSA device in ~/.asoundrc to output to the
> PulseAudio device, the channels of the ALSA device are mixed together
> in various ways and don't correspond 1-1 with the channels of the
> PulseAudio device.
> I find this to be counter-intuitive. If I wanted channels to be mixed
> and remapped in various ways, I would use the PulseAudio module
> module-remap-sink on the PulseAudio side, since AFAICT ALSA does not
> support named channels.

There is an API for querying and configuring PCM device channel maps.
pcm_pulse.c doesn't seem to implement that API, though, so applications
are expected to use the default channel map, and if that doesn't match
the sink channel map, then PulseAudio will do the remapping (and
possibly remixing, if the channel maps differ in other ways than just
channel order).

> I would not expect remixing to happen in the
> ALSA->Pulse bridge, since the relevant PCM plugin contains no channel
> map parameter.

The remixing happens in PulseAudio, not in pcm_pulse.c. pcm_pulse.c
just tells PulseAudio the channel map that the stream uses.

> I don't even know what channel map I should give the PulseAudio device
> in order to prevent remixing from occurring. The file pcm_pulse.c
> contains the lines:
>         for (c = pcm->ss.channels; c > 0; c--)
>                 if (pa_channel_map_init_auto(&map, c, PA_CHANNEL_MAP_ALSA))
>                         break;
> This refers to a macro in /usr/include/pulse/channelmap.h:
>     /** \cond fulldocs */
>         /**< The default mapping used by ALSA. This mapping is probably
>          * not too useful since ALSA's default channel mapping depends on
>          * the device string used. */
>     /** \endcond */
> The comment says that the ALSA mapping is "not too useful" - so why
> are we using it?

pcm_pulse.c has to specify some channel map. Do you have better
proposals than PA_CHANNEL_MAP_ALSA?

> Also, how do I find out what it is, if it "depends on
> the device string used"?

There's currently no way to query the sink channel map through the ALSA
API. There's snd_pcm_get_chmap() that pcm_pulse.c could maybe
implement. There's the complication that usually the pulse PCM uses the
default sink, and the default sink can change at any time, so the
channel map can change at any time too, but that's probably not a huge
problem in practice.

> My preference would simply be to have a 1-1 channel map in pcm_pulse,
> so that a PulseAudio device with 6 channels will turn into an ALSA
> device with THE SAME 6 CHANNELS. No mixing. Mixing is confusing in
> this context, and seems undocumented outside of the code.

Remapping/remixing is very much expected in usual media playback cases.
If you have a 5.1 movie, it's easier for the player application to play
the audio in whatever channel order it wants and let the sound server
to remap and remix as necessary.

> I tried using aux0 thru aux5 as the PulseAudio channel map, to prevent
> geometry-based remixing. However, this results in silence - apparently
> none of the 6 ALSA channels end up going anywhere. That was also
> unexpected. Since I am playing 6-channel audio to a 6-channel device,
> which emulates another 6-channel device, I would have thought that the
> channel mapping wouldn't be complicated. Instead, it appears that the
> PulseAudio sink needs to have channels with specific names in order to
> receive data from ALSA.
> Can we fix this, or improve the user experience?

What's the sink channel map in PulseAudio and what's your application's
channel map? Apparently one of them is not using the default ALSA map
for 6 channels.

If your application is not using the default channel map, why not?

If the sink is not using the default channel map, then it's expected
that PulseAudio shuffles the channels around, otherwise audio meant for
the front left speaker could end up in the rear right speaker, for
example. Do you have a use case for ignoring the channel map? Maybe the
SND_PCM_NO_AUTO_CHANNELS flag could be used in pcm_pulse.c to disable
channel remapping (I'm not volunteering to implement that, though).



More information about the pulseaudio-discuss mailing list