1use crate::diagnostics::codes::ValidationCode;
10use crate::diagnostics::{Category, Severity};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub enum IabCode {
22 CodecForbidden,
24 ElectrospatialFormulationForbidden,
26 QuantizationBitsMissing,
28 QuantizationBitsInvalid,
30 ContainerFormatMissing,
32 EssenceContainerInvalid,
34 AudioSamplingRateMissing,
36 AudioSamplingRateInvalid,
38 SoundCompressionMissing,
40 SoundCompressionInvalid,
42 ChannelCountNotZero,
44 SubDescriptorMissing,
46 MCATagSymbolMissing,
48 MCATagSymbolInvalid,
50 MCATagNameMissing,
52 MCATagNameInvalid,
54 MCALabelDictionaryIDMissing,
56 MCALabelDictionaryIDInvalid,
58 MainAudioMissing,
60 IABSequenceNoResources,
62 IABSequenceSourceEncodingInvalid,
64}
65
66macro_rules! define_iab_enum {
71 ($name:ident, $prefix:literal) => {
72 #[doc = $prefix]
74 #[derive(Debug, Clone, Copy, PartialEq, Eq, strum::EnumIter)]
75 pub enum $name {
76 CodecForbidden,
78 ElectrospatialFormulationForbidden,
80 QuantizationBitsMissing,
82 QuantizationBitsInvalid,
84 ContainerFormatMissing,
86 EssenceContainerInvalid,
88 AudioSamplingRateMissing,
90 AudioSamplingRateInvalid,
92 SoundCompressionMissing,
94 SoundCompressionInvalid,
96 ChannelCountNotZero,
98 SubDescriptorMissing,
100 MCATagSymbolMissing,
102 MCATagSymbolInvalid,
104 MCATagNameMissing,
106 MCATagNameInvalid,
108 MCALabelDictionaryIDMissing,
110 MCALabelDictionaryIDInvalid,
112 MainAudioMissing,
114 IABSequenceNoResources,
116 IABSequenceSourceEncodingInvalid,
118 }
119
120 impl ValidationCode for $name {
121 fn code(&self) -> &'static str {
122 match self {
123 Self::CodecForbidden => concat!($prefix, ":5.9/CodecForbidden"),
124 Self::ElectrospatialFormulationForbidden => concat!($prefix, ":5.9/ElectrospatialFormulationForbidden"),
125 Self::QuantizationBitsMissing => concat!($prefix, ":5.9/QuantizationBitsMissing"),
126 Self::QuantizationBitsInvalid => concat!($prefix, ":5.9/QuantizationBitsInvalid"),
127 Self::ContainerFormatMissing => concat!($prefix, ":5.3/ContainerFormatMissing"),
128 Self::EssenceContainerInvalid => concat!($prefix, ":5.3/EssenceContainerInvalid"),
129 Self::AudioSamplingRateMissing => concat!($prefix, ":5.9/AudioSamplingRateMissing"),
130 Self::AudioSamplingRateInvalid => concat!($prefix, ":5.9/AudioSamplingRateInvalid"),
131 Self::SoundCompressionMissing => concat!($prefix, ":5.9/SoundCompressionMissing"),
132 Self::SoundCompressionInvalid => concat!($prefix, ":5.9/SoundCompressionInvalid"),
133 Self::ChannelCountNotZero => concat!($prefix, ":5.9/ChannelCountNotZero"),
134 Self::SubDescriptorMissing => concat!($prefix, ":5.9/SubDescriptorMissing"),
135 Self::MCATagSymbolMissing => concat!($prefix, ":5.9/MCATagSymbolMissing"),
136 Self::MCATagSymbolInvalid => concat!($prefix, ":5.9/MCATagSymbolInvalid"),
137 Self::MCATagNameMissing => concat!($prefix, ":5.9/MCATagNameMissing"),
138 Self::MCATagNameInvalid => concat!($prefix, ":5.9/MCATagNameInvalid"),
139 Self::MCALabelDictionaryIDMissing => concat!($prefix, ":5.9/MCALabelDictionaryIDMissing"),
140 Self::MCALabelDictionaryIDInvalid => concat!($prefix, ":5.9/MCALabelDictionaryIDInvalid"),
141 Self::MainAudioMissing => concat!($prefix, ":6.2/MainAudioMissing"),
142 Self::IABSequenceNoResources => concat!($prefix, ":6.2/IABSequenceNoResources"),
143 Self::IABSequenceSourceEncodingInvalid => concat!($prefix, ":6.2/IABSequenceSourceEncodingInvalid"),
144 }
145 }
146 fn description(&self) -> &'static str {
147 match self {
148 Self::CodecForbidden => "IABEssenceDescriptor: Codec item shall not be present (§5.9).",
149 Self::ElectrospatialFormulationForbidden => "IABEssenceDescriptor: ElectrospatialFormulation shall not be present (§5.9).",
150 Self::QuantizationBitsMissing => "IABEssenceDescriptor: QuantizationBits is missing; shall be 24.",
151 Self::QuantizationBitsInvalid => "IABEssenceDescriptor: QuantizationBits shall be 24.",
152 Self::ContainerFormatMissing => "IABEssenceDescriptor: ContainerFormat is missing.",
153 Self::EssenceContainerInvalid => "IABEssenceDescriptor: ContainerFormat is not the required IAB container UL.",
154 Self::AudioSamplingRateMissing => "IABEssenceDescriptor: AudioSampleRate is missing; shall be 48000/1.",
155 Self::AudioSamplingRateInvalid => "IABEssenceDescriptor: AudioSampleRate shall be 48000/1.",
156 Self::SoundCompressionMissing => "IABEssenceDescriptor: SoundCompression is missing.",
157 Self::SoundCompressionInvalid => "IABEssenceDescriptor: SoundCompression is not the required IAB compression UL.",
158 Self::ChannelCountNotZero => "IABEssenceDescriptor: ChannelCount shall be the distinguished value 0 (2019 edition).",
159 Self::SubDescriptorMissing => "IABEssenceDescriptor: IABSoundfieldLabelSubDescriptor shall be present.",
160 Self::MCATagSymbolMissing => "IABSoundfieldLabelSubDescriptor: MCATagSymbol is missing; shall be \"IAB\".",
161 Self::MCATagSymbolInvalid => "IABSoundfieldLabelSubDescriptor: MCATagSymbol shall be \"IAB\".",
162 Self::MCATagNameMissing => "IABSoundfieldLabelSubDescriptor: MCATagName is missing; shall be \"IAB\".",
163 Self::MCATagNameInvalid => "IABSoundfieldLabelSubDescriptor: MCATagName shall be \"IAB\".",
164 Self::MCALabelDictionaryIDMissing => "IABSoundfieldLabelSubDescriptor: MCALabelDictionaryID is missing.",
165 Self::MCALabelDictionaryIDInvalid => "IABSoundfieldLabelSubDescriptor: MCALabelDictionaryID is not the required IAB label UL.",
166 Self::MainAudioMissing => "Segment has IABSequence but no MainAudioSequence (§6.2).",
167 Self::IABSequenceNoResources => "IABSequence shall contain at least one Resource (§6.2).",
168 Self::IABSequenceSourceEncodingInvalid => "IABSequence Resource.SourceEncoding does not reference an IABEssenceDescriptor (§6.2).",
169 }
170 }
171 fn default_severity(&self) -> Severity {
172 match self {
173 Self::QuantizationBitsMissing
174 | Self::ContainerFormatMissing
175 | Self::AudioSamplingRateMissing
176 | Self::SoundCompressionMissing => Severity::Warning,
177 _ => Severity::Error,
178 }
179 }
180 fn category(&self) -> Category {
181 Category::Audio
182 }
183 }
184
185 impl $name {
186 pub const ALL: &'static [Self] = &[
187 Self::CodecForbidden,
188 Self::ElectrospatialFormulationForbidden,
189 Self::QuantizationBitsMissing,
190 Self::QuantizationBitsInvalid,
191 Self::ContainerFormatMissing,
192 Self::EssenceContainerInvalid,
193 Self::AudioSamplingRateMissing,
194 Self::AudioSamplingRateInvalid,
195 Self::SoundCompressionMissing,
196 Self::SoundCompressionInvalid,
197 Self::ChannelCountNotZero,
198 Self::SubDescriptorMissing,
199 Self::MCATagSymbolMissing,
200 Self::MCATagSymbolInvalid,
201 Self::MCATagNameMissing,
202 Self::MCATagNameInvalid,
203 Self::MCALabelDictionaryIDMissing,
204 Self::MCALabelDictionaryIDInvalid,
205 Self::MainAudioMissing,
206 Self::IABSequenceNoResources,
207 Self::IABSequenceSourceEncodingInvalid,
208 ];
209
210 pub fn for_code(r: IabCode) -> &'static str {
213 match r {
214 IabCode::CodecForbidden => concat!($prefix, ":5.9/CodecForbidden"),
215 IabCode::ElectrospatialFormulationForbidden => concat!($prefix, ":5.9/ElectrospatialFormulationForbidden"),
216 IabCode::QuantizationBitsMissing => concat!($prefix, ":5.9/QuantizationBitsMissing"),
217 IabCode::QuantizationBitsInvalid => concat!($prefix, ":5.9/QuantizationBitsInvalid"),
218 IabCode::ContainerFormatMissing => concat!($prefix, ":5.3/ContainerFormatMissing"),
219 IabCode::EssenceContainerInvalid => concat!($prefix, ":5.3/EssenceContainerInvalid"),
220 IabCode::AudioSamplingRateMissing => concat!($prefix, ":5.9/AudioSamplingRateMissing"),
221 IabCode::AudioSamplingRateInvalid => concat!($prefix, ":5.9/AudioSamplingRateInvalid"),
222 IabCode::SoundCompressionMissing => concat!($prefix, ":5.9/SoundCompressionMissing"),
223 IabCode::SoundCompressionInvalid => concat!($prefix, ":5.9/SoundCompressionInvalid"),
224 IabCode::ChannelCountNotZero => concat!($prefix, ":5.9/ChannelCountNotZero"),
225 IabCode::SubDescriptorMissing => concat!($prefix, ":5.9/SubDescriptorMissing"),
226 IabCode::MCATagSymbolMissing => concat!($prefix, ":5.9/MCATagSymbolMissing"),
227 IabCode::MCATagSymbolInvalid => concat!($prefix, ":5.9/MCATagSymbolInvalid"),
228 IabCode::MCATagNameMissing => concat!($prefix, ":5.9/MCATagNameMissing"),
229 IabCode::MCATagNameInvalid => concat!($prefix, ":5.9/MCATagNameInvalid"),
230 IabCode::MCALabelDictionaryIDMissing => concat!($prefix, ":5.9/MCALabelDictionaryIDMissing"),
231 IabCode::MCALabelDictionaryIDInvalid => concat!($prefix, ":5.9/MCALabelDictionaryIDInvalid"),
232 IabCode::MainAudioMissing => concat!($prefix, ":6.2/MainAudioMissing"),
233 IabCode::IABSequenceNoResources => concat!($prefix, ":6.2/IABSequenceNoResources"),
234 IabCode::IABSequenceSourceEncodingInvalid => concat!($prefix, ":6.2/IABSequenceSourceEncodingInvalid"),
235 }
236 }
237 }
238
239 impl From<$name> for String {
240 fn from(c: $name) -> String {
241 c.code().to_string()
242 }
243 }
244 };
245}
246
247define_iab_enum!(St2067_201_2019, "ST2067-201:2019");
248define_iab_enum!(St2067_201_2021, "ST2067-201:2021");