• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024, Alliance for Open Media. All rights reserved
3  *
4  * This source code is subject to the terms of the BSD 3-Clause Clear License
5  * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
6  * License was not distributed with this source code in the LICENSE file, you
7  * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the
8  * Alliance for Open Media Patent License 1.0 was not distributed with this
9  * source code in the PATENTS file, you can obtain it at
10  * www.aomedia.org/license/patent.
11  */
12 
13 #ifndef CLI_CHANNEL_LABEL_H_
14 #define CLI_CHANNEL_LABEL_H_
15 
16 #include <optional>
17 #include <string>
18 #include <vector>
19 
20 #include "absl/container/flat_hash_set.h"
21 #include "absl/status/statusor.h"
22 #include "absl/strings/string_view.h"
23 #include "iamf/obu/audio_element.h"
24 #include "iamf/obu/recon_gain_info_parameter_data.h"
25 
26 namespace iamf_tools {
27 
28 /*!\brief Enums and static functions to help process channel labels.*/
29 class ChannelLabel {
30  public:
31   /*!\brief Labels associated with input or output channels.
32    *
33    * Labels naming conventions are based on the IAMF spec
34    * (https://aomediacodec.github.io/iamf/#processing-downmixmatrix,
35    * https://aomediacodec.github.io/iamf/#iamfgeneration-scalablechannelaudio-downmixmechanism).
36    */
37   enum Label {
38     kOmitted,
39     // Mono channels.
40     kMono,
41     // Stereo or binaural channels.
42     kL2,
43     kR2,
44     kDemixedR2,
45     // Centre channel common to several layouts (e.g. 3.1.2, 5.x.y, 7.x.y).
46     kCentre,
47     // LFE channel common to several layouts (e.g. 3.1.2, 5.1.y, 7.1.y, 9.1.6).
48     kLFE,
49     // 3.1.2 surround channels.
50     kL3,
51     kR3,
52     kLtf3,
53     kRtf3,
54     kDemixedL3,
55     kDemixedR3,
56     // 5.x.y surround channels.
57     kL5,
58     kR5,
59     kLs5,
60     kRs5,
61     kDemixedL5,
62     kDemixedR5,
63     kDemixedLs5,
64     kDemixedRs5,
65     // Common channels between 5.1.2 and 7.1.2.
66     kLtf2,
67     kRtf2,
68     kDemixedLtf2,
69     kDemixedRtf2,
70     // Common channels between 5.1.4 and 7.1.4.
71     kLtf4,
72     kRtf4,
73     kLtb4,
74     kRtb4,
75     kDemixedLtb4,
76     kDemixedRtb4,
77     // 7.x.y surround channels.
78     kL7,
79     kR7,
80     kLss7,
81     kRss7,
82     kLrs7,
83     kRrs7,
84     kDemixedL7,
85     kDemixedR7,
86     kDemixedLrs7,
87     kDemixedRrs7,
88     // 9.1.6 surround channels.
89     kFLc,
90     kFC,
91     kFRc,
92     kFL,
93     kFR,
94     kSiL,
95     kSiR,
96     kBL,
97     kBR,
98     kTpFL,
99     kTpFR,
100     kTpSiL,
101     kTpSiR,
102     kTpBL,
103     kTpBR,
104     // Ambisonics channels.
105     kA0,
106     kA1,
107     kA2,
108     kA3,
109     kA4,
110     kA5,
111     kA6,
112     kA7,
113     kA8,
114     kA9,
115     kA10,
116     kA11,
117     kA12,
118     kA13,
119     kA14,
120     kA15,
121     kA16,
122     kA17,
123     kA18,
124     kA19,
125     kA20,
126     kA21,
127     kA22,
128     kA23,
129     kA24,
130   };
131 
132   template <typename Sink>
AbslStringify(Sink & sink,Label e)133   friend void AbslStringify(Sink& sink, Label e) {
134     sink.Append(LabelToStringForDebugging(e));
135   }
136 
137   /*!\brief Converts the `Label` to a debugging string.
138    *
139    * \param label Label to convert.
140    * \return Converted label.
141    */
142   static std::string LabelToStringForDebugging(Label label);
143 
144   /*!\brief Gets the channel label for an ambisonics channel number.
145    *
146    * \param ambisonics_channel_number Ambisonics channel number to get the label
147    *        of.
148    * \return Converted label. A specific status on failure.
149    */
150   static absl::StatusOr<Label> AmbisonicsChannelNumberToLabel(
151       int ambisonics_channel_number);
152 
153   /*!\brief Returns the demixed version of a channel label.
154    *
155    * \param label Label to get the demixed version of.
156    * \return Converted label on success. A specific status if the channel is not
157    *         suitable for demixing. A specific status on other failures.
158    */
159   static absl::StatusOr<Label> GetDemixedLabel(Label label);
160 
161   /*!\brief Gets the channel ordering to use for the associated input layout.
162    *
163    * The output is ordered to agree with the "precomputed" EAR matrices. Certain
164    * layouts are based on other layouts. The channels which are excluded are
165    * represented by `ChannelLabel::Label::kOmitted`.
166    *
167    * \param loudspeaker_layout Layout to get the channel ordering from.
168    * \param expanded_loudspeaker_layout Associated expanded loudspeaker layout
169    *        or `std::nullopt` when it is not relevant.
170    * \return Channel ordering associated with the layout if known. Or a specific
171    *         status on failure.
172    */
173   static absl::StatusOr<std::vector<ChannelLabel::Label>>
174   LookupEarChannelOrderFromScalableLoudspeakerLayout(
175       ChannelAudioLayerConfig::LoudspeakerLayout loudspeaker_layout,
176       const std::optional<ChannelAudioLayerConfig::ExpandedLoudspeakerLayout>&
177           expanded_loudspeaker_layout);
178 
179   /*!\brief Gets the labels related to reconstructing the input layout.
180    *
181    * Returns the labels that may be needed to reconstruct the
182    * `loudspeaker_layout`. This function is useful when audio frames represent
183    * channels which do agree with the `loudspeaker_layout`. Usually this occurs
184    * when there are multiple layers in a scalable channel audio element.
185    *
186    * \param loudspeaker_layout Layout to get the labels to reconstruct from.
187    * \param expanded_loudspeaker_layout Associated expanded loudspeaker layout
188    *        or `std::nullopt` when it is not relevant.
189    * \return Labels to reconstruct the associated layout if known. Or a specific
190    *         status on failure.
191    */
192   static absl::StatusOr<absl::flat_hash_set<ChannelLabel::Label>>
193   LookupLabelsToReconstructFromScalableLoudspeakerLayout(
194       ChannelAudioLayerConfig::LoudspeakerLayout loudspeaker_layout,
195       const std::optional<ChannelAudioLayerConfig::ExpandedLoudspeakerLayout>&
196           expanded_loudspeaker_layout);
197 
198   /*!\brief Gets the demixed labels for a given recon gain flag and layout.
199    *
200    * \param loudspeaker_layout Layout of the layer to get the labels from.
201    * \param recon_gain_flag Specifies the recon gain to get the labels for.
202    * \return Demixed channel labels. Or a specific status on failure.
203    */
204   static absl::StatusOr<ChannelLabel::Label> GetDemixedChannelLabelForReconGain(
205       const ChannelAudioLayerConfig::LoudspeakerLayout& layout,
206       const ReconGainElement::ReconGainFlagBitmask& recon_gain_flag);
207 
208   /*!\brief Converts the input string to a `Label`.
209    *
210    * Used only to support the deprecated `AudioFrameObuMetadata.channel_labels`
211    * field.
212    *
213    * Channel Labels, e.g. "L2", "Ls5". For ambisonics, use "A{ACN number}",
214    * e.g. "A0", "A13", but prefer using `AmbisonicsChannelNumberToLabel()`
215    * instead.
216    *
217    * \param label Label to convert.
218    * \return Converted label on success. A specific status on failure.
219    */
220   // TODO(b/330558209): Remove when `AudioFrameObuMetadata.channel_labels` is
221   //                    removed.
222   static absl::StatusOr<Label> DeprecatedStringBasedLabelToLabel(
223       absl::string_view label);
224 };
225 
226 }  // namespace iamf_tools
227 
228 #endif  // CLI_CHANNEL_LABEL_H_
229