ta1394_avc_stream_format/
lib.rs

1// SPDX-License-Identifier: MIT
2// Copyright (c) 2022 Takashi Sakamoto
3
4#![doc = include_str!("../README.md")]
5
6use ta1394_avc_general::*;
7
8/// The attribute for multi bit audio data in AM824 format.
9#[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/// The attribute for one bit audio data in AM824 format.
97#[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/// The stream type for AM824 format.
182#[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/// The stream type for compound AM824 format.
341#[derive(Clone, Copy, Debug, Eq, PartialEq)]
342pub enum CompoundAm824StreamFormat {
343    /// S/PDIF for either uncompressed (PCM) or compressed (AC3/WMA) stream.
344    Iec60958_3,
345    /// AC 3 compressed stream.
346    Iec61937_3,
347    /// MPEG compressed stream.
348    Iec61937_4,
349    /// DTS (Digital Theater Systems) compressed stream.
350    Iec61937_5,
351    /// MPEG-2 AAC compressed stream.
352    Iec61937_6,
353    /// ATRAC and ATRAC 2/3 compressed stream.
354    Iec61937_7,
355    /// Uncompressed linear PCM data stream.
356    MultiBitLinearAudioRaw,
357    MultiBitLinearAudioDvd,
358    HighPrecisionMultiBitLinearAudio,
359    /// Multiplexed MIDI stream.
360    MidiConformant,
361    /// SMPTE time code defined in Audio and Music Data Transmission Protocol v2.1.
362    SmpteTimeCodeConformant,
363    /// Sample count defined in Audio and Music Data Transmission Protocol v2.1.
364    SampleCount,
365    /// Ancillary data defined in Audio and Music Data Transmission Protocol v2.1.
366    AncillaryData,
367    /// Delivery of synchronization information.
368    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/// The entry of stream format.
436#[derive(Clone, Debug, Eq, PartialEq)]
437pub struct CompoundAm824StreamEntry {
438    /// The number of stream formats.
439    pub count: u8,
440    /// The stream format.
441    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/// Whether to support command-based rate control.
472#[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/// The stream format of compound AM824.
511#[derive(Clone, Debug, Eq, PartialEq)]
512pub struct CompoundAm824Stream {
513    /// The nominal sampling frequency.
514    pub freq: u32,
515    /// The synchronization source.
516    pub sync_src: bool,
517    /// Whether to support command-based rate control.
518    pub rate_ctl: RateCtl,
519    /// The entries of available stream format.
520    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/// The type of stream format in Audio and Music hierarchy root.
626#[derive(Clone, Debug, Eq, PartialEq)]
627pub enum AmStream {
628    /// AM824 (single stream) data.
629    Am824(Am824Stream),
630    /// 24 bit * 4 audio pack data.
631    AudioPack,
632    /// 32 bit floating point data.
633    Fp32,
634    /// Compound AM824 (multiplexed stream) data.
635    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/// The format of stream.
708#[derive(Clone, Debug, Eq, PartialEq)]
709pub enum StreamFormat {
710    // Dvcr is not supported currently.
711    /// Defined in Audio and Music Data Transmission Protocol.
712    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    /// The value in `format_hierarchy_root` field for Audio and Music.
724    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    /// Detect stream format for AM824 in Audio and Music hierarchy root.
737    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    /// Detect stream format for Compound AM824 in Audio and Music hierarchy root.
746    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/// The type of plug in unit.
784#[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/// Data of plug in unit.
817#[derive(Clone, Copy, Debug, Eq, PartialEq)]
818pub struct UnitPlugData {
819    /// The type of unit.
820    pub unit_type: UnitPlugType,
821    /// The numeric identifier of plug.
822    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/// Data of plug in subunit.
856#[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/// Data of plug in function block.
883#[derive(Clone, Copy, Debug, Eq, PartialEq)]
884pub struct FunctionBlockPlugData {
885    /// The type of function block.
886    pub fb_type: u8,
887    /// The numeric identifier of function block.
888    pub fb_id: u8,
889    /// The numeric identifier of plug.
890    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/// Mode of addressing to plug.
924#[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/// Direction of stream for plug.
987#[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/// The address of issued plug.
1020#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1021pub struct PlugAddr {
1022    /// The direction of stream for the plug.
1023    pub direction: PlugDirection,
1024    /// The mode of addressing.
1025    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/// The current status of plug (Table 6.17 – support_status field for SINGLE REQUEST subfunction).
1060#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1061pub enum SupportStatus {
1062    /// The format is already set and stream is available.
1063    Active,
1064    /// The format is already set but stream is not available.
1065    Inactive,
1066    /// The format is not uset yet.
1067    NoStreamFormat,
1068    /// For response frame of specific inquiry operation.
1069    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///
1162/// SINGLE subfunction of AV/C EXTENDED STREAM FORMAT INFORMATION.
1163///
1164/// Described in 6.2.3 SINGLE subfunction.
1165#[derive(Clone, Debug, Eq, PartialEq)]
1166pub struct ExtendedStreamFormatSingle {
1167    /// Current status of addressed plug.
1168    pub support_status: SupportStatus,
1169    /// The format of stream.
1170    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///
1235/// LIST subfunction of AV/C EXTENDED STREAM FORMAT INFORMATION.
1236///
1237/// Described in 6.2.4 LIST subfunction.
1238#[derive(Clone, Debug, Eq, PartialEq)]
1239pub struct ExtendedStreamFormatList {
1240    /// Current status of plug.
1241    pub support_status: SupportStatus,
1242    /// The index of stream format.
1243    pub index: u8,
1244    /// The format of stream.
1245    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        // Unit for PCR stream.
1459        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        // Unit for external stream.
1470        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        // Unit for asynchronous stream.
1481        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        // Subunit.
1492        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        // Function block.
1500        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}