1use alloc::vec::Vec;
2use serde::{Deserialize, Serialize};
3
4#[derive(Default, Serialize, Deserialize, Copy, Clone, Debug)]
6pub struct EnvelopePoint {
7 pub frame: usize,
9 pub value: f32,
11}
12
13impl EnvelopePoint {
14 pub fn lerp(a: &EnvelopePoint, b: &EnvelopePoint, pos: usize) -> f32 {
16 if pos <= a.frame {
17 return a.value;
18 } else if pos >= b.frame {
19 return b.value;
20 } else {
21 let p: f32 = (pos - a.frame) as f32 / (b.frame - a.frame) as f32;
22 return a.value * (1.0 - p) + b.value * p;
23 }
24 }
25}
26
27#[derive(Default, Serialize, Deserialize, Clone, Debug)]
29pub struct Envelope {
30 pub enabled: bool,
31
32 pub point: Vec<EnvelopePoint>,
33
34 pub sustain_enabled: bool,
35 pub sustain_start_point: usize,
37 pub sustain_end_point: usize,
39
40 pub loop_enabled: bool,
41 pub loop_start_point: usize,
43 pub loop_end_point: usize,
45}
46
47impl Envelope {
48 pub fn loop_in_sustain(&self, frame: usize) -> usize {
49 if self.sustain_enabled {
50 let sustain_end = self.point[self.sustain_end_point].frame;
51 if frame > sustain_end {
52 return self.point[self.sustain_start_point].frame;
53 }
54 }
55 frame
56 }
57
58 pub fn loop_in_loop(&self, frame: usize) -> usize {
59 if self.loop_enabled {
60 let loop_end = self.point[self.loop_end_point].frame;
61 if frame > loop_end {
62 return self.point[self.loop_start_point].frame;
63 }
64 }
65 frame
66 }
67
68}