Skip to main content

truce_core/
events.rs

1/// A timestamped event within a process block.
2#[derive(Clone, Debug)]
3pub struct Event {
4    /// Sample offset within the block (0..num_samples).
5    pub sample_offset: u32,
6    pub body: EventBody,
7}
8
9#[derive(Clone, Debug)]
10pub enum EventBody {
11    // -- MIDI 1.0 (normalized float values) --
12    NoteOn {
13        channel: u8,
14        note: u8,
15        velocity: f32,
16    },
17    NoteOff {
18        channel: u8,
19        note: u8,
20        velocity: f32,
21    },
22    Aftertouch {
23        channel: u8,
24        note: u8,
25        pressure: f32,
26    },
27    ChannelPressure {
28        channel: u8,
29        pressure: f32,
30    },
31    ControlChange {
32        channel: u8,
33        cc: u8,
34        value: f32,
35    },
36    PitchBend {
37        channel: u8,
38        value: f32,
39    },
40    ProgramChange {
41        channel: u8,
42        program: u8,
43    },
44
45    // -- MIDI 2.0 (high-resolution) --
46    NoteOn2 {
47        group: u8,
48        channel: u8,
49        note: u8,
50        velocity: u16,
51        attribute_type: u8,
52        attribute: u16,
53    },
54    NoteOff2 {
55        group: u8,
56        channel: u8,
57        note: u8,
58        velocity: u16,
59        attribute_type: u8,
60        attribute: u16,
61    },
62    PerNoteCC {
63        channel: u8,
64        note: u8,
65        cc: u8,
66        value: u32,
67    },
68    PerNotePitchBend {
69        channel: u8,
70        note: u8,
71        value: u32,
72    },
73    PerNoteManagement {
74        channel: u8,
75        note: u8,
76        flags: u8,
77    },
78    PolyPressure2 {
79        channel: u8,
80        note: u8,
81        pressure: u32,
82    },
83
84    // -- Automation --
85    ParamChange {
86        id: u32,
87        value: f64,
88    },
89
90    /// Parameter modulation offset (CLAP-specific, zero on other formats).
91    /// The effective value is base + mod. The base value is unchanged.
92    ParamMod {
93        id: u32,
94        note_id: i32,
95        value: f64,
96    },
97
98    // -- Transport --
99    Transport(TransportInfo),
100}
101
102#[derive(Clone, Debug, Default)]
103pub struct TransportInfo {
104    pub playing: bool,
105    pub recording: bool,
106    pub tempo: f64,
107    pub time_sig_num: u8,
108    pub time_sig_den: u8,
109    pub position_samples: i64,
110    pub position_seconds: f64,
111    pub position_beats: f64,
112    pub bar_start_beats: f64,
113    pub loop_active: bool,
114    pub loop_start_beats: f64,
115    pub loop_end_beats: f64,
116}
117
118/// Ordered list of events within a process block.
119#[derive(Clone, Debug, Default)]
120pub struct EventList {
121    events: Vec<Event>,
122}
123
124impl EventList {
125    pub fn new() -> Self {
126        Self { events: Vec::new() }
127    }
128
129    pub fn push(&mut self, event: Event) {
130        self.events.push(event);
131    }
132
133    pub fn clear(&mut self) {
134        self.events.clear();
135    }
136
137    pub fn sort(&mut self) {
138        self.events.sort_by_key(|e| e.sample_offset);
139    }
140
141    pub fn iter(&self) -> impl Iterator<Item = &Event> {
142        self.events.iter()
143    }
144
145    pub fn get(&self, index: usize) -> Option<&Event> {
146        self.events.get(index)
147    }
148
149    pub fn len(&self) -> usize {
150        self.events.len()
151    }
152
153    pub fn is_empty(&self) -> bool {
154        self.events.is_empty()
155    }
156}