18c2ecf20Sopenharmony_ci============================
28c2ecf20Sopenharmony_ciALSA PCM channel-mapping API
38c2ecf20Sopenharmony_ci============================
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ciTakashi Iwai <tiwai@suse.de>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ciGeneral
88c2ecf20Sopenharmony_ci=======
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ciThe channel mapping API allows user to query the possible channel maps
118c2ecf20Sopenharmony_ciand the current channel map, also optionally to modify the channel map
128c2ecf20Sopenharmony_ciof the current stream.
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ciA channel map is an array of position for each PCM channel.
158c2ecf20Sopenharmony_ciTypically, a stereo PCM stream has a channel map of
168c2ecf20Sopenharmony_ci``{ front_left, front_right }``
178c2ecf20Sopenharmony_ciwhile a 4.0 surround PCM stream has a channel map of
188c2ecf20Sopenharmony_ci``{ front left, front right, rear left, rear right }.``
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ciThe problem, so far, was that we had no standard channel map
218c2ecf20Sopenharmony_ciexplicitly, and applications had no way to know which channel
228c2ecf20Sopenharmony_cicorresponds to which (speaker) position.  Thus, applications applied
238c2ecf20Sopenharmony_ciwrong channels for 5.1 outputs, and you hear suddenly strange sound
248c2ecf20Sopenharmony_cifrom rear.  Or, some devices secretly assume that center/LFE is the
258c2ecf20Sopenharmony_cithird/fourth channels while others that C/LFE as 5th/6th channels.
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ciAlso, some devices such as HDMI are configurable for different speaker
288c2ecf20Sopenharmony_cipositions even with the same number of total channels.  However, there
298c2ecf20Sopenharmony_ciwas no way to specify this because of lack of channel map
308c2ecf20Sopenharmony_cispecification.  These are the main motivations for the new channel
318c2ecf20Sopenharmony_cimapping API.
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ciDesign
358c2ecf20Sopenharmony_ci======
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ciActually, "the channel mapping API" doesn't introduce anything new in
388c2ecf20Sopenharmony_cithe kernel/user-space ABI perspective.  It uses only the existing
398c2ecf20Sopenharmony_cicontrol element features.
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ciAs a ground design, each PCM substream may contain a control element
428c2ecf20Sopenharmony_ciproviding the channel mapping information and configuration.  This
438c2ecf20Sopenharmony_cielement is specified by:
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci* iface = SNDRV_CTL_ELEM_IFACE_PCM
468c2ecf20Sopenharmony_ci* name = "Playback Channel Map" or "Capture Channel Map"
478c2ecf20Sopenharmony_ci* device = the same device number for the assigned PCM substream
488c2ecf20Sopenharmony_ci* index = the same index number for the assigned PCM substream
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ciNote the name is different depending on the PCM substream direction.
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ciEach control element provides at least the TLV read operation and the
538c2ecf20Sopenharmony_ciread operation.  Optionally, the write operation can be provided to
548c2ecf20Sopenharmony_ciallow user to change the channel map dynamically.
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ciTLV
578c2ecf20Sopenharmony_ci---
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ciThe TLV operation gives the list of available channel
608c2ecf20Sopenharmony_cimaps.  A list item of a channel map is usually a TLV of
618c2ecf20Sopenharmony_ci``type data-bytes ch0 ch1 ch2...``
628c2ecf20Sopenharmony_ciwhere type is the TLV type value, the second argument is the total
638c2ecf20Sopenharmony_cibytes (not the numbers) of channel values, and the rest are the
648c2ecf20Sopenharmony_ciposition value for each channel.
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ciAs a TLV type, either ``SNDRV_CTL_TLVT_CHMAP_FIXED``,
678c2ecf20Sopenharmony_ci``SNDRV_CTL_TLV_CHMAP_VAR`` or ``SNDRV_CTL_TLVT_CHMAP_PAIRED`` can be used.
688c2ecf20Sopenharmony_ciThe ``_FIXED`` type is for a channel map with the fixed channel position
698c2ecf20Sopenharmony_ciwhile the latter two are for flexible channel positions. ``_VAR`` type is
708c2ecf20Sopenharmony_cifor a channel map where all channels are freely swappable and ``_PAIRED``
718c2ecf20Sopenharmony_citype is where pair-wise channels are swappable.  For example, when you
728c2ecf20Sopenharmony_cihave {FL/FR/RL/RR} channel map, ``_PAIRED`` type would allow you to swap
738c2ecf20Sopenharmony_cionly {RL/RR/FL/FR} while ``_VAR`` type would allow even swapping FL and
748c2ecf20Sopenharmony_ciRR.
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ciThese new TLV types are defined in ``sound/tlv.h``.
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ciThe available channel position values are defined in ``sound/asound.h``,
798c2ecf20Sopenharmony_cihere is a cut:
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci::
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci  /* channel positions */
848c2ecf20Sopenharmony_ci  enum {
858c2ecf20Sopenharmony_ci	SNDRV_CHMAP_UNKNOWN = 0,
868c2ecf20Sopenharmony_ci	SNDRV_CHMAP_NA,		/* N/A, silent */
878c2ecf20Sopenharmony_ci	SNDRV_CHMAP_MONO,	/* mono stream */
888c2ecf20Sopenharmony_ci	/* this follows the alsa-lib mixer channel value + 3 */
898c2ecf20Sopenharmony_ci	SNDRV_CHMAP_FL,		/* front left */
908c2ecf20Sopenharmony_ci	SNDRV_CHMAP_FR,		/* front right */
918c2ecf20Sopenharmony_ci	SNDRV_CHMAP_RL,		/* rear left */
928c2ecf20Sopenharmony_ci	SNDRV_CHMAP_RR,		/* rear right */
938c2ecf20Sopenharmony_ci	SNDRV_CHMAP_FC,		/* front center */
948c2ecf20Sopenharmony_ci	SNDRV_CHMAP_LFE,	/* LFE */
958c2ecf20Sopenharmony_ci	SNDRV_CHMAP_SL,		/* side left */
968c2ecf20Sopenharmony_ci	SNDRV_CHMAP_SR,		/* side right */
978c2ecf20Sopenharmony_ci	SNDRV_CHMAP_RC,		/* rear center */
988c2ecf20Sopenharmony_ci	/* new definitions */
998c2ecf20Sopenharmony_ci	SNDRV_CHMAP_FLC,	/* front left center */
1008c2ecf20Sopenharmony_ci	SNDRV_CHMAP_FRC,	/* front right center */
1018c2ecf20Sopenharmony_ci	SNDRV_CHMAP_RLC,	/* rear left center */
1028c2ecf20Sopenharmony_ci	SNDRV_CHMAP_RRC,	/* rear right center */
1038c2ecf20Sopenharmony_ci	SNDRV_CHMAP_FLW,	/* front left wide */
1048c2ecf20Sopenharmony_ci	SNDRV_CHMAP_FRW,	/* front right wide */
1058c2ecf20Sopenharmony_ci	SNDRV_CHMAP_FLH,	/* front left high */
1068c2ecf20Sopenharmony_ci	SNDRV_CHMAP_FCH,	/* front center high */
1078c2ecf20Sopenharmony_ci	SNDRV_CHMAP_FRH,	/* front right high */
1088c2ecf20Sopenharmony_ci	SNDRV_CHMAP_TC,		/* top center */
1098c2ecf20Sopenharmony_ci	SNDRV_CHMAP_TFL,	/* top front left */
1108c2ecf20Sopenharmony_ci	SNDRV_CHMAP_TFR,	/* top front right */
1118c2ecf20Sopenharmony_ci	SNDRV_CHMAP_TFC,	/* top front center */
1128c2ecf20Sopenharmony_ci	SNDRV_CHMAP_TRL,	/* top rear left */
1138c2ecf20Sopenharmony_ci	SNDRV_CHMAP_TRR,	/* top rear right */
1148c2ecf20Sopenharmony_ci	SNDRV_CHMAP_TRC,	/* top rear center */
1158c2ecf20Sopenharmony_ci	SNDRV_CHMAP_LAST = SNDRV_CHMAP_TRC,
1168c2ecf20Sopenharmony_ci  };
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ciWhen a PCM stream can provide more than one channel map, you can
1198c2ecf20Sopenharmony_ciprovide multiple channel maps in a TLV container type.  The TLV data
1208c2ecf20Sopenharmony_cito be returned will contain such as:
1218c2ecf20Sopenharmony_ci::
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	SNDRV_CTL_TLVT_CONTAINER 96
1248c2ecf20Sopenharmony_ci	    SNDRV_CTL_TLVT_CHMAP_FIXED 4 SNDRV_CHMAP_FC
1258c2ecf20Sopenharmony_ci	    SNDRV_CTL_TLVT_CHMAP_FIXED 8 SNDRV_CHMAP_FL SNDRV_CHMAP_FR
1268c2ecf20Sopenharmony_ci	    SNDRV_CTL_TLVT_CHMAP_FIXED 16 NDRV_CHMAP_FL SNDRV_CHMAP_FR \
1278c2ecf20Sopenharmony_ci		SNDRV_CHMAP_RL SNDRV_CHMAP_RR
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ciThe channel position is provided in LSB 16bits.  The upper bits are
1308c2ecf20Sopenharmony_ciused for bit flags.
1318c2ecf20Sopenharmony_ci::
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	#define SNDRV_CHMAP_POSITION_MASK	0xffff
1348c2ecf20Sopenharmony_ci	#define SNDRV_CHMAP_PHASE_INVERSE	(0x01 << 16)
1358c2ecf20Sopenharmony_ci	#define SNDRV_CHMAP_DRIVER_SPEC		(0x02 << 16)
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci``SNDRV_CHMAP_PHASE_INVERSE`` indicates the channel is phase inverted,
1388c2ecf20Sopenharmony_ci(thus summing left and right channels would result in almost silence).
1398c2ecf20Sopenharmony_ciSome digital mic devices have this.
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ciWhen ``SNDRV_CHMAP_DRIVER_SPEC`` is set, all the channel position values
1428c2ecf20Sopenharmony_cidon't follow the standard definition above but driver-specific.
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ciRead Operation
1458c2ecf20Sopenharmony_ci--------------
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ciThe control read operation is for providing the current channel map of
1488c2ecf20Sopenharmony_cithe given stream.  The control element returns an integer array
1498c2ecf20Sopenharmony_cicontaining the position of each channel.
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ciWhen this is performed before the number of the channel is specified
1528c2ecf20Sopenharmony_ci(i.e. hw_params is set), it should return all channels set to
1538c2ecf20Sopenharmony_ci``UNKNOWN``.
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ciWrite Operation
1568c2ecf20Sopenharmony_ci---------------
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ciThe control write operation is optional, and only for devices that can
1598c2ecf20Sopenharmony_cichange the channel configuration on the fly, such as HDMI.  User needs
1608c2ecf20Sopenharmony_cito pass an integer value containing the valid channel positions for
1618c2ecf20Sopenharmony_ciall channels of the assigned PCM substream.
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ciThis operation is allowed only at PCM PREPARED state.  When called in
1648c2ecf20Sopenharmony_ciother states, it shall return an error.
165