Skip to main content

maolan_engine/hw/
traits.rs

1use crate::message::HwMidiEvent;
2
3pub trait HwWorkerDriver {
4    fn cycle_samples(&self) -> usize;
5    fn sample_rate(&self) -> i32;
6    fn request_stop(&mut self) {}
7    fn close_fds(&mut self) {}
8    fn set_playing(&mut self, _playing: bool) {}
9    fn set_output_gain_balance(&mut self, _gain: f32, _balance: f32) {}
10    fn run_cycle_for_worker(&mut self) -> Result<(), String>;
11    fn run_assist_step_for_worker(&mut self) -> Result<bool, String>;
12
13    /// Give the driver the render-plan slot so its RT cycle can read/write
14    /// plan arena buffers instead of the legacy port buffers. Drivers that
15    /// do not support plan-based I/O yet ignore it.
16    fn set_plan_slot(&mut self, _slot: std::sync::Arc<crate::render_plan::PlanSlot>) {}
17
18    /// File descriptors for async I/O via kqueue/AsyncFd.
19    /// When both return `Some`, the HW worker uses an async select loop
20    /// instead of the blocking assist thread.
21    #[cfg(unix)]
22    fn capture_fd(&self) -> Option<std::os::fd::RawFd> {
23        None
24    }
25    #[cfg(unix)]
26    fn playback_fd(&self) -> Option<std::os::fd::RawFd> {
27        None
28    }
29}
30
31pub trait HwMidiHub {
32    fn open_input(&mut self, _device: &str) -> Result<(), String> {
33        Err("Hardware MIDI input devices are not supported by this backend".to_string())
34    }
35    fn open_output(&mut self, _device: &str) -> Result<(), String> {
36        Err("Hardware MIDI output devices are not supported by this backend".to_string())
37    }
38    fn close_all(&mut self) {}
39    fn read_events_into(&mut self, out: &mut Vec<HwMidiEvent>);
40    fn read_events_blocking_into(&mut self, out: &mut Vec<HwMidiEvent>) {
41        self.read_events_into(out);
42    }
43    fn wait_ready_blocking(&mut self) -> Option<Vec<i32>> {
44        None
45    }
46    fn read_events_for_fds(&mut self, _ready_fds: &[i32], out: &mut Vec<HwMidiEvent>) {
47        self.read_events_into(out);
48    }
49    fn wake_input_waiter(&mut self) {}
50    fn close_input_waiter(&mut self) {}
51    fn write_events(&mut self, events: &[HwMidiEvent]);
52}
53
54pub trait HwDevice {
55    fn input_channels(&self) -> usize;
56    fn output_channels(&self) -> usize;
57    fn sample_rate(&self) -> i32;
58    fn latency_ranges(&self) -> ((usize, usize), (usize, usize));
59}
60
61#[macro_export]
62macro_rules! impl_hw_worker_traits_for_driver {
63    ($driver:ty) => {
64        impl $crate::hw::traits::HwWorkerDriver for $driver {
65            fn cycle_samples(&self) -> usize {
66                self.cycle_samples()
67            }
68
69            fn sample_rate(&self) -> i32 {
70                self.sample_rate()
71            }
72
73            fn close_fds(&mut self) {
74                self.close_fds()
75            }
76
77            fn set_playing(&mut self, playing: bool) {
78                self.set_playing(playing)
79            }
80
81            fn set_output_gain_balance(&mut self, gain: f32, balance: f32) {
82                self.set_output_gain_balance(gain, balance)
83            }
84
85            fn run_cycle_for_worker(&mut self) -> Result<(), String> {
86                self.channel().run_cycle().map_err(|e| e.to_string())
87            }
88
89            fn run_assist_step_for_worker(&mut self) -> Result<bool, String> {
90                self.channel().run_assist_step().map_err(|e| e.to_string())
91            }
92        }
93    };
94}
95
96#[macro_export]
97macro_rules! impl_hw_device_for_driver {
98    ($driver:ty) => {
99        impl $crate::hw::traits::HwDevice for $driver {
100            fn input_channels(&self) -> usize {
101                self.input_channels()
102            }
103
104            fn output_channels(&self) -> usize {
105                self.output_channels()
106            }
107
108            fn sample_rate(&self) -> i32 {
109                self.sample_rate()
110            }
111
112            fn latency_ranges(&self) -> ((usize, usize), (usize, usize)) {
113                self.latency_ranges()
114            }
115        }
116    };
117}
118
119#[macro_export]
120macro_rules! impl_hw_midi_hub_traits {
121    ($hub:ty) => {
122        impl $crate::hw::traits::HwMidiHub for $hub {
123            fn open_input(&mut self, device: &str) -> Result<(), String> {
124                <$hub>::open_input(self, device)
125            }
126
127            fn open_output(&mut self, device: &str) -> Result<(), String> {
128                <$hub>::open_output(self, device)
129            }
130
131            fn close_all(&mut self) {
132                <$hub>::close_all(self);
133            }
134
135            fn read_events_into(&mut self, out: &mut Vec<$crate::message::HwMidiEvent>) {
136                <$hub>::read_events_into(self, out);
137            }
138
139            fn read_events_blocking_into(&mut self, out: &mut Vec<$crate::message::HwMidiEvent>) {
140                <$hub>::read_events_blocking_into(self, out);
141            }
142
143            fn wait_ready_blocking(&mut self) -> Option<Vec<i32>> {
144                <$hub>::wait_ready_blocking(self)
145            }
146
147            fn read_events_for_fds(
148                &mut self,
149                ready_fds: &[i32],
150                out: &mut Vec<$crate::message::HwMidiEvent>,
151            ) {
152                <$hub>::read_events_for_fds(self, ready_fds, out)
153            }
154
155            fn wake_input_waiter(&mut self) {
156                <$hub>::wake_input_waiter(self);
157            }
158
159            fn close_input_waiter(&mut self) {
160                <$hub>::close_input_waiter(self);
161            }
162
163            fn write_events(&mut self, events: &[$crate::message::HwMidiEvent]) {
164                <$hub>::write_events(self, events);
165            }
166        }
167    };
168}