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
use device::DeviceInfo;
use ffi;
use io::{InputPort, OutputPort};
use std::os::raw::c_int;
use types::{Error, PortMidiDeviceId, Result};
pub struct PortMidi {
device_count: u32,
}
impl PortMidi {
pub fn new() -> Result<Self> {
Result::from(unsafe { ffi::Pm_Initialize() })?;
let device_count = unsafe { ffi::Pm_CountDevices() };
if device_count >= 0 {
Ok(PortMidi {
device_count: device_count as u32,
})
} else {
Err(Error::Invalid)
}
}
pub fn device_count(&self) -> PortMidiDeviceId {
self.device_count as c_int
}
pub fn default_input_device_id(&self) -> Result<PortMidiDeviceId> {
match unsafe { ffi::Pm_GetDefaultInputDeviceID() } {
ffi::PM_NO_DEVICE => Err(Error::NoDefaultDevice),
id => Ok(id),
}
}
pub fn default_output_device_id(&self) -> Result<PortMidiDeviceId> {
match unsafe { ffi::Pm_GetDefaultOutputDeviceID() } {
ffi::PM_NO_DEVICE => Err(Error::NoDefaultDevice),
id => Ok(id),
}
}
pub fn device(&self, id: PortMidiDeviceId) -> Result<DeviceInfo> {
DeviceInfo::new(id)
}
pub fn devices(&self) -> Result<Vec<DeviceInfo>> {
let mut devices = Vec::with_capacity(self.device_count() as usize);
for res in (0..self.device_count()).map(|id| self.device(id)) {
match res {
Ok(device) => devices.push(device),
Err(err) => return Err(err),
}
}
Ok(devices)
}
pub fn default_input_port(&self, buffer_size: usize) -> Result<InputPort> {
let info = self
.default_input_device_id()
.and_then(|id| self.device(id))?;
InputPort::new(self, info, buffer_size)
}
pub fn input_port(&self, device: DeviceInfo, buffer_size: usize) -> Result<InputPort> {
if device.is_input() {
InputPort::new(self, device, buffer_size)
} else {
Err(Error::NotAnInputDevice)
}
}
pub fn default_output_port(&self, buffer_size: usize) -> Result<OutputPort> {
let info = self
.default_output_device_id()
.and_then(|id| self.device(id))?;
OutputPort::new(self, info, buffer_size)
}
pub fn output_port(&self, device: DeviceInfo, buffer_size: usize) -> Result<OutputPort> {
if device.is_output() {
OutputPort::new(self, device, buffer_size)
} else {
Err(Error::NotAnOutputDevice)
}
}
}
impl Drop for PortMidi {
fn drop(&mut self) {
Result::from(unsafe { ffi::Pm_Terminate() })
.map_err(|err| println!("Could not terminate: {}", err))
.unwrap();
}
}