xref: /openbmc/linux/Documentation/sound/designs/channel-mapping-api.rst (revision 9095bf25ea08135a5b74875dd0e3eeaddc4218a0)
1*efe541c2STakashi Iwai============================
2*efe541c2STakashi IwaiALSA PCM channel-mapping API
3*efe541c2STakashi Iwai============================
4*efe541c2STakashi Iwai
5*efe541c2STakashi IwaiTakashi Iwai <tiwai@suse.de>
6*efe541c2STakashi Iwai
7*efe541c2STakashi IwaiGeneral
8*efe541c2STakashi Iwai=======
9*efe541c2STakashi Iwai
10*efe541c2STakashi IwaiThe channel mapping API allows user to query the possible channel maps
11*efe541c2STakashi Iwaiand the current channel map, also optionally to modify the channel map
12*efe541c2STakashi Iwaiof the current stream.
13*efe541c2STakashi Iwai
14*efe541c2STakashi IwaiA channel map is an array of position for each PCM channel.
15*efe541c2STakashi IwaiTypically, a stereo PCM stream has a channel map of
16*efe541c2STakashi Iwai``{ front_left, front_right }``
17*efe541c2STakashi Iwaiwhile a 4.0 surround PCM stream has a channel map of
18*efe541c2STakashi Iwai``{ front left, front right, rear left, rear right }.``
19*efe541c2STakashi Iwai
20*efe541c2STakashi IwaiThe problem, so far, was that we had no standard channel map
21*efe541c2STakashi Iwaiexplicitly, and applications had no way to know which channel
22*efe541c2STakashi Iwaicorresponds to which (speaker) position.  Thus, applications applied
23*efe541c2STakashi Iwaiwrong channels for 5.1 outputs, and you hear suddenly strange sound
24*efe541c2STakashi Iwaifrom rear.  Or, some devices secretly assume that center/LFE is the
25*efe541c2STakashi Iwaithird/fourth channels while others that C/LFE as 5th/6th channels.
26*efe541c2STakashi Iwai
27*efe541c2STakashi IwaiAlso, some devices such as HDMI are configurable for different speaker
28*efe541c2STakashi Iwaipositions even with the same number of total channels.  However, there
29*efe541c2STakashi Iwaiwas no way to specify this because of lack of channel map
30*efe541c2STakashi Iwaispecification.  These are the main motivations for the new channel
31*efe541c2STakashi Iwaimapping API.
32*efe541c2STakashi Iwai
33*efe541c2STakashi Iwai
34*efe541c2STakashi IwaiDesign
35*efe541c2STakashi Iwai======
36*efe541c2STakashi Iwai
37*efe541c2STakashi IwaiActually, "the channel mapping API" doesn't introduce anything new in
38*efe541c2STakashi Iwaithe kernel/user-space ABI perspective.  It uses only the existing
39*efe541c2STakashi Iwaicontrol element features.
40*efe541c2STakashi Iwai
41*efe541c2STakashi IwaiAs a ground design, each PCM substream may contain a control element
42*efe541c2STakashi Iwaiproviding the channel mapping information and configuration.  This
43*efe541c2STakashi Iwaielement is specified by:
44*efe541c2STakashi Iwai
45*efe541c2STakashi Iwai* iface = SNDRV_CTL_ELEM_IFACE_PCM
46*efe541c2STakashi Iwai* name = "Playback Channel Map" or "Capture Channel Map"
47*efe541c2STakashi Iwai* device = the same device number for the assigned PCM substream
48*efe541c2STakashi Iwai* index = the same index number for the assigned PCM substream
49*efe541c2STakashi Iwai
50*efe541c2STakashi IwaiNote the name is different depending on the PCM substream direction.
51*efe541c2STakashi Iwai
52*efe541c2STakashi IwaiEach control element provides at least the TLV read operation and the
53*efe541c2STakashi Iwairead operation.  Optionally, the write operation can be provided to
54*efe541c2STakashi Iwaiallow user to change the channel map dynamically.
55*efe541c2STakashi Iwai
56*efe541c2STakashi IwaiTLV
57*efe541c2STakashi Iwai---
58*efe541c2STakashi Iwai
59*efe541c2STakashi IwaiThe TLV operation gives the list of available channel
60*efe541c2STakashi Iwaimaps.  A list item of a channel map is usually a TLV of
61*efe541c2STakashi Iwai``type data-bytes ch0 ch1 ch2...``
62*efe541c2STakashi Iwaiwhere type is the TLV type value, the second argument is the total
63*efe541c2STakashi Iwaibytes (not the numbers) of channel values, and the rest are the
64*efe541c2STakashi Iwaiposition value for each channel.
65*efe541c2STakashi Iwai
66*efe541c2STakashi IwaiAs a TLV type, either ``SNDRV_CTL_TLVT_CHMAP_FIXED``,
67*efe541c2STakashi Iwai``SNDRV_CTL_TLV_CHMAP_VAR`` or ``SNDRV_CTL_TLVT_CHMAP_PAIRED`` can be used.
68*efe541c2STakashi IwaiThe ``_FIXED`` type is for a channel map with the fixed channel position
69*efe541c2STakashi Iwaiwhile the latter two are for flexible channel positions. ``_VAR`` type is
70*efe541c2STakashi Iwaifor a channel map where all channels are freely swappable and ``_PAIRED``
71*efe541c2STakashi Iwaitype is where pair-wise channels are swappable.  For example, when you
72*efe541c2STakashi Iwaihave {FL/FR/RL/RR} channel map, ``_PAIRED`` type would allow you to swap
73*efe541c2STakashi Iwaionly {RL/RR/FL/FR} while ``_VAR`` type would allow even swapping FL and
74*efe541c2STakashi IwaiRR.
75*efe541c2STakashi Iwai
76*efe541c2STakashi IwaiThese new TLV types are defined in ``sound/tlv.h``.
77*efe541c2STakashi Iwai
78*efe541c2STakashi IwaiThe available channel position values are defined in ``sound/asound.h``,
79*efe541c2STakashi Iwaihere is a cut:
80*efe541c2STakashi Iwai
81*efe541c2STakashi Iwai::
82*efe541c2STakashi Iwai
83*efe541c2STakashi Iwai  /* channel positions */
84*efe541c2STakashi Iwai  enum {
85*efe541c2STakashi Iwai	SNDRV_CHMAP_UNKNOWN = 0,
86*efe541c2STakashi Iwai	SNDRV_CHMAP_NA,		/* N/A, silent */
87*efe541c2STakashi Iwai	SNDRV_CHMAP_MONO,	/* mono stream */
88*efe541c2STakashi Iwai	/* this follows the alsa-lib mixer channel value + 3 */
89*efe541c2STakashi Iwai	SNDRV_CHMAP_FL,		/* front left */
90*efe541c2STakashi Iwai	SNDRV_CHMAP_FR,		/* front right */
91*efe541c2STakashi Iwai	SNDRV_CHMAP_RL,		/* rear left */
92*efe541c2STakashi Iwai	SNDRV_CHMAP_RR,		/* rear right */
93*efe541c2STakashi Iwai	SNDRV_CHMAP_FC,		/* front center */
94*efe541c2STakashi Iwai	SNDRV_CHMAP_LFE,	/* LFE */
95*efe541c2STakashi Iwai	SNDRV_CHMAP_SL,		/* side left */
96*efe541c2STakashi Iwai	SNDRV_CHMAP_SR,		/* side right */
97*efe541c2STakashi Iwai	SNDRV_CHMAP_RC,		/* rear center */
98*efe541c2STakashi Iwai	/* new definitions */
99*efe541c2STakashi Iwai	SNDRV_CHMAP_FLC,	/* front left center */
100*efe541c2STakashi Iwai	SNDRV_CHMAP_FRC,	/* front right center */
101*efe541c2STakashi Iwai	SNDRV_CHMAP_RLC,	/* rear left center */
102*efe541c2STakashi Iwai	SNDRV_CHMAP_RRC,	/* rear right center */
103*efe541c2STakashi Iwai	SNDRV_CHMAP_FLW,	/* front left wide */
104*efe541c2STakashi Iwai	SNDRV_CHMAP_FRW,	/* front right wide */
105*efe541c2STakashi Iwai	SNDRV_CHMAP_FLH,	/* front left high */
106*efe541c2STakashi Iwai	SNDRV_CHMAP_FCH,	/* front center high */
107*efe541c2STakashi Iwai	SNDRV_CHMAP_FRH,	/* front right high */
108*efe541c2STakashi Iwai	SNDRV_CHMAP_TC,		/* top center */
109*efe541c2STakashi Iwai	SNDRV_CHMAP_TFL,	/* top front left */
110*efe541c2STakashi Iwai	SNDRV_CHMAP_TFR,	/* top front right */
111*efe541c2STakashi Iwai	SNDRV_CHMAP_TFC,	/* top front center */
112*efe541c2STakashi Iwai	SNDRV_CHMAP_TRL,	/* top rear left */
113*efe541c2STakashi Iwai	SNDRV_CHMAP_TRR,	/* top rear right */
114*efe541c2STakashi Iwai	SNDRV_CHMAP_TRC,	/* top rear center */
115*efe541c2STakashi Iwai	SNDRV_CHMAP_LAST = SNDRV_CHMAP_TRC,
116*efe541c2STakashi Iwai  };
117*efe541c2STakashi Iwai
118*efe541c2STakashi IwaiWhen a PCM stream can provide more than one channel map, you can
119*efe541c2STakashi Iwaiprovide multiple channel maps in a TLV container type.  The TLV data
120*efe541c2STakashi Iwaito be returned will contain such as:
121*efe541c2STakashi Iwai::
122*efe541c2STakashi Iwai
123*efe541c2STakashi Iwai	SNDRV_CTL_TLVT_CONTAINER 96
124*efe541c2STakashi Iwai	    SNDRV_CTL_TLVT_CHMAP_FIXED 4 SNDRV_CHMAP_FC
125*efe541c2STakashi Iwai	    SNDRV_CTL_TLVT_CHMAP_FIXED 8 SNDRV_CHMAP_FL SNDRV_CHMAP_FR
126*efe541c2STakashi Iwai	    SNDRV_CTL_TLVT_CHMAP_FIXED 16 NDRV_CHMAP_FL SNDRV_CHMAP_FR \
127*efe541c2STakashi Iwai		SNDRV_CHMAP_RL SNDRV_CHMAP_RR
128*efe541c2STakashi Iwai
129*efe541c2STakashi IwaiThe channel position is provided in LSB 16bits.  The upper bits are
130*efe541c2STakashi Iwaiused for bit flags.
131*efe541c2STakashi Iwai::
132*efe541c2STakashi Iwai
133*efe541c2STakashi Iwai	#define SNDRV_CHMAP_POSITION_MASK	0xffff
134*efe541c2STakashi Iwai	#define SNDRV_CHMAP_PHASE_INVERSE	(0x01 << 16)
135*efe541c2STakashi Iwai	#define SNDRV_CHMAP_DRIVER_SPEC		(0x02 << 16)
136*efe541c2STakashi Iwai
137*efe541c2STakashi Iwai``SNDRV_CHMAP_PHASE_INVERSE`` indicates the channel is phase inverted,
138*efe541c2STakashi Iwai(thus summing left and right channels would result in almost silence).
139*efe541c2STakashi IwaiSome digital mic devices have this.
140*efe541c2STakashi Iwai
141*efe541c2STakashi IwaiWhen ``SNDRV_CHMAP_DRIVER_SPEC`` is set, all the channel position values
142*efe541c2STakashi Iwaidon't follow the standard definition above but driver-specific.
143*efe541c2STakashi Iwai
144*efe541c2STakashi IwaiRead Operation
145*efe541c2STakashi Iwai--------------
146*efe541c2STakashi Iwai
147*efe541c2STakashi IwaiThe control read operation is for providing the current channel map of
148*efe541c2STakashi Iwaithe given stream.  The control element returns an integer array
149*efe541c2STakashi Iwaicontaining the position of each channel.
150*efe541c2STakashi Iwai
151*efe541c2STakashi IwaiWhen this is performed before the number of the channel is specified
152*efe541c2STakashi Iwai(i.e. hw_params is set), it should return all channels set to
153*efe541c2STakashi Iwai``UNKNOWN``.
154*efe541c2STakashi Iwai
155*efe541c2STakashi IwaiWrite Operation
156*efe541c2STakashi Iwai---------------
157*efe541c2STakashi Iwai
158*efe541c2STakashi IwaiThe control write operation is optional, and only for devices that can
159*efe541c2STakashi Iwaichange the channel configuration on the fly, such as HDMI.  User needs
160*efe541c2STakashi Iwaito pass an integer value containing the valid channel positions for
161*efe541c2STakashi Iwaiall channels of the assigned PCM substream.
162*efe541c2STakashi Iwai
163*efe541c2STakashi IwaiThis operation is allowed only at PCM PREPARED state.  When called in
164*efe541c2STakashi Iwaiother states, it shall return an error.
165