diff options
Diffstat (limited to 'Documentation/sound/alsa/Channel-Mapping-API.txt')
-rw-r--r-- | Documentation/sound/alsa/Channel-Mapping-API.txt | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/Documentation/sound/alsa/Channel-Mapping-API.txt b/Documentation/sound/alsa/Channel-Mapping-API.txt new file mode 100644 index 000000000000..3c43d1a4ca0e --- /dev/null +++ b/Documentation/sound/alsa/Channel-Mapping-API.txt @@ -0,0 +1,153 @@ +ALSA PCM channel-mapping API +============================ + Takashi Iwai <tiwai@suse.de> + +GENERAL +------- + +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 + { front_left, front_right } +while a 4.0 surround PCM stream has a channel map of + { front left, front right, rear left, rear right }. + +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. + + +DESIGN +------ + +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: + 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 + +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. + +* TLV + +The TLV operation gives the list of available channel +maps. A list item of a channel map is usually a TLV of + type data-bytes ch0 ch1 ch2... +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. + +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 +type is where pair-wise channels are swappable. For example, when you +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 +RR. + +These new TLV types are defined in sound/tlv.h. + +The available channel position values are defined in sound/asound.h, +here is a cut: + +/* channel positions */ +enum { + SNDRV_CHMAP_UNKNOWN = 0, + SNDRV_CHMAP_NA, /* N/A, silent */ + SNDRV_CHMAP_MONO, /* mono stream */ + /* this follows the alsa-lib mixer channel value + 3 */ + SNDRV_CHMAP_FL, /* front left */ + SNDRV_CHMAP_FR, /* front right */ + SNDRV_CHMAP_RL, /* rear left */ + SNDRV_CHMAP_RR, /* rear right */ + SNDRV_CHMAP_FC, /* front center */ + SNDRV_CHMAP_LFE, /* LFE */ + SNDRV_CHMAP_SL, /* side left */ + SNDRV_CHMAP_SR, /* side right */ + 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 */ + 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 */ + 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, +}; + +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: + 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. + +#define SNDRV_CHMAP_POSITION_MASK 0xffff +#define SNDRV_CHMAP_PHASE_INVERSE (0x01 << 16) +#define SNDRV_CHMAP_DRIVER_SPEC (0x02 << 16) + +SNDRV_CHMAP_PHASE_INVERSE indicates the channel is phase inverted, +(thus summing left and right channels would result in almost silence). +Some digital mic devices have this. + +When SNDRV_CHMAP_DRIVER_SPEC is set, all the channel position values +don't follow the standard definition above but driver-specific. + +* READ OPERATION + +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 +UNKNOWN. + +* WRITE OPERATION + +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. |