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