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