channel-mapping-api.rst 5.9 KB
Newer Older
1
============================
2 3 4
ALSA PCM channel-mapping API
============================

5 6 7 8
Takashi Iwai <tiwai@suse.de>

General
=======
9 10 11 12 13 14 15

The channel mapping API allows user to query the possible channel maps
and the current channel map, also optionally to modify the channel map
of the current stream.

A channel map is an array of position for each PCM channel.
Typically, a stereo PCM stream has a channel map of
16
``{ front_left, front_right }``
17
while a 4.0 surround PCM stream has a channel map of
18
``{ front left, front right, rear left, rear right }.``
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

The problem, so far, was that we had no standard channel map
explicitly, and applications had no way to know which channel
corresponds to which (speaker) position.  Thus, applications applied
wrong channels for 5.1 outputs, and you hear suddenly strange sound
from rear.  Or, some devices secretly assume that center/LFE is the
third/fourth channels while others that C/LFE as 5th/6th channels.

Also, some devices such as HDMI are configurable for different speaker
positions even with the same number of total channels.  However, there
was no way to specify this because of lack of channel map
specification.  These are the main motivations for the new channel
mapping API.


34 35
Design
======
36 37 38 39 40 41 42 43

Actually, "the channel mapping API" doesn't introduce anything new in
the kernel/user-space ABI perspective.  It uses only the existing
control element features.

As a ground design, each PCM substream may contain a control element
providing the channel mapping information and configuration.  This
element is specified by:
44 45 46 47 48

* iface = SNDRV_CTL_ELEM_IFACE_PCM
* name = "Playback Channel Map" or "Capture Channel Map"
* device = the same device number for the assigned PCM substream
* index = the same index number for the assigned PCM substream
49 50 51 52 53 54 55

Note the name is different depending on the PCM substream direction.

Each control element provides at least the TLV read operation and the
read operation.  Optionally, the write operation can be provided to
allow user to change the channel map dynamically.

56 57
TLV
---
58 59 60

The TLV operation gives the list of available channel
maps.  A list item of a channel map is usually a TLV of
61
``type data-bytes ch0 ch1 ch2...``
62 63 64 65
where type is the TLV type value, the second argument is the total
bytes (not the numbers) of channel values, and the rest are the
position value for each channel.

66 67 68 69 70
As a TLV type, either ``SNDRV_CTL_TLVT_CHMAP_FIXED``,
``SNDRV_CTL_TLV_CHMAP_VAR`` or ``SNDRV_CTL_TLVT_CHMAP_PAIRED`` can be used.
The ``_FIXED`` type is for a channel map with the fixed channel position
while the latter two are for flexible channel positions. ``_VAR`` type is
for a channel map where all channels are freely swappable and ``_PAIRED``
71
type is where pair-wise channels are swappable.  For example, when you
72 73
have {FL/FR/RL/RR} channel map, ``_PAIRED`` type would allow you to swap
only {RL/RR/FL/FR} while ``_VAR`` type would allow even swapping FL and
74 75
RR.

76
These new TLV types are defined in ``sound/tlv.h``.
77

78
The available channel position values are defined in ``sound/asound.h``,
79 80
here is a cut:

81 82 83 84
::

  /* channel positions */
  enum {
85
	SNDRV_CHMAP_UNKNOWN = 0,
86 87 88
	SNDRV_CHMAP_NA,		/* N/A, silent */
	SNDRV_CHMAP_MONO,	/* mono stream */
	/* this follows the alsa-lib mixer channel value + 3 */
89 90 91 92
	SNDRV_CHMAP_FL,		/* front left */
	SNDRV_CHMAP_FR,		/* front right */
	SNDRV_CHMAP_RL,		/* rear left */
	SNDRV_CHMAP_RR,		/* rear right */
93 94
	SNDRV_CHMAP_FC,		/* front center */
	SNDRV_CHMAP_LFE,	/* LFE */
95 96
	SNDRV_CHMAP_SL,		/* side left */
	SNDRV_CHMAP_SR,		/* side right */
97 98 99 100 101 102
	SNDRV_CHMAP_RC,		/* rear center */
	/* new definitions */
	SNDRV_CHMAP_FLC,	/* front left center */
	SNDRV_CHMAP_FRC,	/* front right center */
	SNDRV_CHMAP_RLC,	/* rear left center */
	SNDRV_CHMAP_RRC,	/* rear right center */
103 104 105 106 107 108
	SNDRV_CHMAP_FLW,	/* front left wide */
	SNDRV_CHMAP_FRW,	/* front right wide */
	SNDRV_CHMAP_FLH,	/* front left high */
	SNDRV_CHMAP_FCH,	/* front center high */
	SNDRV_CHMAP_FRH,	/* front right high */
	SNDRV_CHMAP_TC,		/* top center */
109 110 111 112 113 114 115
	SNDRV_CHMAP_TFL,	/* top front left */
	SNDRV_CHMAP_TFR,	/* top front right */
	SNDRV_CHMAP_TFC,	/* top front center */
	SNDRV_CHMAP_TRL,	/* top rear left */
	SNDRV_CHMAP_TRR,	/* top rear right */
	SNDRV_CHMAP_TRC,	/* top rear center */
	SNDRV_CHMAP_LAST = SNDRV_CHMAP_TRC,
116
  };
117 118 119 120

When a PCM stream can provide more than one channel map, you can
provide multiple channel maps in a TLV container type.  The TLV data
to be returned will contain such as:
121 122
::

123 124 125 126 127 128 129 130
	SNDRV_CTL_TLVT_CONTAINER 96
	    SNDRV_CTL_TLVT_CHMAP_FIXED 4 SNDRV_CHMAP_FC
	    SNDRV_CTL_TLVT_CHMAP_FIXED 8 SNDRV_CHMAP_FL SNDRV_CHMAP_FR
	    SNDRV_CTL_TLVT_CHMAP_FIXED 16 NDRV_CHMAP_FL SNDRV_CHMAP_FR \
		SNDRV_CHMAP_RL SNDRV_CHMAP_RR

The channel position is provided in LSB 16bits.  The upper bits are
used for bit flags.
131
::
132

133 134 135
	#define SNDRV_CHMAP_POSITION_MASK	0xffff
	#define SNDRV_CHMAP_PHASE_INVERSE	(0x01 << 16)
	#define SNDRV_CHMAP_DRIVER_SPEC		(0x02 << 16)
136

137
``SNDRV_CHMAP_PHASE_INVERSE`` indicates the channel is phase inverted,
138 139 140
(thus summing left and right channels would result in almost silence).
Some digital mic devices have this.

141
When ``SNDRV_CHMAP_DRIVER_SPEC`` is set, all the channel position values
142 143
don't follow the standard definition above but driver-specific.

144 145
Read Operation
--------------
146 147 148 149 150 151 152

The control read operation is for providing the current channel map of
the given stream.  The control element returns an integer array
containing the position of each channel.

When this is performed before the number of the channel is specified
(i.e. hw_params is set), it should return all channels set to
153
``UNKNOWN``.
154

155 156
Write Operation
---------------
157 158 159 160 161 162 163 164

The control write operation is optional, and only for devices that can
change the channel configuration on the fly, such as HDMI.  User needs
to pass an integer value containing the valid channel positions for
all channels of the assigned PCM substream.

This operation is allowed only at PCM PREPARED state.  When called in
other states, it shall return an error.