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 run_cycle_for_worker(&mut self) -> Result<(), String>;
8    fn run_assist_step_for_worker(&mut self) -> Result<bool, String>;
9
10    /// File descriptors for async I/O via kqueue/AsyncFd.
11    /// When both return `Some`, the HW worker uses an async select loop
12    /// instead of the blocking assist thread.
13    #[cfg(unix)]
14    fn capture_fd(&self) -> Option<std::os::fd::RawFd> {
15        None
16    }
17    #[cfg(unix)]
18    fn playback_fd(&self) -> Option<std::os::fd::RawFd> {
19        None
20    }
21}
22
23pub trait HwMidiHub {
24    fn read_events_into(&mut self, out: &mut Vec<HwMidiEvent>);
25    fn read_events_blocking_into(&mut self, out: &mut Vec<HwMidiEvent>) {
26        self.read_events_into(out);
27    }
28    fn wait_ready_blocking(&mut self) -> Option<Vec<i32>> {
29        None
30    }
31    fn read_events_for_fds(&mut self, _ready_fds: &[i32], out: &mut Vec<HwMidiEvent>) {
32        self.read_events_into(out);
33    }
34    fn wake_input_waiter(&mut self) {}
35    fn close_input_waiter(&mut self) {}
36    fn write_events(&mut self, events: &[HwMidiEvent]);
37}
38
39pub trait HwDevice {
40    fn input_channels(&self) -> usize;
41    fn output_channels(&self) -> usize;
42    fn sample_rate(&self) -> i32;
43    fn latency_ranges(&self) -> ((usize, usize), (usize, usize));
44}
45
46#[macro_export]
47macro_rules! impl_hw_worker_traits_for_driver {
48    ($driver:ty) => {
49        impl $crate::hw::traits::HwWorkerDriver for $driver {
50            fn cycle_samples(&self) -> usize {
51                self.cycle_samples()
52            }
53
54            fn sample_rate(&self) -> i32 {
55                self.sample_rate()
56            }
57
58            fn run_cycle_for_worker(&mut self) -> Result<(), String> {
59                self.channel().run_cycle().map_err(|e| e.to_string())
60            }
61
62            fn run_assist_step_for_worker(&mut self) -> Result<bool, String> {
63                self.channel().run_assist_step().map_err(|e| e.to_string())
64            }
65        }
66    };
67}
68
69#[macro_export]
70macro_rules! impl_hw_device_for_driver {
71    ($driver:ty) => {
72        impl $crate::hw::traits::HwDevice for $driver {
73            fn input_channels(&self) -> usize {
74                self.input_channels()
75            }
76
77            fn output_channels(&self) -> usize {
78                self.output_channels()
79            }
80
81            fn sample_rate(&self) -> i32 {
82                self.sample_rate()
83            }
84
85            fn latency_ranges(&self) -> ((usize, usize), (usize, usize)) {
86                self.latency_ranges()
87            }
88        }
89    };
90}
91
92#[macro_export]
93macro_rules! impl_hw_midi_hub_traits {
94    ($hub:ty) => {
95        impl $crate::hw::traits::HwMidiHub for $hub {
96            fn read_events_into(&mut self, out: &mut Vec<$crate::message::HwMidiEvent>) {
97                <$hub>::read_events_into(self, out);
98            }
99
100            fn read_events_blocking_into(&mut self, out: &mut Vec<$crate::message::HwMidiEvent>) {
101                <$hub>::read_events_blocking_into(self, out);
102            }
103
104            fn wait_ready_blocking(&mut self) -> Option<Vec<i32>> {
105                <$hub>::wait_ready_blocking(self)
106            }
107
108            fn read_events_for_fds(
109                &mut self,
110                ready_fds: &[i32],
111                out: &mut Vec<$crate::message::HwMidiEvent>,
112            ) {
113                <$hub>::read_events_for_fds(self, ready_fds, out)
114            }
115
116            fn wake_input_waiter(&mut self) {
117                <$hub>::wake_input_waiter(self);
118            }
119
120            fn close_input_waiter(&mut self) {
121                <$hub>::close_input_waiter(self);
122            }
123
124            fn write_events(&mut self, events: &[$crate::message::HwMidiEvent]) {
125                <$hub>::write_events(self, events);
126            }
127        }
128    };
129}