ta1394_avc_audio/
lib.rs

1// SPDX-License-Identifier: MIT
2// Copyright (c) 2022 Takashi Sakamoto
3
4#![doc = include_str!("../README.md")]
5
6/// Encoder and decoder of FDF field in Audio and Music Data Transmission Protocol.
7pub mod amdtp;
8
9use ta1394_avc_general::*;
10
11/// The AV/C address of first music subunit for convenience.
12pub const AUDIO_SUBUNIT_0_ADDR: AvcAddr = AvcAddr::Subunit(AUDIO_SUBUNIT_0);
13
14/// The type of function block in audio subunit.
15#[derive(Clone, Copy, Debug, Eq, PartialEq)]
16enum AudioFuncBlkType {
17    /// Selector function block.
18    Selector,
19    /// Feature function block.
20    Feature,
21    /// Processing function block.
22    Processing,
23    Reserved(u8),
24}
25
26impl Default for AudioFuncBlkType {
27    fn default() -> Self {
28        Self::Reserved(0xff)
29    }
30}
31
32impl AudioFuncBlkType {
33    fn from_val(val: u8) -> Self {
34        match val {
35            0x80 => Self::Selector,
36            0x81 => Self::Feature,
37            0x82 => Self::Processing,
38            _ => Self::Reserved(val),
39        }
40    }
41
42    fn to_val(&self) -> u8 {
43        match self {
44            Self::Selector => 0x80,
45            Self::Feature => 0x81,
46            Self::Processing => 0x82,
47            Self::Reserved(val) => *val,
48        }
49    }
50}
51
52/// For attributes of control (clause "4.8 Control Attributes").
53#[derive(Clone, Copy, Debug, Eq, PartialEq)]
54pub enum CtlAttr {
55    /// Minimum scale.
56    Resolution,
57    /// Minimum setting.
58    Minimum,
59    /// Maximum setting.
60    Maximum,
61    /// Default setting.
62    Default,
63    /// Minimum moving time.
64    Duration,
65    /// Current setting.
66    Current,
67    /// Request to change the value during a period equalds to a number of Duration.
68    Move,
69    /// Relative setting in unit steps.
70    Delta,
71    Reserved(u8),
72}
73
74impl Default for CtlAttr {
75    fn default() -> Self {
76        Self::Reserved(0xff)
77    }
78}
79
80impl CtlAttr {
81    fn from_val(val: u8) -> Self {
82        match val {
83            0x01 => Self::Resolution,
84            0x02 => Self::Minimum,
85            0x03 => Self::Maximum,
86            0x04 => Self::Default,
87            0x08 => Self::Duration,
88            0x10 => Self::Current,
89            0x18 => Self::Move,
90            0x19 => Self::Delta,
91            _ => Self::Reserved(val),
92        }
93    }
94
95    fn to_val(&self) -> u8 {
96        match self {
97            Self::Resolution => 0x01,
98            Self::Minimum => 0x02,
99            Self::Maximum => 0x03,
100            Self::Default => 0x04,
101            Self::Duration => 0x08,
102            Self::Current => 0x10,
103            Self::Move => 0x18,
104            Self::Delta => 0x19,
105            Self::Reserved(val) => *val,
106        }
107    }
108}
109
110impl std::fmt::Display for CtlAttr {
111    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112        let label = match self {
113            Self::Resolution => "resolution".to_owned(),
114            Self::Minimum => "minimum".to_owned(),
115            Self::Maximum => "maximum".to_owned(),
116            Self::Default => "default".to_owned(),
117            Self::Duration => "duration".to_owned(),
118            Self::Current => "current".to_owned(),
119            Self::Move => "move".to_owned(),
120            Self::Delta => "delta".to_owned(),
121            Self::Reserved(val) => format!("reserved: {}", val),
122        };
123        write!(f, "{}", &label)
124    }
125}
126
127/// For control information in frame of function block command.
128#[derive(Clone, Debug, Eq, PartialEq)]
129struct AudioFuncBlkCtl {
130    /// The value of control_selector field for the type of control.
131    selector: u8,
132    /// The data in control_data field according to the type.
133    data: Vec<u8>,
134}
135
136impl Default for AudioFuncBlkCtl {
137    fn default() -> Self {
138        Self {
139            selector: 0xff,
140            data: Default::default(),
141        }
142    }
143}
144
145impl AudioFuncBlkCtl {
146    const LENGTH_MIN: usize = 1;
147
148    fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
149        if raw.len() < Self::LENGTH_MIN {
150            Err(AvcRespParseError::TooShortResp(Self::LENGTH_MIN))?;
151        }
152
153        let mut ctl = Self {
154            selector: raw[0],
155            data: Default::default(),
156        };
157        if raw.len() > 1 {
158            let length = raw[1] as usize;
159            if raw.len() >= 2 + length {
160                ctl.data.extend_from_slice(&raw[2..(2 + length)]);
161            }
162        }
163        Ok(ctl)
164    }
165
166    fn to_raw(&self) -> Vec<u8> {
167        let mut raw = Vec::with_capacity(Self::LENGTH_MIN);
168        raw.push(self.selector);
169        if self.data.len() > 0 {
170            raw.push(self.data.len() as u8);
171            raw.extend_from_slice(&self.data);
172        }
173        raw
174    }
175}
176
177/// For operands of frame in function block command (clause "10. Audio Subunit FUNCTION_BLOCK
178/// command")
179#[derive(Clone, Debug, Eq, PartialEq)]
180struct AudioFuncBlk {
181    func_blk_type: AudioFuncBlkType,
182    func_blk_id: u8,
183    ctl_attr: CtlAttr,
184    audio_selector_data: Vec<u8>,
185    ctl: AudioFuncBlkCtl,
186}
187
188impl Default for AudioFuncBlk {
189    fn default() -> Self {
190        Self {
191            func_blk_type: Default::default(),
192            func_blk_id: 0xff,
193            ctl_attr: Default::default(),
194            audio_selector_data: Default::default(),
195            ctl: Default::default(),
196        }
197    }
198}
199
200impl AudioFuncBlk {
201    fn build_operands(&self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
202        if let AvcAddr::Subunit(AvcAddrSubunit {
203            subunit_type: AvcSubunitType::Audio,
204            subunit_id: _,
205        }) = addr
206        {
207            let mut operands = Vec::new();
208            operands.push(self.func_blk_type.to_val());
209            operands.push(self.func_blk_id);
210            operands.push(self.ctl_attr.to_val());
211            operands.push(1 + self.audio_selector_data.len() as u8);
212            operands.extend_from_slice(&self.audio_selector_data);
213            operands.append(&mut self.ctl.to_raw());
214            Ok(operands)
215        } else {
216            Err(AvcCmdBuildError::InvalidAddress)
217        }
218    }
219
220    fn parse_operands(&mut self, operands: &[u8]) -> Result<(), AvcRespParseError> {
221        if operands.len() < 4 {
222            Err(AvcRespParseError::TooShortResp(4))?;
223        }
224        let func_blk_type = AudioFuncBlkType::from_val(operands[0]);
225        if func_blk_type != self.func_blk_type {
226            Err(AvcRespParseError::UnexpectedOperands(0))?;
227        }
228
229        let func_blk_id = operands[1];
230        if func_blk_id != self.func_blk_id {
231            Err(AvcRespParseError::UnexpectedOperands(1))?;
232        }
233
234        let ctl_attr = CtlAttr::from_val(operands[2]);
235        if ctl_attr != self.ctl_attr {
236            Err(AvcRespParseError::UnexpectedOperands(2))?;
237        }
238
239        let mut audio_selector_length = operands[3] as usize;
240        if operands.len() < 3 + audio_selector_length {
241            Err(AvcRespParseError::TooShortResp(3 + audio_selector_length))?;
242        } else if audio_selector_length < 1 {
243            Err(AvcRespParseError::UnexpectedOperands(3))?;
244        }
245        audio_selector_length -= 1;
246        self.audio_selector_data = operands[4..(4 + audio_selector_length)].to_vec();
247
248        self.ctl = AudioFuncBlkCtl::from_raw(&operands[(4 + audio_selector_length)..])
249            .map_err(|err| err.add_offset(4))?;
250
251        Ok(())
252    }
253}
254
255impl AvcOp for AudioFuncBlk {
256    const OPCODE: u8 = 0xb8;
257}
258
259impl AvcStatus for AudioFuncBlk {
260    fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
261        AudioFuncBlk::build_operands(self, addr)
262    }
263
264    fn parse_operands(&mut self, _: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
265        AudioFuncBlk::parse_operands(self, operands)
266    }
267}
268
269impl AvcControl for AudioFuncBlk {
270    fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
271        AudioFuncBlk::build_operands(self, addr)
272    }
273
274    fn parse_operands(&mut self, _: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
275        AudioFuncBlk::parse_operands(self, operands)
276    }
277}
278
279///
280/// AV/C Audio Subunit FUNCTION_BLOCK command for Selector function block
281///
282/// Described in clause "10.2 Selector function block".
283pub struct AudioSelector {
284    pub input_plug_id: u8,
285    func_blk: AudioFuncBlk,
286}
287
288impl AudioSelector {
289    const SELECTOR_CONTROL: u8 = 0x01;
290
291    pub fn new(func_blk_id: u8, ctl_attr: CtlAttr, input_plug_id: u8) -> Self {
292        Self {
293            input_plug_id,
294            func_blk: AudioFuncBlk {
295                func_blk_type: AudioFuncBlkType::Selector,
296                func_blk_id,
297                ctl_attr,
298                ..Default::default()
299            },
300        }
301    }
302
303    fn build_func_blk(&mut self) -> Result<(), AvcCmdBuildError> {
304        self.func_blk.audio_selector_data.clear();
305        self.func_blk.audio_selector_data.push(self.input_plug_id);
306        self.func_blk.ctl.selector = Self::SELECTOR_CONTROL;
307        self.func_blk.ctl.data.clear();
308        Ok(())
309    }
310
311    fn parse_func_blk(&mut self) -> Result<(), AvcRespParseError> {
312        if self.func_blk.ctl.selector != Self::SELECTOR_CONTROL {
313            Err(AvcRespParseError::UnexpectedOperands(5))
314        } else if self.func_blk.ctl.data.len() > 0 {
315            Err(AvcRespParseError::UnexpectedOperands(7))
316        } else {
317            self.input_plug_id = self.func_blk.audio_selector_data[0];
318            Ok(())
319        }
320    }
321}
322
323impl AvcOp for AudioSelector {
324    const OPCODE: u8 = AudioFuncBlk::OPCODE;
325}
326
327impl AvcStatus for AudioSelector {
328    fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
329        self.build_func_blk()
330            .and_then(|_| AvcStatus::build_operands(&mut self.func_blk, addr))
331    }
332
333    fn parse_operands(&mut self, addr: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
334        AvcStatus::parse_operands(&mut self.func_blk, addr, operands)
335            .and_then(|_| self.parse_func_blk())
336    }
337}
338
339impl AvcControl for AudioSelector {
340    fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
341        self.build_func_blk()
342            .and_then(|_| AvcControl::build_operands(&mut self.func_blk, addr))
343    }
344
345    fn parse_operands(&mut self, addr: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
346        AvcControl::parse_operands(&mut self.func_blk, addr, operands)
347            .and_then(|_| self.parse_func_blk())
348    }
349}
350
351/// Parameters for volume.
352///
353/// Table 10.5 – Values for the volume settings.
354#[derive(Debug, Default, Clone, Eq, PartialEq)]
355pub struct VolumeData(pub Vec<i16>);
356
357impl VolumeData {
358    /// The invalid value of volume.
359    pub const VALUE_INVALID: i16 = 0x7fffu16 as i16;
360    /// The maximum value of volume expresses 127.9922 dB.
361    pub const VALUE_MAX: i16 = 0x7ffeu16 as i16;
362    /// The value of volume which expresses 0.00 dB.
363    pub const VALUE_ZERO: i16 = 0;
364    /// The minimum value of volume expresses -127.9961 dB
365    pub const VALUE_MIN: i16 = 0x8001u16 as i16;
366    /// The negative infinity.
367    pub const VALUE_NEG_INFINITY: i16 = 0x8000u16 as i16;
368
369    pub fn new(count: usize) -> Self {
370        Self(vec![Self::VALUE_INVALID; count])
371    }
372
373    fn from_raw<T: AsRef<[u8]>>(raw: &T) -> Self {
374        Self(i16_vector_from_raw(raw.as_ref()))
375    }
376
377    fn to_raw(&self) -> Vec<u8> {
378        i16_vector_to_raw(&self.0)
379    }
380}
381
382/// Parameters for Left-to-Right balance.
383///
384/// Table 10.6 – Values for the LR Balance settings
385#[derive(Debug, Clone, Eq, PartialEq)]
386pub struct LrBalanceData(pub i16);
387
388impl Default for LrBalanceData {
389    fn default() -> Self {
390        Self(Self::VALUE_INVALID)
391    }
392}
393
394impl LrBalanceData {
395    /// The invalid value of volume.
396    pub const VALUE_INVALID: i16 = 0x7fffu16 as i16;
397
398    /// The maximum value of left balance expresses 0.00 dB.
399    pub const VALUE_LEFT_MAX: i16 = 0x7ffeu16 as i16;
400    /// The value of left balance which expresses 0.00 dB.
401    pub const VALUE_LEFT_ZERO: i16 = 0;
402    /// The minimum value of left balance expresses -127.9961 dB
403    pub const VALUE_LEFT_MIN: i16 = 0x8001u16 as i16;
404    /// The negative infinity of left balance.
405    pub const VALUE_LEFT_NEG_INFINITY: i16 = 0x8000u16 as i16;
406
407    /// The maximum value of right balance expresses 0.00 dB.
408    pub const VALUE_RIGHT_MAX: i16 = 0x8000u16 as i16;
409    /// The value of right balance which expresses 0.00 dB.
410    pub const VALUE_RIGHT_ZERO: i16 = 0;
411    /// The minimum value of right balance expresses -127.9961 dB
412    pub const VALUE_RIGHT_MIN: i16 = 0x7ffdu16 as i16;
413    /// The negative infinity of right balance.
414    pub const VALUE_RIGHT_NEG_INFINITY: i16 = 0x7ffeu16 as i16;
415
416    fn from_raw<T: AsRef<[u8]>>(raw: &T) -> Self {
417        Self(i16_from_raw(raw.as_ref()))
418    }
419
420    fn to_raw(&self) -> Vec<u8> {
421        self.0.to_be_bytes().to_vec()
422    }
423}
424
425/// Parameters for Front-to-Rear balance.
426///
427/// Table 10.7 – Values for the FR Balance settings
428#[derive(Debug, Clone, Eq, PartialEq)]
429pub struct FrBalanceData(pub i16);
430
431impl Default for FrBalanceData {
432    fn default() -> Self {
433        Self(Self::VALUE_INVALID)
434    }
435}
436
437impl FrBalanceData {
438    /// The invalid value of volume.
439    pub const VALUE_INVALID: i16 = 0x7fffu16 as i16;
440
441    /// The maximum value of front balance expresses 0.00 dB.
442    pub const VALUE_FRONT_MAX: i16 = 0x7ffeu16 as i16;
443    /// The value of front balance which expresses 0.00 dB.
444    pub const VALUE_FRONT_ZERO: i16 = 0;
445    /// The minimum value of front balance expresses -127.9961 dB
446    pub const VALUE_FRONT_MIN: i16 = 0x8001u16 as i16;
447    /// The negative infinity of front balance.
448    pub const VALUE_FRONT_NEG_INFINITY: i16 = 0x8000u16 as i16;
449
450    /// The maximum value of rear balance expresses 0.00 dB.
451    pub const VALUE_REAR_MAX: i16 = 0x8000u16 as i16;
452    /// The value of rear balance which expresses 0.00 dB.
453    pub const VALUE_REAR_ZERO: i16 = 0;
454    /// The minimum value of rear balance expresses -127.9961 dB
455    pub const VALUE_REAR_MIN: i16 = 0x7ffdu16 as i16;
456    /// The negative infinity of rear balance.
457    pub const VALUE_REAR_NEG_INFINITY: i16 = 0x7ffeu16 as i16;
458
459    fn from_raw<T: AsRef<[u8]>>(raw: &T) -> Self {
460        Self(i16_from_raw(raw.as_ref()))
461    }
462
463    fn to_raw(&self) -> Vec<u8> {
464        self.0.to_be_bytes().to_vec()
465    }
466}
467
468/// Parameters for bass control.
469///
470/// Table 10.8 – Settings for the Bass Control attribute
471#[derive(Debug, Default, Clone, Eq, PartialEq)]
472pub struct BassData(pub Vec<i8>);
473
474impl BassData {
475    /// The invalid value of bass control.
476    pub const VALUE_INVALID: i8 = 0x7f;
477    /// The maximum value of bass control expresses +31.50 dB.
478    pub const VALUE_MAX: i8 = 0x7e;
479    /// The value of bass control which expresses 0.00 dB.
480    pub const VALUE_ZERO: i8 = 0x00;
481    /// The minimum value of bass control expresses -32.0 dB.
482    pub const VALUE_MIN: i8 = 0x80u8 as i8;
483
484    pub fn new(count: usize) -> Self {
485        Self(vec![Self::VALUE_INVALID; count])
486    }
487
488    fn from_raw<T: AsRef<[u8]>>(raw: &T) -> Self {
489        Self(i8_vector_from_raw(raw.as_ref()))
490    }
491
492    fn to_raw(&self) -> Vec<u8> {
493        self.0.iter().map(|v| *v as u8).collect()
494    }
495}
496
497/// Parameters for mid control.
498///
499/// Table 10.9 – Settings for the Mid Control attribute
500#[derive(Debug, Default, Clone, Eq, PartialEq)]
501pub struct MidData(pub Vec<i8>);
502
503impl MidData {
504    /// The invalid value of mid control.
505    pub const VALUE_INVALID: i8 = 0x7f;
506    /// The maximum value of mid control expresses +31.50 dB.
507    pub const VALUE_MAX: i8 = 0x7e;
508    /// The value of mid control which expresses 0.00 dB.
509    pub const VALUE_ZERO: i8 = 0x00;
510    /// The minimum value of mid control expresses -32.00 dB.
511    pub const VALUE_MIN: i8 = 0x80u8 as i8;
512
513    pub fn new(count: usize) -> Self {
514        Self(vec![Self::VALUE_INVALID; count])
515    }
516
517    fn from_raw<T: AsRef<[u8]>>(raw: &T) -> Self {
518        Self(i8_vector_from_raw(raw.as_ref()))
519    }
520
521    fn to_raw(&self) -> Vec<u8> {
522        self.0.iter().map(|v| *v as u8).collect()
523    }
524}
525
526/// Parameters for treble control.
527///
528/// Table 10.10 – Settings for the Treble Control attribute
529#[derive(Debug, Default, Clone, Eq, PartialEq)]
530pub struct TrebleData(pub Vec<i8>);
531
532impl TrebleData {
533    /// The invalid value of treble control.
534    pub const VALUE_INVALID: i8 = 0x7f;
535    /// The maximum value of treble control expresses +31.50 dB.
536    pub const VALUE_MAX: i8 = 0x7e;
537    /// The value of treble control which expresses 0.00 dB.
538    pub const VALUE_ZERO: i8 = 0x00;
539    /// The minimum value of treble control expresses -32.00 dB.
540    pub const VALUE_MIN: i8 = 0x80u8 as i8;
541
542    pub fn new(count: usize) -> Self {
543        Self(vec![Self::VALUE_INVALID; count])
544    }
545
546    fn from_raw<T: AsRef<[u8]>>(raw: &T) -> Self {
547        Self(i8_vector_from_raw(raw.as_ref()))
548    }
549
550    fn to_raw(&self) -> Vec<u8> {
551        self.0.iter().map(|v| *v as u8).collect()
552    }
553}
554
555/// Parameters for graphic equalizer.
556///
557/// Figure 10.30 – First Form of the Graphic Equalizer Control Parameters.
558#[derive(Debug, Copy, Clone, Eq, PartialEq)]
559pub struct GraphicEqualizerData {
560    /// Gains for bands of third octave graphic equalizer, defined in ANSI S1.11-1986.
561    /// The band number with asterisk expresses the band of an octave equalizer.
562    ///
563    /// Band number  | Center of frequency (Hz)
564    /// ------------ | ------------------------
565    /// 14           | 25
566    /// 15*          | 31.5
567    /// 16           | 40
568    /// 17           | 50
569    /// 18*          | 63
570    /// 19           | 80
571    /// 20           | 100
572    /// 21*          | 125
573    /// 22           | 160
574    /// 23           | 200
575    /// 24*          | 250
576    /// 25           | 315
577    /// 26           | 400
578    /// 27*          | 500
579    /// 28           | 630
580    /// 29           | 800
581    /// 30*          | 1000
582    /// 31           | 1250
583    /// 32           | 1600
584    /// 33*          | 2000
585    /// 34           | 2500
586    /// 35           | 3150
587    /// 36*          | 4000
588    /// 37           | 5000
589    /// 38           | 6300
590    /// 39*          | 8000
591    /// 40           | 10000
592    /// 41           | 12500
593    /// 42*          | 16000
594    /// 43           | 20000
595    pub ansi_band_gains: [Option<i8>; Self::ANSI_BAND_COUNT],
596
597    /// Gains for extra bands of six octave graphic equalizer.
598    ///
599    /// Band number  | Center of frequency (Hz)
600    /// ------------ | ------------------------
601    /// 1            | 18
602    /// 2            | 20
603    /// 3            | 22
604    /// 4            | 28
605    /// 5            | 35
606    /// 6            | 44.5
607    /// 7            | 56
608    /// 8            | 70
609    /// 9            | 89
610    /// 10           | 110
611    /// 11           | 140
612    /// 12           | 180
613    /// 13           | 220
614    /// 14           | 280
615    /// 15           | 355
616    /// 16           | 445
617    /// 17           | 560
618    /// 18           | 710
619    /// 19           | 890
620    /// 20           | 1100
621    /// 21           | 1400
622    /// 22           | 1800
623    /// 23           | 2200
624    /// 24           | 2800
625    /// 25           | 3550
626    /// 26           | 4450
627    /// 27           | 5600
628    /// 28           | 7100
629    /// 29           | 8900
630    /// 30           | 11000
631    /// 31           | 14000
632    /// 32           | 18000
633    pub extra_band_gains: [Option<i8>; Self::EXTRA_BAND_COUNT],
634}
635
636impl GraphicEqualizerData {
637    /// The maximum value of gain expresses +31.50 dB.
638    pub const VALUE_MIN: i8 = i8::MIN;
639
640    /// The value of gain expresses zero dB.
641    pub const VALUE_ZERO: i8 = 0;
642
643    /// The minimum value of gain expresses -32.00 dB.
644    pub const VALUE_MAX: i8 = i8::MAX;
645
646    const VALUE_INVALID: u8 = 0x7f;
647
648    const ANSI_BAND_COUNT: usize = 30;
649    const EXTRA_BAND_COUNT: usize = 32;
650
651    const LENGTH_MIN: usize = 8;
652
653    fn from_raw<T: AsRef<[u8]>>(raw: T) -> Self {
654        let mut ansi_band_gains = [None; Self::ANSI_BAND_COUNT];
655        let mut extra_band_gains = [None; Self::EXTRA_BAND_COUNT];
656
657        let mut gain_index = Self::LENGTH_MIN;
658
659        let mut band_gains = [
660            (ansi_band_gains.as_mut_slice(), 0usize),
661            (extra_band_gains.as_mut_slice(), 4usize),
662        ];
663
664        let r = raw.as_ref();
665
666        band_gains.iter_mut().for_each(|(gains, offset)| {
667            gains
668                .iter_mut()
669                .enumerate()
670                .filter(|(i, _)| (r[*offset + i / 8] & (1 << (i % 8)) > 0))
671                .for_each(|(_, gain)| {
672                    *gain = if r.len() < gain_index {
673                        None
674                    } else if r[gain_index] == Self::VALUE_INVALID {
675                        None
676                    } else {
677                        let val = Some(r[gain_index] as i8);
678                        gain_index += 1;
679                        val
680                    }
681                });
682        });
683
684        Self {
685            ansi_band_gains,
686            extra_band_gains,
687        }
688    }
689
690    fn to_raw(&self) -> Vec<u8> {
691        let band_gains = [
692            (self.ansi_band_gains.as_slice(), 0usize),
693            (self.extra_band_gains.as_slice(), 4usize),
694        ];
695        let mut raw = vec![0x00u8; Self::LENGTH_MIN];
696
697        band_gains.iter().for_each(|(gains, offset)| {
698            gains
699                .iter()
700                .enumerate()
701                .filter_map(|(i, gain)| {
702                    if let Some(g) = gain {
703                        Some((i, *g))
704                    } else {
705                        None
706                    }
707                })
708                .for_each(|(i, gain)| {
709                    raw[offset + i / 8] |= 1 << (i % 8);
710                    raw.push(gain as u8);
711                });
712        });
713
714        raw
715    }
716}
717
718/// Parameters for delay.
719///
720/// Table 10.16 – Values for the setting of the Delay attribute
721#[derive(Debug, Default, Clone, Eq, PartialEq)]
722pub struct DelayData(pub Vec<u16>);
723
724impl DelayData {
725    /// The invalid value of volume.
726    pub const VALUE_INVALID: u16 = 0xffff;
727    /// The maximum value of volume expresses 1023.9687 ms.
728    pub const VALUE_MAX: u16 = 0x7ffe;
729    /// The value of volume which expresses 0.0000 ms.
730    pub const VALUE_ZERO: u16 = 0;
731
732    pub fn new(count: usize) -> Self {
733        Self(vec![Self::VALUE_INVALID; count])
734    }
735
736    fn from_raw<T: AsRef<[u8]>>(raw: &T) -> Self {
737        Self(u16_vector_from_raw(raw.as_ref()))
738    }
739
740    fn to_raw(&self) -> Vec<u8> {
741        u16_vector_to_raw(&self.0)
742    }
743}
744
745fn i16_vector_to_raw(data: &[i16]) -> Vec<u8> {
746    data.iter().fold(Vec::new(), |mut raw, d| {
747        raw.extend_from_slice(&d.to_be_bytes());
748        raw
749    })
750}
751
752fn u16_vector_to_raw(data: &[u16]) -> Vec<u8> {
753    data.iter().fold(Vec::new(), |mut raw, d| {
754        raw.extend_from_slice(&d.to_be_bytes());
755        raw
756    })
757}
758
759fn bool_vector_to_raw(data: &[bool]) -> Vec<u8> {
760    data.iter()
761        .map(|&d| {
762            if d {
763                FeatureCtl::TRUE
764            } else {
765                FeatureCtl::FALSE
766            }
767        })
768        .collect()
769}
770
771/// The type of Feature Control.
772#[derive(Clone, Debug, Eq, PartialEq)]
773pub enum FeatureCtl {
774    /// Clause 10.3.1 Mute Control.
775    Mute(Vec<bool>),
776    /// Clause 10.3.2 Volume Control.
777    Volume(VolumeData),
778    /// Clause 10.3.3 LR Balance Control.
779    LrBalance(LrBalanceData),
780    /// Clause 10.3.4 FR Balance Control.
781    FrBalance(FrBalanceData),
782    /// Clause 10.3.5 Bass Control.
783    Bass(BassData),
784    /// Clause 10.3.6 Mid Control.
785    Mid(MidData),
786    /// Clause 10.3.7 Treble Control.
787    Treble(TrebleData),
788    /// Clause 10.3.8 Graphic Equalizer Control.
789    GraphicEqualizer(GraphicEqualizerData),
790    /// Clause 10.3.9 Automatic Gain Control.
791    AutomaticGain(Vec<bool>),
792    /// Clause 10.3.10 Delay Control.
793    Delay(DelayData),
794    /// Clause 10.3.11 Bass Boost Control.
795    BassBoost(Vec<bool>),
796    /// Clause 10.3.12 Loudness Control.
797    Loudness(Vec<bool>),
798    Reserved(Vec<u8>),
799}
800
801impl FeatureCtl {
802    const MUTE: u8 = 0x01;
803    const VOLUME: u8 = 0x02;
804    const LR_BALANCE: u8 = 0x03;
805    const FR_BALANCE: u8 = 0x04;
806    const BASS: u8 = 0x05;
807    const MID: u8 = 0x06;
808    const TREBLE: u8 = 0x07;
809    const GRAPHIC_EQUALIZER: u8 = 0x08;
810    const AUTOMATIC_GAIN: u8 = 0x09;
811    const DELAY: u8 = 0x0a;
812    const BASS_BOOST: u8 = 0x0b;
813    const LOUDNESS: u8 = 0x0c;
814
815    const TRUE: u8 = 0x70;
816    const FALSE: u8 = 0x60;
817}
818
819impl FeatureCtl {
820    fn to_ctl(&self) -> AudioFuncBlkCtl {
821        match self {
822            Self::Mute(data) => AudioFuncBlkCtl {
823                selector: Self::MUTE,
824                data: bool_vector_to_raw(data),
825            },
826            Self::Volume(data) => AudioFuncBlkCtl {
827                selector: Self::VOLUME,
828                data: data.to_raw(),
829            },
830            Self::LrBalance(data) => AudioFuncBlkCtl {
831                selector: Self::LR_BALANCE,
832                data: data.to_raw(),
833            },
834            Self::FrBalance(data) => AudioFuncBlkCtl {
835                selector: Self::FR_BALANCE,
836                data: data.to_raw(),
837            },
838            Self::Bass(data) => AudioFuncBlkCtl {
839                selector: Self::BASS,
840                data: data.to_raw(),
841            },
842            Self::Mid(data) => AudioFuncBlkCtl {
843                selector: Self::MID,
844                data: data.to_raw(),
845            },
846            Self::Treble(data) => AudioFuncBlkCtl {
847                selector: Self::TREBLE,
848                data: data.to_raw(),
849            },
850            Self::GraphicEqualizer(data) => AudioFuncBlkCtl {
851                selector: Self::GRAPHIC_EQUALIZER,
852                data: data.to_raw(),
853            },
854            Self::AutomaticGain(data) => AudioFuncBlkCtl {
855                selector: Self::AUTOMATIC_GAIN,
856                data: bool_vector_to_raw(data),
857            },
858            Self::Delay(data) => AudioFuncBlkCtl {
859                selector: Self::DELAY,
860                data: data.to_raw(),
861            },
862            Self::BassBoost(data) => AudioFuncBlkCtl {
863                selector: Self::BASS_BOOST,
864                data: bool_vector_to_raw(data),
865            },
866            Self::Loudness(data) => AudioFuncBlkCtl {
867                selector: Self::LOUDNESS,
868                data: bool_vector_to_raw(data),
869            },
870            Self::Reserved(data) => AudioFuncBlkCtl {
871                selector: data[0],
872                data: data[2..].to_vec(),
873            },
874        }
875    }
876}
877
878fn i16_vector_from_raw(raw: &[u8]) -> Vec<i16> {
879    (0..(raw.len() / 2))
880        .map(|i| {
881            let mut doublet = [0; 2];
882            doublet.copy_from_slice(&raw[(i * 2)..(i * 2 + 2)]);
883            i16::from_be_bytes(doublet)
884        })
885        .collect()
886}
887
888fn u16_vector_from_raw(raw: &[u8]) -> Vec<u16> {
889    (0..(raw.len() / 2))
890        .map(|i| {
891            let mut doublet = [0; 2];
892            doublet.copy_from_slice(&raw[(i * 2)..(i * 2 + 2)]);
893            u16::from_be_bytes(doublet)
894        })
895        .collect()
896}
897
898fn bool_vector_from_raw(raw: &[u8]) -> Vec<bool> {
899    raw.iter().map(|&b| b == FeatureCtl::TRUE).collect()
900}
901
902fn i8_vector_from_raw(raw: &[u8]) -> Vec<i8> {
903    raw.iter().map(|&b| b as i8).collect()
904}
905
906fn i16_from_raw(data: &[u8]) -> i16 {
907    let mut doublet = [0; 2];
908    doublet.copy_from_slice(&data);
909    i16::from_be_bytes(doublet)
910}
911
912impl FeatureCtl {
913    fn from_ctl(ctl: &AudioFuncBlkCtl) -> Self {
914        match ctl.selector {
915            Self::MUTE => Self::Mute(bool_vector_from_raw(&ctl.data)),
916            Self::VOLUME => Self::Volume(VolumeData::from_raw(&ctl.data)),
917            Self::LR_BALANCE => Self::LrBalance(LrBalanceData::from_raw(&ctl.data)),
918            Self::FR_BALANCE => Self::FrBalance(FrBalanceData::from_raw(&ctl.data)),
919            Self::BASS => Self::Bass(BassData::from_raw(&ctl.data)),
920            Self::MID => Self::Mid(MidData::from_raw(&ctl.data)),
921            Self::TREBLE => Self::Treble(TrebleData::from_raw(&ctl.data)),
922            Self::GRAPHIC_EQUALIZER => {
923                Self::GraphicEqualizer(GraphicEqualizerData::from_raw(&ctl.data))
924            }
925            Self::AUTOMATIC_GAIN => Self::AutomaticGain(bool_vector_from_raw(&ctl.data)),
926            Self::DELAY => Self::Delay(DelayData::from_raw(&ctl.data)),
927            Self::BASS_BOOST => Self::BassBoost(bool_vector_from_raw(&ctl.data)),
928            Self::LOUDNESS => Self::Loudness(bool_vector_from_raw(&ctl.data)),
929            _ => {
930                let mut data = Vec::new();
931                data.push(ctl.selector);
932                data.push(1 + ctl.data.len() as u8);
933                data.extend_from_slice(&ctl.data);
934                Self::Reserved(data)
935            }
936        }
937    }
938}
939
940/// For the value of audio_channel_number field described in clause "10.3 Feature function
941/// block".
942#[derive(Clone, Copy, Debug, Eq, PartialEq)]
943pub enum AudioCh {
944    /// Master channel.
945    Master,
946    /// Each of channel.
947    Each(u8),
948    /// Void channel.
949    Void,
950    /// All channels.
951    All,
952}
953
954impl Default for AudioCh {
955    fn default() -> Self {
956        Self::All
957    }
958}
959
960impl AudioCh {
961    const MASTER: u8 = 0x00;
962    const VOID: u8 = 0xfe;
963    const ALL: u8 = 0xff;
964}
965
966impl AudioCh {
967    fn from_val(val: u8) -> Self {
968        match val {
969            Self::MASTER => Self::Master,
970            Self::ALL => Self::All,
971            Self::VOID => Self::Void,
972            // MEMO: It should be greater than 0 and less than 0xfe, however it' loosely handled
973            // here.
974            _ => Self::Each(val - 1),
975        }
976    }
977
978    fn to_val(&self) -> u8 {
979        match self {
980            Self::Master => Self::MASTER,
981            Self::All => Self::ALL,
982            Self::Void => Self::VOID,
983            Self::Each(val) => val + 1,
984        }
985    }
986}
987
988///
989/// AV/C Audio Subunit FUNCTION_BLOCK command for Feature function block
990///
991/// Described in 10.3 Feature function block.
992#[derive(Clone, Debug, Eq, PartialEq)]
993pub struct AudioFeature {
994    /// The channels to address.
995    pub audio_ch_num: AudioCh,
996    /// The control to manipulate.
997    pub ctl: FeatureCtl,
998
999    func_blk: AudioFuncBlk,
1000}
1001
1002impl AudioFeature {
1003    pub fn new(func_blk_id: u8, ctl_attr: CtlAttr, audio_ch_num: AudioCh, ctl: FeatureCtl) -> Self {
1004        Self {
1005            audio_ch_num,
1006            ctl,
1007            func_blk: AudioFuncBlk {
1008                func_blk_type: AudioFuncBlkType::Feature,
1009                func_blk_id,
1010                ctl_attr,
1011                ..Default::default()
1012            },
1013        }
1014    }
1015
1016    fn build_func_blk(&mut self) -> Result<(), AvcCmdBuildError> {
1017        self.func_blk.audio_selector_data.clear();
1018        self.func_blk
1019            .audio_selector_data
1020            .push(self.audio_ch_num.to_val());
1021        self.func_blk.ctl = self.ctl.to_ctl();
1022        Ok(())
1023    }
1024
1025    fn parse_func_blk(&mut self) -> Result<(), AvcRespParseError> {
1026        let audio_ch_num = AudioCh::from_val(self.func_blk.audio_selector_data[0]);
1027        if audio_ch_num != self.audio_ch_num {
1028            Err(AvcRespParseError::UnexpectedOperands(7))
1029        } else {
1030            self.ctl = FeatureCtl::from_ctl(&self.func_blk.ctl);
1031            Ok(())
1032        }
1033    }
1034}
1035
1036impl AvcOp for AudioFeature {
1037    const OPCODE: u8 = AudioFuncBlk::OPCODE;
1038}
1039
1040impl AvcStatus for AudioFeature {
1041    fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
1042        self.build_func_blk()
1043            .and_then(|_| AvcStatus::build_operands(&mut self.func_blk, addr))
1044    }
1045
1046    fn parse_operands(&mut self, addr: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
1047        AvcStatus::parse_operands(&mut self.func_blk, addr, operands)
1048            .and_then(|_| self.parse_func_blk())
1049    }
1050}
1051
1052impl AvcControl for AudioFeature {
1053    fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
1054        self.build_func_blk()
1055            .and_then(|_| AvcControl::build_operands(&mut self.func_blk, addr))
1056    }
1057
1058    fn parse_operands(&mut self, addr: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
1059        AvcControl::parse_operands(&mut self.func_blk, addr, operands)
1060            .and_then(|_| self.parse_func_blk())
1061    }
1062}
1063
1064/// The type of processing control.
1065#[derive(Clone, Debug, Eq, PartialEq)]
1066pub enum ProcessingCtl {
1067    Enable(bool),
1068    Mode(Vec<u8>),
1069    Mixer(Vec<i16>),
1070    Reserved(Vec<u8>),
1071}
1072
1073impl ProcessingCtl {
1074    const ENABLE: u8 = 0x01;
1075    const MODE: u8 = 0x02;
1076    const MIXER: u8 = 0x03;
1077
1078    const TRUE: u8 = 0x70;
1079    const FALSE: u8 = 0x60;
1080
1081    pub const INFINITY: i16 = 0x7ffeu16 as i16;
1082    pub const NEG_INFINITY: i16 = 0x8000u16 as i16;
1083}
1084
1085impl ProcessingCtl {
1086    fn to_ctl(&self) -> AudioFuncBlkCtl {
1087        match self {
1088            Self::Enable(data) => AudioFuncBlkCtl {
1089                selector: Self::ENABLE,
1090                data: vec![if *data { Self::TRUE } else { Self::FALSE }],
1091            },
1092            Self::Mode(data) => AudioFuncBlkCtl {
1093                selector: Self::MODE,
1094                data: data.to_vec(),
1095            },
1096            Self::Mixer(data) => AudioFuncBlkCtl {
1097                selector: Self::MIXER,
1098                data: i16_vector_to_raw(data),
1099            },
1100            Self::Reserved(data) => AudioFuncBlkCtl {
1101                selector: data[0],
1102                data: data[2..].to_vec(),
1103            },
1104        }
1105    }
1106
1107    fn from_ctl(ctl_blk: &AudioFuncBlkCtl) -> Self {
1108        match ctl_blk.selector {
1109            Self::ENABLE => Self::Enable(ctl_blk.data[0] == Self::TRUE),
1110            Self::MODE => Self::Mode(ctl_blk.data.to_vec()),
1111            Self::MIXER => Self::Mixer(i16_vector_from_raw(&ctl_blk.data)),
1112            _ => {
1113                let mut data = Vec::new();
1114                data.push(ctl_blk.selector);
1115                data.push(1 + ctl_blk.data.len() as u8);
1116                data.extend_from_slice(&ctl_blk.data);
1117                Self::Reserved(data)
1118            }
1119        }
1120    }
1121}
1122
1123///
1124/// AV/C Audio Subunit FUNCTION_BLOCK command for processing function block
1125///
1126/// Described in 10.4 Processing function block.
1127pub struct AudioProcessing {
1128    /// Function block input plug number (FBPN).
1129    pub input_plug_id: u8,
1130    /// Input audio channel (ICN).
1131    pub input_ch: AudioCh,
1132    /// Output audio channel (OCN).
1133    pub output_ch: AudioCh,
1134    /// Processing function block type dependent parameters.
1135    pub ctl: ProcessingCtl,
1136
1137    func_blk: AudioFuncBlk,
1138}
1139
1140impl AudioProcessing {
1141    pub fn new(
1142        func_blk_id: u8,
1143        ctl_attr: CtlAttr,
1144        input_plug_id: u8,
1145        input_ch: AudioCh,
1146        output_ch: AudioCh,
1147        ctl: ProcessingCtl,
1148    ) -> Self {
1149        Self {
1150            input_plug_id,
1151            input_ch,
1152            output_ch,
1153            ctl,
1154            func_blk: AudioFuncBlk {
1155                func_blk_type: AudioFuncBlkType::Processing,
1156                func_blk_id,
1157                ctl_attr,
1158                ..Default::default()
1159            },
1160        }
1161    }
1162
1163    fn build_func_blk(&mut self) -> Result<(), AvcCmdBuildError> {
1164        self.func_blk.audio_selector_data.clear();
1165        self.func_blk.audio_selector_data.push(self.input_plug_id);
1166        self.func_blk
1167            .audio_selector_data
1168            .push(self.input_ch.to_val());
1169        self.func_blk
1170            .audio_selector_data
1171            .push(self.output_ch.to_val());
1172        self.func_blk.ctl = self.ctl.to_ctl();
1173        Ok(())
1174    }
1175
1176    fn parse_func_blk(&mut self) -> Result<(), AvcRespParseError> {
1177        if self.func_blk.audio_selector_data[0] != self.input_plug_id {
1178            Err(AvcRespParseError::UnexpectedOperands(7))?;
1179        }
1180
1181        let input_ch = AudioCh::from_val(self.func_blk.audio_selector_data[1]);
1182        if input_ch != self.input_ch {
1183            Err(AvcRespParseError::UnexpectedOperands(8))?;
1184        }
1185
1186        let output_ch = AudioCh::from_val(self.func_blk.audio_selector_data[2]);
1187        if output_ch != self.output_ch {
1188            Err(AvcRespParseError::UnexpectedOperands(9))?;
1189        }
1190
1191        self.ctl = ProcessingCtl::from_ctl(&self.func_blk.ctl);
1192        Ok(())
1193    }
1194}
1195
1196impl AvcOp for AudioProcessing {
1197    const OPCODE: u8 = AudioFuncBlk::OPCODE;
1198}
1199
1200impl AvcStatus for AudioProcessing {
1201    fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
1202        self.build_func_blk()
1203            .and_then(|_| AvcStatus::build_operands(&mut self.func_blk, addr))
1204    }
1205
1206    fn parse_operands(&mut self, addr: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
1207        AvcStatus::parse_operands(&mut self.func_blk, addr, operands)
1208            .and_then(|_| self.parse_func_blk())
1209    }
1210}
1211
1212impl AvcControl for AudioProcessing {
1213    fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
1214        self.build_func_blk()
1215            .and_then(|_| AvcControl::build_operands(&mut self.func_blk, addr))
1216    }
1217
1218    fn parse_operands(&mut self, addr: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
1219        AvcControl::parse_operands(&mut self.func_blk, addr, operands)
1220            .and_then(|_| self.parse_func_blk())
1221    }
1222}
1223
1224#[cfg(test)]
1225mod test {
1226    use crate::*;
1227
1228    #[test]
1229    fn func_blk_operands() {
1230        let mut op = AudioFuncBlk {
1231            func_blk_type: AudioFuncBlkType::Selector,
1232            func_blk_id: 0xfe,
1233            ctl_attr: CtlAttr::Resolution,
1234            ..Default::default()
1235        };
1236        op.audio_selector_data
1237            .extend_from_slice(&[0xde, 0xad, 0xbe, 0xef]);
1238        op.ctl.selector = 0x11;
1239        op.ctl.data.extend_from_slice(&[0xbe, 0xef]);
1240
1241        let operands = AvcStatus::build_operands(&mut op, &AUDIO_SUBUNIT_0_ADDR).unwrap();
1242        assert_eq!(
1243            &operands,
1244            &[0x80, 0xfe, 0x01, 0x05, 0xde, 0xad, 0xbe, 0xef, 0x11, 0x02, 0xbe, 0xef]
1245        );
1246
1247        AvcStatus::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1248        assert_eq!(op.func_blk_type, AudioFuncBlkType::Selector);
1249        assert_eq!(op.func_blk_id, 0xfe);
1250        assert_eq!(op.ctl_attr, CtlAttr::Resolution);
1251        assert_eq!(&op.audio_selector_data, &[0xde, 0xad, 0xbe, 0xef]);
1252        assert_eq!(op.ctl.selector, 0x11);
1253        assert_eq!(&op.ctl.data, &[0xbe, 0xef]);
1254
1255        let mut op = AudioFuncBlk {
1256            func_blk_type: AudioFuncBlkType::Selector,
1257            func_blk_id: 0xfd,
1258            ctl_attr: CtlAttr::Minimum,
1259            ..Default::default()
1260        };
1261        op.audio_selector_data
1262            .extend_from_slice(&[0xde, 0xad, 0xbe, 0xef]);
1263        op.ctl.selector = 0x12;
1264        op.ctl.data.extend_from_slice(&[0xbe, 0xef]);
1265
1266        let operands = AvcControl::build_operands(&mut op, &AUDIO_SUBUNIT_0_ADDR).unwrap();
1267        assert_eq!(
1268            &operands,
1269            &[0x80, 0xfd, 0x02, 0x05, 0xde, 0xad, 0xbe, 0xef, 0x12, 0x02, 0xbe, 0xef]
1270        );
1271
1272        AvcControl::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1273        assert_eq!(op.func_blk_type, AudioFuncBlkType::Selector);
1274        assert_eq!(op.func_blk_id, 0xfd);
1275        assert_eq!(op.ctl_attr, CtlAttr::Minimum);
1276        assert_eq!(&op.audio_selector_data, &[0xde, 0xad, 0xbe, 0xef]);
1277        assert_eq!(op.ctl.selector, 0x12);
1278        assert_eq!(&op.ctl.data, &[0xbe, 0xef]);
1279
1280        // For the case that audio_selector_data is empty.
1281        let mut op = AudioFuncBlk {
1282            func_blk_type: AudioFuncBlkType::Feature,
1283            func_blk_id: 0xfc,
1284            ctl_attr: CtlAttr::Maximum,
1285            ..Default::default()
1286        };
1287        op.ctl.selector = 0x13;
1288        op.ctl.data.extend_from_slice(&[0xfe, 0xeb, 0xda, 0xed]);
1289
1290        let operands = AvcStatus::build_operands(&mut op, &AUDIO_SUBUNIT_0_ADDR).unwrap();
1291        assert_eq!(
1292            &operands,
1293            &[0x81, 0xfc, 0x03, 0x01, 0x13, 0x04, 0xfe, 0xeb, 0xda, 0xed]
1294        );
1295
1296        AvcStatus::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1297        assert_eq!(op.func_blk_type, AudioFuncBlkType::Feature);
1298        assert_eq!(op.func_blk_id, 0xfc);
1299        assert_eq!(op.ctl_attr, CtlAttr::Maximum);
1300        assert_eq!(&op.audio_selector_data, &[]);
1301        assert_eq!(op.ctl.selector, 0x13);
1302        assert_eq!(&op.ctl.data, &[0xfe, 0xeb, 0xda, 0xed]);
1303
1304        let mut op = AudioFuncBlk {
1305            func_blk_type: AudioFuncBlkType::Feature,
1306            func_blk_id: 0xfb,
1307            ctl_attr: CtlAttr::Default,
1308            ctl: AudioFuncBlkCtl {
1309                selector: 0x14,
1310                data: vec![0xfe, 0xeb, 0xda, 0xed],
1311            },
1312            ..Default::default()
1313        };
1314
1315        let operands = AvcControl::build_operands(&mut op, &AUDIO_SUBUNIT_0_ADDR).unwrap();
1316        assert_eq!(
1317            &operands,
1318            &[0x81, 0xfb, 0x04, 0x01, 0x14, 0x04, 0xfe, 0xeb, 0xda, 0xed]
1319        );
1320
1321        AvcControl::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1322        assert_eq!(op.func_blk_type, AudioFuncBlkType::Feature);
1323        assert_eq!(op.func_blk_id, 0xfb);
1324        assert_eq!(op.ctl_attr, CtlAttr::Default);
1325        assert_eq!(&op.audio_selector_data, &[]);
1326        assert_eq!(op.ctl.selector, 0x14);
1327        assert_eq!(&op.ctl.data, &[0xfe, 0xeb, 0xda, 0xed]);
1328
1329        // For the case that ctl_data is empty.
1330        let mut op = AudioFuncBlk {
1331            func_blk_type: AudioFuncBlkType::Processing,
1332            func_blk_id: 0xfa,
1333            ctl_attr: CtlAttr::Duration,
1334            audio_selector_data: vec![0xda, 0xed],
1335            ctl: AudioFuncBlkCtl {
1336                selector: 0x15,
1337                ..Default::default()
1338            },
1339        };
1340
1341        let operands = AvcStatus::build_operands(&mut op, &AUDIO_SUBUNIT_0_ADDR).unwrap();
1342        assert_eq!(&operands, &[0x82, 0xfa, 0x08, 0x03, 0xda, 0xed, 0x15]);
1343
1344        AvcStatus::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1345        assert_eq!(op.func_blk_type, AudioFuncBlkType::Processing);
1346        assert_eq!(op.func_blk_id, 0xfa);
1347        assert_eq!(op.ctl_attr, CtlAttr::Duration);
1348        assert_eq!(&op.audio_selector_data, &[0xda, 0xed]);
1349        assert_eq!(op.ctl.selector, 0x15);
1350        assert_eq!(&op.ctl.data, &[]);
1351
1352        let mut op = AudioFuncBlk {
1353            func_blk_type: AudioFuncBlkType::Processing,
1354            func_blk_id: 0xf9,
1355            ctl_attr: CtlAttr::Current,
1356            audio_selector_data: vec![0xda, 0xed],
1357            ctl: AudioFuncBlkCtl {
1358                selector: 0x16,
1359                ..Default::default()
1360            },
1361        };
1362
1363        let operands = AvcControl::build_operands(&mut op, &AUDIO_SUBUNIT_0_ADDR).unwrap();
1364        assert_eq!(&operands, &[0x82, 0xf9, 0x10, 0x03, 0xda, 0xed, 0x16]);
1365
1366        AvcControl::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1367        assert_eq!(op.func_blk_type, AudioFuncBlkType::Processing);
1368        assert_eq!(op.func_blk_id, 0xf9);
1369        assert_eq!(op.ctl_attr, CtlAttr::Current);
1370        assert_eq!(&op.audio_selector_data, &[0xda, 0xed]);
1371        assert_eq!(op.ctl.selector, 0x16);
1372        assert_eq!(&op.ctl.data, &[]);
1373    }
1374
1375    #[test]
1376    fn avcaudioselector_operands() {
1377        let mut op = AudioSelector::new(0xe5, CtlAttr::Duration, 0x28);
1378        let operands = AvcStatus::build_operands(&mut op, &AUDIO_SUBUNIT_0_ADDR).unwrap();
1379        assert_eq!(&operands, &[0x80, 0xe5, 0x08, 0x02, 0x28, 0x01]);
1380
1381        AvcStatus::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1382        assert_eq!(op.input_plug_id, 0x28);
1383
1384        let mut op = AudioSelector::new(0x1e, CtlAttr::Move, 0x96);
1385        let operands = AvcControl::build_operands(&mut op, &AUDIO_SUBUNIT_0_ADDR).unwrap();
1386        assert_eq!(&operands, &[0x80, 0x1e, 0x18, 0x02, 0x96, 0x01]);
1387
1388        AvcControl::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1389        assert_eq!(op.input_plug_id, 0x96);
1390    }
1391
1392    #[test]
1393    fn featurectl_from() {
1394        let ctl = FeatureCtl::Mute(vec![false, true, false]);
1395        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1396
1397        let data = VolumeData(vec![0x1234, 0x3456, 0x789a]);
1398        let ctl = FeatureCtl::Volume(data);
1399        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1400
1401        let ctl = FeatureCtl::LrBalance(LrBalanceData(-123));
1402        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1403
1404        let ctl = FeatureCtl::FrBalance(FrBalanceData(321));
1405        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1406
1407        let ctl = FeatureCtl::Bass(BassData(vec![10, -10, 20, -20]));
1408        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1409
1410        let ctl = FeatureCtl::Mid(MidData(vec![30, -30, -40, 40]));
1411        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1412
1413        let data = GraphicEqualizerData {
1414            ansi_band_gains: [
1415                Some(-1),
1416                Some(-2),
1417                Some(-3),
1418                Some(10),
1419                None,
1420                None,
1421                None,
1422                None,
1423                Some(14),
1424                Some(-40),
1425                Some(-100),
1426                Some(33),
1427                None,
1428                None,
1429                None,
1430                None,
1431                Some(-1),
1432                Some(-2),
1433                Some(-3),
1434                Some(10),
1435                None,
1436                None,
1437                None,
1438                None,
1439                Some(14),
1440                Some(-40),
1441                Some(-100),
1442                Some(33),
1443                None,
1444                None,
1445            ],
1446            extra_band_gains: [
1447                Some(87),
1448                Some(99),
1449                Some(-123),
1450                Some(100),
1451                None,
1452                None,
1453                None,
1454                None,
1455                Some(-76),
1456                Some(-97),
1457                Some(18),
1458                Some(21),
1459                None,
1460                None,
1461                None,
1462                None,
1463                Some(87),
1464                Some(99),
1465                Some(-123),
1466                Some(100),
1467                None,
1468                None,
1469                None,
1470                None,
1471                Some(-76),
1472                Some(-97),
1473                Some(18),
1474                Some(21),
1475                None,
1476                None,
1477                None,
1478                None,
1479            ],
1480        };
1481        let ctl = FeatureCtl::GraphicEqualizer(data);
1482        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1483
1484        let ctl = FeatureCtl::Treble(TrebleData(vec![50, 60, -70, -80]));
1485        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1486
1487        let ctl = FeatureCtl::AutomaticGain(vec![false, true, false]);
1488        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1489
1490        let ctl = FeatureCtl::Delay(DelayData(vec![0x1234, 0x3456, 0x789a]));
1491        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1492
1493        let ctl = FeatureCtl::BassBoost(vec![true, false, true]);
1494        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1495
1496        let ctl = FeatureCtl::Loudness(vec![false, true, false]);
1497        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1498
1499        let ctl = FeatureCtl::Reserved(vec![0xff, 0x04, 0xad, 0xbe, 0xef]);
1500        assert_eq!(ctl, FeatureCtl::from_ctl(&ctl.to_ctl()));
1501    }
1502
1503    #[test]
1504    fn avcaudiofeature_operands() {
1505        let data = VolumeData(vec![-1234, 5678, 3210]);
1506        let ctl = FeatureCtl::Volume(data);
1507        let mut op = AudioFeature::new(0x03, CtlAttr::Minimum, AudioCh::Each(0x1b), ctl.clone());
1508        let operands = AvcStatus::build_operands(&mut op, &AUDIO_SUBUNIT_0_ADDR).unwrap();
1509        assert_eq!(
1510            &operands,
1511            &[0x81, 0x03, 0x02, 0x02, 0x1c, 0x02, 0x06, 0xfb, 0x2e, 0x16, 0x2e, 0x0c, 0x8a]
1512        );
1513
1514        AvcStatus::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1515        assert_eq!(AudioCh::Each(0x1b), op.audio_ch_num);
1516        assert_eq!(ctl, op.ctl);
1517
1518        let ctl = FeatureCtl::Treble(TrebleData(vec![40, -33, 123, -96]));
1519        let mut op = AudioFeature::new(0x33, CtlAttr::Resolution, AudioCh::Each(0xd8), ctl.clone());
1520        let operands = AvcControl::build_operands(&mut op, &AUDIO_SUBUNIT_0_ADDR).unwrap();
1521        assert_eq!(
1522            &operands,
1523            &[0x81, 0x33, 0x01, 0x2, 0xd9, 0x07, 0x04, 0x28, 0xdf, 0x7b, 0xa0]
1524        );
1525
1526        AvcControl::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1527        assert_eq!(AudioCh::Each(0xd8), op.audio_ch_num);
1528        assert_eq!(ctl, op.ctl);
1529    }
1530
1531    #[test]
1532    fn processingctl_from() {
1533        let ctl = ProcessingCtl::Enable(true);
1534        assert_eq!(ctl, ProcessingCtl::from_ctl(&ctl.to_ctl()));
1535
1536        let ctl = ProcessingCtl::Mode(vec![0xde, 0xad, 0xbe, 0xef]);
1537        assert_eq!(ctl, ProcessingCtl::from_ctl(&ctl.to_ctl()));
1538
1539        let ctl = ProcessingCtl::Mixer(vec![-73, -157]);
1540        assert_eq!(ctl, ProcessingCtl::from_ctl(&ctl.to_ctl()));
1541    }
1542
1543    #[test]
1544    fn avcaudioprocessing_operands() {
1545        let ctl = ProcessingCtl::Enable(true);
1546        let mut op = AudioProcessing::new(
1547            0xf5,
1548            CtlAttr::Default,
1549            0x71,
1550            AudioCh::Each(0xa8),
1551            AudioCh::Each(0x3e),
1552            ctl.clone(),
1553        );
1554        let operands = AvcStatus::build_operands(&mut op, &AUDIO_SUBUNIT_0_ADDR).unwrap();
1555        assert_eq!(
1556            &operands,
1557            &[0x82, 0xf5, 0x04, 0x04, 0x71, 0xa9, 0x3f, 0x01, 0x01, 0x70]
1558        );
1559
1560        AvcStatus::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1561        assert_eq!(0x71, op.input_plug_id);
1562        assert_eq!(AudioCh::Each(0xa8), op.input_ch);
1563        assert_eq!(AudioCh::Each(0x3e), op.output_ch);
1564        assert_eq!(ctl, op.ctl);
1565
1566        let ctl = ProcessingCtl::Mixer(vec![10, -10]);
1567        let mut op = AudioProcessing::new(
1568            0x11,
1569            CtlAttr::Minimum,
1570            0x22,
1571            AudioCh::Each(0x32),
1572            AudioCh::Each(0x43),
1573            ctl.clone(),
1574        );
1575        let operands = AvcControl::build_operands(&mut op, &AUDIO_SUBUNIT_0_ADDR).unwrap();
1576        assert_eq!(
1577            &operands,
1578            &[0x82, 0x11, 0x02, 0x04, 0x22, 0x33, 0x44, 0x03, 0x04, 0x00, 0x0a, 0xff, 0xf6]
1579        );
1580
1581        AvcControl::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
1582        assert_eq!(0x22, op.input_plug_id);
1583        assert_eq!(AudioCh::Each(0x32), op.input_ch);
1584        assert_eq!(AudioCh::Each(0x43), op.output_ch);
1585        assert_eq!(ctl, op.ctl);
1586    }
1587}