rea_rs/
hardware_functions.rs1use std::mem::MaybeUninit;
2
3use log::debug;
4
5use crate::{
6 utils::{as_string, as_string_mut, make_c_string_buf},
7 HardwareSocket, Reaper, SampleAmount,
8};
9
10impl Reaper {
11 pub fn get_latency(&self) -> (SampleAmount, SampleAmount) {
15 unsafe {
16 let (mut input, mut output) =
17 (MaybeUninit::new(0), MaybeUninit::new(0));
18 self.low().GetInputOutputLatency(
19 input.as_mut_ptr(),
20 output.as_mut_ptr(),
21 );
22 (
23 SampleAmount::new(input.assume_init() as u32),
24 SampleAmount::new(output.assume_init() as u32),
25 )
26 }
27 }
28
29 pub fn get_approximate_samplerate(&self) -> u32 {
33 let secs_raw = self.low().GetOutputLatency();
34 let (_, samples) = self.get_latency();
35 debug!(
36 "latency in samples: {:?}, latency in seconds: {:?}",
37 samples, secs_raw
38 );
39 let rate = samples.get() as f64 / secs_raw;
40 rate as u32
41 }
42
43 pub fn audio_init(&self) {
45 self.low().Audio_Init()
46 }
47
48 pub fn midi_reinit(&self) {
50 self.low().midi_reinit()
51 }
52
53 pub fn audio_is_pre_buffer(&self) -> bool {
55 self.low().Audio_IsPreBuffer() != 0
56 }
57
58 pub fn audio_is_running(&self) -> bool {
60 self.low().Audio_IsRunning() != 0
61 }
62
63 pub fn get_n_audio_inputs(&self) -> usize {
64 self.low().GetNumAudioInputs() as usize
65 }
66
67 pub fn get_n_audio_outputs(&self) -> usize {
68 self.low().GetNumAudioOutputs() as usize
69 }
70
71 pub fn iter_audio_inputs(&self) -> AudioInputsIterator {
72 AudioInputsIterator::new(self.get_n_audio_inputs())
73 }
74
75 pub fn iter_audio_outputs(&self) -> AudioOutputsIterator {
76 AudioOutputsIterator::new(self.get_n_audio_outputs())
77 }
78
79 pub fn get_max_midi_inputs(&self) -> usize {
80 self.low().GetMaxMidiInputs() as usize
81 }
82
83 pub fn get_midi_input(&self, index: usize) -> Option<HardwareSocket> {
84 let size = 256;
85 let buf = make_c_string_buf(size).into_raw();
86 let status = unsafe {
87 self.low().GetMIDIInputName(index as i32, buf, size as i32)
88 };
89 match status {
90 false => None,
91 true => HardwareSocket::new(
92 index as u32,
93 as_string_mut(buf).expect("Can not convert name to String."),
94 )
95 .into(),
96 }
97 }
98
99 pub fn get_max_midi_outputs(&self) -> usize {
100 self.low().GetMaxMidiOutputs() as usize
101 }
102
103 pub fn get_midi_output(&self, index: usize) -> Option<HardwareSocket> {
104 let size = 256;
105 let buf = make_c_string_buf(size).into_raw();
106 let status = unsafe {
107 self.low().GetMIDIOutputName(index as i32, buf, size as i32)
108 };
109 match status {
110 false => None,
111 true => HardwareSocket::new(
112 index as u32,
113 as_string_mut(buf).expect("Can not convert name to String."),
114 )
115 .into(),
116 }
117 }
118
119 pub fn get_audio_input(&self, index: usize) -> Option<HardwareSocket> {
120 let result = self.low().GetInputChannelName(index as i32);
121 match as_string(result) {
122 Err(_) => None,
123 Ok(name) => {
124 if &name == "" {
125 return None;
126 }
127 HardwareSocket::new(index as u32, name).into()
128 }
129 }
130 }
131
132 pub fn get_audio_output(&self, index: usize) -> Option<HardwareSocket> {
133 let result = self.low().GetOutputChannelName(index as i32);
134 match as_string(result) {
135 Err(_) => None,
136 Ok(name) => {
137 if &name == "" {
138 return None;
139 }
140 HardwareSocket::new(index as u32, name).into()
141 }
142 }
143 }
144
145 pub fn get_n_midi_inputs(&self) -> usize {
146 self.low().GetNumMIDIInputs() as usize
147 }
148
149 pub fn get_n_midi_outputs(&self) -> usize {
150 self.low().GetNumMIDIOutputs() as usize
151 }
152
153 pub fn iter_midi_inputs(&self) -> MidiInputsIterator {
154 MidiInputsIterator::new(self.get_n_midi_inputs())
155 }
156
157 pub fn iter_midi_outputs(&self) -> MidiOutputsIterator {
158 MidiOutputsIterator::new(self.get_n_midi_outputs())
159 }
160}
161
162pub struct AudioInputsIterator {
163 index: usize,
164 amount: usize,
165}
166impl AudioInputsIterator {
167 pub fn new(num_inputs: usize) -> Self {
168 Self {
169 index: 0,
170 amount: num_inputs,
171 }
172 }
173}
174impl Iterator for AudioInputsIterator {
175 type Item = HardwareSocket;
176 fn next(&mut self) -> Option<Self::Item> {
177 if self.index >= self.amount {
178 return None;
179 }
180 self.index += 1;
181 Reaper::get().get_audio_input(self.index - 1)
182 }
183}
184
185pub struct AudioOutputsIterator {
186 index: usize,
187 amount: usize,
188}
189impl AudioOutputsIterator {
190 pub fn new(num_outputs: usize) -> Self {
191 Self {
192 index: 0,
193 amount: num_outputs,
194 }
195 }
196}
197impl Iterator for AudioOutputsIterator {
198 type Item = HardwareSocket;
199 fn next(&mut self) -> Option<Self::Item> {
200 if self.index >= self.amount {
201 return None;
202 }
203 self.index += 1;
204 Reaper::get().get_audio_output(self.index - 1)
205 }
206}
207
208pub struct MidiInputsIterator {
209 index: usize,
210 amount: usize,
211}
212impl MidiInputsIterator {
213 pub fn new(num_inputs: usize) -> Self {
214 Self {
215 index: 0,
216 amount: num_inputs,
217 }
218 }
219}
220impl Iterator for MidiInputsIterator {
221 type Item = HardwareSocket;
222 fn next(&mut self) -> Option<Self::Item> {
223 if self.index >= self.amount {
224 return None;
225 }
226 self.index += 1;
227 Reaper::get().get_midi_input(self.index - 1)
228 }
229}
230
231pub struct MidiOutputsIterator {
232 index: usize,
233 amount: usize,
234}
235impl MidiOutputsIterator {
236 pub fn new(num_outputs: usize) -> Self {
237 Self {
238 index: 0,
239 amount: num_outputs,
240 }
241 }
242}
243impl Iterator for MidiOutputsIterator {
244 type Item = HardwareSocket;
245 fn next(&mut self) -> Option<Self::Item> {
246 if self.index >= self.amount {
247 return None;
248 }
249 self.index += 1;
250 Reaper::get().get_midi_output(self.index - 1)
251 }
252}