Skip to main content

midi2/detail/
encode_7bit.rs

1use ux::{u14, u21, u28, u7};
2
3pub trait Byte: Copy {
4    fn to_u8(self) -> u8;
5    fn from_u8(v: u8) -> Self;
6}
7
8impl Byte for u7 {
9    fn to_u8(self) -> u8 {
10        self.into()
11    }
12    fn from_u8(v: u8) -> Self {
13        u7::new(v & 0x7F)
14    }
15}
16
17impl Byte for u8 {
18    fn from_u8(v: u8) -> Self {
19        v & 0x7F
20    }
21    fn to_u8(self) -> u8 {
22        self & 0x7F
23    }
24}
25
26pub trait Encode7Bit {
27    fn from_u7s<T: Byte>(u7s: &[T]) -> Self;
28    fn to_u7s<T: Byte>(&self, data: &mut [T]);
29}
30
31impl Encode7Bit for u28 {
32    fn to_u7s<T: Byte>(&self, data: &mut [T]) {
33        debug_assert!(data.len() == 4);
34
35        let v = u32::from(*self);
36
37        data[0] = T::from_u8(v as u8);
38        data[1] = T::from_u8((v >> 7) as u8);
39        data[2] = T::from_u8((v >> (7 * 2)) as u8);
40        data[3] = T::from_u8((v >> (7 * 3)) as u8);
41    }
42    fn from_u7s<T: Byte>(u7s: &[T]) -> Self {
43        debug_assert!(u7s.len() == 4);
44
45        let mut ret: u28 = Default::default();
46
47        ret |= u28::from(u7s[0].to_u8() & 0x7F);
48        ret |= u28::from(u7s[1].to_u8() & 0x7F) << 7;
49        ret |= u28::from(u7s[2].to_u8() & 0x7F) << (7 * 2);
50        ret |= u28::from(u7s[3].to_u8() & 0x7F) << (7 * 3);
51
52        ret
53    }
54}
55
56impl Encode7Bit for u21 {
57    fn to_u7s<T: Byte>(&self, data: &mut [T]) {
58        debug_assert!(data.len() == 3);
59
60        let v = u32::from(*self);
61
62        data[0] = T::from_u8(v as u8);
63        data[1] = T::from_u8((v >> 7) as u8);
64        data[2] = T::from_u8((v >> (7 * 2)) as u8);
65    }
66    fn from_u7s<T: Byte>(u7s: &[T]) -> Self {
67        debug_assert!(u7s.len() == 3);
68
69        let mut ret: u21 = Default::default();
70
71        ret |= u21::from(u7s[0].to_u8() & 0x7F);
72        ret |= u21::from(u7s[1].to_u8() & 0x7F) << 7;
73        ret |= u21::from(u7s[2].to_u8() & 0x7F) << (7 * 2);
74
75        ret
76    }
77}
78
79impl Encode7Bit for u14 {
80    fn to_u7s<T: Byte>(&self, data: &mut [T]) {
81        debug_assert!(data.len() == 2);
82
83        let v = u16::from(*self);
84
85        data[0] = T::from_u8(v as u8);
86        data[1] = T::from_u8((v >> 7) as u8);
87    }
88    fn from_u7s<T: Byte>(u7s: &[T]) -> Self {
89        debug_assert!(u7s.len() == 2);
90
91        let mut ret: u14 = Default::default();
92
93        ret |= u14::from(u7s[0].to_u8() & 0x7F);
94        ret |= u14::from(u7s[1].to_u8() & 0x7F) << 7;
95
96        ret
97    }
98}