1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use std::error::Error;
use std::{thread, time};
use crate::proc::SceneNum;
use crate::backend::*;
use super::{RunArguments, Runner};
pub enum BackendType {
Null,
#[cfg(feature = "alsa")]
Alsa,
}
pub struct ConfigArguments<'a> {
pub backend: BackendType,
pub client_name: &'a str,
pub in_ports: &'a [[&'a str; 2]],
pub out_ports: &'a [[&'a str; 2]],
pub data_offset: u8,
pub scene_offset: SceneNum,
pub initial_scene: SceneNum,
pub start_delay: f32,
}
impl ConfigArguments<'_> {
pub fn default() -> ConfigArguments<'static> {
ConfigArguments {
#[cfg(feature = "alsa")]
backend: BackendType::Alsa,
#[cfg(not(feature = "alsa"))]
backend: BackendType::Null,
client_name: "RMididings",
in_ports: &[],
out_ports: &[],
data_offset: 1,
scene_offset: 1,
initial_scene: 0,
start_delay: 0.0,
}
}
}
pub struct RMididings<'a> {
backends: Vec<Box::<dyn Backend<'a> + 'a>>,
port_offset: u8,
channel_offset: u8,
scene_offset: u8,
initial_scene_num: SceneNum,
}
impl<'a, 'cfgargs: 'a> RMididings<'a> {
pub fn new() -> Result<Self, Box<dyn Error>> {
Ok(Self {
backends: vec![],
port_offset: 1,
channel_offset: 1,
scene_offset: 1,
initial_scene_num: 0,
})
}
pub fn config(&mut self, args: ConfigArguments<'cfgargs>) -> Result<(), Box<dyn Error>> {
self.backends = vec![match args.backend {
BackendType::Null => Box::new(NullBackend::new()?),
#[cfg(feature = "alsa")]
BackendType::Alsa => Box::new(AlsaBackend::new()?),
},
#[cfg(feature = "osc")]
Box::new(OscBackend::new()?),
];
for b in self.backends.iter_mut() { b.set_client_name(args.client_name)?; }
for (port_id, [name, connect]) in args.in_ports.iter().enumerate() {
for backend in self.backends.iter_mut() {
if backend.create_in_port(port_id, name)? {
backend.connect_in_port(port_id, connect)?;
break;
}
}
}
for (port_id, [name, connect]) in args.out_ports.iter().enumerate() {
for backend in self.backends.iter_mut() {
if backend.create_out_port(port_id, name)? {
backend.connect_out_port(port_id, connect)?;
break;
}
}
}
if args.start_delay > 0.0 {
thread::sleep(time::Duration::from_secs_f32(args.start_delay));
}
self.initial_scene_num = args.initial_scene;
self.port_offset = args.data_offset;
self.channel_offset = args.data_offset;
self.scene_offset = args.scene_offset;
Ok(())
}
pub fn run(&mut self, args: RunArguments<'_>) -> Result<(), Box<dyn Error>> {
Runner::new(
args,
&mut self.backends,
self.port_offset,
self.channel_offset,
self.scene_offset,
self.initial_scene_num,
).run()
}
}