sim_lib_audio_graph_core/
bridge.rs1use sim_lib_stream_core::{ClockDomain, DomainBridgeDescriptor};
2
3use crate::{PortDecl, PortDir, PortMedia, ProcessBlock, Processor};
4
5#[derive(Clone, Debug)]
11pub struct DomainBridgeProcessor {
12 descriptor: DomainBridgeDescriptor,
13 media: PortMedia,
14}
15
16impl DomainBridgeProcessor {
17 pub fn new(descriptor: DomainBridgeDescriptor, media: PortMedia) -> Self {
19 Self { descriptor, media }
20 }
21
22 pub fn resampler(input_hz: u32, output_hz: u32) -> sim_kernel::Result<Self> {
24 Ok(Self::new(
25 DomainBridgeDescriptor::resampler(input_hz, output_hz)?,
26 PortMedia::Audio,
27 ))
28 }
29
30 pub fn jitter_buffer(max_late_packets: u32) -> Self {
32 Self::new(
33 DomainBridgeDescriptor::jitter_buffer(max_late_packets),
34 PortMedia::Event,
35 )
36 }
37
38 pub fn latency_comp_delay(frames: u64) -> Self {
40 Self::new(
41 DomainBridgeDescriptor::latency_comp_delay(frames),
42 PortMedia::Audio,
43 )
44 }
45
46 pub fn event_rate_gate(input_domain: ClockDomain) -> sim_kernel::Result<Self> {
48 Ok(Self::new(
49 DomainBridgeDescriptor::event_rate_gate(input_domain)?,
50 PortMedia::Event,
51 ))
52 }
53
54 pub fn control_rate_gate(input_domain: ClockDomain) -> sim_kernel::Result<Self> {
56 Ok(Self::new(
57 DomainBridgeDescriptor::event_rate_gate(input_domain)?,
58 PortMedia::Control,
59 ))
60 }
61
62 pub fn bridge_descriptor(&self) -> &DomainBridgeDescriptor {
64 &self.descriptor
65 }
66
67 pub fn media(&self) -> PortMedia {
69 self.media
70 }
71}
72
73impl Processor for DomainBridgeProcessor {
74 fn prepare(&mut self, _cfg: crate::PrepareConfig) {}
75
76 fn reset(&mut self) {}
77
78 fn process(&mut self, block: &mut ProcessBlock<'_>) {
79 match self.media {
80 PortMedia::Audio => copy_audio(block),
81 PortMedia::Control | PortMedia::Event => {
82 for event in block.in_events {
83 let _ = block.out_events.push(*event);
84 }
85 }
86 }
87 }
88
89 fn clock_domain(&self) -> ClockDomain {
90 self.descriptor.output_rate().clock_domain()
91 }
92
93 fn latency_class(&self) -> sim_lib_stream_core::LatencyClass {
94 self.descriptor.output_rate().latency_class()
95 }
96
97 fn realtime_pin(&self) -> bool {
98 false
99 }
100
101 fn ports(&self, in_channels: u16, out_channels: u16) -> Vec<PortDecl> {
102 let mut ports = Vec::new();
103 if in_channels > 0 {
104 ports.push(
105 PortDecl::new("in", self.media, PortDir::In, in_channels)
106 .with_rate_contract(self.descriptor.input_rate()),
107 );
108 }
109 if out_channels > 0 {
110 ports.push(
111 PortDecl::new("out", self.media, PortDir::Out, out_channels)
112 .with_rate_contract(self.descriptor.output_rate()),
113 );
114 }
115 ports
116 }
117
118 fn tail_frames(&self) -> u64 {
119 self.descriptor.latency().frame_count()
120 }
121}
122
123fn copy_audio(block: &mut ProcessBlock<'_>) {
124 let frames = block.frames as usize;
125 for (input, output) in block.in_audio.iter().zip(block.out_audio.iter_mut()) {
126 output[..frames].copy_from_slice(&input[..frames]);
127 }
128}