midi_msg/system_exclusive/
controller_destination.rs1use crate::message::Channel;
2use crate::parse_error::*;
3use crate::util::*;
4use alloc::vec::Vec;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct ControllerDestination {
12 pub channel: Channel,
13 pub param_ranges: Vec<(ControlledParameter, u8)>,
15}
16
17impl ControllerDestination {
18 pub(crate) fn extend_midi(&self, v: &mut Vec<u8>) {
19 v.push(self.channel as u8);
20 for (p, r) in self.param_ranges.iter() {
21 v.push(*p as u8);
22 push_u7(*r, v);
23 }
24 }
25
26 #[allow(dead_code)]
27 pub(crate) fn from_midi(_m: &[u8]) -> Result<(Self, usize), ParseError> {
28 Err(ParseError::NotImplemented("ControllerDestination"))
29 }
30}
31
32#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct ControlChangeControllerDestination {
38 pub channel: Channel,
39 pub control_number: u8,
42 pub param_ranges: Vec<(ControlledParameter, u8)>,
44}
45
46impl ControlChangeControllerDestination {
47 pub(crate) fn extend_midi(&self, v: &mut Vec<u8>) {
48 v.push(self.channel as u8);
49 if self.control_number < 0x40 {
50 v.push(self.control_number.clamp(0x01, 0x1F));
51 } else {
52 v.push(self.control_number.clamp(0x40, 0x5F));
53 }
54 for (p, r) in self.param_ranges.iter() {
55 v.push(*p as u8);
56 push_u7(*r, v);
57 }
58 }
59
60 #[allow(dead_code)]
61 pub(crate) fn from_midi(_m: &[u8]) -> Result<(Self, usize), ParseError> {
62 Err(ParseError::NotImplemented(
63 "ControlChangeControllerDestination",
64 ))
65 }
66}
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
70pub enum ControlledParameter {
71 PitchControl = 0,
72 FilterCutoffControl = 1,
73 AmplitudeControl = 2,
74 LFOPitchDepth = 3,
75 LFOFilterDepth = 4,
76 LFOAmplitudeDepth = 5,
77}
78
79#[cfg(test)]
80mod tests {
81 use crate::*;
82 use alloc::vec;
83
84 #[test]
85 fn serialize_controller_destination() {
86 assert_eq!(
87 MidiMsg::SystemExclusive {
88 msg: SystemExclusiveMsg::UniversalRealTime {
89 device: DeviceID::AllCall,
90 msg: UniversalRealTimeMsg::ControlChangeControllerDestination(
91 ControlChangeControllerDestination {
92 channel: Channel::Ch2,
93 control_number: 0x50,
94 param_ranges: vec![
95 (ControlledParameter::PitchControl, 0x42),
96 (ControlledParameter::FilterCutoffControl, 0x60)
97 ]
98 }
99 ),
100 }
101 }
102 .to_midi(),
103 vec![
104 0xF0, 0x7F, 0x7F, 0x9, 0x3, 0x1, 0x50, 0x0, 0x42, 0x1, 0x60, 0xF7
107 ]
108 );
109 }
110}