Skip to main content

midi2/
channel_voice2.rs

1#![doc = include_str!("channel_voice2/README.md")]
2
3mod assignable_controller;
4mod assignable_per_note_controller;
5mod attribute;
6mod channel_pitch_bend;
7mod channel_pressure;
8mod control_change;
9mod controller;
10mod key_pressure;
11mod note_off;
12mod note_on;
13mod packet;
14mod per_note_management;
15mod per_note_pitch_bend;
16mod program_change;
17mod registered_controller;
18mod registered_per_note_controller;
19mod relative_assignable_controller;
20mod relative_registered_controller;
21
22pub use assignable_controller::*;
23pub use assignable_per_note_controller::*;
24pub use attribute::Attribute as NoteAttribute;
25pub use channel_pitch_bend::*;
26pub use channel_pressure::*;
27pub use control_change::*;
28pub use controller::Controller;
29pub use key_pressure::*;
30pub use note_off::*;
31pub use note_on::*;
32pub use packet::Packet;
33pub use per_note_management::*;
34pub use per_note_pitch_bend::*;
35pub use program_change::*;
36pub use registered_controller::*;
37pub use registered_per_note_controller::*;
38pub use relative_assignable_controller::*;
39pub use relative_registered_controller::*;
40
41pub(crate) const UMP_MESSAGE_TYPE: u8 = 0x4;
42
43#[derive(
44    derive_more::From,
45    midi2_proc::Data,
46    midi2_proc::Packets,
47    midi2_proc::Channeled,
48    midi2_proc::Grouped,
49    midi2_proc::RebufferFrom,
50    midi2_proc::RebufferFromArray,
51    midi2_proc::TryRebufferFrom,
52    Clone,
53    Copy,
54    Debug,
55    PartialEq,
56    Eq,
57)]
58pub enum ChannelVoice2<B: crate::buffer::Ump> {
59    AssignableController(assignable_controller::AssignableController<B>),
60    AssignablePerNoteController(assignable_per_note_controller::AssignablePerNoteController<B>),
61    ChannelPitchBend(channel_pitch_bend::ChannelPitchBend<B>),
62    ChannelPressure(channel_pressure::ChannelPressure<B>),
63    ControlChange(control_change::ControlChange<B>),
64    KeyPressure(key_pressure::KeyPressure<B>),
65    NoteOff(note_off::NoteOff<B>),
66    NoteOn(note_on::NoteOn<B>),
67    PerNoteManagement(per_note_management::PerNoteManagement<B>),
68    PerNotePitchBend(per_note_pitch_bend::PerNotePitchBend<B>),
69    ProgramChange(program_change::ProgramChange<B>),
70    RegisteredController(registered_controller::RegisteredController<B>),
71    RegisteredPerNoteController(registered_per_note_controller::RegisteredPerNoteController<B>),
72    RelativeAssignableController(relative_assignable_controller::RelativeAssignableController<B>),
73    RelativeRegisteredController(relative_registered_controller::RelativeRegisteredController<B>),
74}
75
76impl<'a> TryFrom<&'a [u32]> for ChannelVoice2<&'a [u32]> {
77    type Error = crate::error::InvalidData;
78    fn try_from(buffer: &'a [u32]) -> Result<Self, Self::Error> {
79        if buffer.is_empty() {
80            return Err(crate::error::InvalidData(
81                crate::detail::common_err_strings::ERR_SLICE_TOO_SHORT,
82            ));
83        };
84
85        use crate::detail::BitOps;
86
87        Ok(match u8::from(buffer[0].nibble(2)) {
88            assignable_controller::STATUS => {
89                assignable_controller::AssignableController::try_from(buffer)?.into()
90            }
91            assignable_per_note_controller::STATUS => {
92                assignable_per_note_controller::AssignablePerNoteController::try_from(buffer)?
93                    .into()
94            }
95            channel_pitch_bend::STATUS => {
96                channel_pitch_bend::ChannelPitchBend::try_from(buffer)?.into()
97            }
98            channel_pressure::STATUS => channel_pressure::ChannelPressure::try_from(buffer)?.into(),
99            control_change::STATUS => control_change::ControlChange::try_from(buffer)?.into(),
100            key_pressure::STATUS => key_pressure::KeyPressure::try_from(buffer)?.into(),
101            note_off::STATUS => note_off::NoteOff::try_from(buffer)?.into(),
102            note_on::STATUS => note_on::NoteOn::try_from(buffer)?.into(),
103            per_note_management::STATUS => {
104                per_note_management::PerNoteManagement::try_from(buffer)?.into()
105            }
106            per_note_pitch_bend::STATUS => {
107                per_note_pitch_bend::PerNotePitchBend::try_from(buffer)?.into()
108            }
109            program_change::STATUS => program_change::ProgramChange::try_from(buffer)?.into(),
110            registered_controller::STATUS => {
111                registered_controller::RegisteredController::try_from(buffer)?.into()
112            }
113            registered_per_note_controller::STATUS => {
114                registered_per_note_controller::RegisteredPerNoteController::try_from(buffer)?
115                    .into()
116            }
117            relative_assignable_controller::STATUS => {
118                relative_assignable_controller::RelativeAssignableController::try_from(buffer)?
119                    .into()
120            }
121            relative_registered_controller::STATUS => {
122                relative_registered_controller::RelativeRegisteredController::try_from(buffer)?
123                    .into()
124            }
125            _ => Err(crate::error::InvalidData(
126                "Unknown midi2 channel voice status",
127            ))?,
128        })
129    }
130}
131
132#[cfg(test)]
133mod test {
134    use super::*;
135    use pretty_assertions::assert_eq;
136
137    #[test]
138    fn channel() {
139        use crate::traits::Channeled;
140        use crate::ux::u4;
141
142        assert_eq!(
143            ChannelVoice2::try_from(&[0x4BAC_5900, 0xC0B83064][..])
144                .unwrap()
145                .channel(),
146            u4::new(0xC),
147        );
148    }
149
150    #[test]
151    fn packets() {
152        use crate::Packets;
153
154        let message = ChannelVoice2::try_from(&[0x4BAC_5900, 0xC0B83064][..]).unwrap();
155        let mut packets = message.packets();
156        assert_eq!(&*packets.next().unwrap(), &[0x4BAC_5900, 0xC0B83064][..]);
157        assert_eq!(packets.next(), None);
158    }
159
160    #[test]
161    fn rebuffer_from_array() {
162        use crate::ArrayRebufferFrom;
163
164        let message = ChannelVoice2::try_from(&[0x4BAC_5900, 0xC0B83064][..]).unwrap();
165        let _ = ChannelVoice2::<[u32; 2]>::array_rebuffer_from(message);
166    }
167}