← Documents Documentation/sound/designs/channel-mapping-api.rst GitHub 원문 ↗

Linux 6.18.37 · Sound

ALSA PCM 채널 매핑 API

기존 ALSA control element와 TLV를 사용해 PCM channel의 speaker 위치를 조회·선택하는 API, 표준 위치 enum과 PREPARED 상태 write 규칙을 설명합니다.

Source pathDocumentation/sound/designs/channel-mapping-api.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

channel-mapping-api.rst:1-164

기존 ALSA control element와 TLV를 사용해 PCM channel의 speaker 위치를 조회·선택하는 API, 표준 위치 enum과 PREPARED 상태 write 규칙을 설명합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

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

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

목적과 채널 위치 문제

1-31

저자는 Takashi Iwai(`[email protected]`)다. ALSA PCM channel-mapping API를 사용하면 응용 프로그램이 가능한 channel map과 현재 map을 조회하고, 선택적으로 현재 stream의 map을 바꿀 수 있다.

Channel map은 PCM channel마다 하나씩 대응하는 위치 값의 배열이다. 일반 stereo stream은 `{ front_left, front_right }`, 4.0 surround stream은 `{ front left, front right, rear left, rear right }`처럼 표현한다.

이 API 이전에는 명시적인 표준 channel map이 없어 응용 프로그램이 channel과 speaker 위치의 대응을 알 수 없었다. 그 결과 5.1 출력에서 잘못된 channel을 적용해 rear speaker에서 예상 밖의 소리가 나기도 했다. 일부 장치는 center/LFE를 세 번째·네 번째 channel로, 다른 장치는 다섯 번째·여섯 번째로 가정했다.

HDMI 같은 장치는 전체 channel 수가 같아도 서로 다른 speaker 위치로 구성할 수 있지만, channel map 명세가 없어 이를 지정할 수 없었다. 이런 문제들이 새 API의 주된 동기다.

PCM channel map 예
StreamChannel map
Stereo{ front_left, front_right }
4.0 surround{ front_left, front_right, rear_left, rear_right }
5.1 장치 차이center/LFE가 3·4번 또는 5·6번일 수 있음
HDMI같은 channel 수에서도 여러 speaker 배치 가능

배열 순서가 각 PCM channel의 물리적 speaker 위치를 뜻한다.

============================
ALSA PCM channel-mapping API
============================

Takashi Iwai <[email protected]>

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.

기존 control element를 이용한 설계

32-55

Channel-mapping API는 kernel/user-space ABI 관점에서 새 mechanism을 추가하지 않고 기존 ALSA control element 기능만 사용한다.

기본 설계에서 각 PCM substream은 channel map 정보와 구성을 제공하는 control element를 가질 수 있다. `iface`는 `SNDRV_CTL_ELEM_IFACE_PCM`, 이름은 방향에 따라 `Playback Channel Map` 또는 `Capture Channel Map`, `device`와 `index`는 연결된 PCM substream과 같은 번호다.

Channel map control 식별자
필드
ifaceSNDRV_CTL_ELEM_IFACE_PCM
namePlayback Channel Map 또는 Capture Channel Map
device할당된 PCM substream의 device 번호
index할당된 PCM substream의 index 번호

PCM substream 방향과 번호로 control element를 연결한다.

각 control element는 최소한 TLV read operation과 일반 read operation을 제공한다. 장치가 channel map을 동적으로 바꿀 수 있다면 선택적으로 write operation을 제공할 수 있다.



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 형식과 교환 가능 범위

56-77

TLV operation은 사용 가능한 channel map 목록을 반환한다. 일반적인 한 map 항목은 `type data-bytes ch0 ch1 ch2...` 형식이다. `type`은 TLV type 값이고 두 번째 값은 channel 값의 개수가 아니라 전체 byte 수이며, 나머지는 channel별 위치 값이다.

TLV type으로 `SNDRV_CTL_TLVT_CHMAP_FIXED`, `SNDRV_CTL_TLV_CHMAP_VAR`, `SNDRV_CTL_TLVT_CHMAP_PAIRED`를 사용할 수 있다. `_FIXED`는 channel 위치가 고정된 map, `_VAR`와 `_PAIRED`는 위치를 바꿀 수 있는 map이다.

`_VAR`는 모든 channel을 자유롭게 교환할 수 있고 `_PAIRED`는 channel pair 단위로만 교환할 수 있다. `{FL/FR/RL/RR}`에서 `_PAIRED`는 `{RL/RR/FL/FR}`처럼 pair 순서만 바꿀 수 있지만, `_VAR`는 FL과 RR을 직접 맞바꾸는 것도 허용한다. 새 TLV type은 `sound/tlv.h`에 정의된다.

Channel-map TLV type
Type의미{FL/FR/RL/RR} 예
SNDRV_CTL_TLVT_CHMAP_FIXED고정 위치변경 불가
SNDRV_CTL_TLV_CHMAP_VAR모든 channel 자유 교환FL과 RR도 교환 가능
SNDRV_CTL_TLVT_CHMAP_PAIREDpair 단위 교환{RL/RR/FL/FR} 가능

교환 가능한 위치의 범위를 구분한다.

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``.

표준 channel 위치 enum

78-116

사용 가능한 channel 위치 값은 `sound/asound.h`에 정의된다. `UNKNOWN`, 무음인 `NA`, `MONO`를 시작으로 front/rear/side/LFE 위치와 wide, high, top 위치까지 포함한다. 원문의 enum 발췌는 다음과 같다.

/* 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,
};
Channel 위치 그룹
그룹Symbol
기본UNKNOWN, NA, MONO
평면 기본FL, FR, RL, RR, FC, LFE, SL, SR, RC
중간·wideFLC, FRC, RLC, RRC, FLW, FRW
높은 frontFLH, FCH, FRH
천장TC, TFL, TFR, TFC, TRL, TRR, TRC

enum 이름의 위치 계층을 묶어 보여준다.

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,
  };

여러 map의 TLV container와 bit flag

117-143

하나의 PCM stream이 여러 channel map을 제공할 수 있으면 TLV container type 안에 여러 map을 넣는다. 다음 예는 mono, stereo, 4-channel 고정 map을 한 container에 담는다. 4-channel 항목의 `NDRV_CHMAP_FL` 표기는 원문 그대로 보존한다.

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

Channel 위치는 하위 16bit에 저장하고 상위 bit는 flag로 사용한다.

#define SNDRV_CHMAP_POSITION_MASK  0xffff
#define SNDRV_CHMAP_PHASE_INVERSE  (0x01 << 16)
#define SNDRV_CHMAP_DRIVER_SPEC    (0x02 << 16)

`SNDRV_CHMAP_PHASE_INVERSE`는 channel 위상이 반전됐음을 나타낸다. 이 경우 좌우 channel을 합치면 거의 무음이 되며 일부 digital microphone 장치가 이 특성을 가진다. `SNDRV_CHMAP_DRIVER_SPEC`가 설정되면 모든 channel 위치 값은 위 표준 정의가 아니라 driver 전용 의미를 따른다.

Channel 위치 bit 구성
Symbol의미
SNDRV_CHMAP_POSITION_MASK0xffff하위 16bit 위치 값
SNDRV_CHMAP_PHASE_INVERSE0x01 << 16위상 반전
SNDRV_CHMAP_DRIVER_SPEC0x02 << 16driver 전용 위치 정의

하위 위치 값과 상위 flag를 구분한다.


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와 선택적 write operation

144-164

Control read operation은 지정 stream의 현재 channel map을 반환한다. 결과는 각 channel의 위치를 담은 integer 배열이다. Channel 수가 정해지기 전, 즉 `hw_params`가 설정되기 전에 읽으면 모든 channel을 `UNKNOWN`으로 반환해야 한다.

Control write operation은 선택 사항이며 HDMI처럼 channel 구성을 실행 중에 바꿀 수 있는 장치에만 사용한다. 사용자 공간은 연결된 PCM substream의 모든 channel에 대해 유효한 위치를 담은 integer 값을 전달해야 한다.

Write는 PCM 상태가 `PREPARED`일 때만 허용된다. 다른 상태에서 호출하면 오류를 반환해야 한다.

Channel map operation
Operation동작조건
TLV read사용 가능한 map 목록항상 제공
read현재 위치 integer 배열hw_params 전에는 모두 UNKNOWN
write모든 channel의 새 위치선택 사항, PCM PREPARED에서만 허용

조회와 동적 변경의 반환·허용 조건이다.

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.