ksynth/k5000/
harmonic.rs

1//! Data models for the harmonic levels and envelopes.
2//!
3
4use bit::BitIndex;
5
6use crate::{
7    SystemExclusiveData,
8    ParseError
9};
10use crate::k5000::morf::Loop;
11use crate::k5000::addkit::HARMONIC_COUNT;
12use crate::k5000::{
13    EnvelopeRate,
14    HarmonicEnvelopeLevel
15};
16
17pub type Level = u8;
18
19/// Harmonic levels (soft and loud).
20pub struct Levels {
21    pub soft: [Level; HARMONIC_COUNT],
22    pub loud: [Level; HARMONIC_COUNT],
23}
24
25impl Default for Levels {
26    fn default() -> Self {
27        Levels {
28            soft: [0; HARMONIC_COUNT],
29            loud: [0; HARMONIC_COUNT],
30        }
31    }
32}
33
34impl SystemExclusiveData for Levels {
35    fn from_bytes(data: &[u8]) -> Result<Self, ParseError> {
36        let mut offset = 0;
37
38        let mut soft: [u8; HARMONIC_COUNT] = [0; HARMONIC_COUNT];
39        for i in 0..HARMONIC_COUNT {
40            soft[i] = data[offset];
41            offset += 1;
42        }
43
44        let mut loud: [u8; HARMONIC_COUNT] = [0; HARMONIC_COUNT];
45        for i in 0..HARMONIC_COUNT {
46            loud[i] = data[offset];
47            offset += 1;
48        }
49
50        Ok(Levels { soft, loud })
51    }
52
53    fn to_bytes(&self) -> Vec<u8> {
54        let mut result: Vec<u8> = Vec::new();
55        result.extend(self.soft.to_vec());
56        result.extend(self.loud.to_vec());
57        result
58    }
59
60    fn data_size() -> usize {
61        2 * HARMONIC_COUNT
62    }
63}
64
65/// Harmonic envelope segment.
66#[derive(Debug, Copy, Clone)]
67pub struct EnvelopeSegment {
68    pub rate: EnvelopeRate,
69    pub level: HarmonicEnvelopeLevel,
70}
71
72impl Default for EnvelopeSegment {
73    fn default() -> Self {
74        EnvelopeSegment {
75            rate: EnvelopeRate::new(0),
76            level: HarmonicEnvelopeLevel::new(0),
77        }
78    }
79}
80
81impl SystemExclusiveData for EnvelopeSegment {
82    fn from_bytes(data: &[u8]) -> Result<Self, ParseError> {
83        Ok(EnvelopeSegment {
84            rate: EnvelopeRate::from(data[0]),
85            level: HarmonicEnvelopeLevel::from(data[1]),
86        })
87    }
88
89    fn to_bytes(&self) -> Vec<u8> {
90        vec![self.rate.into(), self.level.into()]
91    }
92
93    fn data_size() -> usize { 2 }
94}
95
96/// Harmonic envelope with four segments and loop type.
97#[derive(Debug, Copy, Clone, Default)]
98pub struct Envelope {
99    pub attack: EnvelopeSegment,
100    pub decay1: EnvelopeSegment,
101    pub decay2: EnvelopeSegment,
102    pub release: EnvelopeSegment,
103    pub loop_type: Loop,
104}
105
106impl Envelope {
107    /// Creates a harmonic envelope with default values.
108    pub fn new() -> Self {
109        let zero_segment = EnvelopeSegment {
110            rate: EnvelopeRate::new(0),
111            level: HarmonicEnvelopeLevel::new(0),
112        };
113
114        Envelope {
115            attack: zero_segment,
116            decay1: zero_segment,
117            decay2: zero_segment,
118            release: zero_segment,
119            loop_type: Loop::Off,
120        }
121    }
122}
123
124impl SystemExclusiveData for Envelope {
125    fn from_bytes(data: &[u8]) -> Result<Self, ParseError> {
126        let segment0_rate = EnvelopeRate::from(data[0]);
127        let segment0_level = HarmonicEnvelopeLevel::from(data[1] & 0b0011_1111);
128        let segment1_rate = EnvelopeRate::from(data[2]);
129        let segment1_level = HarmonicEnvelopeLevel::from(data[3] & 0b0011_1111);
130        let segment1_level_bit6 = data[3].bit(6);
131        let segment2_rate = EnvelopeRate::from(data[4]);
132        let mut segment2_level_byte = data[5];
133        let segment2_level_bit6 = data[5].bit(6);
134        segment2_level_byte.set_bit(6, false);
135        let segment2_level = HarmonicEnvelopeLevel::from(segment2_level_byte & 0b0011_1111);
136        let segment3_rate = EnvelopeRate::from(data[6]);
137        let segment3_level = HarmonicEnvelopeLevel::from(data[7] & 0b0011_1111);
138
139        Ok(Envelope {
140            attack: EnvelopeSegment {
141                rate: segment0_rate,
142                level: segment0_level,
143            },
144            decay1: EnvelopeSegment {
145                rate: segment1_rate,
146                level: segment1_level,
147            },
148            decay2: EnvelopeSegment {
149                rate: segment2_rate,
150                level: segment2_level,
151            },
152            release: EnvelopeSegment {
153                rate: segment3_rate,
154                level: segment3_level,
155            },
156            loop_type: {
157                match (segment1_level_bit6, segment2_level_bit6) {
158                    (true, false) => Loop::Off,
159                    (true, true) => Loop::Loop1,
160                    (false, true) => Loop::Loop2,
161                    (false, false) => Loop::Off,
162                }
163            }
164        })
165    }
166
167    fn to_bytes(&self) -> Vec<u8> {
168        let mut result: Vec<u8> = Vec::new();
169
170        result.extend(self.attack.to_bytes());
171
172        // When emitting decay1 and decay2 data,
173        // we need to bake the loop type into the levels.
174
175        let mut decay1_level_byte: u8 = self.decay1.level.into();
176        let mut decay2_level_byte: u8 = self.decay2.level.into();
177
178        match self.loop_type {
179            Loop::Loop1 => {
180                decay1_level_byte.set_bit(6, true);
181                decay2_level_byte.set_bit(6, true);
182            },
183            Loop::Loop2 => {
184                decay1_level_byte.set_bit(6, false);
185                decay2_level_byte.set_bit(6, true);
186            },
187            Loop::Off => {
188                decay1_level_byte.set_bit(6, false);
189                decay2_level_byte.set_bit(6, false);
190            }
191        }
192
193        let mut decay1_data = self.decay1.to_bytes();
194        decay1_data[1] = decay1_level_byte;
195        result.extend(decay1_data);
196
197        let mut decay2_data = self.decay2.to_bytes();
198        decay2_data[1] = decay2_level_byte;
199        result.extend(decay2_data);
200
201        result.extend(self.release.to_bytes());
202
203        result
204    }
205
206    fn data_size() -> usize { 8 }
207}