1#![doc = include_str!("../README.md")]
5
6use ta1394_avc_general::*;
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub struct Am824MultiBitAudioAttr {
11 pub freq: u32,
12 pub rate_ctl: bool,
13}
14
15impl Default for Am824MultiBitAudioAttr {
16 fn default() -> Self {
17 Self {
18 freq: 22050,
19 rate_ctl: Default::default(),
20 }
21 }
22}
23
24impl Am824MultiBitAudioAttr {
25 const FREQ_CODE_22050: u8 = 0x00;
26 const FREQ_CODE_24000: u8 = 0x01;
27 const FREQ_CODE_32000: u8 = 0x02;
28 const FREQ_CODE_44100: u8 = 0x03;
29 const FREQ_CODE_48000: u8 = 0x04;
30 const FREQ_CODE_96000: u8 = 0x05;
31 const FREQ_CODE_176400: u8 = 0x06;
32 const FREQ_CODE_192000: u8 = 0x07;
33
34 const FREQ_CODE_MASK: u8 = 0x0f;
35 const FREQ_CODE_SHIFT: usize = 4;
36
37 const RATE_CTL_SUPPORTED: u8 = 0x00;
38 const RATE_CTL_DONT_CARE: u8 = 0x01;
39
40 const RATE_CTL_MASK: u8 = 0x01;
41 const RATE_CTL_SHIFT: usize = 0;
42
43 const LENGTH: usize = 2;
44
45 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
46 if raw.len() < Self::LENGTH {
47 Err(AvcRespParseError::TooShortResp(Self::LENGTH))?;
48 }
49
50 let freq_code = (raw[0] >> Self::FREQ_CODE_SHIFT) & Self::FREQ_CODE_MASK;
51 let freq = match freq_code {
52 Self::FREQ_CODE_22050 => 22050,
53 Self::FREQ_CODE_24000 => 24000,
54 Self::FREQ_CODE_32000 => 32000,
55 Self::FREQ_CODE_44100 => 44100,
56 Self::FREQ_CODE_48000 => 48000,
57 Self::FREQ_CODE_96000 => 96000,
58 Self::FREQ_CODE_176400 => 176400,
59 Self::FREQ_CODE_192000 => 192000,
60 _ => Err(AvcRespParseError::UnexpectedOperands(0))?,
61 };
62
63 let rate_ctl_code = (raw[0] >> Self::RATE_CTL_SHIFT) & Self::RATE_CTL_MASK;
64 let rate_ctl = rate_ctl_code == Self::RATE_CTL_SUPPORTED;
65
66 Ok(Am824MultiBitAudioAttr { freq, rate_ctl })
67 }
68
69 fn to_raw(&self) -> Result<[u8; Self::LENGTH], AvcCmdBuildError> {
70 let freq_code = match self.freq {
71 22050 => Self::FREQ_CODE_22050,
72 24000 => Self::FREQ_CODE_24000,
73 32000 => Self::FREQ_CODE_32000,
74 44100 => Self::FREQ_CODE_44100,
75 48000 => Self::FREQ_CODE_48000,
76 96000 => Self::FREQ_CODE_96000,
77 176400 => Self::FREQ_CODE_176400,
78 192000 => Self::FREQ_CODE_192000,
79 _ => Err(AvcCmdBuildError::InvalidOperands)?,
80 };
81
82 let rate_ctl_code = if self.rate_ctl {
83 Self::RATE_CTL_SUPPORTED
84 } else {
85 Self::RATE_CTL_DONT_CARE
86 };
87
88 let mut raw = [0xff; Self::LENGTH];
89 raw[0] = ((freq_code & Self::FREQ_CODE_MASK) << Self::FREQ_CODE_SHIFT)
90 | ((rate_ctl_code & Self::RATE_CTL_MASK) << Self::RATE_CTL_SHIFT);
91
92 Ok(raw)
93 }
94}
95
96#[derive(Clone, Copy, Debug, Eq, PartialEq)]
98pub struct Am824OneBitAudioAttr {
99 pub freq: u32,
100 pub rate_ctl: bool,
101}
102
103impl Default for Am824OneBitAudioAttr {
104 fn default() -> Self {
105 Self {
106 freq: 2048000,
107 rate_ctl: Default::default(),
108 }
109 }
110}
111
112impl Am824OneBitAudioAttr {
113 const FREQ_CODE_2048000: u8 = 0x00;
114 const FREQ_CODE_2822400: u8 = 0x01;
115 const FREQ_CODE_3072000: u8 = 0x02;
116 const FREQ_CODE_5644800: u8 = 0x03;
117 const FREQ_CODE_6144000: u8 = 0x04;
118 const FREQ_CODE_11289600: u8 = 0x05;
119 const FREQ_CODE_12288000: u8 = 0x06;
120
121 const FREQ_CODE_MASK: u8 = 0x0f;
122 const FREQ_CODE_SHIFT: usize = 4;
123
124 const RATE_CTL_SUPPORTED: u8 = 0x00;
125 const RATE_CTL_DONT_CARE: u8 = 0x01;
126
127 const RATE_CTL_MASK: u8 = 0x01;
128 const RATE_CTL_SHIFT: usize = 0;
129
130 const LENGTH: usize = 2;
131
132 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
133 if raw.len() < Self::LENGTH {
134 Err(AvcRespParseError::TooShortResp(Self::LENGTH))?;
135 }
136
137 let freq_code = (raw[0] >> Self::FREQ_CODE_SHIFT) & Self::FREQ_CODE_MASK;
138 let freq = match freq_code {
139 Self::FREQ_CODE_2048000 => 2048000,
140 Self::FREQ_CODE_2822400 => 2822400,
141 Self::FREQ_CODE_3072000 => 3072000,
142 Self::FREQ_CODE_5644800 => 5644800,
143 Self::FREQ_CODE_6144000 => 6144000,
144 Self::FREQ_CODE_11289600 => 11289600,
145 Self::FREQ_CODE_12288000 => 12288000,
146 _ => Err(AvcRespParseError::UnexpectedOperands(0))?,
147 };
148
149 let rate_ctl_code = (raw[0] >> Self::RATE_CTL_SHIFT) & Self::RATE_CTL_MASK;
150 let rate_ctl = rate_ctl_code == Self::RATE_CTL_SUPPORTED;
151
152 Ok(Am824OneBitAudioAttr { freq, rate_ctl })
153 }
154
155 fn to_raw(&self) -> Result<[u8; Self::LENGTH], AvcCmdBuildError> {
156 let freq_code = match self.freq {
157 2048000 => Self::FREQ_CODE_2048000,
158 2822400 => Self::FREQ_CODE_2822400,
159 3072000 => Self::FREQ_CODE_3072000,
160 5644800 => Self::FREQ_CODE_5644800,
161 6144000 => Self::FREQ_CODE_6144000,
162 11289600 => Self::FREQ_CODE_11289600,
163 12288000 => Self::FREQ_CODE_12288000,
164 _ => Err(AvcCmdBuildError::InvalidOperands)?,
165 };
166
167 let rate_ctl_code = if self.rate_ctl {
168 Self::RATE_CTL_SUPPORTED
169 } else {
170 Self::RATE_CTL_DONT_CARE
171 };
172
173 let mut raw = [0xff; Self::LENGTH];
174 raw[0] = ((freq_code & Self::FREQ_CODE_MASK) << Self::FREQ_CODE_SHIFT)
175 | ((rate_ctl_code & Self::RATE_CTL_MASK) << Self::RATE_CTL_SHIFT);
176
177 Ok(raw)
178 }
179}
180
181#[derive(Clone, Copy, Debug, Eq, PartialEq)]
183pub enum Am824Stream {
184 Iec60958_3(Am824MultiBitAudioAttr),
185 Iec61937_3(Am824MultiBitAudioAttr),
186 Iec61937_4(Am824MultiBitAudioAttr),
187 Iec61937_5(Am824MultiBitAudioAttr),
188 Iec61937_6(Am824MultiBitAudioAttr),
189 Iec61937_7(Am824MultiBitAudioAttr),
190 MultiBitLinearAudioRaw(Am824MultiBitAudioAttr),
191 MultiBitLinearAudioDvd(Am824MultiBitAudioAttr),
192 OneBitAudioPlainRaw(Am824OneBitAudioAttr),
193 OneBitAudioPlainSacd(Am824OneBitAudioAttr),
194 OneBitAudioEncodedRaw(Am824OneBitAudioAttr),
195 OneBitAudioEncodedSacd(Am824OneBitAudioAttr),
196 HighPrecisionMultiBitLinearAudio(Am824MultiBitAudioAttr),
197 MidiConformant([u8; 2]),
198 Reserved([u8; 4]),
199}
200
201impl Default for Am824Stream {
202 fn default() -> Self {
203 Self::Reserved([0xff; 4])
204 }
205}
206
207impl Am824Stream {
208 const IEC60958_3: u8 = 0x00;
209 const IEC61937_3: u8 = 0x01;
210 const IEC61937_4: u8 = 0x02;
211 const IEC61937_5: u8 = 0x03;
212 const IEC61937_6: u8 = 0x04;
213 const IEC61937_7: u8 = 0x05;
214 const MULTI_BIT_LINEAR_AUDIO_RAW: u8 = 0x06;
215 const MULTI_BIT_LINEAR_AUDIO_DVD: u8 = 0x07;
216 const ONE_BIT_AUDIO_PLAIN_RAW: u8 = 0x08;
217 const ONE_BIT_AUDIO_PLAIN_SACD: u8 = 0x09;
218 const ONE_BIT_AUDIO_ENCODED_RAW: u8 = 0x0a;
219 const ONE_BIT_AUDIO_ENCODED_SACD: u8 = 0x0b;
220 const HIGH_PRECISION_MULTI_BIT_LINEAR_AUDIO: u8 = 0x0c;
221 const MIDI_CONFORMANT: u8 = 0x0d;
222
223 const LENGTH: usize = 4;
224
225 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
226 if raw.len() < Self::LENGTH {
227 Err(AvcRespParseError::TooShortResp(Self::LENGTH))?;
228 }
229
230 let fmt = match raw[0] {
231 Self::IEC60958_3
232 | Self::IEC61937_3
233 | Self::IEC61937_4
234 | Self::IEC61937_5
235 | Self::IEC61937_6
236 | Self::IEC61937_7
237 | Self::MULTI_BIT_LINEAR_AUDIO_RAW
238 | Self::MULTI_BIT_LINEAR_AUDIO_DVD
239 | Self::HIGH_PRECISION_MULTI_BIT_LINEAR_AUDIO => {
240 let attrs =
241 Am824MultiBitAudioAttr::from_raw(&raw[2..]).map_err(|err| err.add_offset(2))?;
242 match raw[0] {
243 Self::IEC60958_3 => Self::Iec60958_3(attrs),
244 Self::IEC61937_3 => Self::Iec61937_3(attrs),
245 Self::IEC61937_4 => Self::Iec61937_4(attrs),
246 Self::IEC61937_5 => Self::Iec61937_5(attrs),
247 Self::IEC61937_6 => Self::Iec61937_6(attrs),
248 Self::IEC61937_7 => Self::Iec61937_7(attrs),
249 Self::MULTI_BIT_LINEAR_AUDIO_RAW => Self::MultiBitLinearAudioRaw(attrs),
250 Self::MULTI_BIT_LINEAR_AUDIO_DVD => Self::MultiBitLinearAudioDvd(attrs),
251 Self::HIGH_PRECISION_MULTI_BIT_LINEAR_AUDIO => {
252 Self::HighPrecisionMultiBitLinearAudio(attrs)
253 }
254 _ => Err(AvcRespParseError::UnexpectedOperands(0))?,
255 }
256 }
257 Self::ONE_BIT_AUDIO_PLAIN_RAW
258 | Self::ONE_BIT_AUDIO_PLAIN_SACD
259 | Self::ONE_BIT_AUDIO_ENCODED_RAW
260 | Self::ONE_BIT_AUDIO_ENCODED_SACD => {
261 let attrs =
262 Am824OneBitAudioAttr::from_raw(&raw[2..]).map_err(|err| err.add_offset(2))?;
263 match raw[0] {
264 Self::ONE_BIT_AUDIO_PLAIN_RAW => Self::OneBitAudioPlainRaw(attrs),
265 Self::ONE_BIT_AUDIO_PLAIN_SACD => Self::OneBitAudioPlainSacd(attrs),
266 Self::ONE_BIT_AUDIO_ENCODED_RAW => Self::OneBitAudioEncodedRaw(attrs),
267 Self::ONE_BIT_AUDIO_ENCODED_SACD => Self::OneBitAudioEncodedSacd(attrs),
268 _ => Err(AvcRespParseError::UnexpectedOperands(0))?,
269 }
270 }
271 Self::MIDI_CONFORMANT => {
272 let mut r = [0; 2];
273 r.copy_from_slice(&raw[2..4]);
274 Self::MidiConformant(r)
275 }
276 _ => {
277 let mut r = [0xff; 4];
278 r.copy_from_slice(&raw);
279 Self::Reserved(r)
280 }
281 };
282
283 Ok(fmt)
284 }
285
286 fn to_raw(&self) -> Result<[u8; Self::LENGTH], AvcCmdBuildError> {
287 let mut raw = [0xff; Self::LENGTH];
288 match self {
289 Self::Iec60958_3(attrs)
290 | Self::Iec61937_3(attrs)
291 | Self::Iec61937_4(attrs)
292 | Self::Iec61937_5(attrs)
293 | Self::Iec61937_6(attrs)
294 | Self::Iec61937_7(attrs)
295 | Self::MultiBitLinearAudioRaw(attrs)
296 | Self::MultiBitLinearAudioDvd(attrs)
297 | Self::HighPrecisionMultiBitLinearAudio(attrs) => {
298 raw[0] = match self {
299 Self::Iec60958_3(_) => Self::IEC60958_3,
300 Self::Iec61937_3(_) => Self::IEC61937_3,
301 Self::Iec61937_4(_) => Self::IEC61937_4,
302 Self::Iec61937_5(_) => Self::IEC61937_5,
303 Self::Iec61937_6(_) => Self::IEC61937_6,
304 Self::Iec61937_7(_) => Self::IEC61937_7,
305 Self::MultiBitLinearAudioRaw(_) => Self::MULTI_BIT_LINEAR_AUDIO_RAW,
306 Self::MultiBitLinearAudioDvd(_) => Self::MULTI_BIT_LINEAR_AUDIO_DVD,
307 Self::HighPrecisionMultiBitLinearAudio(_) => {
308 Self::HIGH_PRECISION_MULTI_BIT_LINEAR_AUDIO
309 }
310 _ => Err(AvcCmdBuildError::InvalidOperands)?,
311 };
312 let r = attrs.to_raw()?;
313 raw[2..4].copy_from_slice(&r)
314 }
315 Self::OneBitAudioPlainRaw(attrs)
316 | Self::OneBitAudioPlainSacd(attrs)
317 | Self::OneBitAudioEncodedRaw(attrs)
318 | Self::OneBitAudioEncodedSacd(attrs) => {
319 raw[0] = match self {
320 Self::OneBitAudioPlainRaw(_) => Self::ONE_BIT_AUDIO_PLAIN_RAW,
321 Self::OneBitAudioPlainSacd(_) => Self::ONE_BIT_AUDIO_PLAIN_SACD,
322 Self::OneBitAudioEncodedRaw(_) => Self::ONE_BIT_AUDIO_ENCODED_RAW,
323 Self::OneBitAudioEncodedSacd(_) => Self::ONE_BIT_AUDIO_ENCODED_SACD,
324 _ => Err(AvcCmdBuildError::InvalidOperands)?,
325 };
326 let r = attrs.to_raw()?;
327 raw[2..4].copy_from_slice(&r);
328 }
329 Self::MidiConformant(d) => {
330 raw[0] = Self::MIDI_CONFORMANT;
331 raw[2..4].copy_from_slice(d);
332 }
333 Self::Reserved(r) => raw.copy_from_slice(r),
334 }
335
336 Ok(raw)
337 }
338}
339
340#[derive(Clone, Copy, Debug, Eq, PartialEq)]
342pub enum CompoundAm824StreamFormat {
343 Iec60958_3,
345 Iec61937_3,
347 Iec61937_4,
349 Iec61937_5,
351 Iec61937_6,
353 Iec61937_7,
355 MultiBitLinearAudioRaw,
357 MultiBitLinearAudioDvd,
358 HighPrecisionMultiBitLinearAudio,
359 MidiConformant,
361 SmpteTimeCodeConformant,
363 SampleCount,
365 AncillaryData,
367 SyncStream,
369 Reserved(u8),
370}
371
372impl Default for CompoundAm824StreamFormat {
373 fn default() -> Self {
374 Self::Reserved(0xff)
375 }
376}
377
378impl CompoundAm824StreamFormat {
379 const IEC60958_3: u8 = 0x00;
380 const IEC61937_3: u8 = 0x01;
381 const IEC61937_4: u8 = 0x02;
382 const IEC61937_5: u8 = 0x03;
383 const IEC61937_6: u8 = 0x04;
384 const IEC61937_7: u8 = 0x05;
385 const MULTI_BIT_LINEAR_AUDIO_RAW: u8 = 0x06;
386 const MULTI_BIT_LINEAR_AUDIO_DVD: u8 = 0x07;
387 const HIGH_PRECISION_MULTI_BIT_LINEAR_AUDIO: u8 = 0x0c;
388 const MIDI_CONFORMANT: u8 = 0x0d;
389 const SMPTE_TIME_CODE_CONFORMANT: u8 = 0x0e;
390 const SAMPLE_COUNT: u8 = 0x0f;
391 const ANCILLARY_DATA: u8 = 0x10;
392 const SYNC_STREAM: u8 = 0x40;
393
394 fn from_val(val: u8) -> Self {
395 match val {
396 Self::IEC60958_3 => Self::Iec60958_3,
397 Self::IEC61937_3 => Self::Iec61937_3,
398 Self::IEC61937_4 => Self::Iec61937_4,
399 Self::IEC61937_5 => Self::Iec61937_5,
400 Self::IEC61937_6 => Self::Iec61937_6,
401 Self::IEC61937_7 => Self::Iec61937_7,
402 Self::MULTI_BIT_LINEAR_AUDIO_RAW => Self::MultiBitLinearAudioRaw,
403 Self::MULTI_BIT_LINEAR_AUDIO_DVD => Self::MultiBitLinearAudioDvd,
404 Self::HIGH_PRECISION_MULTI_BIT_LINEAR_AUDIO => Self::HighPrecisionMultiBitLinearAudio,
405 Self::MIDI_CONFORMANT => Self::MidiConformant,
406 Self::SMPTE_TIME_CODE_CONFORMANT => Self::SmpteTimeCodeConformant,
407 Self::SAMPLE_COUNT => Self::SampleCount,
408 Self::ANCILLARY_DATA => Self::AncillaryData,
409 Self::SYNC_STREAM => Self::SyncStream,
410 _ => Self::Reserved(val),
411 }
412 }
413
414 fn to_val(&self) -> u8 {
415 match self {
416 Self::Iec60958_3 => Self::IEC60958_3,
417 Self::Iec61937_3 => Self::IEC61937_3,
418 Self::Iec61937_4 => Self::IEC61937_4,
419 Self::Iec61937_5 => Self::IEC61937_5,
420 Self::Iec61937_6 => Self::IEC61937_6,
421 Self::Iec61937_7 => Self::IEC61937_7,
422 Self::MultiBitLinearAudioRaw => Self::MULTI_BIT_LINEAR_AUDIO_RAW,
423 Self::MultiBitLinearAudioDvd => Self::MULTI_BIT_LINEAR_AUDIO_DVD,
424 Self::HighPrecisionMultiBitLinearAudio => Self::HIGH_PRECISION_MULTI_BIT_LINEAR_AUDIO,
425 Self::MidiConformant => Self::MIDI_CONFORMANT,
426 Self::SmpteTimeCodeConformant => Self::SMPTE_TIME_CODE_CONFORMANT,
427 Self::SampleCount => Self::SAMPLE_COUNT,
428 Self::AncillaryData => Self::ANCILLARY_DATA,
429 Self::SyncStream => Self::SYNC_STREAM,
430 Self::Reserved(val) => *val,
431 }
432 }
433}
434
435#[derive(Clone, Debug, Eq, PartialEq)]
437pub struct CompoundAm824StreamEntry {
438 pub count: u8,
440 pub format: CompoundAm824StreamFormat,
442}
443
444impl Default for CompoundAm824StreamEntry {
445 fn default() -> Self {
446 Self {
447 count: 0,
448 format: Default::default(),
449 }
450 }
451}
452
453impl CompoundAm824StreamEntry {
454 const LENGTH: usize = 2;
455
456 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
457 if raw.len() < Self::LENGTH {
458 Err(AvcRespParseError::TooShortResp(Self::LENGTH))?;
459 }
460 Ok(Self {
461 count: raw[0],
462 format: CompoundAm824StreamFormat::from_val(raw[1]),
463 })
464 }
465
466 fn to_raw(&self) -> Result<[u8; Self::LENGTH], AvcCmdBuildError> {
467 Ok([self.count, self.format.to_val()])
468 }
469}
470
471#[derive(Clone, Copy, Debug, Eq, PartialEq)]
473pub enum RateCtl {
474 Supported,
475 DontCare,
476 NotSupported,
477 Reserved(u8),
478}
479
480impl Default for RateCtl {
481 fn default() -> Self {
482 Self::Reserved(0xff)
483 }
484}
485
486impl RateCtl {
487 const SUPPORTED: u8 = 0x00;
488 const DONT_CARE: u8 = 0x01;
489 const NOT_SUPPORTED: u8 = 0x02;
490
491 fn to_val(&self) -> u8 {
492 match self {
493 Self::Supported => Self::SUPPORTED,
494 Self::DontCare => Self::DONT_CARE,
495 Self::NotSupported => Self::NOT_SUPPORTED,
496 Self::Reserved(val) => *val,
497 }
498 }
499
500 fn from_val(val: u8) -> Self {
501 match val {
502 Self::SUPPORTED => Self::Supported,
503 Self::DONT_CARE => Self::DontCare,
504 Self::NOT_SUPPORTED => Self::NotSupported,
505 _ => Self::Reserved(val),
506 }
507 }
508}
509
510#[derive(Clone, Debug, Eq, PartialEq)]
512pub struct CompoundAm824Stream {
513 pub freq: u32,
515 pub sync_src: bool,
517 pub rate_ctl: RateCtl,
519 pub entries: Vec<CompoundAm824StreamEntry>,
521}
522
523impl Default for CompoundAm824Stream {
524 fn default() -> Self {
525 Self {
526 freq: 22050,
527 sync_src: Default::default(),
528 rate_ctl: Default::default(),
529 entries: Default::default(),
530 }
531 }
532}
533
534impl CompoundAm824Stream {
535 const FREQ_CODE_22050: u8 = 0x00;
536 const FREQ_CODE_24000: u8 = 0x01;
537 const FREQ_CODE_32000: u8 = 0x02;
538 const FREQ_CODE_44100: u8 = 0x03;
539 const FREQ_CODE_48000: u8 = 0x04;
540 const FREQ_CODE_96000: u8 = 0x05;
541 const FREQ_CODE_176400: u8 = 0x06;
542 const FREQ_CODE_192000: u8 = 0x07;
543 const FREQ_CODE_88200: u8 = 0x0a;
544
545 const SYNC_SRC_MASK: u8 = 0x01;
546 const SYNC_SRC_SHIFT: usize = 2;
547
548 const RATE_CTL_MASK: u8 = 0x03;
549 const RATE_CTL_SHIFT: usize = 0;
550
551 const LENGTH_MIN: usize = 3;
552
553 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
554 if raw.len() < Self::LENGTH_MIN {
555 Err(AvcRespParseError::TooShortResp(Self::LENGTH_MIN))?;
556 }
557
558 let freq = match raw[0] {
559 Self::FREQ_CODE_22050 => 22050,
560 Self::FREQ_CODE_24000 => 24000,
561 Self::FREQ_CODE_32000 => 32000,
562 Self::FREQ_CODE_44100 => 44100,
563 Self::FREQ_CODE_48000 => 48000,
564 Self::FREQ_CODE_96000 => 96000,
565 Self::FREQ_CODE_176400 => 176400,
566 Self::FREQ_CODE_192000 => 192000,
567 Self::FREQ_CODE_88200 => 88200,
568 _ => Err(AvcRespParseError::UnexpectedOperands(0))?,
569 };
570 let sync_src_code = (raw[1] >> Self::SYNC_SRC_SHIFT) & Self::SYNC_SRC_MASK;
571 let sync_src = sync_src_code > 0;
572 let rate_ctl_code = (raw[1] >> Self::RATE_CTL_SHIFT) & Self::RATE_CTL_MASK;
573 let rate_ctl = RateCtl::from_val(rate_ctl_code);
574 let entry_count = raw[2] as usize;
575
576 let mut entries = Vec::with_capacity(entry_count);
577 let mut pos = 3;
578 while pos + CompoundAm824StreamEntry::LENGTH <= raw.len() {
579 let entry = CompoundAm824StreamEntry::from_raw(&raw[pos..])
580 .map_err(|err| err.add_offset(pos))?;
581 entries.push(entry);
582 pos += CompoundAm824StreamEntry::LENGTH;
583 }
584
585 if entries.len() != entry_count {
586 Err(AvcRespParseError::UnexpectedOperands(2))?;
587 }
588
589 Ok(Self {
590 freq,
591 sync_src,
592 rate_ctl,
593 entries,
594 })
595 }
596
597 fn to_raw(&self) -> Result<Vec<u8>, AvcCmdBuildError> {
598 let mut raw = Vec::with_capacity(Self::LENGTH_MIN);
599 let freq_code = match self.freq {
600 22050 => Self::FREQ_CODE_22050,
601 24000 => Self::FREQ_CODE_24000,
602 32000 => Self::FREQ_CODE_32000,
603 44100 => Self::FREQ_CODE_44100,
604 48000 => Self::FREQ_CODE_48000,
605 96000 => Self::FREQ_CODE_96000,
606 176400 => Self::FREQ_CODE_176400,
607 192000 => Self::FREQ_CODE_192000,
608 88200 => Self::FREQ_CODE_88200,
609 _ => Err(AvcCmdBuildError::InvalidOperands)?,
610 };
611 raw.push(freq_code);
612
613 let sync_src_code = ((self.sync_src as u8) & Self::SYNC_SRC_MASK) << Self::SYNC_SRC_SHIFT;
614 let rate_ctl_code = (self.rate_ctl.to_val() & Self::RATE_CTL_MASK) << Self::RATE_CTL_SHIFT;
615 raw.push(sync_src_code | rate_ctl_code);
616
617 raw.push(self.entries.len() as u8);
618 self.entries
619 .iter()
620 .try_for_each(|entry| entry.to_raw().map(|r| raw.extend_from_slice(&r)))
621 .map(|_| raw)
622 }
623}
624
625#[derive(Clone, Debug, Eq, PartialEq)]
627pub enum AmStream {
628 Am824(Am824Stream),
630 AudioPack,
632 Fp32,
634 CompoundAm824(CompoundAm824Stream),
636 Reserved(Vec<u8>),
637}
638
639impl Default for AmStream {
640 fn default() -> Self {
641 Self::Reserved(vec![0xff; Self::LENGTH_MIN])
642 }
643}
644
645impl AmStream {
646 const HIER_LEVEL_1_AM824: u8 = 0x00;
647 const HIER_LEVEL_1_AUDIO_PACK: u8 = 0x01;
648 const HIER_LEVEL_1_FP32: u8 = 0x02;
649 pub const HIER_LEVEL_1_COMPOUND_AM824: u8 = 0x40;
650
651 const LENGTH_MIN: usize = 4;
652}
653
654impl AmStream {
655 pub fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
656 if raw.len() < Self::LENGTH_MIN {
657 Err(AvcRespParseError::TooShortResp(Self::LENGTH_MIN))?;
658 }
659
660 let s = match raw[0] {
661 Self::HIER_LEVEL_1_AM824 => {
662 let format = Am824Stream::from_raw(&raw[1..]).map_err(|err| err.add_offset(1))?;
663 Self::Am824(format)
664 }
665 Self::HIER_LEVEL_1_AUDIO_PACK => Self::AudioPack,
666 Self::HIER_LEVEL_1_FP32 => Self::Fp32,
667 Self::HIER_LEVEL_1_COMPOUND_AM824 => {
668 let s =
669 CompoundAm824Stream::from_raw(&raw[1..]).map_err(|err| err.add_offset(1))?;
670 Self::CompoundAm824(s)
671 }
672 _ => Self::Reserved(raw.to_vec()),
673 };
674
675 Ok(s)
676 }
677
678 pub fn to_raw(&self) -> Result<Vec<u8>, AvcCmdBuildError> {
679 let mut raw = Vec::with_capacity(AmStream::LENGTH_MIN);
680 match self {
681 AmStream::Am824(format) => {
682 raw.push(AmStream::HIER_LEVEL_1_AM824);
683 let r = format.to_raw()?;
684 raw.extend_from_slice(&r);
685 }
686 AmStream::AudioPack => {
687 raw.push(AmStream::HIER_LEVEL_1_AUDIO_PACK);
688 raw.extend_from_slice(&[0xff, 0xff, 0xff, 0xff]);
689 }
690 AmStream::Fp32 => {
691 raw.push(AmStream::HIER_LEVEL_1_FP32);
692 raw.extend_from_slice(&[0xff, 0xff, 0xff, 0xff]);
693 }
694 AmStream::CompoundAm824(s) => {
695 raw.push(AmStream::HIER_LEVEL_1_COMPOUND_AM824);
696 let mut r = s.to_raw()?;
697 raw.append(&mut r);
698 }
699 AmStream::Reserved(d) => {
700 raw.copy_from_slice(d);
701 }
702 }
703 Ok(raw)
704 }
705}
706
707#[derive(Clone, Debug, Eq, PartialEq)]
709pub enum StreamFormat {
710 Am(AmStream),
713 Reserved(Vec<u8>),
714}
715
716impl Default for StreamFormat {
717 fn default() -> Self {
718 Self::Reserved(vec![0xff; Self::LENGTH_MIN])
719 }
720}
721
722impl StreamFormat {
723 pub const HIER_ROOT_AM: u8 = 0x90;
725
726 const LENGTH_MIN: usize = 1;
727
728 fn as_am_stream(&self) -> Option<&AmStream> {
729 if let StreamFormat::Am(i) = self {
730 Some(i)
731 } else {
732 None
733 }
734 }
735
736 pub fn as_am824_stream(&self) -> Option<&Am824Stream> {
738 if let AmStream::Am824(s) = self.as_am_stream()? {
739 Some(s)
740 } else {
741 None
742 }
743 }
744
745 pub fn as_compound_am824_stream(&self) -> Option<&CompoundAm824Stream> {
747 if let AmStream::CompoundAm824(s) = self.as_am_stream()? {
748 Some(s)
749 } else {
750 None
751 }
752 }
753
754 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
755 if raw.len() < Self::LENGTH_MIN {
756 Err(AvcRespParseError::TooShortResp(Self::LENGTH_MIN))?;
757 }
758
759 let s = match raw[0] {
760 Self::HIER_ROOT_AM => {
761 let am = AmStream::from_raw(&raw[1..]).map_err(|err| err.add_offset(1))?;
762 StreamFormat::Am(am)
763 }
764 _ => StreamFormat::Reserved(raw.to_vec()),
765 };
766
767 Ok(s)
768 }
769
770 fn to_raw(&self) -> Result<Vec<u8>, AvcCmdBuildError> {
771 let mut raw = Vec::with_capacity(Self::LENGTH_MIN);
772 match self {
773 StreamFormat::Am(am) => {
774 raw.push(StreamFormat::HIER_ROOT_AM);
775 am.to_raw().map(|mut r| raw.append(&mut r))?;
776 }
777 StreamFormat::Reserved(d) => raw.extend_from_slice(d),
778 }
779 Ok(raw)
780 }
781}
782
783#[derive(Clone, Copy, Debug, Eq, PartialEq)]
785pub enum UnitPlugType {
786 Pcr,
787 External,
788 Async,
789}
790
791impl Default for UnitPlugType {
792 fn default() -> Self {
793 Self::Pcr
794 }
795}
796
797impl UnitPlugType {
798 fn from_val(val: u8) -> Result<Self, AvcRespParseError> {
799 match val {
800 0 => Ok(Self::Pcr),
801 1 => Ok(Self::External),
802 2 => Ok(Self::Async),
803 _ => Err(AvcRespParseError::UnexpectedOperands(0))?,
804 }
805 }
806
807 fn to_val(&self) -> u8 {
808 match self {
809 Self::Pcr => 0,
810 Self::External => 1,
811 Self::Async => 2,
812 }
813 }
814}
815
816#[derive(Clone, Copy, Debug, Eq, PartialEq)]
818pub struct UnitPlugData {
819 pub unit_type: UnitPlugType,
821 pub plug_id: u8,
823}
824
825impl Default for UnitPlugData {
826 fn default() -> Self {
827 Self {
828 unit_type: Default::default(),
829 plug_id: 0xff,
830 }
831 }
832}
833
834impl UnitPlugData {
835 const LENGTH: usize = 3;
836
837 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
838 if raw.len() < Self::LENGTH {
839 Err(AvcRespParseError::TooShortResp(Self::LENGTH))?;
840 }
841
842 let unit_type = UnitPlugType::from_val(raw[0])?;
843
844 Ok(Self {
845 unit_type,
846 plug_id: raw[1],
847 })
848 }
849
850 fn to_raw(&self) -> [u8; Self::LENGTH] {
851 [self.unit_type.to_val(), self.plug_id, 0xff]
852 }
853}
854
855#[derive(Clone, Copy, Debug, Eq, PartialEq)]
857pub struct SubunitPlugData {
858 pub plug_id: u8,
859}
860
861impl Default for SubunitPlugData {
862 fn default() -> Self {
863 Self { plug_id: 0xff }
864 }
865}
866
867impl SubunitPlugData {
868 const LENGTH: usize = 3;
869
870 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
871 if raw.len() < Self::LENGTH {
872 Err(AvcRespParseError::TooShortResp(Self::LENGTH))?;
873 }
874 Ok(Self { plug_id: raw[0] })
875 }
876
877 fn to_raw(&self) -> [u8; Self::LENGTH] {
878 [self.plug_id, 0xff, 0xff]
879 }
880}
881
882#[derive(Clone, Copy, Debug, Eq, PartialEq)]
884pub struct FunctionBlockPlugData {
885 pub fb_type: u8,
887 pub fb_id: u8,
889 pub plug_id: u8,
891}
892
893impl Default for FunctionBlockPlugData {
894 fn default() -> Self {
895 Self {
896 fb_type: 0xff,
897 fb_id: 0xff,
898 plug_id: 0xff,
899 }
900 }
901}
902
903impl FunctionBlockPlugData {
904 const LENGTH: usize = 3;
905
906 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
907 if raw.len() < Self::LENGTH {
908 Err(AvcRespParseError::TooShortResp(Self::LENGTH))?;
909 }
910
911 Ok(Self {
912 fb_type: raw[0],
913 fb_id: raw[1],
914 plug_id: raw[2],
915 })
916 }
917
918 fn to_raw(&self) -> [u8; Self::LENGTH] {
919 [self.fb_type, self.fb_id, self.plug_id]
920 }
921}
922
923#[derive(Clone, Copy, Debug, Eq, PartialEq)]
925pub enum PlugAddrMode {
926 Unit(UnitPlugData),
927 Subunit(SubunitPlugData),
928 FunctionBlock(FunctionBlockPlugData),
929}
930
931impl Default for PlugAddrMode {
932 fn default() -> Self {
933 Self::Unit(Default::default())
934 }
935}
936
937impl PlugAddrMode {
938 const LENGTH: usize = 4;
939
940 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
941 if raw.len() < Self::LENGTH {
942 Err(AvcRespParseError::TooShortResp(Self::LENGTH))?;
943 }
944
945 let mode = match raw[0] {
946 0 => {
947 let data = UnitPlugData::from_raw(&raw[1..4]).map_err(|err| err.add_offset(1))?;
948 Self::Unit(data)
949 }
950 1 => {
951 let data =
952 SubunitPlugData::from_raw(&raw[1..4]).map_err(|err| err.add_offset(1))?;
953 Self::Subunit(data)
954 }
955 2 => {
956 let data =
957 FunctionBlockPlugData::from_raw(&raw[1..4]).map_err(|err| err.add_offset(1))?;
958 Self::FunctionBlock(data)
959 }
960 _ => Err(AvcRespParseError::UnexpectedOperands(0))?,
961 };
962
963 Ok(mode)
964 }
965
966 fn to_raw(&self) -> Result<[u8; Self::LENGTH], AvcCmdBuildError> {
967 let mut raw = [0xff; Self::LENGTH];
968 match self {
969 Self::Unit(data) => {
970 raw[0] = 0;
971 raw[1..4].copy_from_slice(&data.to_raw());
972 }
973 Self::Subunit(data) => {
974 raw[0] = 1;
975 raw[1..4].copy_from_slice(&data.to_raw());
976 }
977 Self::FunctionBlock(data) => {
978 raw[0] = 2;
979 raw[1..4].copy_from_slice(&data.to_raw());
980 }
981 }
982 Ok(raw)
983 }
984}
985
986#[derive(Clone, Copy, Debug, Eq, PartialEq)]
988pub enum PlugDirection {
989 Input,
990 Output,
991}
992
993impl Default for PlugDirection {
994 fn default() -> Self {
995 Self::Input
996 }
997}
998
999impl PlugDirection {
1000 const INPUT: u8 = 0;
1001 const OUTPUT: u8 = 1;
1002
1003 fn from_val(val: u8) -> Result<Self, AvcRespParseError> {
1004 match val {
1005 Self::INPUT => Ok(Self::Input),
1006 Self::OUTPUT => Ok(Self::Output),
1007 _ => Err(AvcRespParseError::UnexpectedOperands(0)),
1008 }
1009 }
1010
1011 fn to_val(&self) -> u8 {
1012 match self {
1013 Self::Input => Self::INPUT,
1014 Self::Output => Self::OUTPUT,
1015 }
1016 }
1017}
1018
1019#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1021pub struct PlugAddr {
1022 pub direction: PlugDirection,
1024 pub mode: PlugAddrMode,
1026}
1027
1028impl Default for PlugAddr {
1029 fn default() -> Self {
1030 Self {
1031 direction: Default::default(),
1032 mode: Default::default(),
1033 }
1034 }
1035}
1036
1037impl PlugAddr {
1038 const LENGTH: usize = 5;
1039
1040 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
1041 if raw.len() < Self::LENGTH {
1042 Err(AvcRespParseError::TooShortResp(Self::LENGTH))?;
1043 }
1044
1045 let direction = PlugDirection::from_val(raw[0])?;
1046 let mode = PlugAddrMode::from_raw(&raw[1..5]).map_err(|err| err.add_offset(1))?;
1047 Ok(Self { direction, mode })
1048 }
1049
1050 fn to_raw(&self) -> Result<[u8; Self::LENGTH], AvcCmdBuildError> {
1051 let mut raw = [0xff; Self::LENGTH];
1052 raw[0] = self.direction.to_val();
1053 let r = self.mode.to_raw()?;
1054 raw[1..5].copy_from_slice(&r);
1055 Ok(raw)
1056 }
1057}
1058
1059#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1061pub enum SupportStatus {
1062 Active,
1064 Inactive,
1066 NoStreamFormat,
1068 NotUsed,
1070 Reserved(u8),
1071}
1072
1073impl Default for SupportStatus {
1074 fn default() -> Self {
1075 SupportStatus::Reserved(0xff)
1076 }
1077}
1078
1079impl SupportStatus {
1080 const ACTIVE: u8 = 0x00;
1081 const INACTIVE: u8 = 0x01;
1082 const NO_STREAM_FORMAT: u8 = 0x02;
1083 const NOT_USED: u8 = 0xff;
1084
1085 fn from_val(val: u8) -> Self {
1086 match val {
1087 Self::ACTIVE => Self::Active,
1088 Self::INACTIVE => Self::Inactive,
1089 Self::NO_STREAM_FORMAT => Self::NoStreamFormat,
1090 Self::NOT_USED => Self::NotUsed,
1091 _ => Self::Reserved(val),
1092 }
1093 }
1094
1095 fn to_val(&self) -> u8 {
1096 match self {
1097 Self::Active => Self::ACTIVE,
1098 Self::Inactive => Self::INACTIVE,
1099 Self::NoStreamFormat => Self::NO_STREAM_FORMAT,
1100 Self::NotUsed => Self::NOT_USED,
1101 Self::Reserved(val) => *val,
1102 }
1103 }
1104}
1105
1106#[derive(Clone, Debug, Eq, PartialEq)]
1107struct ExtendedStreamFormat {
1108 subfunc: u8,
1109 plug_addr: PlugAddr,
1110 support_status: SupportStatus,
1111}
1112
1113impl Default for ExtendedStreamFormat {
1114 fn default() -> Self {
1115 Self {
1116 subfunc: 0xff,
1117 plug_addr: Default::default(),
1118 support_status: Default::default(),
1119 }
1120 }
1121}
1122
1123impl ExtendedStreamFormat {
1124 const OPCODE: u8 = 0xbf;
1125
1126 fn new(subfunc: u8, plug_addr: &PlugAddr) -> Self {
1127 ExtendedStreamFormat {
1128 subfunc,
1129 plug_addr: *plug_addr,
1130 ..Default::default()
1131 }
1132 }
1133
1134 fn build_operands(&mut self, _: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
1135 let mut operands = Vec::new();
1136 operands.push(self.subfunc);
1137 let r = self.plug_addr.to_raw()?;
1138 operands.extend_from_slice(&r);
1139 operands.push(self.support_status.to_val());
1140 Ok(operands)
1141 }
1142
1143 fn parse_operands(&mut self, _: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
1144 if operands.len() < 7 {
1145 Err(AvcRespParseError::TooShortResp(7))
1146 } else if operands[0] != self.subfunc {
1147 Err(AvcRespParseError::UnexpectedOperands(0))
1148 } else {
1149 PlugAddr::from_raw(&operands[1..6]).and_then(|plug_addr| {
1150 if plug_addr != self.plug_addr {
1151 Err(AvcRespParseError::UnexpectedOperands(1))
1152 } else {
1153 self.support_status = SupportStatus::from_val(operands[6]);
1154 Ok(())
1155 }
1156 })
1157 }
1158 }
1159}
1160
1161#[derive(Clone, Debug, Eq, PartialEq)]
1166pub struct ExtendedStreamFormatSingle {
1167 pub support_status: SupportStatus,
1169 pub stream_format: StreamFormat,
1171 op: ExtendedStreamFormat,
1172}
1173
1174impl ExtendedStreamFormatSingle {
1175 const SUBFUNC: u8 = 0xc0;
1176
1177 const LENGTH_MIN: usize = 8;
1178
1179 pub fn new(plug_addr: &PlugAddr) -> Self {
1180 ExtendedStreamFormatSingle {
1181 support_status: SupportStatus::NotUsed,
1182 stream_format: StreamFormat::Reserved(Vec::new()),
1183 op: ExtendedStreamFormat::new(Self::SUBFUNC, plug_addr),
1184 }
1185 }
1186}
1187
1188impl AvcOp for ExtendedStreamFormatSingle {
1189 const OPCODE: u8 = ExtendedStreamFormat::OPCODE;
1190}
1191
1192impl AvcStatus for ExtendedStreamFormatSingle {
1193 fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
1194 self.op.support_status = SupportStatus::Reserved(0xff);
1195 self.op.build_operands(addr)
1196 }
1197
1198 fn parse_operands(&mut self, addr: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
1199 if operands.len() < Self::LENGTH_MIN {
1200 Err(AvcRespParseError::TooShortResp(Self::LENGTH_MIN))?;
1201 }
1202
1203 self.op.parse_operands(addr, operands)?;
1204 StreamFormat::from_raw(&operands[7..]).map(|stream_format| {
1205 self.stream_format = stream_format;
1206 self.support_status = self.op.support_status;
1207 })
1208 }
1209}
1210
1211impl AvcControl for ExtendedStreamFormatSingle {
1212 fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
1213 self.op.build_operands(addr).and_then(|mut operands| {
1214 self.stream_format.to_raw().map(|mut raw| {
1215 operands.append(&mut raw);
1216 operands
1217 })
1218 })
1219 }
1220
1221 fn parse_operands(&mut self, addr: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
1222 if operands.len() < Self::LENGTH_MIN {
1223 Err(AvcRespParseError::TooShortResp(Self::LENGTH_MIN))?;
1224 }
1225
1226 self.op.parse_operands(addr, operands)?;
1227 StreamFormat::from_raw(&operands[7..]).map(|stream_format| {
1228 self.stream_format = stream_format;
1229 self.support_status = self.op.support_status;
1230 })
1231 }
1232}
1233
1234#[derive(Clone, Debug, Eq, PartialEq)]
1239pub struct ExtendedStreamFormatList {
1240 pub support_status: SupportStatus,
1242 pub index: u8,
1244 pub stream_format: StreamFormat,
1246 op: ExtendedStreamFormat,
1247}
1248
1249impl ExtendedStreamFormatList {
1250 const SUBFUNC: u8 = 0xc1;
1251
1252 const LENGTH_MIN: usize = 8;
1253
1254 pub fn new(plug_addr: &PlugAddr, index: u8) -> Self {
1255 ExtendedStreamFormatList {
1256 support_status: SupportStatus::NotUsed,
1257 index,
1258 stream_format: StreamFormat::Reserved(Vec::new()),
1259 op: ExtendedStreamFormat::new(Self::SUBFUNC, plug_addr),
1260 }
1261 }
1262}
1263
1264impl AvcOp for ExtendedStreamFormatList {
1265 const OPCODE: u8 = ExtendedStreamFormat::OPCODE;
1266}
1267
1268impl AvcStatus for ExtendedStreamFormatList {
1269 fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
1270 self.op.support_status = SupportStatus::NotUsed;
1271 self.op.build_operands(addr).map(|mut operands| {
1272 operands.push(self.index);
1273 operands
1274 })
1275 }
1276
1277 fn parse_operands(&mut self, addr: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
1278 if operands.len() < Self::LENGTH_MIN {
1279 Err(AvcRespParseError::TooShortResp(Self::LENGTH_MIN))?;
1280 }
1281
1282 self.op.parse_operands(addr, operands).and_then(|_| {
1283 if self.index != operands[7] {
1284 Err(AvcRespParseError::UnexpectedOperands(7))
1285 } else {
1286 StreamFormat::from_raw(&operands[8..]).map(|stream_format| {
1287 self.stream_format = stream_format;
1288 self.support_status = self.op.support_status;
1289 })
1290 }
1291 })
1292 }
1293}
1294
1295#[cfg(test)]
1296mod tests {
1297 use crate::*;
1298
1299 #[test]
1300 fn am824multibitaudioattr_from() {
1301 let raw = [0x31, 0xff];
1302 let attr = Am824MultiBitAudioAttr::from_raw(&raw).unwrap();
1303 assert_eq!(44100, attr.freq);
1304 assert_eq!(false, attr.rate_ctl);
1305 assert_eq!(Ok(raw), attr.to_raw());
1306 }
1307
1308 #[test]
1309 fn am824onebitaudioattr_from() {
1310 let raw = [0x40, 0xff];
1311 let attr = Am824OneBitAudioAttr::from_raw(&raw).unwrap();
1312 assert_eq!(6144000, attr.freq);
1313 assert_eq!(true, attr.rate_ctl);
1314 assert_eq!(Ok(raw), attr.to_raw());
1315 }
1316
1317 #[test]
1318 fn am824stream_from() {
1319 let raw = [0x06, 0xff, 0x20, 0xff];
1320 let format = Am824Stream::from_raw(&raw).unwrap();
1321 let attr = Am824MultiBitAudioAttr {
1322 freq: 32000,
1323 rate_ctl: true,
1324 };
1325 assert_eq!(format, Am824Stream::MultiBitLinearAudioRaw(attr));
1326 assert_eq!(raw, format.to_raw().unwrap());
1327 }
1328
1329 #[test]
1330 fn amstream_from() {
1331 let raw: &[u8] = &[0x00, 0x08, 0xff, 0x40, 0xff];
1332 let attr = Am824OneBitAudioAttr {
1333 freq: 6144000,
1334 rate_ctl: true,
1335 };
1336 let format = AmStream::from_raw(raw).unwrap();
1337 assert_eq!(
1338 AmStream::Am824(Am824Stream::OneBitAudioPlainRaw(attr)),
1339 format
1340 );
1341 assert_eq!(raw, format.to_raw().unwrap());
1342
1343 let raw: &[u8] = &[0x01, 0xff, 0xff, 0xff, 0xff];
1344 let format = AmStream::from_raw(raw).unwrap();
1345 assert_eq!(AmStream::AudioPack, format);
1346 assert_eq!(raw, format.to_raw().unwrap());
1347
1348 let raw: &[u8] = &[0x02, 0xff, 0xff, 0xff, 0xff];
1349 let format = AmStream::from_raw(raw).unwrap();
1350 assert_eq!(AmStream::Fp32, format);
1351 assert_eq!(raw, format.to_raw().unwrap());
1352 }
1353
1354 #[test]
1355 fn streamformat_from() {
1356 let raw: &[u8] = &[0x90, 0x00, 0x08, 0xff, 0x40, 0xff];
1357 let format = StreamFormat::from_raw(raw).unwrap();
1358 if let StreamFormat::Am(i) = &format {
1359 if let AmStream::Am824(s) = i {
1360 if let Am824Stream::OneBitAudioPlainRaw(attr) = s {
1361 assert_eq!(6144000, attr.freq);
1362 assert_eq!(true, attr.rate_ctl);
1363 } else {
1364 unreachable!();
1365 }
1366 } else {
1367 unreachable!();
1368 }
1369 } else {
1370 unreachable!();
1371 }
1372 assert_eq!(raw, format.to_raw().unwrap());
1373
1374 let mut raw = Vec::<u8>::new();
1375 raw.extend_from_slice(&[0x90, 0x40, 0x04, 0x02, 0x01, 0x1c, 0x02]);
1376 let stream_format = StreamFormat::from_raw(&raw).unwrap();
1377 if let StreamFormat::Am(i) = &stream_format {
1378 if let AmStream::CompoundAm824(s) = i {
1379 assert_eq!(48000, s.freq);
1380 assert_eq!(false, s.sync_src);
1381 assert_eq!(RateCtl::NotSupported, s.rate_ctl);
1382 assert_eq!(1, s.entries.len());
1383 assert_eq!(0x1c, s.entries[0].count);
1384 assert_eq!(CompoundAm824StreamFormat::Iec61937_4, s.entries[0].format);
1385 } else {
1386 unreachable!();
1387 }
1388 } else {
1389 unreachable!();
1390 }
1391 assert_eq!(raw, stream_format.to_raw().unwrap());
1392 }
1393
1394 #[test]
1395 fn compoundam824streamformat_from() {
1396 assert_eq!(0x00, CompoundAm824StreamFormat::from_val(0x00).to_val());
1397 assert_eq!(0x01, CompoundAm824StreamFormat::from_val(0x01).to_val());
1398 assert_eq!(0x02, CompoundAm824StreamFormat::from_val(0x02).to_val());
1399 assert_eq!(0x03, CompoundAm824StreamFormat::from_val(0x03).to_val());
1400 assert_eq!(0x04, CompoundAm824StreamFormat::from_val(0x04).to_val());
1401 assert_eq!(0x05, CompoundAm824StreamFormat::from_val(0x05).to_val());
1402 assert_eq!(0x06, CompoundAm824StreamFormat::from_val(0x06).to_val());
1403 assert_eq!(0x07, CompoundAm824StreamFormat::from_val(0x07).to_val());
1404 assert_eq!(0x0c, CompoundAm824StreamFormat::from_val(0x0c).to_val());
1405 assert_eq!(0x0d, CompoundAm824StreamFormat::from_val(0x0d).to_val());
1406 assert_eq!(0x0e, CompoundAm824StreamFormat::from_val(0x0e).to_val());
1407 assert_eq!(0x0f, CompoundAm824StreamFormat::from_val(0x0f).to_val());
1408 assert_eq!(0x10, CompoundAm824StreamFormat::from_val(0x10).to_val());
1409 assert_eq!(0x40, CompoundAm824StreamFormat::from_val(0x40).to_val());
1410 assert_eq!(0xff, CompoundAm824StreamFormat::from_val(0xff).to_val());
1411 }
1412
1413 #[test]
1414 fn compoundam824streamentry_from() {
1415 let raw = [0x02, 0x04];
1416 let entry = CompoundAm824StreamEntry::from_raw(&raw).unwrap();
1417 assert_eq!(Ok(raw), entry.to_raw());
1418
1419 let raw = [0x19, 0x03];
1420 let entry = CompoundAm824StreamEntry::from_raw(&raw).unwrap();
1421 assert_eq!(Ok(raw), entry.to_raw());
1422
1423 let raw = [0x37, 0x00];
1424 let entry = CompoundAm824StreamEntry::from_raw(&raw).unwrap();
1425 assert_eq!(Ok(raw), entry.to_raw());
1426 }
1427
1428 #[test]
1429 fn ratectl_from() {
1430 assert_eq!(0x00, RateCtl::from_val(0x00).to_val());
1431 assert_eq!(0x01, RateCtl::from_val(0x01).to_val());
1432 assert_eq!(0x02, RateCtl::from_val(0x02).to_val());
1433 assert_eq!(0xff, RateCtl::from_val(0xff).to_val());
1434 }
1435
1436 #[test]
1437 fn compoundam824stream_from() {
1438 let mut raw = Vec::<u8>::new();
1439 raw.extend_from_slice(&[0x03, 0x02, 0x02, 0xee, 0x03, 0x37, 0x0d]);
1440 let s = CompoundAm824Stream::from_raw(&raw).unwrap();
1441 assert_eq!(44100, s.freq);
1442 assert_eq!(false, s.sync_src);
1443 assert_eq!(RateCtl::NotSupported, s.rate_ctl);
1444 assert_eq!(2, s.entries.len());
1445 assert_eq!(0xee, s.entries[0].count);
1446 assert_eq!(CompoundAm824StreamFormat::Iec61937_5, s.entries[0].format);
1447 assert_eq!(0x37, s.entries[1].count);
1448 assert_eq!(
1449 CompoundAm824StreamFormat::MidiConformant,
1450 s.entries[1].format
1451 );
1452 let am = CompoundAm824Stream::from_raw(&raw).unwrap();
1453 assert_eq!(raw, am.to_raw().unwrap());
1454 }
1455
1456 #[test]
1457 fn plug_addr_from() {
1458 let addr = PlugAddr {
1460 direction: PlugDirection::Input,
1461 mode: PlugAddrMode::Unit(UnitPlugData {
1462 unit_type: UnitPlugType::Pcr,
1463 plug_id: 0x2,
1464 }),
1465 };
1466 let raw = addr.to_raw().unwrap();
1467 assert_eq!(addr, PlugAddr::from_raw(&raw).unwrap());
1468
1469 let addr = PlugAddr {
1471 direction: PlugDirection::Input,
1472 mode: PlugAddrMode::Unit(UnitPlugData {
1473 unit_type: UnitPlugType::External,
1474 plug_id: 0x3,
1475 }),
1476 };
1477 let raw = addr.to_raw().unwrap();
1478 assert_eq!(addr, PlugAddr::from_raw(&raw).unwrap());
1479
1480 let addr = PlugAddr {
1482 direction: PlugDirection::Output,
1483 mode: PlugAddrMode::Unit(UnitPlugData {
1484 unit_type: UnitPlugType::Async,
1485 plug_id: 0x4,
1486 }),
1487 };
1488 let raw = addr.to_raw().unwrap();
1489 assert_eq!(addr, PlugAddr::from_raw(&raw).unwrap());
1490
1491 let addr = PlugAddr {
1493 direction: PlugDirection::Output,
1494 mode: PlugAddrMode::Subunit(SubunitPlugData { plug_id: 0x8 }),
1495 };
1496 let raw = addr.to_raw().unwrap();
1497 assert_eq!(addr, PlugAddr::from_raw(&raw).unwrap());
1498
1499 let addr = PlugAddr {
1501 direction: PlugDirection::Input,
1502 mode: PlugAddrMode::FunctionBlock(FunctionBlockPlugData {
1503 fb_type: 0x1f,
1504 fb_id: 0x07,
1505 plug_id: 0x29,
1506 }),
1507 };
1508 let raw = addr.to_raw().unwrap();
1509 assert_eq!(addr, PlugAddr::from_raw(&raw).unwrap());
1510 }
1511
1512 #[test]
1513 fn single_operands() {
1514 let plug_addr = PlugAddr {
1515 direction: PlugDirection::Output,
1516 mode: PlugAddrMode::Unit(UnitPlugData {
1517 unit_type: UnitPlugType::Pcr,
1518 plug_id: 0x03,
1519 }),
1520 };
1521 let mut op = ExtendedStreamFormatSingle::new(&plug_addr);
1522 let operands = AvcStatus::build_operands(&mut op, &AvcAddr::Unit).unwrap();
1523 assert_eq!(&operands, &[0xc0, 0x01, 0x00, 0x00, 0x03, 0xff, 0xff]);
1524
1525 let operands = [
1526 0xc0, 0x01, 0x00, 0x00, 0x03, 0xff, 0x01, 0x90, 0x40, 0x04, 0x00, 0x02, 0x02, 0x06,
1527 0x02, 0x00,
1528 ];
1529 AvcStatus::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1530 assert_eq!(op.op.plug_addr, plug_addr);
1531 assert_eq!(op.op.support_status, SupportStatus::Inactive);
1532
1533 if let StreamFormat::Am(stream_format) = &op.stream_format {
1534 if let AmStream::CompoundAm824(s) = stream_format {
1535 assert_eq!(s.freq, 48000);
1536 assert_eq!(s.sync_src, false);
1537 assert_eq!(s.rate_ctl, RateCtl::Supported);
1538 assert_eq!(s.entries.len(), 2);
1539 assert_eq!(
1540 s.entries[0],
1541 CompoundAm824StreamEntry {
1542 count: 2,
1543 format: CompoundAm824StreamFormat::MultiBitLinearAudioRaw
1544 }
1545 );
1546 assert_eq!(
1547 s.entries[1],
1548 CompoundAm824StreamEntry {
1549 count: 2,
1550 format: CompoundAm824StreamFormat::Iec60958_3
1551 }
1552 );
1553 } else {
1554 unreachable!();
1555 }
1556 } else {
1557 unreachable!();
1558 }
1559
1560 let operands = AvcControl::build_operands(&mut op, &AvcAddr::Unit).unwrap();
1561 assert_eq!(
1562 &operands,
1563 &[
1564 0xc0, 0x01, 0x00, 0x00, 0x03, 0xff, 0x01, 0x90, 0x40, 0x04, 0x00, 0x02, 0x02, 0x06,
1565 0x02, 0x00
1566 ]
1567 );
1568
1569 let mut op = ExtendedStreamFormatSingle::new(&plug_addr);
1570 let operands = [
1571 0xc0, 0x01, 0x00, 0x00, 0x03, 0xff, 0xff, 0x90, 0x40, 0x05, 0x04, 0x02, 0x02, 0x06,
1572 0x02, 0x00,
1573 ];
1574 AvcControl::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1575 assert_eq!(op.op.plug_addr, plug_addr);
1576 assert_eq!(op.op.support_status, SupportStatus::NotUsed);
1577 if let StreamFormat::Am(stream_format) = &op.stream_format {
1578 if let AmStream::CompoundAm824(s) = stream_format {
1579 assert_eq!(s.freq, 96000);
1580 assert_eq!(s.sync_src, true);
1581 assert_eq!(s.rate_ctl, RateCtl::Supported);
1582 assert_eq!(s.entries.len(), 2);
1583 assert_eq!(
1584 s.entries[0],
1585 CompoundAm824StreamEntry {
1586 count: 2,
1587 format: CompoundAm824StreamFormat::MultiBitLinearAudioRaw
1588 }
1589 );
1590 assert_eq!(
1591 s.entries[1],
1592 CompoundAm824StreamEntry {
1593 count: 2,
1594 format: CompoundAm824StreamFormat::Iec60958_3
1595 }
1596 );
1597 } else {
1598 unreachable!();
1599 }
1600 } else {
1601 unreachable!();
1602 }
1603 }
1604
1605 #[test]
1606 fn list_operands() {
1607 let plug_addr = PlugAddr {
1608 direction: PlugDirection::Output,
1609 mode: PlugAddrMode::Unit(UnitPlugData {
1610 unit_type: UnitPlugType::Pcr,
1611 plug_id: 0x03,
1612 }),
1613 };
1614 let mut op = ExtendedStreamFormatList::new(&plug_addr, 0x31);
1615 let operands = AvcStatus::build_operands(&mut op, &AvcAddr::Unit).unwrap();
1616 assert_eq!(&operands, &[0xc1, 0x01, 0x00, 0x00, 0x03, 0xff, 0xff, 0x31]);
1617
1618 let operands = [
1619 0xc1, 0x01, 0x00, 0x00, 0x03, 0xff, 0x01, 0x31, 0x90, 0x40, 0x04, 0x00, 0x02, 0x02,
1620 0x06, 0x02, 0x00,
1621 ];
1622 AvcStatus::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1623 assert_eq!(op.op.plug_addr, plug_addr);
1624 assert_eq!(op.op.support_status, SupportStatus::Inactive);
1625 assert_eq!(op.index, 0x31);
1626 if let StreamFormat::Am(stream_format) = &op.stream_format {
1627 if let AmStream::CompoundAm824(s) = stream_format {
1628 assert_eq!(s.freq, 48000);
1629 assert_eq!(s.sync_src, false);
1630 assert_eq!(s.rate_ctl, RateCtl::Supported);
1631 assert_eq!(s.entries.len(), 2);
1632 assert_eq!(
1633 s.entries[0],
1634 CompoundAm824StreamEntry {
1635 count: 2,
1636 format: CompoundAm824StreamFormat::MultiBitLinearAudioRaw
1637 }
1638 );
1639 assert_eq!(
1640 s.entries[1],
1641 CompoundAm824StreamEntry {
1642 count: 2,
1643 format: CompoundAm824StreamFormat::Iec60958_3
1644 }
1645 );
1646 } else {
1647 unreachable!();
1648 }
1649 } else {
1650 unreachable!();
1651 }
1652 }
1653}