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