Skip to main content

fuchsia_audio/
sigproc.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use flex_fuchsia_hardware_audio_signalprocessing as fhaudio_sigproc;
6use zx_types;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct Topology {
10    pub id: fhaudio_sigproc::TopologyId,
11    pub edge_pairs: Vec<fhaudio_sigproc::EdgePair>,
12}
13
14impl TryFrom<fhaudio_sigproc::Topology> for Topology {
15    type Error = String;
16
17    fn try_from(value: fhaudio_sigproc::Topology) -> Result<Self, Self::Error> {
18        let id = value.id.ok_or_else(|| "missing 'id'".to_string())?;
19        let edge_pairs = value
20            .processing_elements_edge_pairs
21            .ok_or_else(|| "missing 'processing_elements_edge_pairs'".to_string())?;
22        Ok(Self { id, edge_pairs })
23    }
24}
25
26impl From<Topology> for fhaudio_sigproc::Topology {
27    fn from(value: Topology) -> Self {
28        Self {
29            id: Some(value.id),
30            processing_elements_edge_pairs: Some(value.edge_pairs),
31            ..Default::default()
32        }
33    }
34}
35
36#[derive(Debug, Clone, PartialEq)]
37pub struct Element {
38    pub id: fhaudio_sigproc::ElementId,
39    pub type_: fhaudio_sigproc::ElementType,
40    pub type_specific: Option<TypeSpecificElement>,
41    pub description: Option<String>,
42    pub can_stop: Option<bool>,
43    pub can_bypass: Option<bool>,
44}
45
46impl TryFrom<fhaudio_sigproc::Element> for Element {
47    type Error = String;
48
49    fn try_from(value: fhaudio_sigproc::Element) -> Result<Self, Self::Error> {
50        let id = value.id.ok_or_else(|| "missing 'id'".to_string())?;
51        let type_ = value.type_.ok_or_else(|| "missing 'type'".to_string())?;
52        let type_specific: Option<TypeSpecificElement> =
53            value.type_specific.map(TryInto::try_into).transpose()?;
54        Ok(Self {
55            id,
56            type_,
57            type_specific,
58            description: value.description,
59            can_stop: value.can_stop,
60            can_bypass: value.can_bypass,
61        })
62    }
63}
64
65impl From<Element> for fhaudio_sigproc::Element {
66    fn from(value: Element) -> Self {
67        Self {
68            id: Some(value.id),
69            type_: Some(value.type_),
70            type_specific: value.type_specific.map(Into::into),
71            description: value.description,
72            can_stop: value.can_stop,
73            can_bypass: value.can_bypass,
74            ..Default::default()
75        }
76    }
77}
78
79#[derive(Debug, Clone, PartialEq)]
80pub enum TypeSpecificElement {
81    VendorSpecific(VendorSpecific),
82    Gain(Gain),
83    Equalizer(Equalizer),
84    Dynamics(Dynamics),
85    DaiInterconnect(DaiInterconnect),
86}
87
88impl TryFrom<fhaudio_sigproc::TypeSpecificElement> for TypeSpecificElement {
89    type Error = String;
90
91    fn try_from(value: fhaudio_sigproc::TypeSpecificElement) -> Result<Self, Self::Error> {
92        match value {
93            fhaudio_sigproc::TypeSpecificElement::VendorSpecific(vendor_specific) => {
94                Ok(Self::VendorSpecific(vendor_specific.try_into()?))
95            }
96            fhaudio_sigproc::TypeSpecificElement::Gain(gain) => Ok(Self::Gain(gain.try_into()?)),
97            fhaudio_sigproc::TypeSpecificElement::Equalizer(equalizer) => {
98                Ok(Self::Equalizer(equalizer.try_into()?))
99            }
100            fhaudio_sigproc::TypeSpecificElement::Dynamics(dynamics) => {
101                Ok(Self::Dynamics(dynamics.try_into()?))
102            }
103            fhaudio_sigproc::TypeSpecificElement::DaiInterconnect(dai_interconnect) => {
104                Ok(Self::DaiInterconnect(dai_interconnect.try_into()?))
105            }
106            _ => Err("unknown TypeSpecificElement variant".to_string()),
107        }
108    }
109}
110
111impl From<TypeSpecificElement> for fhaudio_sigproc::TypeSpecificElement {
112    fn from(value: TypeSpecificElement) -> Self {
113        match value {
114            TypeSpecificElement::VendorSpecific(vendor_specific) => {
115                Self::VendorSpecific(vendor_specific.into())
116            }
117            TypeSpecificElement::Gain(gain) => Self::Gain(gain.into()),
118            TypeSpecificElement::Equalizer(equalizer) => Self::Equalizer(equalizer.into()),
119            TypeSpecificElement::Dynamics(dynamics) => Self::Dynamics(dynamics.into()),
120            TypeSpecificElement::DaiInterconnect(dai_interconnect) => {
121                Self::DaiInterconnect(dai_interconnect.into())
122            }
123        }
124    }
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq)]
128pub struct VendorSpecific {}
129
130impl TryFrom<fhaudio_sigproc::VendorSpecific> for VendorSpecific {
131    type Error = String;
132
133    fn try_from(_value: fhaudio_sigproc::VendorSpecific) -> Result<Self, Self::Error> {
134        Ok(Self {})
135    }
136}
137
138impl From<VendorSpecific> for fhaudio_sigproc::VendorSpecific {
139    fn from(_value: VendorSpecific) -> Self {
140        Default::default()
141    }
142}
143
144#[derive(Debug, Clone, Copy, PartialEq)]
145pub struct Gain {
146    pub type_: fhaudio_sigproc::GainType,
147    pub domain: Option<fhaudio_sigproc::GainDomain>,
148    pub range: GainRange,
149}
150
151impl TryFrom<fhaudio_sigproc::Gain> for Gain {
152    type Error = String;
153
154    fn try_from(value: fhaudio_sigproc::Gain) -> Result<Self, Self::Error> {
155        let type_ = value.type_.ok_or_else(|| "missing 'type'".to_string())?;
156        let min_gain = value.min_gain.ok_or_else(|| "missing 'min_gain'".to_string())?;
157        let max_gain = value.max_gain.ok_or_else(|| "missing 'max_gain'".to_string())?;
158        let min_gain_step =
159            value.min_gain_step.ok_or_else(|| "missing 'min_gain_step'".to_string())?;
160        let range = GainRange { min: min_gain, max: max_gain, min_step: min_gain_step };
161        Ok(Self { type_, domain: value.domain, range })
162    }
163}
164
165impl From<Gain> for fhaudio_sigproc::Gain {
166    fn from(value: Gain) -> Self {
167        Self {
168            type_: Some(value.type_),
169            domain: value.domain,
170            min_gain: Some(value.range.min),
171            max_gain: Some(value.range.max),
172            min_gain_step: Some(value.range.min_step),
173            ..Default::default()
174        }
175    }
176}
177
178#[derive(Debug, Clone, Copy, PartialEq)]
179pub struct GainRange {
180    pub min: f32,
181    pub max: f32,
182    pub min_step: f32,
183}
184
185#[derive(Debug, Clone, PartialEq)]
186pub struct Equalizer {
187    pub bands: Vec<EqualizerBand>,
188    pub supported_controls: Option<fhaudio_sigproc::EqualizerSupportedControls>,
189    pub can_disable_bands: Option<bool>,
190    pub min_frequency: u32,
191    pub max_frequency: u32,
192    pub max_q: Option<f32>,
193    pub min_gain_db: Option<f32>,
194    pub max_gain_db: Option<f32>,
195}
196
197impl TryFrom<fhaudio_sigproc::Equalizer> for Equalizer {
198    type Error = String;
199
200    fn try_from(value: fhaudio_sigproc::Equalizer) -> Result<Self, Self::Error> {
201        let bands: Vec<EqualizerBand> = value
202            .bands
203            .ok_or_else(|| "missing 'bands'".to_string())?
204            .into_iter()
205            .map(TryInto::try_into)
206            .collect::<Result<Vec<_>, _>>()?;
207        let min_frequency =
208            value.min_frequency.ok_or_else(|| "missing 'min_frequency'".to_string())?;
209        let max_frequency =
210            value.max_frequency.ok_or_else(|| "missing 'max_frequency'".to_string())?;
211        Ok(Self {
212            bands,
213            supported_controls: value.supported_controls,
214            can_disable_bands: value.can_disable_bands,
215            min_frequency,
216            max_frequency,
217            max_q: value.max_q,
218            min_gain_db: value.min_gain_db,
219            max_gain_db: value.max_gain_db,
220        })
221    }
222}
223
224impl From<Equalizer> for fhaudio_sigproc::Equalizer {
225    fn from(value: Equalizer) -> Self {
226        let bands: Vec<fhaudio_sigproc::EqualizerBand> =
227            value.bands.into_iter().map(Into::into).collect();
228        Self {
229            bands: Some(bands),
230            supported_controls: value.supported_controls,
231            can_disable_bands: value.can_disable_bands,
232            min_frequency: Some(value.min_frequency),
233            max_frequency: Some(value.max_frequency),
234            max_q: value.max_q,
235            min_gain_db: value.min_gain_db,
236            max_gain_db: value.max_gain_db,
237            ..Default::default()
238        }
239    }
240}
241
242#[derive(Debug, Clone, Copy, PartialEq, Eq)]
243pub struct EqualizerBand {
244    pub id: u64,
245}
246
247impl TryFrom<fhaudio_sigproc::EqualizerBand> for EqualizerBand {
248    type Error = String;
249
250    fn try_from(value: fhaudio_sigproc::EqualizerBand) -> Result<Self, Self::Error> {
251        let id = value.id.ok_or_else(|| "missing 'id'".to_string())?;
252        Ok(Self { id })
253    }
254}
255
256impl From<EqualizerBand> for fhaudio_sigproc::EqualizerBand {
257    fn from(value: EqualizerBand) -> Self {
258        Self { id: Some(value.id), ..Default::default() }
259    }
260}
261
262#[derive(Debug, Clone, PartialEq)]
263pub struct Dynamics {
264    pub bands: Vec<DynamicsBand>,
265    pub supported_controls: Option<fhaudio_sigproc::DynamicsSupportedControls>,
266}
267
268impl TryFrom<fhaudio_sigproc::Dynamics> for Dynamics {
269    type Error = String;
270
271    fn try_from(value: fhaudio_sigproc::Dynamics) -> Result<Self, Self::Error> {
272        let bands: Vec<DynamicsBand> = value
273            .bands
274            .ok_or_else(|| "missing 'bands'".to_string())?
275            .into_iter()
276            .map(TryInto::try_into)
277            .collect::<Result<Vec<_>, _>>()?;
278        Ok(Self { bands, supported_controls: value.supported_controls })
279    }
280}
281
282impl From<Dynamics> for fhaudio_sigproc::Dynamics {
283    fn from(value: Dynamics) -> Self {
284        let bands: Vec<fhaudio_sigproc::DynamicsBand> =
285            value.bands.into_iter().map(Into::into).collect();
286        Self {
287            bands: Some(bands),
288            supported_controls: value.supported_controls,
289            ..Default::default()
290        }
291    }
292}
293
294#[derive(Debug, Clone, Copy, PartialEq, Eq)]
295pub struct DynamicsBand {
296    pub id: u64,
297}
298
299impl TryFrom<fhaudio_sigproc::DynamicsBand> for DynamicsBand {
300    type Error = String;
301
302    fn try_from(value: fhaudio_sigproc::DynamicsBand) -> Result<Self, Self::Error> {
303        let id = value.id.ok_or_else(|| "missing 'id'".to_string())?;
304        Ok(Self { id })
305    }
306}
307
308impl From<DynamicsBand> for fhaudio_sigproc::DynamicsBand {
309    fn from(value: DynamicsBand) -> Self {
310        Self { id: Some(value.id), ..Default::default() }
311    }
312}
313
314#[derive(Debug, Clone, Copy, PartialEq)]
315pub struct DaiInterconnect {
316    pub plug_detect_capabilities: fhaudio_sigproc::PlugDetectCapabilities,
317}
318
319impl TryFrom<fhaudio_sigproc::DaiInterconnect> for DaiInterconnect {
320    type Error = String;
321
322    fn try_from(value: fhaudio_sigproc::DaiInterconnect) -> Result<Self, Self::Error> {
323        let plug_detect_capabilities = value
324            .plug_detect_capabilities
325            .ok_or_else(|| "missing 'plug_detect_capabilities'".to_string())?;
326        Ok(Self { plug_detect_capabilities })
327    }
328}
329
330impl From<DaiInterconnect> for fhaudio_sigproc::DaiInterconnect {
331    fn from(value: DaiInterconnect) -> Self {
332        Self {
333            plug_detect_capabilities: Some(value.plug_detect_capabilities),
334            ..Default::default()
335        }
336    }
337}
338
339#[derive(Debug, Clone, PartialEq)]
340pub struct ElementState {
341    pub type_specific: Option<TypeSpecificElementState>,
342    pub vendor_specific_data: Option<Vec<u8>>,
343    pub started: bool,
344    pub bypassed: Option<bool>,
345    pub turn_on_delay_ns: Option<zx_types::zx_duration_t>,
346    pub turn_off_delay_ns: Option<zx_types::zx_duration_t>,
347    pub processing_delay_ns: Option<zx_types::zx_duration_t>,
348}
349
350impl TryFrom<fhaudio_sigproc::ElementState> for ElementState {
351    type Error = String;
352
353    fn try_from(value: fhaudio_sigproc::ElementState) -> Result<Self, Self::Error> {
354        let type_specific = value.type_specific.map(TryInto::try_into).transpose()?;
355        let started = value.started.ok_or_else(|| "missing 'started'".to_string())?;
356        Ok(Self {
357            type_specific,
358            vendor_specific_data: value.vendor_specific_data,
359            started,
360            bypassed: value.bypassed,
361            turn_on_delay_ns: value.turn_on_delay,
362            turn_off_delay_ns: value.turn_off_delay,
363            processing_delay_ns: value.processing_delay,
364        })
365    }
366}
367
368impl From<ElementState> for fhaudio_sigproc::ElementState {
369    fn from(value: ElementState) -> Self {
370        Self {
371            type_specific: value.type_specific.map(Into::into),
372            vendor_specific_data: value.vendor_specific_data,
373            started: Some(value.started),
374            bypassed: value.bypassed,
375            turn_on_delay: value.turn_on_delay_ns,
376            turn_off_delay: value.turn_off_delay_ns,
377            processing_delay: value.processing_delay_ns,
378            ..Default::default()
379        }
380    }
381}
382
383#[derive(Debug, Clone, PartialEq)]
384pub enum TypeSpecificElementState {
385    VendorSpecific(VendorSpecificElementState),
386    Gain(GainElementState),
387    Equalizer(EqualizerElementState),
388    Dynamics(DynamicsElementState),
389    DaiInterconnect(DaiInterconnectElementState),
390}
391
392impl TryFrom<fhaudio_sigproc::TypeSpecificElementState> for TypeSpecificElementState {
393    type Error = String;
394
395    fn try_from(value: fhaudio_sigproc::TypeSpecificElementState) -> Result<Self, Self::Error> {
396        match value {
397            fhaudio_sigproc::TypeSpecificElementState::VendorSpecific(vendor_specific_state) => {
398                Ok(Self::VendorSpecific(vendor_specific_state.try_into()?))
399            }
400            fhaudio_sigproc::TypeSpecificElementState::Gain(gain_state) => {
401                Ok(Self::Gain(gain_state.try_into()?))
402            }
403            fhaudio_sigproc::TypeSpecificElementState::Equalizer(equalizer_state) => {
404                Ok(Self::Equalizer(equalizer_state.try_into()?))
405            }
406            fhaudio_sigproc::TypeSpecificElementState::Dynamics(dynamics_state) => {
407                Ok(Self::Dynamics(dynamics_state.try_into()?))
408            }
409            fhaudio_sigproc::TypeSpecificElementState::DaiInterconnect(dai_interconnect_state) => {
410                Ok(Self::DaiInterconnect(dai_interconnect_state.try_into()?))
411            }
412            _ => Err("unknown TypeSpecificElementStateState variant".to_string()),
413        }
414    }
415}
416
417impl From<TypeSpecificElementState> for fhaudio_sigproc::TypeSpecificElementState {
418    fn from(value: TypeSpecificElementState) -> Self {
419        match value {
420            TypeSpecificElementState::VendorSpecific(vendor_specific_state) => {
421                Self::VendorSpecific(vendor_specific_state.into())
422            }
423            TypeSpecificElementState::Gain(gain_state) => Self::Gain(gain_state.into()),
424            TypeSpecificElementState::Equalizer(equalizer_state) => {
425                Self::Equalizer(equalizer_state.into())
426            }
427            TypeSpecificElementState::Dynamics(dynamics_state) => {
428                Self::Dynamics(dynamics_state.into())
429            }
430            TypeSpecificElementState::DaiInterconnect(dai_interconnect_state) => {
431                Self::DaiInterconnect(dai_interconnect_state.into())
432            }
433        }
434    }
435}
436
437#[derive(Debug, Clone, Copy, PartialEq, Eq)]
438pub struct VendorSpecificElementState {}
439
440impl TryFrom<fhaudio_sigproc::VendorSpecificState> for VendorSpecificElementState {
441    type Error = String;
442
443    fn try_from(_value: fhaudio_sigproc::VendorSpecificState) -> Result<Self, Self::Error> {
444        Ok(Self {})
445    }
446}
447
448impl From<VendorSpecificElementState> for fhaudio_sigproc::VendorSpecificState {
449    fn from(_value: VendorSpecificElementState) -> Self {
450        Default::default()
451    }
452}
453
454#[derive(Debug, Clone, Copy, PartialEq)]
455pub struct GainElementState {
456    pub gain: f32,
457}
458
459impl TryFrom<fhaudio_sigproc::GainElementState> for GainElementState {
460    type Error = String;
461
462    fn try_from(value: fhaudio_sigproc::GainElementState) -> Result<Self, Self::Error> {
463        let gain = value.gain.ok_or_else(|| "missing 'gain'".to_string())?;
464        Ok(Self { gain })
465    }
466}
467
468impl From<GainElementState> for fhaudio_sigproc::GainElementState {
469    fn from(value: GainElementState) -> Self {
470        Self { gain: Some(value.gain), ..Default::default() }
471    }
472}
473
474#[derive(Debug, Clone, PartialEq)]
475pub struct EqualizerElementState {
476    pub band_states: Vec<EqualizerBandState>,
477}
478
479impl TryFrom<fhaudio_sigproc::EqualizerElementState> for EqualizerElementState {
480    type Error = String;
481
482    fn try_from(value: fhaudio_sigproc::EqualizerElementState) -> Result<Self, Self::Error> {
483        let band_states = value
484            .band_states
485            .ok_or_else(|| "missing 'band_states'".to_string())?
486            .into_iter()
487            .map(TryInto::try_into)
488            .collect::<Result<Vec<_>, _>>()?;
489        Ok(Self { band_states })
490    }
491}
492
493impl From<EqualizerElementState> for fhaudio_sigproc::EqualizerElementState {
494    fn from(value: EqualizerElementState) -> Self {
495        let band_states: Vec<fhaudio_sigproc::EqualizerBandState> =
496            value.band_states.into_iter().map(Into::into).collect();
497        Self { band_states: Some(band_states), ..Default::default() }
498    }
499}
500
501#[derive(Debug, Clone, PartialEq)]
502pub struct EqualizerBandState {
503    pub id: u64,
504    pub type_: Option<fhaudio_sigproc::EqualizerBandType>,
505    pub frequency: Option<u32>,
506    pub q: Option<f32>,
507    pub gain_db: Option<f32>,
508    pub enabled: Option<bool>,
509}
510
511impl TryFrom<fhaudio_sigproc::EqualizerBandState> for EqualizerBandState {
512    type Error = String;
513
514    fn try_from(value: fhaudio_sigproc::EqualizerBandState) -> Result<Self, Self::Error> {
515        let id = value.id.ok_or_else(|| "missing 'id'".to_string())?;
516        Ok(Self {
517            id,
518            type_: value.type_,
519            frequency: value.frequency,
520            q: value.q,
521            gain_db: value.gain_db,
522            enabled: value.enabled,
523        })
524    }
525}
526
527impl From<EqualizerBandState> for fhaudio_sigproc::EqualizerBandState {
528    fn from(value: EqualizerBandState) -> Self {
529        Self {
530            id: Some(value.id),
531            type_: value.type_,
532            frequency: value.frequency,
533            q: value.q,
534            gain_db: value.gain_db,
535            enabled: value.enabled,
536            ..Default::default()
537        }
538    }
539}
540
541#[derive(Debug, Clone, PartialEq)]
542pub struct DynamicsElementState {
543    pub band_states: Vec<DynamicsBandState>,
544}
545
546impl TryFrom<fhaudio_sigproc::DynamicsElementState> for DynamicsElementState {
547    type Error = String;
548
549    fn try_from(value: fhaudio_sigproc::DynamicsElementState) -> Result<Self, Self::Error> {
550        let band_states = value
551            .band_states
552            .ok_or_else(|| "missing 'band_states'".to_string())?
553            .into_iter()
554            .map(TryInto::try_into)
555            .collect::<Result<Vec<_>, _>>()?;
556        Ok(Self { band_states })
557    }
558}
559
560impl From<DynamicsElementState> for fhaudio_sigproc::DynamicsElementState {
561    fn from(value: DynamicsElementState) -> Self {
562        let band_states: Vec<fhaudio_sigproc::DynamicsBandState> =
563            value.band_states.into_iter().map(Into::into).collect();
564        Self { band_states: Some(band_states), ..Default::default() }
565    }
566}
567
568#[derive(Debug, Clone, PartialEq)]
569pub struct DynamicsBandState {
570    pub id: u64,
571    pub min_frequency: u32,
572    pub max_frequency: u32,
573    pub threshold_db: f32,
574    pub threshold_type: fhaudio_sigproc::ThresholdType,
575    pub ratio: f32,
576    pub knee_width_db: Option<f32>,
577    pub attack: Option<zx_types::zx_duration_t>,
578    pub release: Option<zx_types::zx_duration_t>,
579    pub output_gain_db: Option<f32>,
580    pub input_gain_db: Option<f32>,
581    pub level_type: Option<fhaudio_sigproc::LevelType>,
582    pub lookahead: Option<zx_types::zx_duration_t>,
583    pub linked_channels: Option<bool>,
584}
585
586impl TryFrom<fhaudio_sigproc::DynamicsBandState> for DynamicsBandState {
587    type Error = String;
588
589    fn try_from(value: fhaudio_sigproc::DynamicsBandState) -> Result<Self, Self::Error> {
590        let id = value.id.ok_or_else(|| "missing 'id'".to_string())?;
591        let min_frequency =
592            value.min_frequency.ok_or_else(|| "missing 'min_frequency'".to_string())?;
593        let max_frequency =
594            value.max_frequency.ok_or_else(|| "missing 'max_frequency'".to_string())?;
595        let threshold_db =
596            value.threshold_db.ok_or_else(|| "missing 'threshold_db'".to_string())?;
597        let threshold_type =
598            value.threshold_type.ok_or_else(|| "missing 'threshold_type'".to_string())?;
599        let ratio = value.ratio.ok_or_else(|| "missing 'ratio'".to_string())?;
600        Ok(Self {
601            id,
602            min_frequency,
603            max_frequency,
604            threshold_db,
605            threshold_type,
606            ratio,
607            knee_width_db: value.knee_width_db,
608            attack: value.attack,
609            release: value.release,
610            output_gain_db: value.output_gain_db,
611            input_gain_db: value.input_gain_db,
612            level_type: value.level_type,
613            lookahead: value.lookahead,
614            linked_channels: value.linked_channels,
615        })
616    }
617}
618
619impl From<DynamicsBandState> for fhaudio_sigproc::DynamicsBandState {
620    fn from(value: DynamicsBandState) -> Self {
621        Self {
622            id: Some(value.id),
623            min_frequency: Some(value.min_frequency),
624            max_frequency: Some(value.max_frequency),
625            threshold_db: Some(value.threshold_db),
626            threshold_type: Some(value.threshold_type),
627            ratio: Some(value.ratio),
628            knee_width_db: value.knee_width_db,
629            attack: value.attack,
630            release: value.release,
631            output_gain_db: value.output_gain_db,
632            input_gain_db: value.input_gain_db,
633            level_type: value.level_type,
634            lookahead: value.lookahead,
635            linked_channels: value.linked_channels,
636            ..Default::default()
637        }
638    }
639}
640
641#[derive(Debug, Clone, Copy, PartialEq, Eq)]
642pub struct PlugState {
643    pub plugged: bool,
644    pub plug_state_time: zx_types::zx_time_t,
645}
646
647impl TryFrom<fhaudio_sigproc::PlugState> for PlugState {
648    type Error = String;
649
650    fn try_from(value: fhaudio_sigproc::PlugState) -> Result<Self, Self::Error> {
651        let plugged = value.plugged.ok_or_else(|| "missing 'plugged'".to_string())?;
652        let plug_state_time =
653            value.plug_state_time.ok_or_else(|| "missing 'plug_state_time'".to_string())?;
654        Ok(Self { plugged, plug_state_time })
655    }
656}
657
658impl From<PlugState> for fhaudio_sigproc::PlugState {
659    fn from(value: PlugState) -> Self {
660        Self {
661            plugged: Some(value.plugged),
662            plug_state_time: Some(value.plug_state_time),
663            ..Default::default()
664        }
665    }
666}
667
668#[derive(Debug, Clone, PartialEq)]
669pub struct DaiInterconnectElementState {
670    pub plug_state: PlugState,
671    pub external_delay_ns: Option<zx_types::zx_duration_t>,
672}
673
674impl TryFrom<fhaudio_sigproc::DaiInterconnectElementState> for DaiInterconnectElementState {
675    type Error = String;
676
677    fn try_from(value: fhaudio_sigproc::DaiInterconnectElementState) -> Result<Self, Self::Error> {
678        let plug_state: PlugState =
679            value.plug_state.ok_or_else(|| "missing 'plug_state'".to_string())?.try_into()?;
680        Ok(Self { plug_state, external_delay_ns: value.external_delay })
681    }
682}
683
684impl From<DaiInterconnectElementState> for fhaudio_sigproc::DaiInterconnectElementState {
685    fn from(value: DaiInterconnectElementState) -> Self {
686        Self {
687            plug_state: Some(value.plug_state.into()),
688            external_delay: value.external_delay_ns,
689            ..Default::default()
690        }
691    }
692}