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