diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-08-15 10:06:43 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-09-06 12:01:17 -0400 |
commit | be84bbcccc757b86449daaf924e72f95c95dc00e (patch) | |
tree | 65ec796ddb10fc3980385e7b1b4d0c248d085743 /Documentation/sound/alsa | |
parent | 2d3391ec0ecca37efb6bc995906292f47522b471 (diff) |
ALSA: Add a documentation for channel mapping API
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'Documentation/sound/alsa')
-rw-r--r-- | Documentation/sound/alsa/Channel-Mapping-API.txt | 144 |
1 files changed, 144 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..df930aa4f4d0 --- /dev/null +++ b/Documentation/sound/alsa/Channel-Mapping-API.txt | |||
@@ -0,0 +1,144 @@ | |||
1 | ALSA PCM channel-mapping API | ||
2 | ============================ | ||
3 | Takashi Iwai <tiwai@suse.de> | ||
4 | |||
5 | GENERAL | ||
6 | ------- | ||
7 | |||
8 | The channel mapping API allows user to query the possible channel maps | ||
9 | and the current channel map, also optionally to modify the channel map | ||
10 | of the current stream. | ||
11 | |||
12 | A channel map is an array of position for each PCM channel. | ||
13 | Typically, a stereo PCM stream has a channel map of | ||
14 | { front_left, front_right } | ||
15 | while a 4.0 surround PCM stream has a channel map of | ||
16 | { front left, front right, rear left, rear right }. | ||
17 | |||
18 | The problem, so far, was that we had no standard channel map | ||
19 | explicitly, and applications had no way to know which channel | ||
20 | corresponds to which (speaker) position. Thus, applications applied | ||
21 | wrong channels for 5.1 outputs, and you hear suddenly strange sound | ||
22 | from rear. Or, some devices secretly assume that center/LFE is the | ||
23 | third/fourth channels while others that C/LFE as 5th/6th channels. | ||
24 | |||
25 | Also, some devices such as HDMI are configurable for different speaker | ||
26 | positions even with the same number of total channels. However, there | ||
27 | was no way to specify this because of lack of channel map | ||
28 | specification. These are the main motivations for the new channel | ||
29 | mapping API. | ||
30 | |||
31 | |||
32 | DESIGN | ||
33 | ------ | ||
34 | |||
35 | Actually, "the channel mapping API" doesn't introduce anything new in | ||
36 | the kernel/user-space ABI perspective. It uses only the existing | ||
37 | control element features. | ||
38 | |||
39 | As a ground design, each PCM substream may contain a control element | ||
40 | providing the channel mapping information and configuration. This | ||
41 | element is specified by: | ||
42 | iface = SNDRV_CTL_ELEM_IFACE_PCM | ||
43 | name = "Playback Channel Map" or "Capture Channel Map" | ||
44 | device = the same device number for the assigned PCM substream | ||
45 | index = the same index number for the assigned PCM substream | ||
46 | |||
47 | Note the name is different depending on the PCM substream direction. | ||
48 | |||
49 | Each control element provides at least the TLV read operation and the | ||
50 | read operation. Optionally, the write operation can be provided to | ||
51 | allow user to change the channel map dynamically. | ||
52 | |||
53 | * TLV | ||
54 | |||
55 | The TLV operation gives the list of available channel | ||
56 | maps. A list item of a channel map is usually a TLV of | ||
57 | type data-bytes ch0 ch1 ch2... | ||
58 | where type is the TLV type value, the second argument is the total | ||
59 | bytes (not the numbers) of channel values, and the rest are the | ||
60 | position value for each channel. | ||
61 | |||
62 | As a TLV type, either SNDRV_CTL_TLVT_CHMAP_FIXED, | ||
63 | SNDRV_CTL_TLV_CHMAP_VAR or SNDRV_CTL_TLVT_CHMAP_PAIRED can be used. | ||
64 | The _FIXED type is for a channel map with the fixed channel position | ||
65 | while the latter two are for flexible channel positions. _VAR type is | ||
66 | for a channel map where all channels are freely swappable and _PAIRED | ||
67 | type is where pair-wise channels are swappable. For example, when you | ||
68 | have {FL/FR/RL/RR} channel map, _PAIRED type would allow you to swap | ||
69 | only {RL/RR/FL/FR} while _VAR type would allow even swapping FL and | ||
70 | RR. | ||
71 | |||
72 | These new TLV types are defined in sound/tlv.h. | ||
73 | |||
74 | The available channel position values are defined in sound/asound.h, | ||
75 | here is a cut: | ||
76 | |||
77 | /* channel positions */ | ||
78 | enum { | ||
79 | SNDRV_CHMAP_UNKNOWN = 0, | ||
80 | SNDRV_CHMAP_FL, /* front left */ | ||
81 | SNDRV_CHMAP_FC, /* front center */ | ||
82 | SNDRV_CHMAP_FR, /* front right */ | ||
83 | SNDRV_CHMAP_FLC, /* front left center */ | ||
84 | SNDRV_CHMAP_FRC, /* front right center */ | ||
85 | SNDRV_CHMAP_RL, /* rear left */ | ||
86 | SNDRV_CHMAP_RC, /* rear center */ | ||
87 | SNDRV_CHMAP_RR, /* rear right */ | ||
88 | SNDRV_CHMAP_RLC, /* rear left center */ | ||
89 | SNDRV_CHMAP_RRC, /* rear right center */ | ||
90 | SNDRV_CHMAP_SL, /* side left */ | ||
91 | SNDRV_CHMAP_SR, /* side right */ | ||
92 | SNDRV_CHMAP_LFE, /* LFE */ | ||
93 | SNDRV_CHMAP_FLW, /* front left wide */ | ||
94 | SNDRV_CHMAP_FRW, /* front right wide */ | ||
95 | SNDRV_CHMAP_FLH, /* front left high */ | ||
96 | SNDRV_CHMAP_FCH, /* front center high */ | ||
97 | SNDRV_CHMAP_FRH, /* front right high */ | ||
98 | SNDRV_CHMAP_TC, /* top center */ | ||
99 | SNDRV_CHMAP_NA, /* N/A, silent */ | ||
100 | SNDRV_CHMAP_LAST = SNDRV_CHMAP_NA, | ||
101 | }; | ||
102 | |||
103 | When a PCM stream can provide more than one channel map, you can | ||
104 | provide multiple channel maps in a TLV container type. The TLV data | ||
105 | to be returned will contain such as: | ||
106 | SNDRV_CTL_TLVT_CONTAINER 96 | ||
107 | SNDRV_CTL_TLVT_CHMAP_FIXED 4 SNDRV_CHMAP_FC | ||
108 | SNDRV_CTL_TLVT_CHMAP_FIXED 8 SNDRV_CHMAP_FL SNDRV_CHMAP_FR | ||
109 | SNDRV_CTL_TLVT_CHMAP_FIXED 16 NDRV_CHMAP_FL SNDRV_CHMAP_FR \ | ||
110 | SNDRV_CHMAP_RL SNDRV_CHMAP_RR | ||
111 | |||
112 | The channel position is provided in LSB 16bits. The upper bits are | ||
113 | used for bit flags. | ||
114 | |||
115 | #define SNDRV_CHMAP_POSITION_MASK 0xffff | ||
116 | #define SNDRV_CHMAP_PHASE_INVERSE (0x01 << 16) | ||
117 | #define SNDRV_CHMAP_DRIVER_SPEC (0x02 << 16) | ||
118 | |||
119 | SNDRV_CHMAP_PHASE_INVERSE indicates the channel is phase inverted, | ||
120 | (thus summing left and right channels would result in almost silence). | ||
121 | Some digital mic devices have this. | ||
122 | |||
123 | When SNDRV_CHMAP_DRIVER_SPEC is set, all the channel position values | ||
124 | don't follow the standard definition above but driver-specific. | ||
125 | |||
126 | * READ OPERATION | ||
127 | |||
128 | The control read operation is for providing the current channel map of | ||
129 | the given stream. The control element returns an integer array | ||
130 | containing the position of each channel. | ||
131 | |||
132 | When this is performed before the number of the channel is specified | ||
133 | (i.e. hw_params is set), it should return all channels set to | ||
134 | UNKNOWN. | ||
135 | |||
136 | * WRITE OPERATION | ||
137 | |||
138 | The control write operation is optional, and only for devices that can | ||
139 | change the channel configuration on the fly, such as HDMI. User needs | ||
140 | to pass an integer value containing the valid channel positions for | ||
141 | all channels of the assigned PCM substream. | ||
142 | |||
143 | This operation is allowed only at PCM PREPARED state. When called in | ||
144 | other states, it shall return an error. | ||